~ubuntu-branches/ubuntu/quantal/mysql-workbench/quantal

« back to all changes in this revision

Viewing changes to ext/scintilla/lexers/LexAbaqus.cxx

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2012-03-01 21:57:30 UTC
  • Revision ID: package-import@ubuntu.com-20120301215730-o7y8av8y38n162ro
Tags: upstream-5.2.38+dfsg
ImportĀ upstreamĀ versionĀ 5.2.38+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 ** Sort of completely rewritten by Gertjan Kloosterman
 
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>
 
13
#include <stdio.h>
 
14
#include <stdarg.h>
 
15
#include <assert.h>
 
16
#include <ctype.h>
 
17
 
 
18
#include "ILexer.h"
 
19
#include "Scintilla.h"
 
20
#include "SciLexer.h"
 
21
 
 
22
#include "WordList.h"
 
23
#include "LexAccessor.h"
 
24
#include "Accessor.h"
 
25
#include "StyleContext.h"
 
26
#include "CharacterSet.h"
 
27
#include "LexerModule.h"
 
28
 
 
29
#ifdef SCI_NAMESPACE
 
30
using namespace Scintilla;
 
31
#endif
 
32
 
 
33
static inline bool IsAWordChar(const int ch) {
 
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 == '-')));
 
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
 
 
56
static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */,
 
57
                            Accessor &styler) {
 
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 ;
 
62
 
 
63
        // Do not leak onto next line
 
64
        state = LINE_END ;
 
65
        initStyle = SCE_ABAQUS_DEFAULT;
 
66
        StyleContext sc(startPos, length, initStyle, styler);
 
67
 
 
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
 
75
 
 
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();
 
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
 
 
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) ;
 
448
}
 
449
 
 
450
static void FoldABAQUSDoc(unsigned int startPos, int length, int,
 
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 ;
 
547
                                }
 
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 ;
 
575
                                }
 
576
                break ;
 
577
                        }
 
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 ;
 
605
        }
 
606
        for ( int m = beginComment; m <= endLine; m++ )
 
607
        SafeSetLevel(m, level, styler) ;
 
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);