~ubuntu-branches/ubuntu/trusty/presage/trusty-proposed

« back to all changes in this revision

Viewing changes to apps/gtk/gprompter/scintilla/lexers/LexNsis.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Matteo Vescovi
  • Date: 2011-08-06 09:26:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110806092615-0wvhajaht9974ncx
Tags: upstream-0.8.6
ImportĀ upstreamĀ versionĀ 0.8.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
/** @file LexNsis.cxx
 
3
 ** Lexer for NSIS
 
4
 **/
 
5
// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
 
6
// Last Updated: 03/13/2005
 
7
// The License.txt file describes the conditions under which this software may be distributed.
 
8
 
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
#include <stdio.h>
 
12
#include <stdarg.h>
 
13
#include <assert.h>
 
14
#include <ctype.h>
 
15
 
 
16
#include "ILexer.h"
 
17
#include "Scintilla.h"
 
18
#include "SciLexer.h"
 
19
 
 
20
#include "WordList.h"
 
21
#include "LexAccessor.h"
 
22
#include "Accessor.h"
 
23
#include "StyleContext.h"
 
24
#include "CharacterSet.h"
 
25
#include "LexerModule.h"
 
26
 
 
27
#ifdef SCI_NAMESPACE
 
28
using namespace Scintilla;
 
29
#endif
 
30
 
 
31
/*
 
32
// located in SciLexer.h
 
33
#define SCLEX_NSIS 43
 
34
 
 
35
#define SCE_NSIS_DEFAULT 0
 
36
#define SCE_NSIS_COMMENT 1
 
37
#define SCE_NSIS_STRINGDQ 2
 
38
#define SCE_NSIS_STRINGLQ 3
 
39
#define SCE_NSIS_STRINGRQ 4
 
40
#define SCE_NSIS_FUNCTION 5
 
41
#define SCE_NSIS_VARIABLE 6
 
42
#define SCE_NSIS_LABEL 7
 
43
#define SCE_NSIS_USERDEFINED 8
 
44
#define SCE_NSIS_SECTIONDEF 9
 
45
#define SCE_NSIS_SUBSECTIONDEF 10
 
46
#define SCE_NSIS_IFDEFINEDEF 11
 
47
#define SCE_NSIS_MACRODEF 12
 
48
#define SCE_NSIS_STRINGVAR 13
 
49
#define SCE_NSIS_NUMBER 14
 
50
// ADDED for Scintilla v1.63
 
51
#define SCE_NSIS_SECTIONGROUP 15
 
52
#define SCE_NSIS_PAGEEX 16
 
53
#define SCE_NSIS_FUNCTIONDEF 17
 
54
#define SCE_NSIS_COMMENTBOX 18
 
55
*/
 
56
 
 
57
static bool isNsisNumber(char ch)
 
58
{
 
59
  return (ch >= '0' && ch <= '9');
 
60
}
 
61
 
 
62
static bool isNsisChar(char ch)
 
63
{
 
64
  return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
 
65
}
 
66
 
 
67
static bool isNsisLetter(char ch)
 
68
{
 
69
  return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
 
70
}
 
71
 
 
72
static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
 
73
{
 
74
  int nNextLine = -1;
 
75
  for( unsigned int i = start; i < end; i++ )
 
76
  {
 
77
    char cNext = styler.SafeGetCharAt( i );
 
78
    if( cNext == '\n' )
 
79
    {
 
80
      nNextLine = i+1;
 
81
      break;
 
82
    }
 
83
  }
 
84
 
 
85
  if( nNextLine == -1 ) // We never found the next line...
 
86
    return false;
 
87
 
 
88
  for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
 
89
  {
 
90
    char cNext = styler.SafeGetCharAt( firstChar );
 
91
    if( cNext == ' ' )
 
92
      continue;
 
93
    if( cNext == '\t' )
 
94
      continue;
 
95
    if( cNext == '!' )
 
96
    {
 
97
      if( styler.Match(firstChar, "!else") )
 
98
        return true;
 
99
    }
 
100
    break;
 
101
  }
 
102
 
 
103
  return false;
 
104
}
 
105
 
 
106
static int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase )
 
107
{
 
108
  if( bIgnoreCase )
 
109
     return CompareCaseInsensitive( s1, s2);
 
110
 
 
111
  return strcmp( s1, s2 );
 
112
}
 
113
 
 
114
static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
 
115
{
 
116
  int style = styler.StyleAt(end);
 
117
 
 
118
  // If the word is too long, it is not what we are looking for
 
119
  if( end - start > 20 )
 
120
    return foldlevel;
 
121
 
 
122
  if( foldUtilityCmd )
 
123
  {
 
124
    // Check the style at this point, if it is not valid, then return zero
 
125
    if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
 
126
        style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
 
127
        style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
 
128
        style != SCE_NSIS_PAGEEX )
 
129
          return foldlevel;
 
130
  }
 
131
  else
 
132
  {
 
133
    if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
 
134
        style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
 
135
        style != SCE_NSIS_PAGEEX )
 
136
          return foldlevel;
 
137
  }
 
138
 
 
139
  int newFoldlevel = foldlevel;
 
140
  bool bIgnoreCase = false;
 
141
  if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
 
142
    bIgnoreCase = true;
 
143
 
 
144
  char s[20]; // The key word we are looking for has atmost 13 characters
 
145
  for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
 
146
        {
 
147
                s[i] = static_cast<char>( styler[ start + i ] );
 
148
                s[i + 1] = '\0';
 
149
        }
 
150
 
 
151
  if( s[0] == '!' )
 
152
  {
 
153
    if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
 
154
      newFoldlevel++;
 
155
    else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
 
156
      newFoldlevel--;
 
157
    else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
 
158
      newFoldlevel++;
 
159
  }
 
160
  else
 
161
  {
 
162
    if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
 
163
      newFoldlevel++;
 
164
    else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
 
165
      newFoldlevel--;
 
166
  }
 
167
 
 
168
  return newFoldlevel;
 
169
}
 
170
 
 
171
static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
 
172
{
 
173
  bool bIgnoreCase = false;
 
174
  if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
 
175
    bIgnoreCase = true;
 
176
 
 
177
  bool bUserVars = false;
 
178
  if( styler.GetPropertyInt("nsis.uservars") == 1 )
 
179
    bUserVars = true;
 
180
 
 
181
        char s[100];
 
182
 
 
183
        WordList &Functions = *keywordLists[0];
 
184
        WordList &Variables = *keywordLists[1];
 
185
        WordList &Lables = *keywordLists[2];
 
186
        WordList &UserDefined = *keywordLists[3];
 
187
 
 
188
        for (unsigned int i = 0; i < end - start + 1 && i < 99; i++)
 
189
        {
 
190
    if( bIgnoreCase )
 
191
      s[i] = static_cast<char>( tolower(styler[ start + i ] ) );
 
192
    else
 
193
                  s[i] = static_cast<char>( styler[ start + i ] );
 
194
                s[i + 1] = '\0';
 
195
        }
 
196
 
 
197
        // Check for special words...
 
198
        if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend
 
199
                return SCE_NSIS_MACRODEF;
 
200
 
 
201
        if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 ||  NsisCmp(s, "!ifndef", bIgnoreCase) == 0 ||  NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif
 
202
                return SCE_NSIS_IFDEFINEDEF;
 
203
 
 
204
        if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase )  == 0 ) // Covers !if and else
 
205
                return SCE_NSIS_IFDEFINEDEF;
 
206
 
 
207
        if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase )  == 0 ) // Covers !ifmacrodef and !ifnmacrodef
 
208
                return SCE_NSIS_IFDEFINEDEF;
 
209
 
 
210
  if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
 
211
    return SCE_NSIS_SECTIONGROUP;
 
212
 
 
213
        if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
 
214
                return SCE_NSIS_SECTIONDEF;
 
215
 
 
216
        if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
 
217
                return SCE_NSIS_SUBSECTIONDEF;
 
218
 
 
219
  if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
 
220
    return SCE_NSIS_PAGEEX;
 
221
 
 
222
        if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
 
223
                return SCE_NSIS_FUNCTIONDEF;
 
224
 
 
225
        if ( Functions.InList(s) )
 
226
                return SCE_NSIS_FUNCTION;
 
227
 
 
228
        if ( Variables.InList(s) )
 
229
                return SCE_NSIS_VARIABLE;
 
230
 
 
231
        if ( Lables.InList(s) )
 
232
                return SCE_NSIS_LABEL;
 
233
 
 
234
        if( UserDefined.InList(s) )
 
235
                return SCE_NSIS_USERDEFINED;
 
236
 
 
237
        if( strlen(s) > 3 )
 
238
        {
 
239
                if( s[1] == '{' && s[strlen(s)-1] == '}' )
 
240
                        return SCE_NSIS_VARIABLE;
 
241
        }
 
242
 
 
243
  // See if the variable is a user defined variable
 
244
  if( s[0] == '$' && bUserVars )
 
245
  {
 
246
    bool bHasSimpleNsisChars = true;
 
247
    for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
 
248
          {
 
249
      if( !isNsisChar( s[j] ) )
 
250
      {
 
251
        bHasSimpleNsisChars = false;
 
252
        break;
 
253
      }
 
254
          }
 
255
 
 
256
    if( bHasSimpleNsisChars )
 
257
      return SCE_NSIS_VARIABLE;
 
258
  }
 
259
 
 
260
  // To check for numbers
 
261
  if( isNsisNumber( s[0] ) )
 
262
  {
 
263
    bool bHasSimpleNsisNumber = true;
 
264
    for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
 
265
          {
 
266
      if( !isNsisNumber( s[j] ) )
 
267
      {
 
268
        bHasSimpleNsisNumber = false;
 
269
        break;
 
270
      }
 
271
          }
 
272
 
 
273
    if( bHasSimpleNsisNumber )
 
274
      return SCE_NSIS_NUMBER;
 
275
  }
 
276
 
 
277
        return SCE_NSIS_DEFAULT;
 
278
}
 
279
 
 
280
static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
 
281
{
 
282
        int state = SCE_NSIS_DEFAULT;
 
283
  if( startPos > 0 )
 
284
    state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
 
285
 
 
286
        styler.StartAt( startPos );
 
287
        styler.GetLine( startPos );
 
288
 
 
289
        unsigned int nLengthDoc = startPos + length;
 
290
        styler.StartSegment( startPos );
 
291
 
 
292
        char cCurrChar;
 
293
        bool bVarInString = false;
 
294
  bool bClassicVarInString = false;
 
295
 
 
296
        unsigned int i;
 
297
        for( i = startPos; i < nLengthDoc; i++ )
 
298
        {
 
299
                cCurrChar = styler.SafeGetCharAt( i );
 
300
                char cNextChar = styler.SafeGetCharAt(i+1);
 
301
 
 
302
                switch(state)
 
303
                {
 
304
                        case SCE_NSIS_DEFAULT:
 
305
                                if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line
 
306
                                {
 
307
                                        styler.ColourTo(i-1, state );
 
308
                                        state = SCE_NSIS_COMMENT;
 
309
                                        break;
 
310
                                }
 
311
                                if( cCurrChar == '"' )
 
312
                                {
 
313
                                        styler.ColourTo(i-1, state );
 
314
                                        state = SCE_NSIS_STRINGDQ;
 
315
                                        bVarInString = false;
 
316
          bClassicVarInString = false;
 
317
                                        break;
 
318
                                }
 
319
                                if( cCurrChar == '\'' )
 
320
                                {
 
321
                                        styler.ColourTo(i-1, state );
 
322
                                        state = SCE_NSIS_STRINGRQ;
 
323
                                        bVarInString = false;
 
324
          bClassicVarInString = false;
 
325
                                        break;
 
326
                                }
 
327
                                if( cCurrChar == '`' )
 
328
                                {
 
329
                                        styler.ColourTo(i-1, state );
 
330
                                        state = SCE_NSIS_STRINGLQ;
 
331
                                        bVarInString = false;
 
332
          bClassicVarInString = false;
 
333
                                        break;
 
334
                                }
 
335
 
 
336
                                // NSIS KeyWord,Function, Variable, UserDefined:
 
337
                                if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )
 
338
                                {
 
339
                                        styler.ColourTo(i-1,state);
 
340
                                  state = SCE_NSIS_FUNCTION;
 
341
 
 
342
          // If it is a number, we must check and set style here first...
 
343
          if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
 
344
              styler.ColourTo( i, SCE_NSIS_NUMBER);
 
345
 
 
346
                                        break;
 
347
                                }
 
348
 
 
349
        if( cCurrChar == '/' && cNextChar == '*' )
 
350
        {
 
351
          styler.ColourTo(i-1,state);
 
352
          state = SCE_NSIS_COMMENTBOX;
 
353
          break;
 
354
        }
 
355
 
 
356
                                break;
 
357
                        case SCE_NSIS_COMMENT:
 
358
                                if( cNextChar == '\n' || cNextChar == '\r' )
 
359
        {
 
360
          // Special case:
 
361
          if( cCurrChar == '\\' )
 
362
          {
 
363
            styler.ColourTo(i-2,state);
 
364
            styler.ColourTo(i,SCE_NSIS_DEFAULT);
 
365
          }
 
366
          else
 
367
          {
 
368
                                    styler.ColourTo(i,state);
 
369
            state = SCE_NSIS_DEFAULT;
 
370
          }
 
371
        }
 
372
                                break;
 
373
                        case SCE_NSIS_STRINGDQ:
 
374
      case SCE_NSIS_STRINGLQ:
 
375
      case SCE_NSIS_STRINGRQ:
 
376
 
 
377
        if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
 
378
          break; // Ignore the next character, even if it is a quote of some sort
 
379
 
 
380
        if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
 
381
                                {
 
382
                                        styler.ColourTo(i,state);
 
383
                                  state = SCE_NSIS_DEFAULT;
 
384
          break;
 
385
                                }
 
386
 
 
387
        if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
 
388
        {
 
389
                                        styler.ColourTo(i,state);
 
390
                                  state = SCE_NSIS_DEFAULT;
 
391
          break;
 
392
                                }
 
393
 
 
394
        if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
 
395
                                {
 
396
                                        styler.ColourTo(i,state);
 
397
                                  state = SCE_NSIS_DEFAULT;
 
398
          break;
 
399
                                }
 
400
 
 
401
        if( cNextChar == '\r' || cNextChar == '\n' )
 
402
        {
 
403
          int nCurLine = styler.GetLine(i+1);
 
404
          int nBack = i;
 
405
          // We need to check if the previous line has a \ in it...
 
406
          bool bNextLine = false;
 
407
 
 
408
          while( nBack > 0 )
 
409
          {
 
410
            if( styler.GetLine(nBack) != nCurLine )
 
411
              break;
 
412
 
 
413
            char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
 
414
 
 
415
            if( cTemp == '\\' )
 
416
            {
 
417
              bNextLine = true;
 
418
              break;
 
419
            }
 
420
            if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
 
421
              break;
 
422
 
 
423
            nBack--;
 
424
          }
 
425
 
 
426
          if( bNextLine )
 
427
          {
 
428
            styler.ColourTo(i+1,state);
 
429
          }
 
430
          if( bNextLine == false )
 
431
          {
 
432
            styler.ColourTo(i,state);
 
433
                                    state = SCE_NSIS_DEFAULT;
 
434
          }
 
435
        }
 
436
                                break;
 
437
 
 
438
                        case SCE_NSIS_FUNCTION:
 
439
 
 
440
                                // NSIS KeyWord:
 
441
        if( cCurrChar == '$' )
 
442
          state = SCE_NSIS_DEFAULT;
 
443
        else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
 
444
          state = SCE_NSIS_DEFAULT;
 
445
                                else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
 
446
                                {
 
447
                                        state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
 
448
                                        styler.ColourTo( i, state);
 
449
                                        state = SCE_NSIS_DEFAULT;
 
450
                                }
 
451
                                else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )
 
452
                                {
 
453
          if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )
 
454
             styler.ColourTo( i-1, SCE_NSIS_NUMBER );
 
455
 
 
456
                                        state = SCE_NSIS_DEFAULT;
 
457
 
 
458
                                        if( cCurrChar == '"' )
 
459
                                        {
 
460
                                                state = SCE_NSIS_STRINGDQ;
 
461
                                                bVarInString = false;
 
462
            bClassicVarInString = false;
 
463
                                        }
 
464
                                        else if( cCurrChar == '`' )
 
465
                                        {
 
466
                                                state = SCE_NSIS_STRINGLQ;
 
467
                                                bVarInString = false;
 
468
            bClassicVarInString = false;
 
469
                                        }
 
470
                                        else if( cCurrChar == '\'' )
 
471
                                        {
 
472
                                                state = SCE_NSIS_STRINGRQ;
 
473
                                                bVarInString = false;
 
474
            bClassicVarInString = false;
 
475
                                        }
 
476
                                        else if( cCurrChar == '#' || cCurrChar == ';' )
 
477
          {
 
478
                                                state = SCE_NSIS_COMMENT;
 
479
          }
 
480
                                }
 
481
                                break;
 
482
      case SCE_NSIS_COMMENTBOX:
 
483
 
 
484
        if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
 
485
        {
 
486
          styler.ColourTo(i,state);
 
487
          state = SCE_NSIS_DEFAULT;
 
488
        }
 
489
        break;
 
490
                }
 
491
 
 
492
                if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
 
493
                {
 
494
                        styler.ColourTo(i,state);
 
495
                }
 
496
                else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )
 
497
                {
 
498
      bool bIngoreNextDollarSign = false;
 
499
      bool bUserVars = false;
 
500
      if( styler.GetPropertyInt("nsis.uservars") == 1 )
 
501
        bUserVars = true;
 
502
 
 
503
      if( bVarInString && cCurrChar == '$' )
 
504
      {
 
505
        bVarInString = false;
 
506
        bIngoreNextDollarSign = true;
 
507
      }
 
508
      else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
 
509
      {
 
510
        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
 
511
        bVarInString = false;
 
512
        bIngoreNextDollarSign = false;
 
513
      }
 
514
 
 
515
      // Covers "$INSTDIR and user vars like $MYVAR"
 
516
      else if( bVarInString && !isNsisChar(cNextChar) )
 
517
      {
 
518
        int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
 
519
                                if( nWordState == SCE_NSIS_VARIABLE )
 
520
                                        styler.ColourTo( i, SCE_NSIS_STRINGVAR);
 
521
        else if( bUserVars )
 
522
          styler.ColourTo( i, SCE_NSIS_STRINGVAR);
 
523
        bVarInString = false;
 
524
      }
 
525
      // Covers "${TEST}..."
 
526
      else if( bClassicVarInString && cNextChar == '}' )
 
527
      {
 
528
        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
 
529
                                bClassicVarInString = false;
 
530
      }
 
531
 
 
532
      // Start of var in string
 
533
                        if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )
 
534
                        {
 
535
                                styler.ColourTo( i-1, state);
 
536
                                bClassicVarInString = true;
 
537
        bVarInString = false;
 
538
                        }
 
539
      else if( !bIngoreNextDollarSign && cCurrChar == '$' )
 
540
      {
 
541
        styler.ColourTo( i-1, state);
 
542
        bVarInString = true;
 
543
        bClassicVarInString = false;
 
544
      }
 
545
                }
 
546
        }
 
547
 
 
548
  // Colourise remaining document
 
549
        styler.ColourTo(nLengthDoc-1,state);
 
550
}
 
551
 
 
552
static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
 
553
{
 
554
        // No folding enabled, no reason to continue...
 
555
        if( styler.GetPropertyInt("fold") == 0 )
 
556
                return;
 
557
 
 
558
  bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
 
559
  bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
 
560
  bool blockComment = false;
 
561
 
 
562
  int lineCurrent = styler.GetLine(startPos);
 
563
  unsigned int safeStartPos = styler.LineStart( lineCurrent );
 
564
 
 
565
  bool bArg1 = true;
 
566
  int nWordStart = -1;
 
567
 
 
568
  int levelCurrent = SC_FOLDLEVELBASE;
 
569
        if (lineCurrent > 0)
 
570
                levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 
571
        int levelNext = levelCurrent;
 
572
  int style = styler.StyleAt(safeStartPos);
 
573
  if( style == SCE_NSIS_COMMENTBOX )
 
574
  {
 
575
    if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
 
576
      levelNext++;
 
577
    blockComment = true;
 
578
  }
 
579
 
 
580
  for (unsigned int i = safeStartPos; i < startPos + length; i++)
 
581
        {
 
582
    char chCurr = styler.SafeGetCharAt(i);
 
583
    style = styler.StyleAt(i);
 
584
    if( blockComment && style != SCE_NSIS_COMMENTBOX )
 
585
    {
 
586
      levelNext--;
 
587
      blockComment = false;
 
588
    }
 
589
    else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
 
590
    {
 
591
      levelNext++;
 
592
      blockComment = true;
 
593
    }
 
594
 
 
595
    if( bArg1 && !blockComment)
 
596
    {
 
597
      if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
 
598
      {
 
599
        nWordStart = i;
 
600
      }
 
601
      else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
 
602
      {
 
603
        int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
 
604
 
 
605
        if( newLevel == levelNext )
 
606
        {
 
607
          if( foldAtElse && foldUtilityCmd )
 
608
          {
 
609
            if( NsisNextLineHasElse(i, startPos + length, styler) )
 
610
              levelNext--;
 
611
          }
 
612
        }
 
613
        else
 
614
          levelNext = newLevel;
 
615
        bArg1 = false;
 
616
      }
 
617
    }
 
618
 
 
619
    if( chCurr == '\n' )
 
620
    {
 
621
      if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
 
622
      {
 
623
        if( NsisNextLineHasElse(i, startPos + length, styler) )
 
624
          levelNext--;
 
625
      }
 
626
 
 
627
      // If we are on a new line...
 
628
      int levelUse = levelCurrent;
 
629
                        int lev = levelUse | levelNext << 16;
 
630
      if (levelUse < levelNext )
 
631
                                lev |= SC_FOLDLEVELHEADERFLAG;
 
632
                        if (lev != styler.LevelAt(lineCurrent))
 
633
                                styler.SetLevel(lineCurrent, lev);
 
634
 
 
635
                        lineCurrent++;
 
636
                        levelCurrent = levelNext;
 
637
      bArg1 = true; // New line, lets look at first argument again
 
638
      nWordStart = -1;
 
639
    }
 
640
  }
 
641
 
 
642
        int levelUse = levelCurrent;
 
643
        int lev = levelUse | levelNext << 16;
 
644
        if (levelUse < levelNext)
 
645
                lev |= SC_FOLDLEVELHEADERFLAG;
 
646
        if (lev != styler.LevelAt(lineCurrent))
 
647
                styler.SetLevel(lineCurrent, lev);
 
648
}
 
649
 
 
650
static const char * const nsisWordLists[] = {
 
651
        "Functions",
 
652
        "Variables",
 
653
        "Lables",
 
654
        "UserDefined",
 
655
        0, };
 
656
 
 
657
 
 
658
LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
 
659