]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexAbaqus.cxx
Update Scintilla to version 1.75
[wxWidgets.git] / src / stc / scintilla / src / LexAbaqus.cxx
1 // Scintilla source code edit control
2 /** @file LexABAQUS.cxx
3 ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
4 ** By Sergio Lucato.
5 **/
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 // Code folding copyied and modified from LexBasic.cxx
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15
16 #include "Platform.h"
17
18 #include "PropSet.h"
19 #include "Accessor.h"
20 #include "StyleContext.h"
21 #include "KeyWords.h"
22 #include "Scintilla.h"
23 #include "SciLexer.h"
24
25 #ifdef SCI_NAMESPACE
26 using namespace Scintilla;
27 #endif
28
29 static inline bool IsAWordChar(const int ch) {
30 return (ch < 0x80 && (isalnum(ch) || ch == '_'));
31 }
32
33 static inline bool IsAnOperator(char ch) {
34 // '.' left out as it is used to make up numbers
35 if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
36 ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
37 ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
38 ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
39 ch == '$' || ch == ':' || ch == '%')
40 return true;
41 return false;
42 }
43
44 static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
45 Accessor &styler) {
46
47 int stringStart = ' ';
48
49 WordList &processors = *keywordlists[0];
50 WordList &commands = *keywordlists[1];
51 WordList &slashcommands = *keywordlists[2];
52 WordList &starcommands = *keywordlists[3];
53 WordList &arguments = *keywordlists[4];
54 WordList &functions = *keywordlists[5];
55
56 // Do not leak onto next line
57 initStyle = SCE_ABAQUS_DEFAULT;
58 StyleContext sc(startPos, length, initStyle, styler);
59
60 for (; sc.More(); sc.Forward()) {
61 // Determine if the current state should terminate.
62 if (sc.state == SCE_ABAQUS_NUMBER) {
63 if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
64 ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
65 sc.SetState(SCE_ABAQUS_DEFAULT);
66 }
67 } else if (sc.state == SCE_ABAQUS_COMMENT) {
68 if (sc.atLineEnd) {
69 sc.SetState(SCE_ABAQUS_DEFAULT);
70 }
71 } else if (sc.state == SCE_ABAQUS_COMMENTBLOCK) {
72 if (sc.atLineEnd) {
73 if (sc.ch == '\r') {
74 sc.Forward();
75 }
76 sc.ForwardSetState(SCE_ABAQUS_DEFAULT);
77 }
78 } else if (sc.state == SCE_ABAQUS_STRING) {
79 if (sc.atLineEnd) {
80 sc.SetState(SCE_ABAQUS_DEFAULT);
81 } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
82 sc.ForwardSetState(SCE_ABAQUS_DEFAULT);
83 }
84 } else if (sc.state == SCE_ABAQUS_WORD) {
85 if (!IsAWordChar(sc.ch)) {
86 char s[100];
87 sc.GetCurrentLowered(s, sizeof(s));
88 if (processors.InList(s)) {
89 sc.ChangeState(SCE_ABAQUS_PROCESSOR);
90 } else if (slashcommands.InList(s)) {
91 sc.ChangeState(SCE_ABAQUS_SLASHCOMMAND);
92 } else if (starcommands.InList(s)) {
93 sc.ChangeState(SCE_ABAQUS_STARCOMMAND);
94 } else if (commands.InList(s)) {
95 sc.ChangeState(SCE_ABAQUS_COMMAND);
96 } else if (arguments.InList(s)) {
97 sc.ChangeState(SCE_ABAQUS_ARGUMENT);
98 } else if (functions.InList(s)) {
99 sc.ChangeState(SCE_ABAQUS_FUNCTION);
100 }
101 sc.SetState(SCE_ABAQUS_DEFAULT);
102 }
103 } else if (sc.state == SCE_ABAQUS_OPERATOR) {
104 if (!IsAnOperator(static_cast<char>(sc.ch))) {
105 sc.SetState(SCE_ABAQUS_DEFAULT);
106 }
107 }
108
109 // Determine if a new state should be entered.
110 if (sc.state == SCE_ABAQUS_DEFAULT) {
111 if (sc.ch == '*' && sc.chNext == '*') {
112 sc.SetState(SCE_ABAQUS_COMMENTBLOCK);
113 } else if (sc.ch == '!') {
114 sc.SetState(SCE_ABAQUS_COMMENT);
115 } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
116 sc.SetState(SCE_ABAQUS_NUMBER);
117 } else if (sc.ch == '\'' || sc.ch == '\"') {
118 sc.SetState(SCE_ABAQUS_STRING);
119 stringStart = sc.ch;
120 } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
121 sc.SetState(SCE_ABAQUS_WORD);
122 } else if (IsAnOperator(static_cast<char>(sc.ch))) {
123 sc.SetState(SCE_ABAQUS_OPERATOR);
124 }
125 }
126 }
127 sc.Complete();
128 }
129
130 //------------------------------------------------------------------------------
131 // This copyied and modified from LexBasic.cxx
132 //------------------------------------------------------------------------------
133
134 /* Bits:
135 * 1 - whitespace
136 * 2 - operator
137 * 4 - identifier
138 * 8 - decimal digit
139 * 16 - hex digit
140 * 32 - bin digit
141 */
142 static int character_classification[128] =
143 {
144 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
146 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
147 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
148 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
149 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
150 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
151 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
152 };
153
154 static bool IsSpace(int c) {
155 return c < 128 && (character_classification[c] & 1);
156 }
157
158 static bool IsIdentifier(int c) {
159 return c < 128 && (character_classification[c] & 4);
160 }
161
162 static int LowerCase(int c)
163 {
164 if (c >= 'A' && c <= 'Z')
165 return 'a' + c - 'A';
166 return c;
167 }
168
169 static int CheckABAQUSFoldPoint(char const *token, int &level) {
170 if (!strcmp(token, "*step") ||
171 !strcmp(token, "*part") ||
172 !strcmp(token, "*instance") ||
173 !strcmp(token, "*assembly") ||
174 !strcmp(token, "***region") ) {
175 level |= SC_FOLDLEVELHEADERFLAG;
176 return 1;
177 }
178 if (!strcmp(token, "*end step") ||
179 !strcmp(token, "*end part") ||
180 !strcmp(token, "*end instance") ||
181 !strcmp(token, "*end assembly") ||
182 !strcmp(token, "***end region") ) {
183 return -1;
184 }
185 return 0;
186 }
187
188 static void FoldABAQUSDoc(unsigned int startPos, int length, int,
189 WordList *[], Accessor &styler) {
190
191 int line = styler.GetLine(startPos);
192 int level = styler.LevelAt(line);
193 int go = 0, done = 0;
194 int endPos = startPos + length;
195 char word[256];
196 int wordlen = 0;
197 int i;
198 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
199 // Scan for tokens at the start of the line (they may include
200 // whitespace, for tokens like "End Function"
201 for (i = startPos; i < endPos; i++) {
202 int c = styler.SafeGetCharAt(i);
203 if (!done && !go) {
204 if (wordlen) { // are we scanning a token already?
205 word[wordlen] = static_cast<char>(LowerCase(c));
206 if (!IsIdentifier(c)) { // done with token
207 word[wordlen] = '\0';
208 go = CheckABAQUSFoldPoint(word, level);
209 if (!go) {
210 // Treat any whitespace as single blank, for
211 // things like "End Function".
212 if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
213 word[wordlen] = ' ';
214 if (wordlen < 255)
215 wordlen++;
216 }
217 else // done with this line
218 done = 1;
219 }
220 } else if (wordlen < 255) {
221 wordlen++;
222 }
223 } else { // start scanning at first non-whitespace character
224 if (!IsSpace(c)) {
225 if (IsIdentifier(c)) {
226 word[0] = static_cast<char>(LowerCase(c));
227 wordlen = 1;
228 } else // done with this line
229 done = 1;
230 }
231 }
232 }
233 if (c == '\n') { // line end
234 if (!done && wordlen == 0 && foldCompact) // line was only space
235 level |= SC_FOLDLEVELWHITEFLAG;
236 if (level != styler.LevelAt(line))
237 styler.SetLevel(line, level);
238 level += go;
239 line++;
240 // reset state
241 wordlen = 0;
242 level &= ~SC_FOLDLEVELHEADERFLAG;
243 level &= ~SC_FOLDLEVELWHITEFLAG;
244 go = 0;
245 done = 0;
246 }
247 }
248 }
249
250 static const char * const abaqusWordListDesc[] = {
251 "processors",
252 "commands",
253 "slashommands",
254 "starcommands",
255 "arguments",
256 "functions",
257 0
258 };
259
260 LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);