1 // Scintilla source code edit control
\r
3 ** Lexer for Clarion.
\r
4 ** 2004/12/17 Updated Lexer
\r
6 // Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
\r
7 // The License.txt file describes the conditions under which this software may be distributed.
\r
15 #include "Platform.h"
\r
17 #include "PropSet.h"
\r
18 #include "Accessor.h"
\r
19 #include "StyleContext.h"
\r
20 #include "KeyWords.h"
\r
21 #include "Scintilla.h"
\r
22 #include "SciLexer.h"
\r
24 #ifdef SCI_NAMESPACE
\r
25 using namespace Scintilla;
\r
28 // Is an end of line character
\r
29 inline bool IsEOL(const int ch) {
\r
34 // Convert character to uppercase
\r
35 static char CharacterUpper(char chChar) {
\r
37 if (chChar < 'a' || chChar > 'z') {
\r
41 return(static_cast<char>(chChar - 'a' + 'A'));
\r
45 // Convert string to uppercase
\r
46 static void StringUpper(char *szString) {
\r
49 *szString = CharacterUpper(*szString);
\r
54 // Is a label start character
\r
55 inline bool IsALabelStart(const int iChar) {
\r
57 return(isalpha(iChar) || iChar == '_');
\r
60 // Is a label character
\r
61 inline bool IsALabelCharacter(const int iChar) {
\r
63 return(isalnum(iChar) || iChar == '_' || iChar == ':');
\r
66 // Is the character is a ! and the the next character is not a !
\r
67 inline bool IsACommentStart(const int iChar) {
\r
69 return(iChar == '!');
\r
72 // Is the character a Clarion hex character (ABCDEF)
\r
73 inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
\r
75 // Case insensitive.
\r
76 if (!bCaseSensitive) {
\r
77 if (strchr("ABCDEFabcdef", iChar) != NULL) {
\r
83 if (strchr("ABCDEF", iChar) != NULL) {
\r
90 // Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
\r
91 inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
\r
93 // Case insensitive.
\r
94 if (!bCaseSensitive) {
\r
95 // If character is a numeric base character
\r
96 if (strchr("BOHboh", iChar) != NULL) {
\r
102 // If character is a numeric base character
\r
103 if (strchr("BOH", iChar) != NULL) {
\r
110 // Set the correct numeric constant state
\r
111 inline bool SetNumericConstantState(StyleContext &scDoc) {
\r
113 int iPoints = 0; // Point counter
\r
114 char cNumericString[512]; // Numeric string buffer
\r
116 // Buffer the current numberic string
\r
117 scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
\r
118 // Loop through the string until end of string (NULL termination)
\r
119 for (int iIndex = 0; cNumericString[iIndex] != '\0'; iIndex++) {
\r
120 // Depending on the character
\r
121 switch (cNumericString[iIndex]) {
\r
124 // Increment point counter
\r
131 // If points found (can be more than one for improper formatted number
\r
135 // Else no points found
\r
141 // Get the next word in uppercase from the current position (keyword lookahead)
\r
142 inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) {
\r
144 unsigned int iIndex = 0; // Buffer Index
\r
146 // Loop through the remaining string from the current position
\r
147 for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) {
\r
148 // Get the character from the buffer using the offset
\r
149 char cCharacter = styler[iOffset];
\r
150 if (IsEOL(cCharacter)) {
\r
153 // If the character is alphabet character
\r
154 if (isalpha(cCharacter)) {
\r
155 // Add UPPERCASE character to the word buffer
\r
156 cWord[iIndex++] = CharacterUpper(cCharacter);
\r
159 // Add null termination
\r
160 cWord[iIndex] = '\0';
\r
161 // If no word was found
\r
166 // Else word was found
\r
173 // Clarion Language Colouring Procedure
\r
174 static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
\r
176 int iParenthesesLevel = 0; // Parenthese Level
\r
177 int iColumn1Label = false; // Label starts in Column 1
\r
179 WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
\r
180 WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
\r
181 WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions
\r
182 WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions
\r
183 WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types
\r
184 WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes
\r
185 WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates
\r
186 WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
\r
187 WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
\r
189 const char wlProcReservedKeywordList[] =
\r
190 "PROCEDURE FUNCTION";
\r
191 WordList wlProcReservedKeywords;
\r
192 wlProcReservedKeywords.Set(wlProcReservedKeywordList);
\r
194 const char wlCompilerKeywordList[] =
\r
196 WordList wlCompilerKeywords;
\r
197 wlCompilerKeywords.Set(wlCompilerKeywordList);
\r
199 const char wlLegacyStatementsList[] =
\r
200 "BOF EOF FUNCTION POINTER SHARE";
\r
201 WordList wlLegacyStatements;
\r
202 wlLegacyStatements.Set(wlLegacyStatementsList);
\r
204 StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
\r
207 for (; scDoc.More(); scDoc.Forward())
\r
210 // Determine if the current state should terminate.
\r
213 // Label State Handling
\r
214 if (scDoc.state == SCE_CLW_LABEL) {
\r
215 // If the character is not a valid label
\r
216 if (!IsALabelCharacter(scDoc.ch)) {
\r
217 // If the character is a . (dot syntax)
\r
218 if (scDoc.ch == '.') {
\r
219 // Turn off column 1 label flag as label now cannot be reserved work
\r
220 iColumn1Label = false;
\r
221 // Uncolour the . (dot) to default state, move forward one character,
\r
222 // and change back to the label state.
\r
223 scDoc.SetState(SCE_CLW_DEFAULT);
\r
225 scDoc.SetState(SCE_CLW_LABEL);
\r
227 // Else check label
\r
229 char cLabel[512]; // Label buffer
\r
230 // Buffer the current label string
\r
231 scDoc.GetCurrent(cLabel,sizeof(cLabel));
\r
232 // If case insensitive, convert string to UPPERCASE to match passed keywords.
\r
233 if (!bCaseSensitive) {
\r
234 StringUpper(cLabel);
\r
236 // Else if UPPERCASE label string is in the Clarion compiler keyword list
\r
237 if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
\r
238 // change the label to error state
\r
239 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
\r
241 // Else if UPPERCASE label string is in the Clarion reserved keyword list
\r
242 else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
\r
243 // change the label to error state
\r
244 scDoc.ChangeState(SCE_CLW_ERROR);
\r
246 // Else if UPPERCASE label string is
\r
247 else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
\r
248 char cWord[512]; // Word buffer
\r
249 // Get the next word from the current position
\r
250 if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
\r
251 // If the next word is a procedure reserved word
\r
252 if (wlProcReservedKeywords.InList(cWord)) {
\r
253 // Change the label to error state
\r
254 scDoc.ChangeState(SCE_CLW_ERROR);
\r
258 // Else if label string is in the compiler directive keyword list
\r
259 else if (wlCompilerDirectives.InList(cLabel)) {
\r
260 // change the state to compiler directive state
\r
261 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
\r
263 // Terminate the label state and set to default state
\r
264 scDoc.SetState(SCE_CLW_DEFAULT);
\r
268 // Keyword State Handling
\r
269 else if (scDoc.state == SCE_CLW_KEYWORD) {
\r
270 // If character is : (colon)
\r
271 if (scDoc.ch == ':') {
\r
272 char cEquate[512]; // Equate buffer
\r
273 // Move forward to include : (colon) in buffer
\r
275 // Buffer the equate string
\r
276 scDoc.GetCurrent(cEquate,sizeof(cEquate));
\r
277 // If case insensitive, convert string to UPPERCASE to match passed keywords.
\r
278 if (!bCaseSensitive) {
\r
279 StringUpper(cEquate);
\r
281 // If statement string is in the equate list
\r
282 if (wlStandardEquates.InList(cEquate)) {
\r
283 // Change to equate state
\r
284 scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
\r
287 // If the character is not a valid label character
\r
288 else if (!IsALabelCharacter(scDoc.ch)) {
\r
289 char cStatement[512]; // Statement buffer
\r
290 // Buffer the statement string
\r
291 scDoc.GetCurrent(cStatement,sizeof(cStatement));
\r
292 // If case insensitive, convert string to UPPERCASE to match passed keywords.
\r
293 if (!bCaseSensitive) {
\r
294 StringUpper(cStatement);
\r
296 // If statement string is in the Clarion keyword list
\r
297 if (wlClarionKeywords.InList(cStatement)) {
\r
298 // Change the statement string to the Clarion keyword state
\r
299 scDoc.ChangeState(SCE_CLW_KEYWORD);
\r
301 // Else if statement string is in the compiler directive keyword list
\r
302 else if (wlCompilerDirectives.InList(cStatement)) {
\r
303 // Change the statement string to the compiler directive state
\r
304 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
\r
306 // Else if statement string is in the runtime expressions keyword list
\r
307 else if (wlRuntimeExpressions.InList(cStatement)) {
\r
308 // Change the statement string to the runtime expressions state
\r
309 scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
\r
311 // Else if statement string is in the builtin procedures and functions keyword list
\r
312 else if (wlBuiltInProcsFuncs.InList(cStatement)) {
\r
313 // Change the statement string to the builtin procedures and functions state
\r
314 scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
\r
316 // Else if statement string is in the tructures and data types keyword list
\r
317 else if (wlStructsDataTypes.InList(cStatement)) {
\r
318 // Change the statement string to the structures and data types state
\r
319 scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
\r
321 // Else if statement string is in the procedure attribute keyword list
\r
322 else if (wlAttributes.InList(cStatement)) {
\r
323 // Change the statement string to the procedure attribute state
\r
324 scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
\r
326 // Else if statement string is in the standard equate keyword list
\r
327 else if (wlStandardEquates.InList(cStatement)) {
\r
328 // Change the statement string to the standard equate state
\r
329 scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
\r
331 // Else if statement string is in the deprecated or legacy keyword list
\r
332 else if (wlLegacyStatements.InList(cStatement)) {
\r
333 // Change the statement string to the standard equate state
\r
334 scDoc.ChangeState(SCE_CLW_DEPRECATED);
\r
336 // Else the statement string doesn't match any work list
\r
338 // Change the statement string to the default state
\r
339 scDoc.ChangeState(SCE_CLW_DEFAULT);
\r
341 // Terminate the keyword state and set to default state
\r
342 scDoc.SetState(SCE_CLW_DEFAULT);
\r
345 // String State Handling
\r
346 else if (scDoc.state == SCE_CLW_STRING) {
\r
347 // If the character is an ' (single quote)
\r
348 if (scDoc.ch == '\'') {
\r
349 // Set the state to default and move forward colouring
\r
350 // the ' (single quote) as default state
\r
351 // terminating the string state
\r
352 scDoc.SetState(SCE_CLW_DEFAULT);
\r
355 // If the next character is an ' (single quote)
\r
356 if (scDoc.chNext == '\'') {
\r
357 // Move forward one character and set to default state
\r
358 // colouring the next ' (single quote) as default state
\r
359 // terminating the string state
\r
360 scDoc.ForwardSetState(SCE_CLW_DEFAULT);
\r
364 // Picture String State Handling
\r
365 else if (scDoc.state == SCE_CLW_PICTURE_STRING) {
\r
366 // If the character is an ( (open parenthese)
\r
367 if (scDoc.ch == '(') {
\r
368 // Increment the parenthese level
\r
369 iParenthesesLevel++;
\r
371 // Else if the character is a ) (close parenthese)
\r
372 else if (scDoc.ch == ')') {
\r
373 // If the parenthese level is set to zero
\r
374 // parentheses matched
\r
375 if (!iParenthesesLevel) {
\r
376 scDoc.SetState(SCE_CLW_DEFAULT);
\r
378 // Else parenthese level is greater than zero
\r
379 // still looking for matching parentheses
\r
381 // Decrement the parenthese level
\r
382 iParenthesesLevel--;
\r
386 // Standard Equate State Handling
\r
387 else if (scDoc.state == SCE_CLW_STANDARD_EQUATE) {
\r
388 if (!isalnum(scDoc.ch)) {
\r
389 scDoc.SetState(SCE_CLW_DEFAULT);
\r
392 // Integer Constant State Handling
\r
393 else if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) {
\r
394 // If the character is not a digit (0-9)
\r
395 // or character is not a hexidecimal character (A-F)
\r
396 // or character is not a . (point)
\r
397 // or character is not a numberic base character (B,O,H)
\r
398 if (!(isdigit(scDoc.ch)
\r
399 || IsAHexCharacter(scDoc.ch, bCaseSensitive)
\r
401 || IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
\r
402 // If the number was a real
\r
403 if (SetNumericConstantState(scDoc)) {
\r
404 // Colour the matched string to the real constant state
\r
405 scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
\r
407 // Else the number was an integer
\r
409 // Colour the matched string to an integer constant state
\r
410 scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);
\r
412 // Terminate the integer constant state and set to default state
\r
413 scDoc.SetState(SCE_CLW_DEFAULT);
\r
418 // Determine if a new state should be entered.
\r
421 // Beginning of Line Handling
\r
422 if (scDoc.atLineStart) {
\r
423 // Reset the column 1 label flag
\r
424 iColumn1Label = false;
\r
425 // If column 1 character is a label start character
\r
426 if (IsALabelStart(scDoc.ch)) {
\r
427 // Label character is found in column 1
\r
428 // so set column 1 label flag and clear last column 1 label
\r
429 iColumn1Label = true;
\r
430 // Set the state to label
\r
431 scDoc.SetState(SCE_CLW_LABEL);
\r
433 // else if character is a space or tab
\r
434 else if (IsASpace(scDoc.ch)){
\r
435 // Set to default state
\r
436 scDoc.SetState(SCE_CLW_DEFAULT);
\r
438 // else if comment start (!) or is an * (asterisk)
\r
439 else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
\r
440 // then set the state to comment.
\r
441 scDoc.SetState(SCE_CLW_COMMENT);
\r
443 // else the character is a ? (question mark)
\r
444 else if (scDoc.ch == '?') {
\r
445 // Change to the compiler directive state, move forward,
\r
446 // colouring the ? (question mark), change back to default state.
\r
447 scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
\r
449 scDoc.SetState(SCE_CLW_DEFAULT);
\r
451 // else an invalid character in column 1
\r
453 // Set to error state
\r
454 scDoc.SetState(SCE_CLW_ERROR);
\r
457 // End of Line Handling
\r
458 else if (scDoc.atLineEnd) {
\r
459 // Reset to the default state at the end of each line.
\r
460 scDoc.SetState(SCE_CLW_DEFAULT);
\r
462 // Default Handling
\r
464 // If in default state
\r
465 if (scDoc.state == SCE_CLW_DEFAULT) {
\r
466 // If is a letter could be a possible statement
\r
467 if (isalpha(scDoc.ch)) {
\r
468 // Set the state to Clarion Keyword and verify later
\r
469 scDoc.SetState(SCE_CLW_KEYWORD);
\r
471 // else is a number
\r
472 else if (isdigit(scDoc.ch)) {
\r
473 // Set the state to Integer Constant and verify later
\r
474 scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
\r
476 // else if the start of a comment or a | (line continuation)
\r
477 else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
\r
478 // then set the state to comment.
\r
479 scDoc.SetState(SCE_CLW_COMMENT);
\r
481 // else if the character is a ' (single quote)
\r
482 else if (scDoc.ch == '\'') {
\r
483 // If the character is also a ' (single quote)
\r
484 // Embedded Apostrophe
\r
485 if (scDoc.chNext == '\'') {
\r
486 // Move forward colouring it as default state
\r
487 scDoc.ForwardSetState(SCE_CLW_DEFAULT);
\r
490 // move to the next character and then set the state to comment.
\r
491 scDoc.ForwardSetState(SCE_CLW_STRING);
\r
494 // else the character is an @ (ampersand)
\r
495 else if (scDoc.ch == '@') {
\r
496 // Case insensitive.
\r
497 if (!bCaseSensitive) {
\r
498 // If character is a valid picture token character
\r
499 if (strchr("DEKNPSTdeknpst", scDoc.chNext) != NULL) {
\r
500 // Set to the picture string state
\r
501 scDoc.SetState(SCE_CLW_PICTURE_STRING);
\r
506 // If character is a valid picture token character
\r
507 if (strchr("DEKNPST", scDoc.chNext) != NULL) {
\r
508 // Set the picture string state
\r
509 scDoc.SetState(SCE_CLW_PICTURE_STRING);
\r
520 // Clarion Language Case Sensitive Colouring Procedure
\r
521 static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
\r
523 ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
\r
526 // Clarion Language Case Insensitive Colouring Procedure
\r
527 static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
\r
529 ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
\r
534 static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {
\r
536 unsigned int uiPos = 0;
\r
538 while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
\r
539 szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
\r
542 szBuffer[uiPos] = '\0';
\r
545 // Classify Clarion Fold Point
\r
547 static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
\r
549 if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
\r
550 if (strcmp(szString, "PROCEDURE") == 0) {
\r
551 // iLevel = SC_FOLDLEVELBASE + 1;
\r
553 else if (strcmp(szString, "MAP") == 0 ||
\r
554 strcmp(szString,"ACCEPT") == 0 ||
\r
555 strcmp(szString,"BEGIN") == 0 ||
\r
556 strcmp(szString,"CASE") == 0 ||
\r
557 strcmp(szString,"EXECUTE") == 0 ||
\r
558 strcmp(szString,"IF") == 0 ||
\r
559 strcmp(szString,"ITEMIZE") == 0 ||
\r
560 strcmp(szString,"INTERFACE") == 0 ||
\r
561 strcmp(szString,"JOIN") == 0 ||
\r
562 strcmp(szString,"LOOP") == 0 ||
\r
563 strcmp(szString,"MODULE") == 0 ||
\r
564 strcmp(szString,"RECORD") == 0) {
\r
567 else if (strcmp(szString, "APPLICATION") == 0 ||
\r
568 strcmp(szString, "CLASS") == 0 ||
\r
569 strcmp(szString, "DETAIL") == 0 ||
\r
570 strcmp(szString, "FILE") == 0 ||
\r
571 strcmp(szString, "FOOTER") == 0 ||
\r
572 strcmp(szString, "FORM") == 0 ||
\r
573 strcmp(szString, "GROUP") == 0 ||
\r
574 strcmp(szString, "HEADER") == 0 ||
\r
575 strcmp(szString, "INTERFACE") == 0 ||
\r
576 strcmp(szString, "MENU") == 0 ||
\r
577 strcmp(szString, "MENUBAR") == 0 ||
\r
578 strcmp(szString, "OLE") == 0 ||
\r
579 strcmp(szString, "OPTION") == 0 ||
\r
580 strcmp(szString, "QUEUE") == 0 ||
\r
581 strcmp(szString, "REPORT") == 0 ||
\r
582 strcmp(szString, "SHEET") == 0 ||
\r
583 strcmp(szString, "TAB") == 0 ||
\r
584 strcmp(szString, "TOOLBAR") == 0 ||
\r
585 strcmp(szString, "VIEW") == 0 ||
\r
586 strcmp(szString, "WINDOW") == 0) {
\r
589 else if (strcmp(szString, "END") == 0 ||
\r
590 strcmp(szString, "UNTIL") == 0 ||
\r
591 strcmp(szString, "WHILE") == 0) {
\r
598 // Clarion Language Folding Procedure
\r
599 static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
\r
601 unsigned int uiEndPos = uiStartPos + iLength;
\r
602 int iLineCurrent = accStyler.GetLine(uiStartPos);
\r
603 int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
\r
604 int iLevelCurrent = iLevelPrev;
\r
605 char chNext = accStyler[uiStartPos];
\r
606 int iStyle = iInitStyle;
\r
607 int iStyleNext = accStyler.StyleAt(uiStartPos);
\r
608 int iVisibleChars = 0;
\r
609 int iLastStart = 0;
\r
611 for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
\r
613 char chChar = chNext;
\r
614 chNext = accStyler.SafeGetCharAt(uiPos + 1);
\r
615 int iStylePrev = iStyle;
\r
616 iStyle = iStyleNext;
\r
617 iStyleNext = accStyler.StyleAt(uiPos + 1);
\r
618 bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
\r
620 if (iStylePrev == SCE_CLW_DEFAULT) {
\r
621 if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
\r
622 // Store last word start point.
\r
623 iLastStart = uiPos;
\r
627 if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
\r
628 if(iswordchar(chChar) && !iswordchar(chNext)) {
\r
629 char chBuffer[100];
\r
630 FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
\r
631 iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
\r
632 // if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
\r
633 // accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
\r
634 // iLevelPrev = SC_FOLDLEVELBASE;
\r
640 int iLevel = iLevelPrev;
\r
641 if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
\r
642 iLevel |= SC_FOLDLEVELHEADERFLAG;
\r
643 if (iLevel != accStyler.LevelAt(iLineCurrent)) {
\r
644 accStyler.SetLevel(iLineCurrent,iLevel);
\r
647 iLevelPrev = iLevelCurrent;
\r
651 if (!isspacechar(chChar))
\r
655 // Fill in the real level of the next line, keeping the current flags
\r
656 // as they will be filled in later.
\r
657 int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
\r
658 accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
\r
661 // Word List Descriptions
\r
662 static const char * const rgWordListDescriptions[] = {
\r
663 "Clarion Keywords",
\r
664 "Compiler Directives",
\r
665 "Built-in Procedures and Functions",
\r
666 "Runtime Expressions",
\r
667 "Structure and Data Types",
\r
669 "Standard Equates",
\r
670 "Reserved Words (Labels)",
\r
671 "Reserved Words (Procedure Labels)",
\r
675 // Case Sensitive Clarion Language Lexer
\r
676 LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
\r
678 // Case Insensitive Clarion Language Lexer
\r
679 LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);
\r