]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexAVE.cxx
wxMGL fixes (patch #884758)
[wxWidgets.git] / src / stc / scintilla / src / LexAVE.cxx
1 // SciTE - Scintilla based Text Editor
2 /** @file LexAVE.cxx
3 ** Lexer for Avenue.
4 **
5 ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
6 **/
7 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
8 // The License.txt file describes the conditions under which this software may be distributed.
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <stdarg.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16
17 #include "Platform.h"
18
19 #include "PropSet.h"
20 #include "Accessor.h"
21 #include "StyleContext.h"
22 #include "KeyWords.h"
23 #include "Scintilla.h"
24 #include "SciLexer.h"
25
26
27
28 static inline bool IsAWordChar(const int ch) {
29 return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
30 }
31 static inline bool IsEnumChar(const int ch) {
32 return (ch < 0x80) && (isalnum(ch)|| ch == '_');
33 }
34 static inline bool IsANumberChar(const int ch) {
35 return (ch < 0x80) && (isalnum(ch) || ch == '.' );
36 }
37
38 inline bool IsAWordStart(const int ch) {
39 return (ch < 0x80) && (isalnum(ch) || ch == '_');
40 }
41
42 inline bool isAveOperator(char ch) {
43 if (isalnum(ch))
44 return false;
45 // '.' left out as it is used to make up numbers
46 if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
47 ch == '(' || ch == ')' || ch == '=' ||
48 ch == '{' || ch == '}' ||
49 ch == '[' || ch == ']' || ch == ';' ||
50 ch == '<' || ch == '>' || ch == ',' ||
51 ch == '.' )
52 return true;
53 return false;
54 }
55
56 static void ColouriseAveDoc(
57 unsigned int startPos,
58 int length,
59 int initStyle,
60 WordList *keywordlists[],
61 Accessor &styler) {
62
63 WordList &keywords = *keywordlists[0];
64 WordList &keywords2 = *keywordlists[1];
65 WordList &keywords3 = *keywordlists[2];
66 WordList &keywords4 = *keywordlists[3];
67 WordList &keywords5 = *keywordlists[4];
68 WordList &keywords6 = *keywordlists[5];
69
70 // Do not leak onto next line
71 if (initStyle == SCE_AVE_STRINGEOL) {
72 initStyle = SCE_AVE_DEFAULT;
73 }
74
75 StyleContext sc(startPos, length, initStyle, styler);
76
77 for (; sc.More(); sc.Forward()) {
78 if (sc.atLineEnd) {
79 // Update the line state, so it can be seen by next line
80 int currentLine = styler.GetLine(sc.currentPos);
81 styler.SetLineState(currentLine, 0);
82 }
83 if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {
84 // Prevent SCE_AVE_STRINGEOL from leaking back to previous line
85 sc.SetState(SCE_AVE_STRING);
86 }
87
88
89 // Determine if the current state should terminate.
90 if (sc.state == SCE_AVE_OPERATOR) {
91 sc.SetState(SCE_AVE_DEFAULT);
92 } else if (sc.state == SCE_AVE_NUMBER) {
93 if (!IsANumberChar(sc.ch)) {
94 sc.SetState(SCE_AVE_DEFAULT);
95 }
96 } else if (sc.state == SCE_AVE_ENUM) {
97 if (!IsEnumChar(sc.ch)) {
98 sc.SetState(SCE_AVE_DEFAULT);
99 }
100 } else if (sc.state == SCE_AVE_IDENTIFIER) {
101 if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
102 char s[100];
103 //sc.GetCurrent(s, sizeof(s));
104 sc.GetCurrentLowered(s, sizeof(s));
105 if (keywords.InList(s)) {
106 sc.ChangeState(SCE_AVE_WORD);
107 } else if (keywords2.InList(s)) {
108 sc.ChangeState(SCE_AVE_WORD2);
109 } else if (keywords3.InList(s)) {
110 sc.ChangeState(SCE_AVE_WORD3);
111 } else if (keywords4.InList(s)) {
112 sc.ChangeState(SCE_AVE_WORD4);
113 } else if (keywords5.InList(s)) {
114 sc.ChangeState(SCE_AVE_WORD5);
115 } else if (keywords6.InList(s)) {
116 sc.ChangeState(SCE_AVE_WORD6);
117 }
118 sc.SetState(SCE_AVE_DEFAULT);
119 }
120 } else if (sc.state == SCE_AVE_COMMENT) {
121 if (sc.atLineEnd) {
122 sc.SetState(SCE_AVE_DEFAULT);
123 }
124 } else if (sc.state == SCE_AVE_STRING) {
125 if (sc.ch == '\"') {
126 sc.ForwardSetState(SCE_AVE_DEFAULT);
127 } else if (sc.atLineEnd) {
128 sc.ChangeState(SCE_AVE_STRINGEOL);
129 sc.ForwardSetState(SCE_AVE_DEFAULT);
130 }
131 }
132
133 // Determine if a new state should be entered.
134 if (sc.state == SCE_AVE_DEFAULT) {
135 if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
136 sc.SetState(SCE_AVE_NUMBER);
137 } else if (IsAWordStart(sc.ch)) {
138 sc.SetState(SCE_AVE_IDENTIFIER);
139 } else if (sc.Match('\"')) {
140 sc.SetState(SCE_AVE_STRING);
141 } else if (sc.Match('\'')) {
142 sc.SetState(SCE_AVE_COMMENT);
143 sc.Forward();
144 } else if (isAveOperator(static_cast<char>(sc.ch))) {
145 sc.SetState(SCE_AVE_OPERATOR);
146 } else if (sc.Match('#')) {
147 sc.SetState(SCE_AVE_ENUM);
148 sc.Forward();
149 }
150 }
151 }
152 sc.Complete();
153 }
154
155 static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
156 Accessor &styler) {
157 unsigned int lengthDoc = startPos + length;
158 int visibleChars = 0;
159 int lineCurrent = styler.GetLine(startPos);
160 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
161 int levelCurrent = levelPrev;
162 char chNext = static_cast<char>(tolower(styler[startPos]));
163 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
164 int styleNext = styler.StyleAt(startPos);
165 char s[10];
166
167 for (unsigned int i = startPos; i < lengthDoc; i++) {
168 char ch = static_cast<char>(tolower(chNext));
169 chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
170 int style = styleNext;
171 styleNext = styler.StyleAt(i + 1);
172 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
173 if (style == SCE_AVE_WORD) {
174 if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {
175 for (unsigned int j = 0; j < 6; j++) {
176 if (!iswordchar(styler[i + j])) {
177 break;
178 }
179 s[j] = static_cast<char>(tolower(styler[i + j]));
180 s[j + 1] = '\0';
181 }
182
183 if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
184 levelCurrent++;
185 }
186 if ((strcmp(s, "end") == 0)) {
187 levelCurrent--;
188 }
189 }
190 } else if (style == SCE_AVE_OPERATOR) {
191 if (ch == '{' || ch == '(') {
192 levelCurrent++;
193 } else if (ch == '}' || ch == ')') {
194 levelCurrent--;
195 }
196 }
197
198 if (atEOL) {
199 int lev = levelPrev;
200 if (visibleChars == 0 && foldCompact) {
201 lev |= SC_FOLDLEVELWHITEFLAG;
202 }
203 if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
204 lev |= SC_FOLDLEVELHEADERFLAG;
205 }
206 if (lev != styler.LevelAt(lineCurrent)) {
207 styler.SetLevel(lineCurrent, lev);
208 }
209 lineCurrent++;
210 levelPrev = levelCurrent;
211 visibleChars = 0;
212 }
213 if (!isspacechar(ch)) {
214 visibleChars++;
215 }
216 }
217 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
218
219 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
220 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
221 }
222
223 LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc);
224