]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexCLW.cxx
don't modify the output variable if ToXXX() fails to convert (modified patch 1849041)
[wxWidgets.git] / src / stc / scintilla / src / LexCLW.cxx
1 // Scintilla source code edit control
2 /** @file LexClw.cxx
3 ** Lexer for Clarion.
4 ** 2004/12/17 Updated Lexer
5 **/
6 // Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
7 // The License.txt file describes the conditions under which this software may be distributed.
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <stdarg.h>
13 #include <ctype.h>
14
15 #include "Platform.h"
16
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "StyleContext.h"
20 #include "KeyWords.h"
21 #include "Scintilla.h"
22 #include "SciLexer.h"
23
24 // Is an end of line character
25 inline bool IsEOL(const int ch) {
26
27 return(ch == '\n');
28 }
29
30 // Convert character to uppercase
31 static char CharacterUpper(char chChar) {
32
33 if (chChar < 'a' || chChar > 'z') {
34 return(chChar);
35 }
36 else {
37 return(static_cast<char>(chChar - 'a' + 'A'));
38 }
39 }
40
41 // Convert string to uppercase
42 static void StringUpper(char *szString) {
43
44 while (*szString) {
45 *szString = CharacterUpper(*szString);
46 szString++;
47 }
48 }
49
50 // Is a label start character
51 inline bool IsALabelStart(const int iChar) {
52
53 return(isalpha(iChar) || iChar == '_');
54 }
55
56 // Is a label character
57 inline bool IsALabelCharacter(const int iChar) {
58
59 return(isalnum(iChar) || iChar == '_' || iChar == ':');
60 }
61
62 // Is the character is a ! and the the next character is not a !
63 inline bool IsACommentStart(const int iChar) {
64
65 return(iChar == '!');
66 }
67
68 // Is the character a Clarion hex character (ABCDEF)
69 inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
70
71 // Case insensitive.
72 if (!bCaseSensitive) {
73 if (strchr("ABCDEFabcdef", iChar) != NULL) {
74 return(true);
75 }
76 }
77 // Case sensitive
78 else {
79 if (strchr("ABCDEF", iChar) != NULL) {
80 return(true);
81 }
82 }
83 return(false);
84 }
85
86 // Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
87 inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
88
89 // Case insensitive.
90 if (!bCaseSensitive) {
91 // If character is a numeric base character
92 if (strchr("BOHboh", iChar) != NULL) {
93 return(true);
94 }
95 }
96 // Case sensitive
97 else {
98 // If character is a numeric base character
99 if (strchr("BOH", iChar) != NULL) {
100 return(true);
101 }
102 }
103 return(false);
104 }
105
106 // Set the correct numeric constant state
107 inline bool SetNumericConstantState(StyleContext &scDoc) {
108
109 int iPoints = 0; // Point counter
110 char cNumericString[512]; // Numeric string buffer
111
112 // Buffer the current numberic string
113 scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
114 // Loop through the string until end of string (NULL termination)
115 for (int iIndex = 0; cNumericString[iIndex] != '\0'; iIndex++) {
116 // Depending on the character
117 switch (cNumericString[iIndex]) {
118 // Is a . (point)
119 case '.' :
120 // Increment point counter
121 iPoints++;
122 break;
123 default :
124 break;
125 }
126 }
127 // If points found (can be more than one for improper formatted number
128 if (iPoints > 0) {
129 return(true);
130 }
131 // Else no points found
132 else {
133 return(false);
134 }
135 }
136
137 // Get the next word in uppercase from the current position (keyword lookahead)
138 inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) {
139
140 unsigned int iIndex = 0; // Buffer Index
141
142 // Loop through the remaining string from the current position
143 for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) {
144 // Get the character from the buffer using the offset
145 char cCharacter = styler[iOffset];
146 if (IsEOL(cCharacter)) {
147 break;
148 }
149 // If the character is alphabet character
150 if (isalpha(cCharacter)) {
151 // Add UPPERCASE character to the word buffer
152 cWord[iIndex++] = CharacterUpper(cCharacter);
153 }
154 }
155 // Add null termination
156 cWord[iIndex] = '\0';
157 // If no word was found
158 if (iIndex == 0) {
159 // Return failure
160 return(false);
161 }
162 // Else word was found
163 else {
164 // Return success
165 return(true);
166 }
167 }
168
169 // Clarion Language Colouring Procedure
170 static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
171
172 int iParenthesesLevel = 0; // Parenthese Level
173 int iColumn1Label = false; // Label starts in Column 1
174
175 WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
176 WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
177 WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions
178 WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions
179 WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types
180 WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes
181 WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates
182 WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
183 WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
184
185 const char wlProcReservedKeywordList[] =
186 "PROCEDURE FUNCTION";
187 WordList wlProcReservedKeywords;
188 wlProcReservedKeywords.Set(wlProcReservedKeywordList);
189
190 const char wlCompilerKeywordList[] =
191 "COMPILE OMIT";
192 WordList wlCompilerKeywords;
193 wlCompilerKeywords.Set(wlCompilerKeywordList);
194
195 const char wlLegacyStatementsList[] =
196 "BOF EOF FUNCTION POINTER SHARE";
197 WordList wlLegacyStatements;
198 wlLegacyStatements.Set(wlLegacyStatementsList);
199
200 StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
201
202 // lex source code
203 for (; scDoc.More(); scDoc.Forward())
204 {
205 //
206 // Determine if the current state should terminate.
207 //
208
209 // Label State Handling
210 if (scDoc.state == SCE_CLW_LABEL) {
211 // If the character is not a valid label
212 if (!IsALabelCharacter(scDoc.ch)) {
213 // If the character is a . (dot syntax)
214 if (scDoc.ch == '.') {
215 // Turn off column 1 label flag as label now cannot be reserved work
216 iColumn1Label = false;
217 // Uncolour the . (dot) to default state, move forward one character,
218 // and change back to the label state.
219 scDoc.SetState(SCE_CLW_DEFAULT);
220 scDoc.Forward();
221 scDoc.SetState(SCE_CLW_LABEL);
222 }
223 // Else check label
224 else {
225 char cLabel[512]; // Label buffer
226 // Buffer the current label string
227 scDoc.GetCurrent(cLabel,sizeof(cLabel));
228 // If case insensitive, convert string to UPPERCASE to match passed keywords.
229 if (!bCaseSensitive) {
230 StringUpper(cLabel);
231 }
232 // Else if UPPERCASE label string is in the Clarion compiler keyword list
233 if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
234 // change the label to error state
235 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
236 }
237 // Else if UPPERCASE label string is in the Clarion reserved keyword list
238 else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
239 // change the label to error state
240 scDoc.ChangeState(SCE_CLW_ERROR);
241 }
242 // Else if UPPERCASE label string is
243 else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
244 char cWord[512]; // Word buffer
245 // Get the next word from the current position
246 if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
247 // If the next word is a procedure reserved word
248 if (wlProcReservedKeywords.InList(cWord)) {
249 // Change the label to error state
250 scDoc.ChangeState(SCE_CLW_ERROR);
251 }
252 }
253 }
254 // Else if label string is in the compiler directive keyword list
255 else if (wlCompilerDirectives.InList(cLabel)) {
256 // change the state to compiler directive state
257 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
258 }
259 // Terminate the label state and set to default state
260 scDoc.SetState(SCE_CLW_DEFAULT);
261 }
262 }
263 }
264 // Keyword State Handling
265 else if (scDoc.state == SCE_CLW_KEYWORD) {
266 // If character is : (colon)
267 if (scDoc.ch == ':') {
268 char cEquate[512]; // Equate buffer
269 // Move forward to include : (colon) in buffer
270 scDoc.Forward();
271 // Buffer the equate string
272 scDoc.GetCurrent(cEquate,sizeof(cEquate));
273 // If case insensitive, convert string to UPPERCASE to match passed keywords.
274 if (!bCaseSensitive) {
275 StringUpper(cEquate);
276 }
277 // If statement string is in the equate list
278 if (wlStandardEquates.InList(cEquate)) {
279 // Change to equate state
280 scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
281 }
282 }
283 // If the character is not a valid label character
284 else if (!IsALabelCharacter(scDoc.ch)) {
285 char cStatement[512]; // Statement buffer
286 // Buffer the statement string
287 scDoc.GetCurrent(cStatement,sizeof(cStatement));
288 // If case insensitive, convert string to UPPERCASE to match passed keywords.
289 if (!bCaseSensitive) {
290 StringUpper(cStatement);
291 }
292 // If statement string is in the Clarion keyword list
293 if (wlClarionKeywords.InList(cStatement)) {
294 // Change the statement string to the Clarion keyword state
295 scDoc.ChangeState(SCE_CLW_KEYWORD);
296 }
297 // Else if statement string is in the compiler directive keyword list
298 else if (wlCompilerDirectives.InList(cStatement)) {
299 // Change the statement string to the compiler directive state
300 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
301 }
302 // Else if statement string is in the runtime expressions keyword list
303 else if (wlRuntimeExpressions.InList(cStatement)) {
304 // Change the statement string to the runtime expressions state
305 scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
306 }
307 // Else if statement string is in the builtin procedures and functions keyword list
308 else if (wlBuiltInProcsFuncs.InList(cStatement)) {
309 // Change the statement string to the builtin procedures and functions state
310 scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
311 }
312 // Else if statement string is in the tructures and data types keyword list
313 else if (wlStructsDataTypes.InList(cStatement)) {
314 // Change the statement string to the structures and data types state
315 scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
316 }
317 // Else if statement string is in the procedure attribute keyword list
318 else if (wlAttributes.InList(cStatement)) {
319 // Change the statement string to the procedure attribute state
320 scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
321 }
322 // Else if statement string is in the standard equate keyword list
323 else if (wlStandardEquates.InList(cStatement)) {
324 // Change the statement string to the standard equate state
325 scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
326 }
327 // Else if statement string is in the deprecated or legacy keyword list
328 else if (wlLegacyStatements.InList(cStatement)) {
329 // Change the statement string to the standard equate state
330 scDoc.ChangeState(SCE_CLW_DEPRECATED);
331 }
332 // Else the statement string doesn't match any work list
333 else {
334 // Change the statement string to the default state
335 scDoc.ChangeState(SCE_CLW_DEFAULT);
336 }
337 // Terminate the keyword state and set to default state
338 scDoc.SetState(SCE_CLW_DEFAULT);
339 }
340 }
341 // String State Handling
342 else if (scDoc.state == SCE_CLW_STRING) {
343 // If the character is an ' (single quote)
344 if (scDoc.ch == '\'') {
345 // Set the state to default and move forward colouring
346 // the ' (single quote) as default state
347 // terminating the string state
348 scDoc.SetState(SCE_CLW_DEFAULT);
349 scDoc.Forward();
350 }
351 // If the next character is an ' (single quote)
352 if (scDoc.chNext == '\'') {
353 // Move forward one character and set to default state
354 // colouring the next ' (single quote) as default state
355 // terminating the string state
356 scDoc.ForwardSetState(SCE_CLW_DEFAULT);
357 scDoc.Forward();
358 }
359 }
360 // Picture String State Handling
361 else if (scDoc.state == SCE_CLW_PICTURE_STRING) {
362 // If the character is an ( (open parenthese)
363 if (scDoc.ch == '(') {
364 // Increment the parenthese level
365 iParenthesesLevel++;
366 }
367 // Else if the character is a ) (close parenthese)
368 else if (scDoc.ch == ')') {
369 // If the parenthese level is set to zero
370 // parentheses matched
371 if (!iParenthesesLevel) {
372 scDoc.SetState(SCE_CLW_DEFAULT);
373 }
374 // Else parenthese level is greater than zero
375 // still looking for matching parentheses
376 else {
377 // Decrement the parenthese level
378 iParenthesesLevel--;
379 }
380 }
381 }
382 // Standard Equate State Handling
383 else if (scDoc.state == SCE_CLW_STANDARD_EQUATE) {
384 if (!isalnum(scDoc.ch)) {
385 scDoc.SetState(SCE_CLW_DEFAULT);
386 }
387 }
388 // Integer Constant State Handling
389 else if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) {
390 // If the character is not a digit (0-9)
391 // or character is not a hexidecimal character (A-F)
392 // or character is not a . (point)
393 // or character is not a numberic base character (B,O,H)
394 if (!(isdigit(scDoc.ch)
395 || IsAHexCharacter(scDoc.ch, bCaseSensitive)
396 || scDoc.ch == '.'
397 || IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
398 // If the number was a real
399 if (SetNumericConstantState(scDoc)) {
400 // Colour the matched string to the real constant state
401 scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
402 }
403 // Else the number was an integer
404 else {
405 // Colour the matched string to an integer constant state
406 scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);
407 }
408 // Terminate the integer constant state and set to default state
409 scDoc.SetState(SCE_CLW_DEFAULT);
410 }
411 }
412
413 //
414 // Determine if a new state should be entered.
415 //
416
417 // Beginning of Line Handling
418 if (scDoc.atLineStart) {
419 // Reset the column 1 label flag
420 iColumn1Label = false;
421 // If column 1 character is a label start character
422 if (IsALabelStart(scDoc.ch)) {
423 // Label character is found in column 1
424 // so set column 1 label flag and clear last column 1 label
425 iColumn1Label = true;
426 // Set the state to label
427 scDoc.SetState(SCE_CLW_LABEL);
428 }
429 // else if character is a space or tab
430 else if (IsASpace(scDoc.ch)){
431 // Set to default state
432 scDoc.SetState(SCE_CLW_DEFAULT);
433 }
434 // else if comment start (!) or is an * (asterisk)
435 else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
436 // then set the state to comment.
437 scDoc.SetState(SCE_CLW_COMMENT);
438 }
439 // else the character is a ? (question mark)
440 else if (scDoc.ch == '?') {
441 // Change to the compiler directive state, move forward,
442 // colouring the ? (question mark), change back to default state.
443 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
444 scDoc.Forward();
445 scDoc.SetState(SCE_CLW_DEFAULT);
446 }
447 // else an invalid character in column 1
448 else {
449 // Set to error state
450 scDoc.SetState(SCE_CLW_ERROR);
451 }
452 }
453 // End of Line Handling
454 else if (scDoc.atLineEnd) {
455 // Reset to the default state at the end of each line.
456 scDoc.SetState(SCE_CLW_DEFAULT);
457 }
458 // Default Handling
459 else {
460 // If in default state
461 if (scDoc.state == SCE_CLW_DEFAULT) {
462 // If is a letter could be a possible statement
463 if (isalpha(scDoc.ch)) {
464 // Set the state to Clarion Keyword and verify later
465 scDoc.SetState(SCE_CLW_KEYWORD);
466 }
467 // else is a number
468 else if (isdigit(scDoc.ch)) {
469 // Set the state to Integer Constant and verify later
470 scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
471 }
472 // else if the start of a comment or a | (line continuation)
473 else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
474 // then set the state to comment.
475 scDoc.SetState(SCE_CLW_COMMENT);
476 }
477 // else if the character is a ' (single quote)
478 else if (scDoc.ch == '\'') {
479 // If the character is also a ' (single quote)
480 // Embedded Apostrophe
481 if (scDoc.chNext == '\'') {
482 // Move forward colouring it as default state
483 scDoc.ForwardSetState(SCE_CLW_DEFAULT);
484 }
485 else {
486 // move to the next character and then set the state to comment.
487 scDoc.ForwardSetState(SCE_CLW_STRING);
488 }
489 }
490 // else the character is an @ (ampersand)
491 else if (scDoc.ch == '@') {
492 // Case insensitive.
493 if (!bCaseSensitive) {
494 // If character is a valid picture token character
495 if (strchr("DEKNPSTdeknpst", scDoc.chNext) != NULL) {
496 // Set to the picture string state
497 scDoc.SetState(SCE_CLW_PICTURE_STRING);
498 }
499 }
500 // Case sensitive
501 else {
502 // If character is a valid picture token character
503 if (strchr("DEKNPST", scDoc.chNext) != NULL) {
504 // Set the picture string state
505 scDoc.SetState(SCE_CLW_PICTURE_STRING);
506 }
507 }
508 }
509 }
510 }
511 }
512 // lexing complete
513 scDoc.Complete();
514 }
515
516 // Clarion Language Case Sensitive Colouring Procedure
517 static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
518
519 ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
520 }
521
522 // Clarion Language Case Insensitive Colouring Procedure
523 static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
524
525 ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
526 }
527
528 // Fill Buffer
529
530 static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {
531
532 unsigned int uiPos = 0;
533
534 while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
535 szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
536 uiPos++;
537 }
538 szBuffer[uiPos] = '\0';
539 }
540
541 // Classify Clarion Fold Point
542
543 static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
544
545 if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
546 if (strcmp(szString, "PROCEDURE") == 0) {
547 // iLevel = SC_FOLDLEVELBASE + 1;
548 }
549 else if (strcmp(szString, "MAP") == 0 ||
550 strcmp(szString,"ACCEPT") == 0 ||
551 strcmp(szString,"BEGIN") == 0 ||
552 strcmp(szString,"CASE") == 0 ||
553 strcmp(szString,"EXECUTE") == 0 ||
554 strcmp(szString,"IF") == 0 ||
555 strcmp(szString,"ITEMIZE") == 0 ||
556 strcmp(szString,"INTERFACE") == 0 ||
557 strcmp(szString,"JOIN") == 0 ||
558 strcmp(szString,"LOOP") == 0 ||
559 strcmp(szString,"MODULE") == 0 ||
560 strcmp(szString,"RECORD") == 0) {
561 iLevel++;
562 }
563 else if (strcmp(szString, "APPLICATION") == 0 ||
564 strcmp(szString, "CLASS") == 0 ||
565 strcmp(szString, "DETAIL") == 0 ||
566 strcmp(szString, "FILE") == 0 ||
567 strcmp(szString, "FOOTER") == 0 ||
568 strcmp(szString, "FORM") == 0 ||
569 strcmp(szString, "GROUP") == 0 ||
570 strcmp(szString, "HEADER") == 0 ||
571 strcmp(szString, "INTERFACE") == 0 ||
572 strcmp(szString, "MENU") == 0 ||
573 strcmp(szString, "MENUBAR") == 0 ||
574 strcmp(szString, "OLE") == 0 ||
575 strcmp(szString, "OPTION") == 0 ||
576 strcmp(szString, "QUEUE") == 0 ||
577 strcmp(szString, "REPORT") == 0 ||
578 strcmp(szString, "SHEET") == 0 ||
579 strcmp(szString, "TAB") == 0 ||
580 strcmp(szString, "TOOLBAR") == 0 ||
581 strcmp(szString, "VIEW") == 0 ||
582 strcmp(szString, "WINDOW") == 0) {
583 iLevel++;
584 }
585 else if (strcmp(szString, "END") == 0 ||
586 strcmp(szString, "UNTIL") == 0 ||
587 strcmp(szString, "WHILE") == 0) {
588 iLevel--;
589 }
590 }
591 return(iLevel);
592 }
593
594 // Clarion Language Folding Procedure
595 static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
596
597 unsigned int uiEndPos = uiStartPos + iLength;
598 int iLineCurrent = accStyler.GetLine(uiStartPos);
599 int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
600 int iLevelCurrent = iLevelPrev;
601 char chNext = accStyler[uiStartPos];
602 int iStyle = iInitStyle;
603 int iStyleNext = accStyler.StyleAt(uiStartPos);
604 int iVisibleChars = 0;
605 int iLastStart = 0;
606
607 for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
608
609 char chChar = chNext;
610 chNext = accStyler.SafeGetCharAt(uiPos + 1);
611 int iStylePrev = iStyle;
612 iStyle = iStyleNext;
613 iStyleNext = accStyler.StyleAt(uiPos + 1);
614 bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
615
616 if (iStylePrev == SCE_CLW_DEFAULT) {
617 if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
618 // Store last word start point.
619 iLastStart = uiPos;
620 }
621 }
622
623 if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
624 if(iswordchar(chChar) && !iswordchar(chNext)) {
625 char chBuffer[100];
626 FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
627 iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
628 // if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
629 // accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
630 // iLevelPrev = SC_FOLDLEVELBASE;
631 // }
632 }
633 }
634
635 if (bEOL) {
636 int iLevel = iLevelPrev;
637 if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
638 iLevel |= SC_FOLDLEVELHEADERFLAG;
639 if (iLevel != accStyler.LevelAt(iLineCurrent)) {
640 accStyler.SetLevel(iLineCurrent,iLevel);
641 }
642 iLineCurrent++;
643 iLevelPrev = iLevelCurrent;
644 iVisibleChars = 0;
645 }
646
647 if (!isspacechar(chChar))
648 iVisibleChars++;
649 }
650
651 // Fill in the real level of the next line, keeping the current flags
652 // as they will be filled in later.
653 int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
654 accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
655 }
656
657 // Word List Descriptions
658 static const char * const rgWordListDescriptions[] = {
659 "Clarion Keywords",
660 "Compiler Directives",
661 "Built-in Procedures and Functions",
662 "Runtime Expressions",
663 "Structure and Data Types",
664 "Attributes",
665 "Standard Equates",
666 "Reserved Words (Labels)",
667 "Reserved Words (Procedure Labels)",
668 0,
669 };
670
671 // Case Sensitive Clarion Language Lexer
672 LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
673
674 // Case Insensitive Clarion Language Lexer
675 LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);