OSDN Git Service

Enable X64 Build
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / LexCLW.cxx
1 // Scintilla source code edit control\r
2 /** @file LexClw.cxx\r
3  ** Lexer for Clarion.\r
4  ** 2004/12/17 Updated Lexer\r
5  **/\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
8 \r
9 #include <stdlib.h>\r
10 #include <string.h>\r
11 #include <stdio.h>\r
12 #include <stdarg.h>\r
13 #include <ctype.h>\r
14 \r
15 #include "Platform.h"\r
16 \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
23 \r
24 #ifdef SCI_NAMESPACE\r
25 using namespace Scintilla;\r
26 #endif\r
27 \r
28 // Is an end of line character\r
29 inline bool IsEOL(const int ch) {\r
30 \r
31         return(ch == '\n');\r
32 }\r
33 \r
34 // Convert character to uppercase\r
35 static char CharacterUpper(char chChar) {\r
36 \r
37         if (chChar < 'a' || chChar > 'z') {\r
38                 return(chChar);\r
39         }\r
40         else {\r
41                 return(static_cast<char>(chChar - 'a' + 'A'));\r
42         }\r
43 }\r
44 \r
45 // Convert string to uppercase\r
46 static void StringUpper(char *szString) {\r
47 \r
48         while (*szString) {\r
49                 *szString = CharacterUpper(*szString);\r
50                 szString++;\r
51         }\r
52 }\r
53 \r
54 // Is a label start character\r
55 inline bool IsALabelStart(const int iChar) {\r
56 \r
57         return(isalpha(iChar) || iChar == '_');\r
58 }\r
59 \r
60 // Is a label character\r
61 inline bool IsALabelCharacter(const int iChar) {\r
62 \r
63         return(isalnum(iChar) || iChar == '_' || iChar == ':'); \r
64 }\r
65 \r
66 // Is the character is a ! and the the next character is not a ! \r
67 inline bool IsACommentStart(const int iChar) {\r
68 \r
69         return(iChar == '!');\r
70 }\r
71 \r
72 // Is the character a Clarion hex character (ABCDEF)\r
73 inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {\r
74 \r
75         // Case insensitive.\r
76         if (!bCaseSensitive) {\r
77                 if (strchr("ABCDEFabcdef", iChar) != NULL) {\r
78                         return(true);\r
79                 }\r
80         }\r
81         // Case sensitive\r
82         else {\r
83                 if (strchr("ABCDEF", iChar) != NULL) {\r
84                         return(true);\r
85                 }\r
86         }\r
87         return(false);\r
88 }\r
89 \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
92 \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
97                         return(true);\r
98                 }\r
99         }\r
100         // Case sensitive\r
101         else {\r
102                 // If character is a numeric base character\r
103                 if (strchr("BOH", iChar) != NULL) {\r
104                         return(true);\r
105                 }\r
106         }\r
107         return(false);\r
108 }\r
109 \r
110 // Set the correct numeric constant state\r
111 inline bool SetNumericConstantState(StyleContext &scDoc) {\r
112 \r
113         int iPoints = 0;                        // Point counter\r
114         char cNumericString[512];       // Numeric string buffer\r
115 \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
122                         // Is a . (point)\r
123                         case '.' :\r
124                                 // Increment point counter\r
125                                 iPoints++;\r
126                                 break;\r
127                         default :\r
128                                 break;\r
129                 }       \r
130         }\r
131         // If points found (can be more than one for improper formatted number\r
132         if (iPoints > 0) {\r
133                 return(true);\r
134         }\r
135         // Else no points found\r
136         else {\r
137                 return(false);\r
138         }\r
139 }\r
140 \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
143 \r
144         unsigned int iIndex = 0;                // Buffer Index\r
145 \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
151                         break;\r
152                 }\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
157                 }\r
158         }\r
159         // Add null termination\r
160         cWord[iIndex] = '\0';\r
161         // If no word was found\r
162         if (iIndex == 0) {\r
163                 // Return failure\r
164                 return(false);\r
165         }\r
166         // Else word was found\r
167         else {\r
168                 // Return success\r
169                 return(true);\r
170         }\r
171 }\r
172 \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
175 \r
176         int iParenthesesLevel = 0;              // Parenthese Level\r
177         int iColumn1Label = false;              // Label starts in Column 1\r
178 \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
188 \r
189         const char wlProcReservedKeywordList[] = \r
190         "PROCEDURE FUNCTION";\r
191         WordList wlProcReservedKeywords;\r
192         wlProcReservedKeywords.Set(wlProcReservedKeywordList);\r
193 \r
194         const char wlCompilerKeywordList[] = \r
195         "COMPILE OMIT";\r
196         WordList wlCompilerKeywords;\r
197         wlCompilerKeywords.Set(wlCompilerKeywordList);\r
198 \r
199         const char wlLegacyStatementsList[] =\r
200         "BOF EOF FUNCTION POINTER SHARE";\r
201         WordList wlLegacyStatements;\r
202         wlLegacyStatements.Set(wlLegacyStatementsList);\r
203 \r
204         StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);\r
205 \r
206         // lex source code\r
207     for (; scDoc.More(); scDoc.Forward())\r
208         {\r
209                 //\r
210                 // Determine if the current state should terminate.\r
211                 //\r
212 \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
224                                         scDoc.Forward();\r
225                                         scDoc.SetState(SCE_CLW_LABEL);\r
226                                 }\r
227                                 // Else check label\r
228                                 else {\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
235                                         }\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
240                                         }\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
245                                         }\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
255                                                         }\r
256                                                 }\r
257                                         }\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
262                                         }\r
263                                         // Terminate the label state and set to default state\r
264                                         scDoc.SetState(SCE_CLW_DEFAULT);\r
265                                 }\r
266                         }\r
267                 }\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
274                                 scDoc.Forward();\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
280                                 }\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
285                                 }\r
286                         }\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
295                                 }\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
300                                 }\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
305                                 }\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
310                                 }\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
315                                 }\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
320                                 }\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
325                                 }\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
330                                 }\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
335                                 }\r
336                                 // Else the statement string doesn't match any work list\r
337                                 else {\r
338                                         // Change the statement string to the default state\r
339                                         scDoc.ChangeState(SCE_CLW_DEFAULT);\r
340                                 }\r
341                                 // Terminate the keyword state and set to default state\r
342                                 scDoc.SetState(SCE_CLW_DEFAULT);\r
343                         }\r
344                 }\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
353                                 scDoc.Forward();\r
354                         }\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
361                                 scDoc.Forward();\r
362                         }\r
363                 }\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
370                         }\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
377                                 } \r
378                                 // Else parenthese level is greater than zero\r
379                                 // still looking for matching parentheses\r
380                                 else {\r
381                                         // Decrement the parenthese level\r
382                                         iParenthesesLevel--;\r
383                                 }\r
384                         }\r
385                 }\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
390                         }\r
391                 }\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
400                         || scDoc.ch == '.'\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
406                                 }\r
407                                 // Else the number was an integer\r
408                                 else {\r
409                                         // Colour the matched string to an integer constant state\r
410                                         scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);\r
411                                 }\r
412                                 // Terminate the integer constant state and set to default state\r
413                                 scDoc.SetState(SCE_CLW_DEFAULT);\r
414                         }\r
415                 }\r
416 \r
417                 //\r
418                 // Determine if a new state should be entered.\r
419                 //\r
420 \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
432                         }\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
437                         }\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
442                         }\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
448                                 scDoc.Forward();\r
449                                 scDoc.SetState(SCE_CLW_DEFAULT);\r
450                         }\r
451                         // else an invalid character in column 1\r
452                         else {\r
453                                 // Set to error state\r
454                                 scDoc.SetState(SCE_CLW_ERROR);\r
455                         }\r
456                 }\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
461                 }\r
462                 // Default Handling\r
463                 else {\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
470                                 }\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
475                                 }\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
480                                 }               \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
488                                         }\r
489                                         else {\r
490                                                 // move to the next character and then set the state to comment.\r
491                                                 scDoc.ForwardSetState(SCE_CLW_STRING);\r
492                                         }\r
493                                 }               \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
502                                                 }\r
503                                         }\r
504                                         // Case sensitive\r
505                                         else {\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
510                                                 }\r
511                                         }\r
512                                 }               \r
513                         }\r
514                 }\r
515         }\r
516         // lexing complete\r
517         scDoc.Complete();\r
518 }\r
519 \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
522 \r
523         ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);\r
524 }\r
525 \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
528 \r
529         ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);\r
530 }\r
531 \r
532 // Fill Buffer\r
533 \r
534 static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {\r
535 \r
536         unsigned int uiPos = 0;\r
537 \r
538         while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {\r
539                 szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));\r
540                 uiPos++;\r
541         }\r
542         szBuffer[uiPos] = '\0';\r
543 }\r
544 \r
545 // Classify Clarion Fold Point\r
546 \r
547 static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {\r
548 \r
549         if (!(isdigit(szString[0]) || (szString[0] == '.'))) {\r
550                 if (strcmp(szString, "PROCEDURE") == 0) {\r
551         //              iLevel = SC_FOLDLEVELBASE + 1;\r
552                 }\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
565                         iLevel++;\r
566                 }\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
587                         iLevel++;\r
588                 }\r
589                 else if (strcmp(szString, "END") == 0 ||\r
590                         strcmp(szString, "UNTIL") == 0 ||\r
591                         strcmp(szString, "WHILE") == 0) {\r
592                         iLevel--;\r
593                 }\r
594         }\r
595         return(iLevel);\r
596 }\r
597 \r
598 // Clarion Language Folding Procedure\r
599 static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {\r
600 \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
610 \r
611         for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {\r
612 \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
619         \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
624                         }\r
625                 }\r
626 \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
635                         //      }\r
636                         }\r
637                 }\r
638 \r
639                 if (bEOL) {\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
645                         }\r
646                         iLineCurrent++;\r
647                         iLevelPrev = iLevelCurrent;\r
648                         iVisibleChars = 0;\r
649                 }\r
650                 \r
651                 if (!isspacechar(chChar))\r
652                         iVisibleChars++;\r
653         }\r
654 \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
659 }\r
660 \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
668         "Attributes",\r
669         "Standard Equates",\r
670         "Reserved Words (Labels)",\r
671         "Reserved Words (Procedure Labels)",\r
672         0,\r
673 };\r
674 \r
675 // Case Sensitive Clarion Language Lexer\r
676 LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);\r
677 \r
678 // Case Insensitive Clarion Language Lexer\r
679 LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);\r