aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/ScintillaHistory.html4
-rw-r--r--lexlib/LexerBase.cxx5
-rw-r--r--lexlib/WordList.cxx38
-rw-r--r--lexlib/WordList.h2
-rw-r--r--test/unit/testWordList.cxx15
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"));