~ubuntu-branches/ubuntu/raring/codeblocks/raring-proposed

« back to all changes in this revision

Viewing changes to src/sdk/wxscintilla/src/scintilla/src/LexPowerPro.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-08-09 04:38:38 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20100809043838-a59ygguym4eg0jgw
Tags: 10.05-0ubuntu1
* New upstream release. Closes (LP: #322350)
 - Switch to dpkg-source 3.0 (quilt) format
 - Remove unneeded README.source
 - Add debian/get-source-orig script that removes all
   Windows prebuilt binaries
* Bump Standards-Version to 3.9.1
 - Stop shipping *.la files
* debian/control
 - Add cdbs package as Build-Depend
 - Add libbz2-dev and zlib1g-dev packages as
   Build-Depends (needed by libhelp_plugin.so)
 - Remove dpatch package of Build-Depends
 - Add codeblocks-contrib-debug package
 - Split architecture-independent files of codeblocks
   package in codeblocks-common package
* debian/rules
 - Switch to CDBS rules system
 - Add parallel build support
 - Add a call to debian/get-source-orig script
 - Use lzma compression (saves 23,5 MB of free space)
* debian/patches
 - Refresh 01_codeblocks_plugin_path
 - Add 02_no_Makefiles_in_debian_dir to remove any link
   in codeblocks build system to deleted Makefiles of debian directory
 - Drop 02_ftbfs_gcc44 and 03_ftbfs_glib221 (merged in upstream)
* debian/watch
 - Update to use the new host (berlios.de)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
// @file LexPowerPro.cxx
 
3
// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com
 
4
// PowerPro lexer is written by Christopher Bean (cbean@cb-software.net)
 
5
//
 
6
// Lexer code heavily borrowed from: 
 
7
//      LexAU3.cxx by Jos van der Zande
 
8
//      LexCPP.cxx by Neil Hodgson
 
9
//      LexVB.cxx by Neil Hodgson
 
10
//
 
11
// Changes:
 
12
//      2008-10-25 - Initial release
 
13
//      2008-10-26 - Changed how <name> is hilighted in  'function <name>' so that 
 
14
//                               local isFunction = "" and local functions = "" don't get falsely highlighted
 
15
//      2008-12-14 - Added bounds checking for szKeyword and szDo
 
16
//                         - Replaced SetOfCharacters with CharacterSet
 
17
//                         - Made sure that CharacterSet::Contains is passed only positive values
 
18
//                         - Made sure that the return value of Accessor::SafeGetCharAt is positive before 
 
19
//                               passsing to functions that require positive values like isspacechar()
 
20
//                         - Removed unused visibleChars processing from ColourisePowerProDoc()
 
21
//                         - Fixed bug with folding logic where line continuations didn't end where 
 
22
//                               they were supposed to
 
23
//                         - Moved all helper functions to the top of the file
 
24
//
 
25
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
 
26
// The License.txt file describes the conditions under which this software may be distributed.
 
27
 
 
28
#include <ctype.h>
 
29
#include <stdarg.h>
 
30
#include <stdio.h>
 
31
#include <stdlib.h>
 
32
#include <string.h>
 
33
 
 
34
#include "Platform.h"
 
35
#include "PropSet.h"
 
36
#include "Accessor.h"
 
37
#include "StyleContext.h"
 
38
#include "KeyWords.h"
 
39
#include "Scintilla.h"
 
40
#include "SciLexer.h"
 
41
#include "CharacterSet.h"
 
42
 
 
43
#ifdef SCI_NAMESPACE
 
44
using namespace Scintilla;
 
45
#endif
 
46
 
 
47
static inline bool IsStreamCommentStyle(int style) {
 
48
        return style == SCE_POWERPRO_COMMENTBLOCK;
 
49
}
 
50
 
 
51
static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
 
52
{
 
53
        int nsPos = styler.LineStart(szLine);
 
54
        int nePos = styler.LineStart(szLine + 1) - 2;
 
55
        while (nsPos < nePos)
 
56
        {
 
57
                int stylech = styler.StyleAt(nsPos);
 
58
                if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {
 
59
                        char ch = styler.SafeGetCharAt(nePos);
 
60
                        char chPrev = styler.SafeGetCharAt(nePos-1);
 
61
                        char chPrevPrev = styler.SafeGetCharAt(nePos-2);
 
62
                        if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) {
 
63
                                if (chPrevPrev == ';' && chPrev == ';' && ch == '+')
 
64
                                        return true;
 
65
                                else
 
66
                                        return false;
 
67
                        }
 
68
                }
 
69
                nePos--; // skip to next char
 
70
        }
 
71
        return false;
 
72
}
 
73
 
 
74
// Routine to find first none space on the current line and return its Style
 
75
// needed for comment lines not starting on pos 1 
 
76
static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
 
77
{
 
78
        int nsPos = styler.LineStart(szLine);
 
79
        int nePos = styler.LineStart(szLine+1) - 1;
 
80
        char ch = styler.SafeGetCharAt(nsPos);
 
81
        
 
82
        while (ch > 0 && isspacechar(ch) && nsPos < nePos)
 
83
        {
 
84
                nsPos++; // skip to next char
 
85
                ch = styler.SafeGetCharAt(nsPos);
 
86
 
 
87
        }
 
88
        return styler.StyleAt(nsPos);
 
89
}
 
90
 
 
91
//returns true if there is a function to highlight
 
92
//used to highlight <name> in 'function <name>'
 
93
static bool HasFunction(Accessor &styler, unsigned int currentPos) {
 
94
        
 
95
        //check for presence of 'function '
 
96
        return  (styler.SafeGetCharAt(currentPos) == ' '        
 
97
        && tolower(styler.SafeGetCharAt(currentPos-1)) == 'n' 
 
98
        && tolower(styler.SafeGetCharAt(currentPos-2)) == 'o'
 
99
        && tolower(styler.SafeGetCharAt(currentPos-3)) == 'i'
 
100
        && tolower(styler.SafeGetCharAt(currentPos-4)) == 't'
 
101
        && tolower(styler.SafeGetCharAt(currentPos-5)) == 'c'
 
102
        && tolower(styler.SafeGetCharAt(currentPos-6)) == 'n'
 
103
        && tolower(styler.SafeGetCharAt(currentPos-7)) == 'u'
 
104
        && tolower(styler.SafeGetCharAt(currentPos-8)) == 'f'
 
105
        //only allow 'function ' to appear at the beginning of a line
 
106
        && (styler.SafeGetCharAt(currentPos-9) == '\n'                  
 
107
                || styler.SafeGetCharAt(currentPos-9) == '\r'
 
108
                || (styler.SafeGetCharAt(currentPos -9, '\0')) == '\0') //is the first line
 
109
        );
 
110
}
 
111
 
 
112
static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 
113
                            Accessor &styler, bool caseSensitive) {
 
114
 
 
115
        WordList &keywords  = *keywordlists[0];
 
116
        WordList &keywords2 = *keywordlists[1];
 
117
        WordList &keywords3 = *keywordlists[2];
 
118
        WordList &keywords4 = *keywordlists[3];
 
119
        
 
120
        //define the character sets 
 
121
        CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
 
122
        CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
 
123
 
 
124
        StyleContext sc(startPos, length, initStyle, styler);
 
125
        char s_save[100]; //for last line highlighting
 
126
        
 
127
        for (; sc.More(); sc.Forward()) {
 
128
                        
 
129
                // **********************************************
 
130
                // save the total current word for eof processing
 
131
                char s[100];
 
132
                sc.GetCurrentLowered(s, sizeof(s));
 
133
                 
 
134
                if ((sc.ch > 0) && setWord.Contains(sc.ch)) 
 
135
                {
 
136
                        strcpy(s_save,s);
 
137
                        int tp = strlen(s_save);
 
138
                        if (tp < 99) {
 
139
                                s_save[tp] = static_cast<char>(tolower(sc.ch));
 
140
                                s_save[tp+1] = '\0';
 
141
                        }
 
142
                }
 
143
                // **********************************************
 
144
                //
 
145
 
 
146
                if (sc.atLineStart) {
 
147
                        if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
 
148
                                // Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which
 
149
                                // ends with a line continuation by locking in the state upto this position.
 
150
                                sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
 
151
                        }
 
152
                }
 
153
 
 
154
                // Determine if the current state should terminate.
 
155
                switch (sc.state) {
 
156
                        case SCE_POWERPRO_OPERATOR:
 
157
                                sc.SetState(SCE_POWERPRO_DEFAULT);
 
158
                                break;
 
159
                        
 
160
                        case SCE_POWERPRO_NUMBER:
 
161
 
 
162
                                if (!IsADigit(sc.ch))
 
163
                                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
164
                                
 
165
                                break;
 
166
 
 
167
                        case SCE_POWERPRO_IDENTIFIER:
 
168
                                //if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized
 
169
                                if ((sc.ch > 0) && !setWord.Contains(sc.ch)){  // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately
 
170
                                        char s[1000];
 
171
                                        if (caseSensitive) {
 
172
                                                sc.GetCurrent(s, sizeof(s));
 
173
                                        } else {
 
174
                                                sc.GetCurrentLowered(s, sizeof(s));
 
175
                                        }
 
176
                                        if (keywords.InList(s)) {
 
177
                                                sc.ChangeState(SCE_POWERPRO_WORD);
 
178
                                        } else if (keywords2.InList(s)) {
 
179
                                                sc.ChangeState(SCE_POWERPRO_WORD2);
 
180
                                        } else if (keywords3.InList(s)) {
 
181
                                                sc.ChangeState(SCE_POWERPRO_WORD3);
 
182
                                        } else if (keywords4.InList(s)) {
 
183
                                                sc.ChangeState(SCE_POWERPRO_WORD4);
 
184
                                        }
 
185
                                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
186
                                }
 
187
                                break;
 
188
 
 
189
                        case SCE_POWERPRO_LINECONTINUE:
 
190
                                if (sc.atLineStart) {
 
191
                                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
192
                                } else if (sc.Match('/', '*') || sc.Match('/', '/')) {
 
193
                                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
194
                                }
 
195
                                break;
 
196
 
 
197
                        case SCE_POWERPRO_COMMENTBLOCK:
 
198
                                if (sc.Match('*', '/')) {
 
199
                                        sc.Forward();
 
200
                                        sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
 
201
                                }
 
202
                                break;
 
203
 
 
204
                        case SCE_POWERPRO_COMMENTLINE:
 
205
                                if (sc.atLineStart) {
 
206
                                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
207
                                }
 
208
                                break;
 
209
 
 
210
                        case SCE_POWERPRO_DOUBLEQUOTEDSTRING:
 
211
                                if (sc.atLineEnd) {
 
212
                                        sc.ChangeState(SCE_POWERPRO_STRINGEOL);
 
213
                                } else if (sc.ch == '\\') {
 
214
                                        if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 
215
                                                sc.Forward();
 
216
                                        }
 
217
                                } else if (sc.ch == '\"') {
 
218
                                        sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
 
219
                                }
 
220
                                break;
 
221
 
 
222
                        case SCE_POWERPRO_SINGLEQUOTEDSTRING:
 
223
                                if (sc.atLineEnd) {
 
224
                                        sc.ChangeState(SCE_POWERPRO_STRINGEOL);
 
225
                                } else if (sc.ch == '\\') {
 
226
                                        if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 
227
                                                sc.Forward();
 
228
                                        }
 
229
                                } else if (sc.ch == '\'') {
 
230
                                        sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
 
231
                                }
 
232
                                break;
 
233
 
 
234
                        case SCE_POWERPRO_STRINGEOL:
 
235
                                if (sc.atLineStart) {
 
236
                                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
237
                                }
 
238
                                break;
 
239
 
 
240
                        case SCE_POWERPRO_VERBATIM:
 
241
                                if (sc.ch == '\"') {
 
242
                                        if (sc.chNext == '\"') {
 
243
                                                sc.Forward();
 
244
                                        } else {
 
245
                                                sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
 
246
                                        }
 
247
                                }
 
248
                                break;
 
249
 
 
250
                        case SCE_POWERPRO_ALTQUOTE:
 
251
                                if (sc.ch == '#') {
 
252
                                        if (sc.chNext == '#') {
 
253
                                                sc.Forward();
 
254
                                        } else {
 
255
                                                sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
 
256
                                        }
 
257
                                }
 
258
                                break;
 
259
                                
 
260
                        case SCE_POWERPRO_FUNCTION:
 
261
                                if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') {
 
262
                                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
263
                                }
 
264
                        break;
 
265
                }
 
266
 
 
267
                // Determine if a new state should be entered.
 
268
                if (sc.state == SCE_POWERPRO_DEFAULT) {
 
269
                        if (sc.Match('?', '\"')) {
 
270
                                sc.SetState(SCE_POWERPRO_VERBATIM);
 
271
                                sc.Forward();
 
272
                        } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 
273
                                sc.SetState(SCE_POWERPRO_NUMBER);
 
274
                        }else if (sc.Match('?','#')) {
 
275
                                if (sc.ch == '?' && sc.chNext == '#') {
 
276
                                        sc.SetState(SCE_POWERPRO_ALTQUOTE);
 
277
                                        sc.Forward();
 
278
                                }
 
279
                        } else if (HasFunction(styler, sc.currentPos)) {        //highlight <name> in 'function <name>'
 
280
                                sc.SetState(SCE_POWERPRO_FUNCTION); 
 
281
                        } else if (sc.ch == '@' && sc.atLineStart) {            //alternate function definition [label]
 
282
                                sc.SetState(SCE_POWERPRO_FUNCTION);
 
283
                        } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {
 
284
                                sc.SetState(SCE_POWERPRO_IDENTIFIER);
 
285
                        } else if (sc.Match(";;+")) { 
 
286
                                sc.SetState(SCE_POWERPRO_LINECONTINUE);
 
287
                        } else if (sc.Match('/', '*')) {
 
288
                                sc.SetState(SCE_POWERPRO_COMMENTBLOCK);
 
289
                                sc.Forward();   // Eat the * so it isn't used for the end of the comment
 
290
                        } else if (sc.Match('/', '/')) {
 
291
                                sc.SetState(SCE_POWERPRO_COMMENTLINE);
 
292
                        } else if (sc.atLineStart && sc.ch == ';') {            //legacy comment that can only appear at the beginning of a line
 
293
                                sc.SetState(SCE_POWERPRO_COMMENTLINE);
 
294
                        } else if (sc.Match(";;")) {
 
295
                                sc.SetState(SCE_POWERPRO_COMMENTLINE);
 
296
                        } else if (sc.ch == '\"') {
 
297
                                sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
 
298
                        } else if (sc.ch == '\'') {
 
299
                                sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING);
 
300
                        } else if (isoperator(static_cast<char>(sc.ch))) {
 
301
                                sc.SetState(SCE_POWERPRO_OPERATOR);
 
302
                        }
 
303
                }
 
304
        }
 
305
 
 
306
        //*************************************
 
307
        // Colourize the last word correctly 
 
308
        //*************************************
 
309
        if (sc.state == SCE_POWERPRO_IDENTIFIER)
 
310
        {
 
311
                if (keywords.InList(s_save)) {
 
312
                        sc.ChangeState(SCE_POWERPRO_WORD);
 
313
                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
314
                }
 
315
                else if (keywords2.InList(s_save)) {
 
316
                        sc.ChangeState(SCE_POWERPRO_WORD2);
 
317
                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
318
                }
 
319
                else if (keywords3.InList(s_save)) {
 
320
                        sc.ChangeState(SCE_POWERPRO_WORD3);
 
321
                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
322
                }
 
323
                else if (keywords4.InList(s_save)) {
 
324
                        sc.ChangeState(SCE_POWERPRO_WORD4);
 
325
                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
326
                }
 
327
                else {
 
328
                        sc.SetState(SCE_POWERPRO_DEFAULT);
 
329
                }
 
330
        }
 
331
        sc.Complete();
 
332
}
 
333
 
 
334
static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
 
335
{
 
336
        //define the character sets
 
337
        CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
 
338
        CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
 
339
 
 
340
        bool isFoldingAll = true; //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
 
341
        int endPos = startPos + length;
 
342
        int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
 
343
 
 
344
        // get settings from the config files for folding comments and preprocessor lines
 
345
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 
346
        bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
 
347
        bool foldCompact = true;
 
348
        
 
349
        // Backtrack to previous line in case need to fix its fold status
 
350
        int lineCurrent = styler.GetLine(startPos);
 
351
        if (startPos > 0) {
 
352
                isFoldingAll = false;
 
353
                if (lineCurrent > 0) {
 
354
                        lineCurrent--;
 
355
                        startPos = styler.LineStart(lineCurrent);
 
356
                }
 
357
        }
 
358
        // vars for style of previous/current/next lines 
 
359
        int style = GetStyleFirstWord(lineCurrent,styler);
 
360
        int stylePrev = 0;
 
361
        
 
362
        // find the first previous line without continuation character at the end
 
363
        while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
 
364
               (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
 
365
                lineCurrent--;
 
366
                startPos = styler.LineStart(lineCurrent);
 
367
        }
 
368
        if (lineCurrent > 0) {
 
369
                stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
 
370
        }
 
371
        // vars for getting first word to check for keywords
 
372
        bool FirstWordStart = false;
 
373
        bool FirstWordEnd = false;
 
374
                
 
375
        const unsigned int KEYWORD_MAX = 10;
 
376
        char szKeyword[KEYWORD_MAX]="";
 
377
        unsigned int     szKeywordlen = 0;
 
378
        
 
379
        char szDo[3]="";
 
380
        int      szDolen = 0;
 
381
        bool DoFoundLast = false;
 
382
        
 
383
        // var for indentlevel
 
384
        int levelCurrent = SC_FOLDLEVELBASE;
 
385
        if (lineCurrent > 0) {
 
386
                levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 
387
        }
 
388
        int levelNext = levelCurrent;
 
389
        
 
390
        int     visibleChars = 0;
 
391
        int functionCount = 0;
 
392
        
 
393
        char chNext = styler.SafeGetCharAt(startPos);
 
394
        char chPrev = '\0';
 
395
        char chPrevPrev = '\0';
 
396
        char chPrevPrevPrev = '\0';
 
397
        
 
398
        for (int i = startPos; i < endPos; i++) {
 
399
 
 
400
                char ch = chNext;
 
401
                chNext = styler.SafeGetCharAt(i + 1);
 
402
                
 
403
                if ((ch > 0) && setWord.Contains(ch)) {
 
404
                        visibleChars++;
 
405
                }
 
406
                
 
407
                // get the syle for the current character neede to check in comment
 
408
                int stylech = styler.StyleAt(i);
 
409
                
 
410
                // get first word for the line for indent check max 9 characters
 
411
                if (FirstWordStart && (!(FirstWordEnd))) {
 
412
                        if ((ch > 0) && !setWord.Contains(ch)) {
 
413
                                FirstWordEnd = true;
 
414
                        }
 
415
                        else if (szKeywordlen < KEYWORD_MAX - 1) {
 
416
                                szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
 
417
                                szKeyword[szKeywordlen] = '\0';
 
418
                        }
 
419
                }
 
420
                
 
421
                // start the capture of the first word 
 
422
                if (!(FirstWordStart)) {
 
423
                        if ((ch > 0) && (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/')) {
 
424
                                FirstWordStart = true;
 
425
                                if (szKeywordlen < KEYWORD_MAX - 1) {
 
426
                                        szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
 
427
                                        szKeyword[szKeywordlen] = '\0';
 
428
                                }
 
429
                        }
 
430
                }
 
431
                // only process this logic when not in comment section
 
432
                if (stylech != SCE_POWERPRO_COMMENTLINE) {
 
433
                        if (DoFoundLast) {
 
434
                                if (DoFoundLast && (ch > 0) && setWord.Contains(ch)) {
 
435
                                        DoFoundLast = false;
 
436
                                }               
 
437
                        }
 
438
                        // find out if the word "do" is the last on a "if" line
 
439
                        if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
 
440
                                if (szDolen == 2) {
 
441
                                        szDo[0] = szDo[1];
 
442
                                        szDo[1] = static_cast<char>(tolower(ch));
 
443
                                        szDo[2] = '\0';
 
444
                                        if (strcmp(szDo,"do") == 0 ) {
 
445
                                                DoFoundLast = true;
 
446
                                        }
 
447
                                }
 
448
                                else if (szDolen < 2) {
 
449
                                        szDo[szDolen++] = static_cast<char>(tolower(ch));
 
450
                                        szDo[szDolen] = '\0';
 
451
                                }
 
452
                        }
 
453
                }
 
454
 
 
455
                // End of Line found so process the information 
 
456
                 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
 
457
                 
 
458
                        // **************************
 
459
                        // Folding logic for Keywords
 
460
                        // **************************
 
461
                        
 
462
                        // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)
 
463
                        //    and we are not inside a commentblock.
 
464
                        if (szKeywordlen > 0 && 
 
465
                                (!(chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev ==';')) && 
 
466
                                ((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
 
467
                        
 
468
                                // only fold "if" last keyword is "then"  (else its a one line if)
 
469
                                if (strcmp(szKeyword,"if") == 0  && DoFoundLast) {
 
470
                                                levelNext++;
 
471
                                }
 
472
                                // create new fold for these words 
 
473
                                if (strcmp(szKeyword,"for") == 0) {
 
474
                                        levelNext++;
 
475
                                }
 
476
                                
 
477
                                //handle folding for functions/labels
 
478
                                //Note: Functions and labels don't have an explicit end like [end function]
 
479
                                //      1. functions/labels end at the start of another function
 
480
                                //      2. functions/labels end at the end of the file
 
481
                                if ((strcmp(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) {
 
482
                                        if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
 
483
                                                
 
484
                                                if (functionCount > 0) {
 
485
                                                        levelCurrent--;
 
486
                                                } else {
 
487
                                                        levelNext++;
 
488
                                                }
 
489
                                                functionCount++;        
 
490
                                                
 
491
                                        } else { //if just folding a small piece (by clicking on the minus sign next to the word)
 
492
                                                levelCurrent--;
 
493
                                        }
 
494
                                }
 
495
                                                                                                
 
496
                                // end the fold for these words before the current line
 
497
                                if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) {
 
498
                                                levelNext--;
 
499
                                                levelCurrent--;
 
500
                                }
 
501
                                // end the fold for these words before the current line and Start new fold 
 
502
                                if (strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) {
 
503
                                                levelCurrent--;
 
504
                                }
 
505
                        }
 
506
                        // Preprocessor and Comment folding
 
507
                        int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
 
508
 
 
509
                        // *********************************
 
510
                        // Folding logic for Comment blocks
 
511
                        // *********************************
 
512
                        if (foldComment && IsStreamCommentStyle(style)) {
 
513
                                // Start of a comment block
 
514
                                if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
 
515
                                    levelNext++;
 
516
                                } 
 
517
                                // fold till the last line for normal comment lines
 
518
                                else if (IsStreamCommentStyle(stylePrev) 
 
519
                                                && !(styleNext == SCE_POWERPRO_COMMENTLINE)
 
520
                                                && stylePrev == SCE_POWERPRO_COMMENTLINE 
 
521
                                                && style == SCE_POWERPRO_COMMENTLINE) {
 
522
                                        levelNext--;
 
523
                                }
 
524
                                // fold till the one but last line for Blockcomment lines
 
525
                                else if (IsStreamCommentStyle(stylePrev) 
 
526
                                                && !(styleNext == SCE_POWERPRO_COMMENTBLOCK)
 
527
                                                && style == SCE_POWERPRO_COMMENTBLOCK) {
 
528
                                        levelNext--;
 
529
                                        levelCurrent--;
 
530
                                }
 
531
                        }
 
532
 
 
533
                        int levelUse = levelCurrent;
 
534
                        int lev = levelUse | levelNext << 16;
 
535
                        if (visibleChars == 0 && foldCompact)
 
536
                                lev |= SC_FOLDLEVELWHITEFLAG;
 
537
                        if (levelUse < levelNext) {
 
538
                                lev |= SC_FOLDLEVELHEADERFLAG;
 
539
                        }
 
540
                        if (lev != styler.LevelAt(lineCurrent)) {
 
541
                                styler.SetLevel(lineCurrent, lev);
 
542
                        }
 
543
 
 
544
                        // reset values for the next line
 
545
                        lineCurrent++;
 
546
                        stylePrev = style;
 
547
                        style = styleNext;
 
548
                        levelCurrent = levelNext;
 
549
                        visibleChars = 0;
 
550
                        
 
551
                        // if the last characters are ;;+ then don't reset since the line continues on the next line.
 
552
                        if (chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev == ';') {
 
553
                                //do nothing
 
554
                        } else {
 
555
                                szKeywordlen = 0;
 
556
                                szDolen = 0;
 
557
                                FirstWordStart = false;
 
558
                                FirstWordEnd = false;
 
559
                                DoFoundLast = false;
 
560
                                //blank out keyword
 
561
                                for (unsigned int i = 0; i < KEYWORD_MAX; i++) {
 
562
                                        szKeyword[i] = '\0';
 
563
                                }
 
564
                        }
 
565
                }
 
566
 
 
567
                // save the last processed characters
 
568
                if ((ch > 0) && !isspacechar(ch)) {
 
569
                        chPrevPrevPrev = chPrevPrev;
 
570
                        chPrevPrev = chPrev;
 
571
                        chPrev = ch;
 
572
                        visibleChars++;
 
573
                }
 
574
        }
 
575
 
 
576
        //close folds on the last line - without this a 'phantom' 
 
577
        //fold can appear when an open fold is on the last line
 
578
        //this can occur because functions and labels don't have an explicit end
 
579
        if (lineCurrent >= lastLine) {
 
580
                int lev = 0;
 
581
                lev |= SC_FOLDLEVELWHITEFLAG;
 
582
                styler.SetLevel(lineCurrent, lev);
 
583
        }
 
584
 
 
585
}
 
586
 
 
587
static const char * const powerProWordLists[] = {
 
588
            "Keyword list 1",
 
589
            "Keyword list 2",
 
590
            "Keyword list 3",
 
591
            "Keyword list 4",
 
592
            0,
 
593
        };
 
594
 
 
595
static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 
596
                                       Accessor &styler) {
 
597
        ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false);
 
598
}
 
599
 
 
600
LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);