1 skipped line |
2 | | 2 | | /** @file LexNsis.cxx |
|
|
|
5 | | // Copyright 2003, 2004 by Angelo Mandato <angelo [at] spaceblue [dot] com> | | 5 | | // Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com> |
6 | | // Last Updated: 02/22/2004 | | 6 | | // Last Updated: 03/13/2005 |
7 | | 7 | | // The License.txt file describes the conditions under which this software may be distributed. |
|
|
|
28 skipped lines |
38 | | 38 | | #define SCE_NSIS_MACRODEF 12 |
|
39 | | 39 | | #define SCE_NSIS_STRINGVAR 13 |
|
40 | | 40 | | #define SCE_NSIS_NUMBER 14 |
|
| | 41 | | // ADDED for Scintilla v1.63 |
| | 42 | | #define SCE_NSIS_SECTIONGROUP 15 |
| | 43 | | #define SCE_NSIS_PAGEEX 16 |
| | 44 | | #define SCE_NSIS_FUNCTIONDEF 17 |
| | 45 | | #define SCE_NSIS_COMMENTBOX 18 |
|
|
43 | | 48 | | static bool isNsisNumber(char ch) |
|
11 skipped lines |
55 | | 60 | | return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); |
|
|
|
| | 63 | | static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler) |
| | 64 | | { |
| | 65 | | int nNextLine = -1; |
| | 66 | | for( unsigned int i = start; i < end; i++ ) |
| | 67 | | { |
24 skipped lines |
| | 92 | | } |
| | 93 | | |
| | 94 | | return false; |
| | 95 | | } |
| | 96 | | |
58 | | 97 | | static int NsisCmp( char *s1, char *s2, bool bIgnoreCase ) |
|
|
|
2 skipped lines |
63 | | 102 | | return strcmp( s1, s2 ); |
|
|
|
66 | | static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler ) | | 105 | | static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd ) |
|
| | 107 | | int style = styler.StyleAt(end); |
| | 108 | | |
68 | | 109 | | // If the word is too long, it is not what we are looking for |
|
69 | | if( end - start > 13 ) | | 110 | | if( end - start > 20 ) |
|
|
| | 113 | | if( foldUtilityCmd ) |
| | 114 | | { |
72 | | // Check the style at this point, if it is not valid, then return zero | | 115 | | // Check the style at this point, if it is not valid, then return zero |
73 | | if( styler.StyleAt(end) != SCE_NSIS_FUNCTION && styler.StyleAt(end) != SCE_NSIS_SECTIONDEF && | | 116 | | if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF && |
74 | | styler.StyleAt(end) != SCE_NSIS_SUBSECTIONDEF && styler.StyleAt(end) != SCE_NSIS_IFDEFINEDEF && | | 117 | | style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF && |
75 | | styler.StyleAt(end) != SCE_NSIS_MACRODEF ) | | 118 | | style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP && |
| | 119 | | style != SCE_NSIS_PAGEEX ) |
| | 120 | | return foldlevel; |
| | 121 | | } |
| | 122 | | else |
| | 123 | | { |
| | 124 | | if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF && |
| | 125 | | style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP && |
| | 126 | | style != SCE_NSIS_PAGEEX ) |
76 | | return foldlevel; | | 127 | | return foldlevel; |
| | 128 | | } |
|
78 | | 130 | | int newFoldlevel = foldlevel; |
|
79 | | 131 | | bool bIgnoreCase = false; |
|
80 | | 132 | | if( styler.GetPropertyInt("nsis.ignorecase") == 1 ) |
|
81 | | 133 | | bIgnoreCase = true; |
|
|
83 | | char s[15]; // The key word we are looking for has atmost 13 characters | | 135 | | char s[20]; // The key word we are looking for has atmost 13 characters |
84 | | for (unsigned int i = 0; i < end - start + 1 && i < 14; i++) | | 136 | | for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) |
|
86 | | 138 | | s[i] = static_cast<char>( styler[ start + i ] ); |
|
|
5 skipped lines |
|
94 | | 146 | | else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 ) |
|
|
| | 148 | | else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 ) |
| | 149 | | newFoldlevel++; |
|
|
|
99 | | if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 ) | | 153 | | 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 ) |
|
101 | | else if( NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 ) | | 155 | | 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 ) |
|
|
104 | | | | 158 | | |
105 | | 159 | | return newFoldlevel; |
|
|
|
30 skipped lines |
138 | | 192 | | if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 ) |
|
139 | | 193 | | return SCE_NSIS_IFDEFINEDEF; |
|
|
| | 195 | | if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 ) |
| | 196 | | return SCE_NSIS_IFDEFINEDEF; |
| | 197 | | |
| | 198 | | if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd |
| | 199 | | return SCE_NSIS_SECTIONGROUP; |
| | 200 | | |
141 | | 201 | | if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd |
|
142 | | 202 | | return SCE_NSIS_SECTIONDEF; |
|
|
144 | | 204 | | if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd |
|
145 | | 205 | | return SCE_NSIS_SUBSECTIONDEF; |
|
|
| | 207 | | if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd |
| | 208 | | return SCE_NSIS_PAGEEX; |
| | 209 | | |
147 | | if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd | | 210 | | if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd |
148 | | return SCE_NSIS_FUNCTION; | | 211 | | return SCE_NSIS_FUNCTIONDEF; |
|
150 | | 213 | | if ( Functions.InList(s) ) |
|
151 | | 214 | | return SCE_NSIS_FUNCTION; |
|
36 skipped lines |
188 | | 251 | | bool bHasSimpleNsisNumber = true; |
|
189 | | 252 | | for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) |
|
|
191 | | if( s[j] == '\0' || s[j] == '\r' || s[j] == '\n' ) | | |
192 | | break; | | |
193 | | | | |
194 | | 254 | | if( !isNsisNumber( s[j] ) ) |
|
|
196 | | 256 | | bHasSimpleNsisNumber = false; |
|
11 skipped lines |
208 | | 268 | | static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) |
|
|
210 | | 270 | | int state = SCE_NSIS_DEFAULT; |
|
| | 271 | | if( startPos > 0 ) |
| | 272 | | state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox |
| | 273 | | |
211 | | 274 | | styler.StartAt( startPos ); |
|
212 | | 275 | | styler.GetLine( startPos ); |
|
|
56 skipped lines |
|
|
|
| | 336 | | |
| | 337 | | if( cCurrChar == '/' && cNextChar == '*' ) |
| | 338 | | { |
| | 339 | | styler.ColourTo(i-1,state); |
| | 340 | | state = SCE_NSIS_COMMENTBOX; |
| | 341 | | break; |
| | 342 | | } |
| | 343 | | |
|
274 | | 345 | | case SCE_NSIS_COMMENT: |
|
275 | | 346 | | if( cNextChar == '\n' || cNextChar == '\r' ) |
|
|
| | 348 | | // Special case: |
| | 349 | | if( cCurrChar == '\\' ) |
| | 350 | | { |
277 | | styler.ColourTo(i,state); | | 351 | | styler.ColourTo(i-2,state); |
| | 352 | | styler.ColourTo(i,SCE_NSIS_DEFAULT); |
| | 353 | | } |
| | 354 | | else |
| | 355 | | { |
| | 356 | | styler.ColourTo(i,state); |
278 | | state = SCE_NSIS_DEFAULT; | | 357 | | state = SCE_NSIS_DEFAULT; |
| | 358 | | } |
|
|
281 | | 361 | | case SCE_NSIS_STRINGDQ: |
|
| | 362 | | case SCE_NSIS_STRINGLQ: |
| | 363 | | case SCE_NSIS_STRINGRQ: |
| | 364 | | |
282 | | if( cCurrChar == '"' || cNextChar == '\r' || cNextChar == '\n' ) | | 365 | | if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' ) |
| | 366 | | break; // Ignore the next character, even if it is a quote of some sort |
| | 367 | | |
| | 368 | | if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ ) |
|
284 | | styler.ColourTo(i,SCE_NSIS_STRINGDQ); | | 370 | | styler.ColourTo(i,state); |
285 | | 371 | | state = SCE_NSIS_DEFAULT; |
|
| | 372 | | break; |
|
287 | | break; | | 374 | | |
288 | | case SCE_NSIS_STRINGLQ: | | |
289 | | if( cCurrChar == '`' || cNextChar == '\r' || cNextChar == '\n' ) | | 375 | | if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ ) |
290 | | { | | 376 | | { |
291 | | styler.ColourTo(i,SCE_NSIS_STRINGLQ); | | 377 | | styler.ColourTo(i,state); |
292 | | 378 | | state = SCE_NSIS_DEFAULT; |
|
| | 379 | | break; |
|
294 | | break; | | 381 | | |
295 | | case SCE_NSIS_STRINGRQ: | | |
296 | | if( cCurrChar == '\'' || cNextChar == '\r' || cNextChar == '\n' ) | | 382 | | if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ ) |
|
298 | | styler.ColourTo(i,SCE_NSIS_STRINGRQ); | | 384 | | styler.ColourTo(i,state); |
299 | | 385 | | state = SCE_NSIS_DEFAULT; |
|
| | 386 | | break; |
|
| | 388 | | |
| | 389 | | if( cNextChar == '\r' || cNextChar == '\n' ) |
| | 390 | | { |
| | 391 | | int nCurLine = styler.GetLine(i+1); |
| | 392 | | int nBack = i; |
26 skipped lines |
| | 419 | | { |
| | 420 | | styler.ColourTo(i,state); |
| | 421 | | state = SCE_NSIS_DEFAULT; |
| | 422 | | } |
| | 423 | | } |
|
| | 425 | | |
302 | | 426 | | case SCE_NSIS_FUNCTION: |
|
|
|
3 skipped lines |
308 | | 432 | | state = SCE_NSIS_DEFAULT; |
|
309 | | 433 | | else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) |
|
|
311 | | state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler); | | 435 | | state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler ); |
312 | | 436 | | styler.ColourTo( i, state); |
|
313 | | 437 | | state = SCE_NSIS_DEFAULT; |
|
|
28 skipped lines |
|
|
|
| | 470 | | case SCE_NSIS_COMMENTBOX: |
| | 471 | | |
| | 472 | | if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' ) |
| | 473 | | { |
| | 474 | | styler.ColourTo(i,state); |
| | 475 | | state = SCE_NSIS_DEFAULT; |
| | 476 | | } |
| | 477 | | break; |
|
|
348 | | if( state == SCE_NSIS_COMMENT ) | | 480 | | if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX ) |
|
350 | | 482 | | styler.ColourTo(i,state); |
|
|
9 skipped lines |
361 | | 493 | | bVarInString = false; |
|
362 | | 494 | | bIngoreNextDollarSign = true; |
|
|
364 | | else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) ) | | 496 | | else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) |
|
| | 498 | | styler.ColourTo( i+1, SCE_NSIS_STRINGVAR); |
366 | | 499 | | bVarInString = false; |
|
367 | | bIngoreNextDollarSign = true; | | 500 | | bIngoreNextDollarSign = false; |
|
|
370 | | 503 | | // Covers "$INSTDIR and user vars like $MYVAR" |
|
30 skipped lines |
|
|
403 | | 536 | | // Colourise remaining document |
|
404 | | switch( state ) | | |
405 | | { | | |
406 | | case SCE_NSIS_COMMENT: | | |
407 | | case SCE_NSIS_STRINGDQ: | | |
408 | | case SCE_NSIS_STRINGLQ: | | |
409 | | case SCE_NSIS_STRINGRQ: | | |
410 | | case SCE_NSIS_VARIABLE: | | |
411 | | case SCE_NSIS_STRINGVAR: | | |
412 | | styler.ColourTo(nLengthDoc-1,state); break; | | 537 | | styler.ColourTo(nLengthDoc-1,state); |
413 | | | | |
414 | | default: | | |
415 | | styler.ColourTo(nLengthDoc-1,SCE_NSIS_DEFAULT); break; | | |
416 | | } | | |
|
|
419 | | 540 | | static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) |
|
2 skipped lines |
422 | | 543 | | if( styler.GetPropertyInt("fold") == 0 ) |
|
|
|
| | 546 | | bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1; |
| | 547 | | bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1; |
| | 548 | | bool blockComment = false; |
| | 549 | | |
425 | | 550 | | int lineCurrent = styler.GetLine(startPos); |
|
426 | | 551 | | unsigned int safeStartPos = styler.LineStart( lineCurrent ); |
|
|
4 skipped lines |
432 | | 557 | | if (lineCurrent > 0) |
|
433 | | 558 | | levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; |
|
434 | | 559 | | int levelNext = levelCurrent; |
|
| | 560 | | int style = styler.StyleAt(safeStartPos); |
| | 561 | | if( style == SCE_NSIS_COMMENTBOX ) |
| | 562 | | { |
| | 563 | | if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' ) |
| | 564 | | levelNext++; |
| | 565 | | blockComment = true; |
| | 566 | | } |
|
436 | | 568 | | for (unsigned int i = safeStartPos; i < startPos + length; i++) |
|
|
438 | | 570 | | char chCurr = styler.SafeGetCharAt(i); |
|
| | 571 | | style = styler.StyleAt(i); |
| | 572 | | if( blockComment && style != SCE_NSIS_COMMENTBOX ) |
| | 573 | | { |
| | 574 | | levelNext--; |
| | 575 | | blockComment = false; |
| | 576 | | } |
| | 577 | | else if( !blockComment && style == SCE_NSIS_COMMENTBOX ) |
| | 578 | | { |
| | 579 | | levelNext++; |
| | 580 | | blockComment = true; |
| | 581 | | } |
|
440 | | if( bArg1 ) //&& chCurr != '\n' ) | | 583 | | if( bArg1 && !blockComment) |
|
442 | | 585 | | if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') ) |
|
| | 586 | | { |
|
| | 588 | | } |
444 | | else if( !isNsisLetter(chCurr) && nWordStart > -1 ) | | 589 | | else if( isNsisLetter(chCurr) == false && nWordStart > -1 ) |
|
446 | | int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler ); | | 591 | | int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd ); |
| | 592 | | |
447 | | if( newLevel != levelNext ) | | 593 | | if( newLevel == levelNext ) |
| | 594 | | { |
| | 595 | | if( foldAtElse && foldUtilityCmd ) |
| | 596 | | { |
| | 597 | | if( NsisNextLineHasElse(i, startPos + length, styler) ) |
| | 598 | | levelNext--; |
| | 599 | | } |
| | 600 | | } |
| | 601 | | else |
448 | | 602 | | levelNext = newLevel; |
|
|
|
1 skipped line |
|
453 | | 607 | | if( chCurr == '\n' ) |
|
|
| | 609 | | if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment ) |
| | 610 | | { |
| | 611 | | if( NsisNextLineHasElse(i, startPos + length, styler) ) |
| | 612 | | levelNext--; |
| | 613 | | } |
| | 614 | | |
455 | | 615 | | // If we are on a new line... |
|
456 | | 616 | | int levelUse = levelCurrent; |
|
457 | | 617 | | int lev = levelUse | levelNext << 16; |
|
458 | | if (levelUse < levelNext) | | 618 | | if (levelUse < levelNext ) |
459 | | 619 | | lev |= SC_FOLDLEVELHEADERFLAG; |
|
460 | | 620 | | if (lev != styler.LevelAt(lineCurrent)) |
|
461 | | 621 | | styler.SetLevel(lineCurrent, lev); |
|
22 skipped lines |
|
|
486 | | 646 | | LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists); |
|
| | 647 | | |
|