]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/lexlib/WordList.cxx
1 // Scintilla source code edit control
3 ** Colourise for particular languages.
5 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
19 using namespace Scintilla
;
23 * Creates an array that points into each word in the string and puts \0 terminators
26 static char **ArrayFromWordList(char *wordlist
, int *len
, bool onlyLineEnds
= false) {
29 // For rapid determination of whether a character is a separator, build
31 bool wordSeparator
[256];
32 for (int i
=0; i
<256; i
++) {
33 wordSeparator
[i
] = false;
35 wordSeparator
['\r'] = true;
36 wordSeparator
['\n'] = true;
38 wordSeparator
[' '] = true;
39 wordSeparator
['\t'] = true;
41 for (int j
= 0; wordlist
[j
]; j
++) {
42 int curr
= static_cast<unsigned char>(wordlist
[j
]);
43 if (!wordSeparator
[curr
] && wordSeparator
[prev
])
47 char **keywords
= new char *[words
+ 1];
51 size_t slen
= strlen(wordlist
);
52 for (size_t k
= 0; k
< slen
; k
++) {
53 if (!wordSeparator
[static_cast<unsigned char>(wordlist
[k
])]) {
55 keywords
[words
] = &wordlist
[k
];
63 keywords
[words
] = &wordlist
[slen
];
71 bool WordList::operator!=(const WordList
&other
) const {
74 for (int i
=0; i
<len
; i
++) {
75 if (strcmp(words
[i
], other
.words
[i
]) != 0)
81 void WordList::Clear() {
93 static bool cmpWords(const char *a
, const char *b
) {
94 return strcmp(a
, b
) == -1;
99 static int cmpWords(const void *a
, const void *b
) {
100 return strcmp(*static_cast<const char * const *>(a
), *static_cast<const char * const *>(b
));
103 static void SortWordList(char **words
, unsigned int len
) {
104 qsort(reinterpret_cast<void *>(words
), len
, sizeof(*words
), cmpWords
);
109 void WordList::Set(const char *s
) {
111 list
= new char[strlen(s
) + 1];
113 words
= ArrayFromWordList(list
, &len
, onlyLineEnds
);
115 std::sort(words
, words
+ len
, cmpWords
);
117 SortWordList(words
, len
);
119 for (unsigned int k
= 0; k
< (sizeof(starts
) / sizeof(starts
[0])); k
++)
121 for (int l
= len
- 1; l
>= 0; l
--) {
122 unsigned char indexChar
= words
[l
][0];
123 starts
[indexChar
] = l
;
127 /** Check whether a string is in the list.
128 * List elements are either exact matches or prefixes.
129 * Prefix elements start with '^' and match all strings that start with the rest of the element
130 * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'.
132 bool WordList::InList(const char *s
) const {
135 unsigned char firstChar
= s
[0];
136 int j
= starts
[firstChar
];
138 while (static_cast<unsigned char>(words
[j
][0]) == firstChar
) {
139 if (s
[1] == words
[j
][1]) {
140 const char *a
= words
[j
] + 1;
141 const char *b
= s
+ 1;
142 while (*a
&& *a
== *b
) {
154 while (words
[j
][0] == '^') {
155 const char *a
= words
[j
] + 1;
157 while (*a
&& *a
== *b
) {
169 /** similar to InList, but word s can be a substring of keyword.
170 * eg. the keyword define is defined as def~ine. This means the word must start
171 * with def to be a keyword, but also defi, defin and define are valid.
172 * The marker is ~ in this case.
174 bool WordList::InListAbbreviated(const char *s
, const char marker
) const {
177 unsigned char firstChar
= s
[0];
178 int j
= starts
[firstChar
];
180 while (static_cast<unsigned char>(words
[j
][0]) == firstChar
) {
181 bool isSubword
= false;
183 if (words
[j
][1] == marker
) {
187 if (s
[1] == words
[j
][start
]) {
188 const char *a
= words
[j
] + start
;
189 const char *b
= s
+ 1;
190 while (*a
&& *a
== *b
) {
198 if ((!*a
|| isSubword
) && !*b
)
206 while (words
[j
][0] == '^') {
207 const char *a
= words
[j
] + 1;
209 while (*a
&& *a
== *b
) {