| 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 | | |
|