diff options
| -rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
| -rw-r--r-- | lexlib/LexerBase.cxx | 5 | ||||
| -rw-r--r-- | lexlib/WordList.cxx | 38 | ||||
| -rw-r--r-- | lexlib/WordList.h | 2 | ||||
| -rw-r--r-- | test/unit/testWordList.cxx | 15 | 
5 files changed, 50 insertions, 14 deletions
| diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 72ed06c0a..30bb32a5c 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -580,6 +580,10 @@  	<a href="https://sourceforge.net/p/scintilla/feature-requests/1306/">Feature #1306</a>.  	</li>   	<li> +	Optimize setting up keyword lists in lexers. +	<a href="https://sourceforge.net/p/scintilla/feature-requests/1305/">Feature #1305</a>. +	</li> + 	<li>  	On Win32, stop the IME candidate window moving unnecessarily and position it better.<br />  	Stop candidate window overlapping composition text and taskbar.<br />  	Position candidate window closer to composition text.<br /> diff --git a/lexlib/LexerBase.cxx b/lexlib/LexerBase.cxx index f9e6292a1..ee3aa797e 100644 --- a/lexlib/LexerBase.cxx +++ b/lexlib/LexerBase.cxx @@ -75,10 +75,7 @@ const char * SCI_METHOD LexerBase::DescribeWordListSets() {  Sci_Position SCI_METHOD LexerBase::WordListSet(int n, const char *wl) {  	if (n < numWordLists) { -		WordList wlNew; -		wlNew.Set(wl); -		if (*keyWordLists[n] != wlNew) { -			keyWordLists[n]->Set(wl); +		if (keyWordLists[n]->Set(wl)) {  			return 0;  		}  	} diff --git a/lexlib/WordList.cxx b/lexlib/WordList.cxx index c8b4cd63b..937f18948 100644 --- a/lexlib/WordList.cxx +++ b/lexlib/WordList.cxx @@ -20,7 +20,7 @@ using namespace Scintilla;   * Creates an array that points into each word in the string and puts \0 terminators   * after each word.   */ -static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) { +static char **ArrayFromWordList(char *wordlist, size_t slen, int *len, bool onlyLineEnds = false) {  	int prev = '\n';  	int words = 0;  	// For rapid determination of whether a character is a separator, build @@ -40,7 +40,6 @@ static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = fa  	}  	char **keywords = new char *[words + 1];  	int wordsStore = 0; -	const size_t slen = strlen(wordlist);  	if (words) {  		prev = '\0';  		for (size_t k = 0; k < slen; k++) { @@ -117,22 +116,43 @@ static void SortWordList(char **words, unsigned int len) {  #endif -void WordList::Set(const char *s) { -	Clear(); +bool WordList::Set(const char *s) {  	const size_t lenS = strlen(s) + 1; -	list = new char[lenS]; -	memcpy(list, s, lenS); -	words = ArrayFromWordList(list, &len, onlyLineEnds); +	char *listTemp = new char[lenS]; +	memcpy(listTemp, s, lenS); +	int lenTemp = 0; +	char **wordsTemp = ArrayFromWordList(listTemp, lenS - 1, &lenTemp, onlyLineEnds);  #ifdef _MSC_VER -	std::sort(words, words + len, cmpWords); +	std::sort(wordsTemp, wordsTemp + lenTemp, cmpWords);  #else -	SortWordList(words, len); +	SortWordList(wordsTemp, lenTemp);  #endif + +	if (lenTemp == len) { +		bool changed = false; +		for (int i = 0; i < lenTemp; i++) { +			if (strcmp(words[i], wordsTemp[i]) != 0) { +				changed = true; +				break; +			} +		} +		if (!changed) { +			delete []listTemp; +			delete []wordsTemp; +			return false; +		} +	} + +	Clear(); +	words = wordsTemp; +	list = listTemp; +	len = lenTemp;  	std::fill(starts, std::end(starts), -1);  	for (int l = len - 1; l >= 0; l--) {  		unsigned char indexChar = words[l][0];  		starts[indexChar] = l;  	} +	return true;  }  /** Check whether a string is in the list. diff --git a/lexlib/WordList.h b/lexlib/WordList.h index a9f2d4ab2..c1253cec6 100644 --- a/lexlib/WordList.h +++ b/lexlib/WordList.h @@ -26,7 +26,7 @@ public:  	bool operator!=(const WordList &other) const;  	int Length() const;  	void Clear(); -	void Set(const char *s); +	bool Set(const char *s);  	bool InList(const char *s) const;  	bool InListAbbreviated(const char *s, const char marker) const;  	bool InListAbridged(const char *s, const char marker) const; diff --git a/test/unit/testWordList.cxx b/test/unit/testWordList.cxx index 4d7805d1e..3970d37d4 100644 --- a/test/unit/testWordList.cxx +++ b/test/unit/testWordList.cxx @@ -26,6 +26,21 @@ TEST_CASE("WordList") {  		REQUIRE(!wl.InList("class"));  	} +	SECTION("Set") { +		// Check whether Set returns whether it has changed correctly +		const bool changed = wl.Set("else struct"); +		REQUIRE(changed); +		// Changing to same thing +		const bool changed2 = wl.Set("else struct"); +		REQUIRE(!changed2); +		// Changed order shouldn't be seen as a change +		const bool changed3 = wl.Set("struct else"); +		REQUIRE(!changed3); +		// Removing word is a change +		const bool changed4 = wl.Set("struct"); +		REQUIRE(changed4); +	} +  	SECTION("WordAt") {  		wl.Set("else struct");  		REQUIRE(0 == strcmp(wl.WordAt(0), "else")); | 
