]>
Commit | Line | Data |
---|---|---|
7e0c58e9 RD |
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. | |
9e96e16f | 5 | ** Sort of completely rewritten by Gertjan Kloosterman |
7e0c58e9 RD |
6 | **/ |
7 | // The License.txt file describes the conditions under which this software may be distributed. | |
8 | ||
9 | // Code folding copyied and modified from LexBasic.cxx | |
10 | ||
11 | #include <stdlib.h> | |
12 | #include <string.h> | |
7e0c58e9 RD |
13 | #include <stdio.h> |
14 | #include <stdarg.h> | |
1dcf666d RD |
15 | #include <assert.h> |
16 | #include <ctype.h> | |
7e0c58e9 | 17 | |
1dcf666d RD |
18 | #include "ILexer.h" |
19 | #include "Scintilla.h" | |
20 | #include "SciLexer.h" | |
7e0c58e9 | 21 | |
1dcf666d RD |
22 | #include "WordList.h" |
23 | #include "LexAccessor.h" | |
7e0c58e9 RD |
24 | #include "Accessor.h" |
25 | #include "StyleContext.h" | |
1dcf666d RD |
26 | #include "CharacterSet.h" |
27 | #include "LexerModule.h" | |
7e0c58e9 RD |
28 | |
29 | #ifdef SCI_NAMESPACE | |
30 | using namespace Scintilla; | |
31 | #endif | |
32 | ||
33 | static inline bool IsAWordChar(const int ch) { | |
9e96e16f RD |
34 | return (ch < 0x80 && (isalnum(ch) || (ch == '_'))); |
35 | } | |
36 | ||
37 | static inline bool IsAKeywordChar(const int ch) { | |
38 | return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' '))); | |
39 | } | |
40 | ||
41 | static inline bool IsASetChar(const int ch) { | |
42 | return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-'))); | |
7e0c58e9 RD |
43 | } |
44 | ||
45 | static inline bool IsAnOperator(char ch) { | |
46 | // '.' left out as it is used to make up numbers | |
47 | if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || | |
48 | ch == '(' || ch == ')' || ch == '=' || ch == '^' || | |
49 | ch == '[' || ch == ']' || ch == '<' || ch == '&' || | |
50 | ch == '>' || ch == ',' || ch == '|' || ch == '~' || | |
51 | ch == '$' || ch == ':' || ch == '%') | |
52 | return true; | |
53 | return false; | |
54 | } | |
55 | ||
9e96e16f | 56 | static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */, |
7e0c58e9 | 57 | Accessor &styler) { |
9e96e16f RD |
58 | enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \ |
59 | DAT_LINE_VAL, DAT_LINE_COMMA,\ | |
60 | COMMENT_LINE,\ | |
61 | ST_ERROR, LINE_END } state ; | |
7e0c58e9 RD |
62 | |
63 | // Do not leak onto next line | |
9e96e16f | 64 | state = LINE_END ; |
7e0c58e9 RD |
65 | initStyle = SCE_ABAQUS_DEFAULT; |
66 | StyleContext sc(startPos, length, initStyle, styler); | |
67 | ||
9e96e16f RD |
68 | // Things are actually quite simple |
69 | // we have commentlines | |
70 | // keywordlines and datalines | |
71 | // On a data line there will only be colouring of numbers | |
72 | // a keyword line is constructed as | |
73 | // *word,[ paramname[=paramvalue]]* | |
74 | // if the line ends with a , the keyword line continues onto the new line | |
7e0c58e9 | 75 | |
9e96e16f RD |
76 | for (; sc.More(); sc.Forward()) { |
77 | switch ( state ) { | |
78 | case KW_LINE_KW : | |
79 | if ( sc.atLineEnd ) { | |
80 | // finished the line in keyword state, switch to LINE_END | |
81 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
82 | state = LINE_END ; | |
83 | } else if ( IsAKeywordChar(sc.ch) ) { | |
84 | // nothing changes | |
85 | state = KW_LINE_KW ; | |
86 | } else if ( sc.ch == ',' ) { | |
87 | // Well well we say a comma, arguments *MUST* follow | |
88 | sc.SetState(SCE_ABAQUS_OPERATOR) ; | |
89 | state = KW_LINE_COMMA ; | |
90 | } else { | |
91 | // Flag an error | |
92 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
93 | state = ST_ERROR ; | |
94 | } | |
95 | // Done with processing | |
96 | break ; | |
97 | case KW_LINE_COMMA : | |
98 | // acomma on a keywordline was seen | |
99 | if ( IsAKeywordChar(sc.ch)) { | |
100 | sc.SetState(SCE_ABAQUS_ARGUMENT) ; | |
101 | state = KW_LINE_PAR ; | |
102 | } else if ( sc.atLineEnd || (sc.ch == ',') ) { | |
103 | // we remain in keyword mode | |
104 | state = KW_LINE_COMMA ; | |
105 | } else if ( sc.ch == ' ' ) { | |
106 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
107 | state = KW_LINE_COMMA ; | |
108 | } else { | |
109 | // Anything else constitutes an error | |
110 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
111 | state = ST_ERROR ; | |
112 | } | |
113 | break ; | |
114 | case KW_LINE_PAR : | |
115 | if ( sc.atLineEnd ) { | |
116 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
117 | state = LINE_END ; | |
118 | } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) { | |
119 | // remain in this state | |
120 | state = KW_LINE_PAR ; | |
121 | } else if ( sc.ch == ',' ) { | |
122 | sc.SetState(SCE_ABAQUS_OPERATOR) ; | |
123 | state = KW_LINE_COMMA ; | |
124 | } else if ( sc.ch == '=' ) { | |
125 | sc.SetState(SCE_ABAQUS_OPERATOR) ; | |
126 | state = KW_LINE_EQ ; | |
127 | } else { | |
128 | // Anything else constitutes an error | |
129 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
130 | state = ST_ERROR ; | |
131 | } | |
132 | break ; | |
133 | case KW_LINE_EQ : | |
134 | if ( sc.ch == ' ' ) { | |
135 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
136 | // remain in this state | |
137 | state = KW_LINE_EQ ; | |
138 | } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) { | |
139 | sc.SetState(SCE_ABAQUS_NUMBER) ; | |
140 | state = KW_LINE_VAL ; | |
141 | } else if ( IsAKeywordChar(sc.ch) ) { | |
142 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
143 | state = KW_LINE_VAL ; | |
144 | } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) { | |
145 | sc.SetState(SCE_ABAQUS_STRING) ; | |
146 | state = KW_LINE_VAL ; | |
147 | } else { | |
148 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
149 | state = ST_ERROR ; | |
150 | } | |
151 | break ; | |
152 | case KW_LINE_VAL : | |
153 | if ( sc.atLineEnd ) { | |
154 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
155 | state = LINE_END ; | |
156 | } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) { | |
157 | // nothing changes | |
158 | state = KW_LINE_VAL ; | |
159 | } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') || | |
160 | ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) && | |
161 | (sc.state == SCE_ABAQUS_NUMBER)) { | |
162 | // remain in number mode | |
163 | state = KW_LINE_VAL ; | |
164 | } else if (sc.state == SCE_ABAQUS_STRING) { | |
165 | // accept everything until a closing quote | |
166 | if ( sc.ch == '\'' || sc.ch == '\"' ) { | |
167 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
168 | state = KW_LINE_VAL ; | |
169 | } | |
170 | } else if ( sc.ch == ',' ) { | |
171 | sc.SetState(SCE_ABAQUS_OPERATOR) ; | |
172 | state = KW_LINE_COMMA ; | |
173 | } else { | |
174 | // anything else is an error | |
175 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
176 | state = ST_ERROR ; | |
177 | } | |
178 | break ; | |
179 | case DAT_LINE_VAL : | |
180 | if ( sc.atLineEnd ) { | |
181 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
182 | state = LINE_END ; | |
183 | } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) { | |
184 | // nothing changes | |
185 | state = DAT_LINE_VAL ; | |
186 | } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') || | |
187 | ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) && | |
188 | (sc.state == SCE_ABAQUS_NUMBER)) { | |
189 | // remain in number mode | |
190 | state = DAT_LINE_VAL ; | |
191 | } else if (sc.state == SCE_ABAQUS_STRING) { | |
192 | // accept everything until a closing quote | |
193 | if ( sc.ch == '\'' || sc.ch == '\"' ) { | |
194 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
195 | state = DAT_LINE_VAL ; | |
196 | } | |
197 | } else if ( sc.ch == ',' ) { | |
198 | sc.SetState(SCE_ABAQUS_OPERATOR) ; | |
199 | state = DAT_LINE_COMMA ; | |
200 | } else { | |
201 | // anything else is an error | |
202 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
203 | state = ST_ERROR ; | |
204 | } | |
205 | break ; | |
206 | case DAT_LINE_COMMA : | |
207 | // a comma on a data line was seen | |
208 | if ( sc.atLineEnd ) { | |
209 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
210 | state = LINE_END ; | |
211 | } else if ( sc.ch == ' ' ) { | |
212 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
213 | state = DAT_LINE_COMMA ; | |
214 | } else if (sc.ch == ',') { | |
215 | sc.SetState(SCE_ABAQUS_OPERATOR) ; | |
216 | state = DAT_LINE_COMMA ; | |
217 | } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) { | |
218 | sc.SetState(SCE_ABAQUS_NUMBER) ; | |
219 | state = DAT_LINE_VAL ; | |
220 | } else if ( IsAKeywordChar(sc.ch) ) { | |
221 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
222 | state = DAT_LINE_VAL ; | |
223 | } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) { | |
224 | sc.SetState(SCE_ABAQUS_STRING) ; | |
225 | state = DAT_LINE_VAL ; | |
226 | } else { | |
227 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
228 | state = ST_ERROR ; | |
229 | } | |
230 | break ; | |
231 | case COMMENT_LINE : | |
232 | if ( sc.atLineEnd ) { | |
233 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
234 | state = LINE_END ; | |
235 | } | |
236 | break ; | |
237 | case ST_ERROR : | |
238 | if ( sc.atLineEnd ) { | |
239 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
240 | state = LINE_END ; | |
241 | } | |
242 | break ; | |
243 | case LINE_END : | |
244 | if ( sc.atLineEnd || sc.ch == ' ' ) { | |
245 | // nothing changes | |
246 | state = LINE_END ; | |
247 | } else if ( sc.ch == '*' ) { | |
248 | if ( sc.chNext == '*' ) { | |
249 | state = COMMENT_LINE ; | |
250 | sc.SetState(SCE_ABAQUS_COMMENT) ; | |
251 | } else { | |
252 | state = KW_LINE_KW ; | |
253 | sc.SetState(SCE_ABAQUS_STARCOMMAND) ; | |
254 | } | |
255 | } else { | |
256 | // it must be a data line, things are as if we are in DAT_LINE_COMMA | |
257 | if ( sc.ch == ',' ) { | |
258 | sc.SetState(SCE_ABAQUS_OPERATOR) ; | |
259 | state = DAT_LINE_COMMA ; | |
260 | } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) { | |
261 | sc.SetState(SCE_ABAQUS_NUMBER) ; | |
262 | state = DAT_LINE_VAL ; | |
263 | } else if ( IsAKeywordChar(sc.ch) ) { | |
264 | sc.SetState(SCE_ABAQUS_DEFAULT) ; | |
265 | state = DAT_LINE_VAL ; | |
266 | } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) { | |
267 | sc.SetState(SCE_ABAQUS_STRING) ; | |
268 | state = DAT_LINE_VAL ; | |
269 | } else { | |
270 | sc.SetState(SCE_ABAQUS_PROCESSOR) ; | |
271 | state = ST_ERROR ; | |
272 | } | |
273 | } | |
274 | break ; | |
275 | } | |
276 | } | |
277 | sc.Complete(); | |
7e0c58e9 RD |
278 | } |
279 | ||
280 | //------------------------------------------------------------------------------ | |
281 | // This copyied and modified from LexBasic.cxx | |
282 | //------------------------------------------------------------------------------ | |
283 | ||
284 | /* Bits: | |
285 | * 1 - whitespace | |
286 | * 2 - operator | |
287 | * 4 - identifier | |
288 | * 8 - decimal digit | |
289 | * 16 - hex digit | |
290 | * 32 - bin digit | |
291 | */ | |
292 | static int character_classification[128] = | |
293 | { | |
294 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, | |
295 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
296 | 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6, | |
297 | 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, | |
298 | 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
299 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, | |
300 | 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
301 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0 | |
302 | }; | |
303 | ||
304 | static bool IsSpace(int c) { | |
305 | return c < 128 && (character_classification[c] & 1); | |
306 | } | |
307 | ||
308 | static bool IsIdentifier(int c) { | |
309 | return c < 128 && (character_classification[c] & 4); | |
310 | } | |
311 | ||
312 | static int LowerCase(int c) | |
313 | { | |
314 | if (c >= 'A' && c <= 'Z') | |
315 | return 'a' + c - 'A'; | |
316 | return c; | |
317 | } | |
318 | ||
9e96e16f RD |
319 | static int LineEnd(int line, Accessor &styler) |
320 | { | |
321 | const int docLines = styler.GetLine(styler.Length() - 1); // Available last line | |
322 | int eol_pos ; | |
323 | // if the line is the last line, the eol_pos is styler.Length() | |
324 | // eol will contain a new line, or a virtual new line | |
325 | if ( docLines == line ) | |
326 | eol_pos = styler.Length() ; | |
327 | else | |
328 | eol_pos = styler.LineStart(line + 1) - 1; | |
329 | return eol_pos ; | |
330 | } | |
331 | ||
332 | static int LineStart(int line, Accessor &styler) | |
333 | { | |
334 | return styler.LineStart(line) ; | |
335 | } | |
336 | ||
337 | // LineType | |
338 | // | |
339 | // bits determines the line type | |
340 | // 1 : data line | |
341 | // 2 : only whitespace | |
342 | // 3 : data line with only whitespace | |
343 | // 4 : keyword line | |
344 | // 5 : block open keyword line | |
345 | // 6 : block close keyword line | |
346 | // 7 : keyword line in error | |
347 | // 8 : comment line | |
348 | static int LineType(int line, Accessor &styler) { | |
349 | int pos = LineStart(line, styler) ; | |
350 | int eol_pos = LineEnd(line, styler) ; | |
351 | ||
352 | int c ; | |
353 | char ch = ' '; | |
354 | ||
355 | int i = pos ; | |
356 | while ( i < eol_pos ) { | |
357 | c = styler.SafeGetCharAt(i); | |
358 | ch = static_cast<char>(LowerCase(c)); | |
359 | // We can say something as soon as no whitespace | |
360 | // was encountered | |
361 | if ( !IsSpace(c) ) | |
362 | break ; | |
363 | i++ ; | |
364 | } | |
365 | ||
366 | if ( i >= eol_pos ) { | |
367 | // This is a whitespace line, currently | |
368 | // classifies as data line | |
369 | return 3 ; | |
370 | } | |
371 | ||
372 | if ( ch != '*' ) { | |
373 | // This is a data line | |
374 | return 1 ; | |
375 | } | |
376 | ||
377 | if ( i == eol_pos - 1 ) { | |
378 | // Only a single *, error but make keyword line | |
379 | return 4+3 ; | |
380 | } | |
381 | ||
382 | // This means we can have a second character | |
383 | // if that is also a * this means a comment | |
384 | // otherwise it is a keyword. | |
385 | c = styler.SafeGetCharAt(i+1); | |
386 | ch = static_cast<char>(LowerCase(c)); | |
387 | if ( ch == '*' ) { | |
388 | return 8 ; | |
389 | } | |
390 | ||
391 | // At this point we know this is a keyword line | |
392 | // the character at position i is a * | |
393 | // it is not a comment line | |
394 | char word[256] ; | |
395 | int wlen = 0; | |
396 | ||
397 | word[wlen] = '*' ; | |
398 | wlen++ ; | |
399 | ||
400 | i++ ; | |
401 | while ( (i < eol_pos) && (wlen < 255) ) { | |
402 | c = styler.SafeGetCharAt(i); | |
403 | ch = static_cast<char>(LowerCase(c)); | |
404 | ||
405 | if ( (!IsSpace(c)) && (!IsIdentifier(c)) ) | |
406 | break ; | |
407 | ||
408 | if ( IsIdentifier(c) ) { | |
409 | word[wlen] = ch ; | |
410 | wlen++ ; | |
411 | } | |
412 | ||
413 | i++ ; | |
414 | } | |
415 | ||
416 | word[wlen] = 0 ; | |
417 | ||
418 | // Make a comparison | |
419 | if ( !strcmp(word, "*step") || | |
420 | !strcmp(word, "*part") || | |
421 | !strcmp(word, "*instance") || | |
422 | !strcmp(word, "*assembly")) { | |
423 | return 4+1 ; | |
424 | } | |
425 | ||
426 | if ( !strcmp(word, "*endstep") || | |
427 | !strcmp(word, "*endpart") || | |
428 | !strcmp(word, "*endinstance") || | |
429 | !strcmp(word, "*endassembly")) { | |
430 | return 4+2 ; | |
431 | } | |
432 | ||
433 | return 4 ; | |
434 | } | |
435 | ||
436 | static void SafeSetLevel(int line, int level, Accessor &styler) | |
437 | { | |
438 | if ( line < 0 ) | |
439 | return ; | |
440 | ||
441 | int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG)); | |
442 | ||
443 | if ( (level & mask) < 0 ) | |
444 | return ; | |
445 | ||
446 | if ( styler.LevelAt(line) != level ) | |
447 | styler.SetLevel(line, level) ; | |
7e0c58e9 RD |
448 | } |
449 | ||
450 | static void FoldABAQUSDoc(unsigned int startPos, int length, int, | |
9e96e16f RD |
451 | WordList *[], Accessor &styler) { |
452 | int startLine = styler.GetLine(startPos) ; | |
453 | int endLine = styler.GetLine(startPos+length-1) ; | |
454 | ||
455 | // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; | |
456 | // We want to deal with all the cases | |
457 | // To know the correct indentlevel, we need to look back to the | |
458 | // previous command line indentation level | |
459 | // order of formatting keyline datalines commentlines | |
460 | int beginData = -1 ; | |
461 | int beginComment = -1 ; | |
462 | int prvKeyLine = startLine ; | |
463 | int prvKeyLineTp = 0 ; | |
464 | ||
465 | // Scan until we find the previous keyword line | |
466 | // this will give us the level reference that we need | |
467 | while ( prvKeyLine > 0 ) { | |
468 | prvKeyLine-- ; | |
469 | prvKeyLineTp = LineType(prvKeyLine, styler) ; | |
470 | if ( prvKeyLineTp & 4 ) | |
471 | break ; | |
472 | } | |
473 | ||
474 | // Determine the base line level of all lines following | |
475 | // the previous keyword | |
476 | // new keyword lines are placed on this level | |
477 | //if ( prvKeyLineTp & 4 ) { | |
478 | int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ; | |
479 | //} | |
480 | ||
481 | // uncomment line below if weird behaviour continues | |
482 | prvKeyLine = -1 ; | |
483 | ||
484 | // Now start scanning over the lines. | |
485 | for ( int line = startLine; line <= endLine; line++ ) { | |
486 | int lineType = LineType(line, styler) ; | |
487 | ||
488 | // Check for comment line | |
489 | if ( lineType == 8 ) { | |
490 | if ( beginComment < 0 ) { | |
491 | beginComment = line ; | |
492 | } | |
493 | } | |
494 | ||
495 | // Check for data line | |
496 | if ( (lineType == 1) || (lineType == 3) ) { | |
497 | if ( beginData < 0 ) { | |
498 | if ( beginComment >= 0 ) { | |
499 | beginData = beginComment ; | |
500 | } else { | |
501 | beginData = line ; | |
502 | } | |
503 | } | |
504 | beginComment = -1 ; | |
505 | } | |
506 | ||
507 | // Check for keywordline. | |
508 | // As soon as a keyword line is encountered, we can set the | |
509 | // levels of everything from the previous keyword line to this one | |
510 | if ( lineType & 4 ) { | |
511 | // this is a keyword, we can now place the previous keyword | |
512 | // all its data lines and the remainder | |
513 | ||
514 | // Write comments and data line | |
515 | if ( beginComment < 0 ) { | |
516 | beginComment = line ; | |
517 | } | |
518 | ||
519 | if ( beginData < 0 ) { | |
520 | beginData = beginComment ; | |
521 | if ( prvKeyLineTp != 5 ) | |
522 | SafeSetLevel(prvKeyLine, level, styler) ; | |
523 | else | |
524 | SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; | |
525 | } else { | |
526 | SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; | |
527 | } | |
528 | ||
529 | int datLevel = level + 1 ; | |
530 | if ( !(prvKeyLineTp & 4) ) { | |
531 | datLevel = level ; | |
532 | } | |
533 | ||
534 | for ( int ll = beginData; ll < beginComment; ll++ ) | |
535 | SafeSetLevel(ll, datLevel, styler) ; | |
536 | ||
537 | // The keyword we just found is going to be written at another level | |
538 | // if we have a type 5 and type 6 | |
539 | if ( prvKeyLineTp == 5 ) { | |
540 | level += 1 ; | |
541 | } | |
542 | ||
543 | if ( prvKeyLineTp == 6 ) { | |
544 | level -= 1 ; | |
545 | if ( level < 0 ) { | |
546 | level = 0 ; | |
7e0c58e9 | 547 | } |
9e96e16f RD |
548 | } |
549 | ||
550 | for ( int lll = beginComment; lll < line; lll++ ) | |
551 | SafeSetLevel(lll, level, styler) ; | |
552 | ||
553 | // wrap and reset | |
554 | beginComment = -1 ; | |
555 | beginData = -1 ; | |
556 | prvKeyLine = line ; | |
557 | prvKeyLineTp = lineType ; | |
558 | } | |
559 | ||
560 | } | |
561 | ||
562 | if ( beginComment < 0 ) { | |
563 | beginComment = endLine + 1 ; | |
564 | } else { | |
565 | // We need to find out whether this comment block is followed by | |
566 | // a data line or a keyword line | |
567 | const int docLines = styler.GetLine(styler.Length() - 1); | |
568 | ||
569 | for ( int line = endLine + 1; line <= docLines; line++ ) { | |
570 | int lineType = LineType(line, styler) ; | |
571 | ||
572 | if ( lineType != 8 ) { | |
573 | if ( !(lineType & 4) ) { | |
574 | beginComment = endLine + 1 ; | |
7e0c58e9 | 575 | } |
9e96e16f | 576 | break ; |
7e0c58e9 | 577 | } |
9e96e16f RD |
578 | } |
579 | } | |
580 | ||
581 | if ( beginData < 0 ) { | |
582 | beginData = beginComment ; | |
583 | if ( prvKeyLineTp != 5 ) | |
584 | SafeSetLevel(prvKeyLine, level, styler) ; | |
585 | else | |
586 | SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; | |
587 | } else { | |
588 | SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; | |
589 | } | |
590 | ||
591 | int datLevel = level + 1 ; | |
592 | if ( !(prvKeyLineTp & 4) ) { | |
593 | datLevel = level ; | |
594 | } | |
595 | ||
596 | for ( int ll = beginData; ll < beginComment; ll++ ) | |
597 | SafeSetLevel(ll, datLevel, styler) ; | |
598 | ||
599 | if ( prvKeyLineTp == 5 ) { | |
600 | level += 1 ; | |
601 | } | |
602 | ||
603 | if ( prvKeyLineTp == 6 ) { | |
604 | level -= 1 ; | |
7e0c58e9 | 605 | } |
9e96e16f RD |
606 | for ( int m = beginComment; m <= endLine; m++ ) |
607 | SafeSetLevel(m, level, styler) ; | |
7e0c58e9 RD |
608 | } |
609 | ||
610 | static const char * const abaqusWordListDesc[] = { | |
611 | "processors", | |
612 | "commands", | |
613 | "slashommands", | |
614 | "starcommands", | |
615 | "arguments", | |
616 | "functions", | |
617 | 0 | |
618 | }; | |
619 | ||
620 | LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc); |