]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/KeyWords.cxx
5e4de668d04ebf747f196811cb546349a290aa34
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 #include "Scintilla.h"
23 using namespace Scintilla
;
27 * Creates an array that points into each word in the string and puts \0 terminators
30 static char **ArrayFromWordList(char *wordlist
, int *len
, bool onlyLineEnds
= false) {
33 // For rapid determination of whether a character is a separator, build
35 bool wordSeparator
[256];
36 for (int i
=0;i
<256; i
++) {
37 wordSeparator
[i
] = false;
39 wordSeparator
['\r'] = true;
40 wordSeparator
['\n'] = true;
42 wordSeparator
[' '] = true;
43 wordSeparator
['\t'] = true;
45 for (int j
= 0; wordlist
[j
]; j
++) {
46 int curr
= static_cast<unsigned char>(wordlist
[j
]);
47 if (!wordSeparator
[curr
] && wordSeparator
[prev
])
51 char **keywords
= new char *[words
+ 1];
55 size_t slen
= strlen(wordlist
);
56 for (size_t k
= 0; k
< slen
; k
++) {
57 if (!wordSeparator
[static_cast<unsigned char>(wordlist
[k
])]) {
59 keywords
[words
] = &wordlist
[k
];
67 keywords
[words
] = &wordlist
[slen
];
75 void WordList::Clear() {
86 void WordList::Set(const char *s
) {
87 list
= new char[strlen(s
) + 1];
90 words
= ArrayFromWordList(list
, &len
, onlyLineEnds
);
93 extern "C" int cmpString(const void *a1
, const void *a2
) {
94 // Can't work out the correct incantation to use modern casts here
95 return strcmp(*(char**)(a1
), *(char**)(a2
));
98 static void SortWordList(char **words
, unsigned int len
) {
99 qsort(reinterpret_cast<void*>(words
), len
, sizeof(*words
),
103 bool WordList::InList(const char *s
) {
108 SortWordList(words
, len
);
109 for (unsigned int k
= 0; k
< (sizeof(starts
) / sizeof(starts
[0])); k
++)
111 for (int l
= len
- 1; l
>= 0; l
--) {
112 unsigned char indexChar
= words
[l
][0];
113 starts
[indexChar
] = l
;
116 unsigned char firstChar
= s
[0];
117 int j
= starts
[firstChar
];
119 while ((unsigned char)words
[j
][0] == firstChar
) {
120 if (s
[1] == words
[j
][1]) {
121 const char *a
= words
[j
] + 1;
122 const char *b
= s
+ 1;
123 while (*a
&& *a
== *b
) {
135 while (words
[j
][0] == '^') {
136 const char *a
= words
[j
] + 1;
138 while (*a
&& *a
== *b
) {
150 /** similar to InList, but word s can be a substring of keyword.
151 * eg. the keyword define is defined as def~ine. This means the word must start
152 * with def to be a keyword, but also defi, defin and define are valid.
153 * The marker is ~ in this case.
155 bool WordList::InListAbbreviated(const char *s
, const char marker
) {
160 SortWordList(words
, len
);
161 for (unsigned int k
= 0; k
< (sizeof(starts
) / sizeof(starts
[0])); k
++)
163 for (int l
= len
- 1; l
>= 0; l
--) {
164 unsigned char indexChar
= words
[l
][0];
165 starts
[indexChar
] = l
;
168 unsigned char firstChar
= s
[0];
169 int j
= starts
[firstChar
];
171 while (words
[j
][0] == firstChar
) {
172 bool isSubword
= false;
174 if (words
[j
][1] == marker
) {
178 if (s
[1] == words
[j
][start
]) {
179 const char *a
= words
[j
] + start
;
180 const char *b
= s
+ 1;
181 while (*a
&& *a
== *b
) {
189 if ((!*a
|| isSubword
) && !*b
)
197 while (words
[j
][0] == '^') {
198 const char *a
= words
[j
] + 1;
200 while (*a
&& *a
== *b
) {
212 const LexerModule
*LexerModule::base
= 0;
213 int LexerModule::nextLanguage
= SCLEX_AUTOMATIC
+1;
215 LexerModule::LexerModule(int language_
,
216 LexerFunction fnLexer_
,
217 const char *languageName_
,
218 LexerFunction fnFolder_
,
219 const char * const wordListDescriptions_
[],
224 wordListDescriptions(wordListDescriptions_
),
225 styleBits(styleBits_
),
226 languageName(languageName_
) {
229 if (language
== SCLEX_AUTOMATIC
) {
230 language
= nextLanguage
;
235 int LexerModule::GetNumWordLists() const {
236 if (wordListDescriptions
== NULL
) {
239 int numWordLists
= 0;
241 while (wordListDescriptions
[numWordLists
]) {
249 const char *LexerModule::GetWordListDescription(int index
) const {
250 static const char *emptyStr
= "";
252 PLATFORM_ASSERT(index
< GetNumWordLists());
253 if (index
>= GetNumWordLists()) {
256 return wordListDescriptions
[index
];
260 int LexerModule::GetStyleBitsNeeded() const {
264 const LexerModule
*LexerModule::Find(int language
) {
265 const LexerModule
*lm
= base
;
267 if (lm
->language
== language
) {
275 const LexerModule
*LexerModule::Find(const char *languageName
) {
277 const LexerModule
*lm
= base
;
279 if (lm
->languageName
&& 0 == strcmp(lm
->languageName
, languageName
)) {
288 void LexerModule::Lex(unsigned int startPos
, int lengthDoc
, int initStyle
,
289 WordList
*keywordlists
[], Accessor
&styler
) const {
291 fnLexer(startPos
, lengthDoc
, initStyle
, keywordlists
, styler
);
294 void LexerModule::Fold(unsigned int startPos
, int lengthDoc
, int initStyle
,
295 WordList
*keywordlists
[], Accessor
&styler
) const {
297 int lineCurrent
= styler
.GetLine(startPos
);
298 // Move back one line in case deletion wrecked current line fold state
299 if (lineCurrent
> 0) {
301 int newStartPos
= styler
.LineStart(lineCurrent
);
302 lengthDoc
+= startPos
- newStartPos
;
303 startPos
= newStartPos
;
306 initStyle
= styler
.StyleAt(startPos
- 1);
309 fnFolder(startPos
, lengthDoc
, initStyle
, keywordlists
, styler
);
313 // Alternative historical name for Scintilla_LinkLexers
314 int wxForceScintillaLexers(void) {
315 return Scintilla_LinkLexers();
318 // To add or remove a lexer, add or remove its file and run LexGen.py.
320 // Force a reference to all of the Scintilla lexers so that the linker will
321 // not remove the code of the lexers.
322 int Scintilla_LinkLexers() {
323 static int forcer
= 0;
325 // Shorten the code that declares a lexer and ensures it is linked in by calling a method.
326 #define LINK_LEXER(lexer) extern LexerModule lexer; forcer += lexer.GetLanguage();
328 //++Autogenerated -- run src/LexGen.py to regenerate
329 //**\(\tLINK_LEXER(\*);\n\)
330 LINK_LEXER(lmAbaqus
);
341 LINK_LEXER(lmBlitzBasic
);
342 LINK_LEXER(lmBullant
);
345 LINK_LEXER(lmClwNoCase
);
350 LINK_LEXER(lmCPPNoCase
);
351 LINK_LEXER(lmCsound
);
355 LINK_LEXER(lmEiffel
);
356 LINK_LEXER(lmEiffelkw
);
357 LINK_LEXER(lmErlang
);
358 LINK_LEXER(lmErrorList
);
359 LINK_LEXER(lmESCRIPT
);
361 LINK_LEXER(lmFlagShip
);
363 LINK_LEXER(lmFortran
);
364 LINK_LEXER(lmFreeBasic
);
366 LINK_LEXER(lmGui4Cli
);
367 LINK_LEXER(lmHaskell
);
376 LINK_LEXER(lmMagikSF
);
378 LINK_LEXER(lmMarkdown
);
379 LINK_LEXER(lmMatlab
);
380 LINK_LEXER(lmMETAPOST
);
381 LINK_LEXER(lmMMIXAL
);
384 LINK_LEXER(lmNimrod
);
385 LINK_LEXER(lmNncrontab
);
388 LINK_LEXER(lmOctave
);
390 LINK_LEXER(lmPascal
);
393 LINK_LEXER(lmPHPSCRIPT
);
397 LINK_LEXER(lmPowerPro
);
398 LINK_LEXER(lmPowerShell
);
399 LINK_LEXER(lmProgress
);
402 LINK_LEXER(lmPureBasic
);
403 LINK_LEXER(lmPython
);
407 LINK_LEXER(lmScriptol
);
408 LINK_LEXER(lmSmalltalk
);
411 LINK_LEXER(lmSpecman
);
420 LINK_LEXER(lmVBScript
);
421 LINK_LEXER(lmVerilog
);
426 //--Autogenerated -- end of automatically generated section