~ubuntu-branches/ubuntu/wily/tora/wily-proposed

« back to all changes in this revision

Viewing changes to src/qscintilla2/src/LexAbaqus.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Meskes
  • Date: 2009-11-19 15:18:19 UTC
  • mfrom: (1.2.9 upstream) (3.3.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091119151819-me89ezmxzkvl0lws
Tags: 2.1.1-1
New upstream version.

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