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

« back to all changes in this revision

Viewing changes to src/sdk/wxscintilla/src/scintilla/src/LexOthers.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:
14
14
 
15
15
#include "Platform.h"
16
16
 
 
17
#include "CharClassify.h"
17
18
#include "PropSet.h"
18
19
#include "Accessor.h"
19
20
#include "KeyWords.h"
20
21
#include "Scintilla.h"
21
22
#include "SciLexer.h"
22
23
 
 
24
#ifdef SCI_NAMESPACE
 
25
using namespace Scintilla;
 
26
#endif
 
27
 
 
28
static bool strstart(const char *haystack, const char *needle) {
 
29
        return strncmp(haystack, needle, strlen(needle)) == 0;
 
30
}
 
31
 
23
32
static bool Is0To9(char ch) {
24
33
        return (ch >= '0') && (ch <= '9');
25
34
}
41
50
 
42
51
// Tests for BATCH Separators
43
52
static bool IsBSeparator(char ch) {
44
 
        return (ch == ':') || (ch == '\\') || (ch == '.') || (ch == ';') ||
 
53
        return (ch == '\\') || (ch == '.') || (ch == ';') ||
45
54
                (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
46
55
}
47
56
 
50
59
    unsigned int lengthLine,
51
60
    unsigned int startLine,
52
61
    unsigned int endPos,
53
 
    WordList &keywords,
 
62
    WordList *keywordlists[],
54
63
    Accessor &styler) {
55
64
 
56
65
        unsigned int offset = 0;        // Line Buffer Offset
57
 
        unsigned int enVarEnd;          // Environment Variable End point
58
66
        unsigned int cmdLoc;            // External Command / Program Location
59
67
        char wordBuffer[81];            // Word Buffer - large to catch long paths
60
68
        unsigned int wbl;               // Word Buffer Length
61
69
        unsigned int wbo;               // Word Buffer Offset - also Special Keyword Buffer Length
62
 
        bool forFound = false;          // No Local Variable without FOR statement
 
70
        WordList &keywords = *keywordlists[0];      // Internal Commands
 
71
        WordList &keywords2 = *keywordlists[1];     // External Commands (optional)
 
72
 
63
73
        // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
64
74
        //   Toggling Regular Keyword Checking off improves readability
65
75
        // Other Regular Keywords and External Commands / Programs might also benefit from toggling
105
115
        if (lineBuffer[offset] == '@') {
106
116
                styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
107
117
                offset++;
108
 
        // Check for Argument (%n) or Environment Variable (%x...%)
109
 
        } else if (lineBuffer[offset] == '%') {
110
 
                enVarEnd = offset + 1;
111
 
                // Search end of word for second % (can be a long path)
112
 
                while ((enVarEnd < lengthLine) &&
113
 
                        (!isspacechar(lineBuffer[enVarEnd])) &&
114
 
                        (lineBuffer[enVarEnd] != '%') &&
115
 
                        (!IsBOperator(lineBuffer[enVarEnd])) &&
116
 
                        (!IsBSeparator(lineBuffer[enVarEnd]))) {
117
 
                        enVarEnd++;
118
 
                }
119
 
                // Check for Argument (%n)
120
 
                if ((Is0To9(lineBuffer[offset + 1])) &&
121
 
                        (lineBuffer[enVarEnd] != '%')) {
122
 
                        // Colorize Argument
123
 
                        styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
124
 
                        offset += 2;
125
 
                        // Check for External Command / Program
126
 
                        if (!isspacechar(lineBuffer[offset])) {
127
 
                                cmdLoc = offset;
128
 
                        }
129
 
                // Check for Environment Variable (%x...%)
130
 
                } else if ((lineBuffer[offset + 1] != '%') &&
131
 
                        (lineBuffer[enVarEnd] == '%')) {
132
 
                        offset = enVarEnd;
133
 
                        // Colorize Environment Variable
134
 
                        styler.ColourTo(startLine + offset, SCE_BAT_IDENTIFIER);
135
 
                        offset++;
136
 
                        // Check for External Command / Program
137
 
                        if (!isspacechar(lineBuffer[offset])) {
138
 
                                cmdLoc = offset;
139
 
                        }
140
 
                }
141
118
        }
142
119
        // Skip next spaces
143
120
        while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
174
151
                                // Reset Offset to re-process remainder of word
175
152
                                offset -= (wbl - 1);
176
153
                                // Colorize External Command / Program
177
 
                                styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 
154
                                if (!keywords2) {
 
155
                                        styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 
156
                                } else if (keywords2.InList(wordBuffer)) {
 
157
                                        styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 
158
                                } else {
 
159
                                        styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
 
160
                                }
178
161
                                // Reset External Command / Program Location
179
162
                                cmdLoc = offset;
180
163
                        } else {
186
169
                // Check for Regular Keyword in list
187
170
                } else if ((keywords.InList(wordBuffer)) &&
188
171
                        (continueProcessing)) {
189
 
                        // Local Variables do not exist if no FOR statement
190
 
                        if (CompareCaseInsensitive(wordBuffer, "for") == 0) {
191
 
                                forFound = true;
192
 
                        }
193
172
                        // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
194
173
                        if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
195
174
                                (CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
235
214
                        // No need to Reset Offset
236
215
                // Check for Special Keyword in list, External Command / Program, or Default Text
237
216
                } else if ((wordBuffer[0] != '%') &&
 
217
                                   (wordBuffer[0] != '!') &&
238
218
                        (!IsBOperator(wordBuffer[0])) &&
239
219
                        (continueProcessing)) {
240
220
                        // Check for Special Keyword
261
241
                                        styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
262
242
                                        // Reset Offset to re-process remainder of word
263
243
                                        offset -= (wbl - wbo);
 
244
                                }
264
245
                        }
265
 
                }
266
246
                        // Check for External Command / Program or Default Text
267
247
                        if (!sKeywordFound) {
268
248
                                wbo = 0;
271
251
                                        // Read up to %, Operator or Separator
272
252
                                        while ((wbo < wbl) &&
273
253
                                                (wordBuffer[wbo] != '%') &&
 
254
                                                (wordBuffer[wbo] != '!') &&
274
255
                                                (!IsBOperator(wordBuffer[wbo])) &&
275
256
                                                (!IsBSeparator(wordBuffer[wbo]))) {
276
257
                                                wbo++;
306
287
                                                        }
307
288
                                                }
308
289
                                        }
309
 
                                        // Colorize External command / program
310
 
                                        styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 
290
                                        // Colorize External Command / Program
 
291
                                        if (!keywords2) {
 
292
                                                styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 
293
                                        } else if (keywords2.InList(wordBuffer)) {
 
294
                                                styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 
295
                                        } else {
 
296
                                                styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
 
297
                                        }
311
298
                                        // No need to Reset Offset
312
299
                                // Check for Default Text
313
300
                                } else {
314
301
                                        // Read up to %, Operator or Separator
315
302
                                        while ((wbo < wbl) &&
316
303
                                                (wordBuffer[wbo] != '%') &&
 
304
                                                (wordBuffer[wbo] != '!') &&
317
305
                                                (!IsBOperator(wordBuffer[wbo])) &&
318
306
                                                (!IsBSeparator(wordBuffer[wbo]))) {
319
307
                                                wbo++;
336
324
                                (!IsBSeparator(wordBuffer[wbo]))) {
337
325
                                wbo++;
338
326
                        }
339
 
                        // Check for Argument (%n)
340
 
                        if ((Is0To9(wordBuffer[1])) &&
 
327
                        // Check for Argument (%n) or (%*)
 
328
                        if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
341
329
                                (wordBuffer[wbo] != '%')) {
342
330
                                // Check for External Command / Program
343
331
                                if (cmdLoc == offset - wbl) {
347
335
                                styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
348
336
                                // Reset Offset to re-process remainder of word
349
337
                                offset -= (wbl - 2);
 
338
                        // Check for Expanded Argument (%~...) / Variable (%%~...)
 
339
                        } else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
 
340
                                ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
 
341
                                // Check for External Command / Program
 
342
                                if (cmdLoc == offset - wbl) {
 
343
                                        cmdLoc = offset - (wbl - wbo);
 
344
                                }
 
345
                                // Colorize Expanded Argument / Variable
 
346
                                styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
 
347
                                // Reset Offset to re-process remainder of word
 
348
                                offset -= (wbl - wbo);
350
349
                        // Check for Environment Variable (%x...%)
351
350
                        } else if ((wordBuffer[1] != '%') &&
352
351
                                (wordBuffer[wbo] == '%')) {
354
353
                                // Check for External Command / Program
355
354
                                if (cmdLoc == offset - wbl) {
356
355
                                        cmdLoc = offset - (wbl - wbo);
357
 
                        }
 
356
                                }
358
357
                                // Colorize Environment Variable
359
358
                                styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
360
359
                                // Reset Offset to re-process remainder of word
361
360
                                offset -= (wbl - wbo);
362
361
                        // Check for Local Variable (%%a)
363
 
                        } else if ((forFound) &&
 
362
                        } else if (
 
363
                                (wbl > 2) &&
364
364
                                (wordBuffer[1] == '%') &&
365
365
                                (wordBuffer[2] != '%') &&
366
366
                                (!IsBOperator(wordBuffer[2])) &&
374
374
                                // Reset Offset to re-process remainder of word
375
375
                                offset -= (wbl - 3);
376
376
                        }
 
377
                // Check for Environment Variable (!x...!)
 
378
                } else if (wordBuffer[0] == '!') {
 
379
                        // Colorize Default Text
 
380
                        styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
 
381
                        wbo++;
 
382
                        // Search to end of word for second ! (can be a long path)
 
383
                        while ((wbo < wbl) &&
 
384
                                (wordBuffer[wbo] != '!') &&
 
385
                                (!IsBOperator(wordBuffer[wbo])) &&
 
386
                                (!IsBSeparator(wordBuffer[wbo]))) {
 
387
                                wbo++;
 
388
                        }
 
389
                        if (wordBuffer[wbo] == '!') {
 
390
                                wbo++;
 
391
                                // Check for External Command / Program
 
392
                                if (cmdLoc == offset - wbl) {
 
393
                                        cmdLoc = offset - (wbl - wbo);
 
394
                                }
 
395
                                // Colorize Environment Variable
 
396
                                styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
 
397
                                // Reset Offset to re-process remainder of word
 
398
                                offset -= (wbl - wbo);
 
399
                        }
377
400
                // Check for Operator
378
401
                } else if (IsBOperator(wordBuffer[0])) {
379
402
                        // Colorize Default Text
421
444
                        // Read up to %, Operator or Separator
422
445
                        while ((wbo < wbl) &&
423
446
                                (wordBuffer[wbo] != '%') &&
 
447
                                (wordBuffer[wbo] != '!') &&
424
448
                                (!IsBOperator(wordBuffer[wbo])) &&
425
449
                                (!IsBSeparator(wordBuffer[wbo]))) {
426
450
                                wbo++;
447
471
    Accessor &styler) {
448
472
 
449
473
        char lineBuffer[1024];
450
 
        WordList &keywords = *keywordlists[0];
451
474
 
452
475
        styler.StartAt(startPos);
453
476
        styler.StartSegment(startPos);
458
481
                if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
459
482
                        // End of line (or of line buffer) met, colourise it
460
483
                        lineBuffer[linePos] = '\0';
461
 
                        ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywords, styler);
 
484
                        ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler);
462
485
                        linePos = 0;
463
486
                        startLine = i + 1;
464
487
                }
465
488
        }
466
489
        if (linePos > 0) {      // Last line does not have ending characters
 
490
                lineBuffer[linePos] = '\0';
467
491
                ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
468
 
                                   keywords, styler);
 
492
                                   keywordlists, styler);
469
493
        }
470
494
}
471
495
 
476
500
        // otherwise it is considered a comment (Only in..., Binary file...)
477
501
        if (0 == strncmp(lineBuffer, "diff ", 5)) {
478
502
                styler.ColourTo(endLine, SCE_DIFF_COMMAND);
479
 
        } else if (0 == strncmp(lineBuffer, "--- ", 4)) {
 
503
        } else if (0 == strncmp(lineBuffer, "Index: ", 7)) {  // For subversion's diff
 
504
                styler.ColourTo(endLine, SCE_DIFF_COMMAND);
 
505
        } else if (0 == strncmp(lineBuffer, "---", 3)) {
480
506
                // In a context diff, --- appears in both the header and the position markers
481
 
                if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
 
507
                if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
 
508
                        styler.ColourTo(endLine, SCE_DIFF_POSITION);
 
509
                else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
482
510
                        styler.ColourTo(endLine, SCE_DIFF_POSITION);
483
511
                else
484
512
                        styler.ColourTo(endLine, SCE_DIFF_HEADER);
511
539
                styler.ColourTo(endLine, SCE_DIFF_DELETED);
512
540
        } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
513
541
                styler.ColourTo(endLine, SCE_DIFF_ADDED);
 
542
        } else if (lineBuffer[0] == '!') {
 
543
                styler.ColourTo(endLine, SCE_DIFF_CHANGED);
514
544
        } else if (lineBuffer[0] != ' ') {
515
545
                styler.ColourTo(endLine, SCE_DIFF_COMMENT);
516
546
        } else {
537
567
        }
538
568
}
539
569
 
540
 
static void FoldDiffDoc(unsigned int startPos, int length, int, WordList*[], Accessor &styler) {
 
570
static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
541
571
        int curLine = styler.GetLine(startPos);
542
 
        int prevLevel = SC_FOLDLEVELBASE;
543
 
        if (curLine > 0)
544
 
                prevLevel = styler.LevelAt(curLine-1);
545
 
 
546
572
        int curLineStart = styler.LineStart(curLine);
 
573
        int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE;
 
574
        int nextLevel;
 
575
 
547
576
        do {
548
 
                int nextLevel = prevLevel;
549
 
                if (prevLevel & SC_FOLDLEVELHEADERFLAG)
550
 
                        nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
551
 
 
552
577
                int lineType = styler.StyleAt(curLineStart);
553
578
                if (lineType == SCE_DIFF_COMMAND)
 
579
                        nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 
580
                else if (lineType == SCE_DIFF_HEADER)
554
581
                        nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
555
 
                else if (lineType == SCE_DIFF_HEADER) {
 
582
                else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-')
556
583
                        nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
557
 
                } else if (lineType == SCE_DIFF_POSITION)
558
 
                        nextLevel = (SC_FOLDLEVELBASE + 3) | SC_FOLDLEVELHEADERFLAG;
 
584
                else if (prevLevel & SC_FOLDLEVELHEADERFLAG)
 
585
                        nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
 
586
                else
 
587
                        nextLevel = prevLevel;
559
588
 
560
589
                if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
561
590
                        styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
567
596
        } while (static_cast<int>(startPos) + length > curLineStart);
568
597
}
569
598
 
 
599
static void ColourisePoLine(
 
600
    char *lineBuffer,
 
601
    unsigned int lengthLine,
 
602
    unsigned int startLine,
 
603
    unsigned int endPos,
 
604
    Accessor &styler) {
 
605
 
 
606
        unsigned int i = 0;
 
607
        static unsigned int state = SCE_PO_DEFAULT;
 
608
        unsigned int state_start = SCE_PO_DEFAULT;
 
609
 
 
610
        while ((i < lengthLine) && isspacechar(lineBuffer[i]))  // Skip initial spaces
 
611
                i++;
 
612
        if (i < lengthLine) {
 
613
                if (lineBuffer[i] == '#') {
 
614
                        // check if the comment contains any flags ("#, ") and
 
615
                        // then whether the flags contain "fuzzy"
 
616
                        if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
 
617
                                styler.ColourTo(endPos, SCE_PO_FUZZY);
 
618
                        else
 
619
                                styler.ColourTo(endPos, SCE_PO_COMMENT);
 
620
                } else {
 
621
                        if (lineBuffer[0] == '"') {
 
622
                                // line continuation, use previous style
 
623
                                styler.ColourTo(endPos, state);
 
624
                                return;
 
625
                        // this implicitly also matches "msgid_plural"
 
626
                        } else if (strstart(lineBuffer, "msgid")) {
 
627
                                state_start = SCE_PO_MSGID;
 
628
                                state = SCE_PO_MSGID_TEXT;
 
629
                        } else if (strstart(lineBuffer, "msgstr")) {
 
630
                                state_start = SCE_PO_MSGSTR;
 
631
                                state = SCE_PO_MSGSTR_TEXT;
 
632
                        } else if (strstart(lineBuffer, "msgctxt")) {
 
633
                                state_start = SCE_PO_MSGCTXT;
 
634
                                state = SCE_PO_MSGCTXT_TEXT;
 
635
                        }
 
636
                        if (state_start != SCE_PO_DEFAULT) {
 
637
                                // find the next space
 
638
                                while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
 
639
                                        i++;
 
640
                                styler.ColourTo(startLine + i - 1, state_start);
 
641
                                styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
 
642
                                styler.ColourTo(endPos, state);
 
643
                        }
 
644
                }
 
645
        } else {
 
646
                styler.ColourTo(endPos, SCE_PO_DEFAULT);
 
647
        }
 
648
}
 
649
 
 
650
static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
 
651
        char lineBuffer[1024];
 
652
        styler.StartAt(startPos);
 
653
        styler.StartSegment(startPos);
 
654
        unsigned int linePos = 0;
 
655
        unsigned int startLine = startPos;
 
656
        for (unsigned int i = startPos; i < startPos + length; i++) {
 
657
                lineBuffer[linePos++] = styler[i];
 
658
                if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
 
659
                        // End of line (or of line buffer) met, colourise it
 
660
                        lineBuffer[linePos] = '\0';
 
661
                        ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
 
662
                        linePos = 0;
 
663
                        startLine = i + 1;
 
664
                }
 
665
        }
 
666
        if (linePos > 0) {      // Last line does not have ending characters
 
667
                ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
 
668
        }
 
669
}
 
670
 
 
671
static inline bool isassignchar(unsigned char ch) {
 
672
        return (ch == '=') || (ch == ':');
 
673
}
570
674
 
571
675
static void ColourisePropsLine(
572
676
    char *lineBuffer,
573
677
    unsigned int lengthLine,
574
678
    unsigned int startLine,
575
679
    unsigned int endPos,
576
 
    Accessor &styler) {
 
680
    Accessor &styler,
 
681
    bool allowInitialSpaces) {
577
682
 
578
683
        unsigned int i = 0;
579
 
        while ((i < lengthLine) && isspacechar(lineBuffer[i]))  // Skip initial spaces
580
 
                i++;
 
684
        if (allowInitialSpaces) {
 
685
                while ((i < lengthLine) && isspacechar(lineBuffer[i]))  // Skip initial spaces
 
686
                        i++;
 
687
        } else {
 
688
                if (isspacechar(lineBuffer[i])) // don't allow initial spaces
 
689
                        i = lengthLine;
 
690
        }
 
691
 
581
692
        if (i < lengthLine) {
582
693
                if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
583
694
                        styler.ColourTo(endPos, SCE_PROPS_COMMENT);
585
696
                        styler.ColourTo(endPos, SCE_PROPS_SECTION);
586
697
                } else if (lineBuffer[i] == '@') {
587
698
                        styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL);
588
 
                        if (lineBuffer[++i] == '=')
 
699
                        if (isassignchar(lineBuffer[i++]))
589
700
                                styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
590
701
                        styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
591
702
                } else {
592
703
                        // Search for the '=' character
593
 
                        while ((i < lengthLine) && (lineBuffer[i] != '='))
 
704
                        while ((i < lengthLine) && !isassignchar(lineBuffer[i]))
594
705
                                i++;
595
 
                        if ((i < lengthLine) && (lineBuffer[i] == '=')) {
596
 
                                styler.ColourTo(startLine + i - 1, SCE_PROPS_DEFAULT);
597
 
                                styler.ColourTo(startLine + i, 3);
 
706
                        if ((i < lengthLine) && isassignchar(lineBuffer[i])) {
 
707
                                styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);
 
708
                                styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
598
709
                                styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
599
710
                        } else {
600
711
                                styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
611
722
        styler.StartSegment(startPos);
612
723
        unsigned int linePos = 0;
613
724
        unsigned int startLine = startPos;
 
725
 
 
726
        // property lexer.props.allow.initial.spaces 
 
727
        //      For properties files, set to 0 to style all lines that start with whitespace in the default style. 
 
728
        //      This is not suitable for SciTE .properties files which use indentation for flow control but 
 
729
        //      can be used for RFC2822 text where indentation is used for continuation lines. 
 
730
        bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
 
731
 
614
732
        for (unsigned int i = startPos; i < startPos + length; i++) {
615
733
                lineBuffer[linePos++] = styler[i];
616
734
                if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
617
735
                        // End of line (or of line buffer) met, colourise it
618
736
                        lineBuffer[linePos] = '\0';
619
 
                        ColourisePropsLine(lineBuffer, linePos, startLine, i, styler);
 
737
                        ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces);
620
738
                        linePos = 0;
621
739
                        startLine = i + 1;
622
740
                }
623
741
        }
624
742
        if (linePos > 0) {      // Last line does not have ending characters
625
 
                ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
 
743
                ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces);
626
744
        }
627
745
}
628
746
 
697
815
                lev = SC_FOLDLEVELBASE;
698
816
        }
699
817
        int flagsNext = styler.LevelAt(lineCurrent);
700
 
        styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
 
818
        styler.SetLevel(lineCurrent, lev | (flagsNext & ~SC_FOLDLEVELNUMBERMASK));
701
819
}
702
820
 
703
821
static void ColouriseMakeLine(
711
829
        int lastNonSpace = -1;
712
830
        unsigned int state = SCE_MAKE_DEFAULT;
713
831
        bool bSpecial = false;
 
832
 
 
833
        // check for a tab character in column 0 indicating a command
 
834
        bool bCommand = false;
 
835
        if ((lengthLine > 0) && (lineBuffer[0] == '\t'))
 
836
                bCommand = true;
 
837
 
714
838
        // Skip initial spaces
715
839
        while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
716
840
                i++;
731
855
                        styler.ColourTo(startLine + i, state);
732
856
                        state = SCE_MAKE_DEFAULT;
733
857
                }
734
 
                if (!bSpecial) {
 
858
 
 
859
                // skip identifier and target styling if this is a command line
 
860
                if (!bSpecial && !bCommand) {
735
861
                        if (lineBuffer[i] == ':') {
736
 
                                // We should check that no colouring was made since the beginning of the line,
737
 
                                // to avoid colouring stuff like /OUT:file
738
 
                                if (lastNonSpace >= 0)
739
 
                                        styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
740
 
                                styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
741
 
                                styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
 
862
                                if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) {
 
863
                                        // it's a ':=', so style as an identifier
 
864
                                        if (lastNonSpace >= 0)
 
865
                                                styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
 
866
                                        styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
 
867
                                        styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR);
 
868
                                } else {
 
869
                                        // We should check that no colouring was made since the beginning of the line,
 
870
                                        // to avoid colouring stuff like /OUT:file
 
871
                                        if (lastNonSpace >= 0)
 
872
                                                styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
 
873
                                        styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
 
874
                                        styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
 
875
                                }
742
876
                                bSpecial = true;        // Only react to the first ':' of the line
743
877
                                state = SCE_MAKE_DEFAULT;
744
878
                        } else if (lineBuffer[i] == '=') {
783
917
        }
784
918
}
785
919
 
786
 
static bool strstart(const char *haystack, const char *needle) {
787
 
        return strncmp(haystack, needle, strlen(needle)) == 0;
788
 
}
789
 
 
790
 
static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine) {
 
920
static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine, int &startValue) {
791
921
        if (lineBuffer[0] == '>') {
792
922
                // Command or return status
793
923
                return SCE_ERR_CMD;
870
1000
                // Microsoft: <filename>(<line>,<column>)<message>
871
1001
                // CTags: \t<message>
872
1002
                // Lua 5 traceback: \t<filename>:<line>:<message>
 
1003
                // Lua 5.1: <exe>: <filename>:<line>:<message>
873
1004
                bool initialTab = (lineBuffer[0] == '\t');
874
 
                enum { stInitial, 
 
1005
                bool initialColonPart = false;
 
1006
                enum { stInitial,
875
1007
                        stGccStart, stGccDigit, stGcc,
876
1008
                        stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
877
1009
                        stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags,
885
1017
                        if (state == stInitial) {
886
1018
                                if (ch == ':') {
887
1019
                                        // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
888
 
                                        if ((chNext != '\\') && (chNext != '/')) {
 
1020
                                        if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) {
889
1021
                                                // This check is not completely accurate as may be on
890
1022
                                                // GTK+ with a file name that includes ':'.
891
1023
                                                state = stGccStart;
 
1024
                                        } else if (chNext == ' ') { // indicates a Lua 5.1 error message
 
1025
                                                initialColonPart = true;
892
1026
                                        }
893
1027
                                } else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {
894
1028
                                        // May be Microsoft
903
1037
                        } else if (state == stGccDigit) {       // <filename>:<line>
904
1038
                                if (ch == ':') {
905
1039
                                        state = stGcc;  // :9.*: is GCC
 
1040
                                        startValue = i + 1;
906
1041
                                        break;
907
1042
                                } else if (!Is0To9(ch)) {
908
1043
                                        state = stUnrecognized;
933
1068
                                        for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
934
1069
                                                word[chPos++] = lineBuffer[j];
935
1070
                                        word[chPos] = 0;
936
 
                                        if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") || 
937
 
                                                !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") || 
 
1071
                                        if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") ||
 
1072
                                                !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") ||
938
1073
                                                !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) {
939
1074
                                                state = stMsVc;
940
1075
                                        } else
963
1098
                        }
964
1099
                }
965
1100
                if (state == stGcc) {
966
 
                        return SCE_ERR_GCC;
 
1101
                        return initialColonPart ? SCE_ERR_LUA : SCE_ERR_GCC;
967
1102
                } else if ((state == stMsVc) || (state == stMsDotNet)) {
968
1103
                        return SCE_ERR_MS;
969
1104
                } else if ((state == stCtagsStringDollar) || (state == stCtags)) {
978
1113
    char *lineBuffer,
979
1114
    unsigned int lengthLine,
980
1115
    unsigned int endPos,
981
 
    Accessor &styler) {
982
 
        styler.ColourTo(endPos, RecogniseErrorListLine(lineBuffer, lengthLine));
 
1116
    Accessor &styler,
 
1117
        bool valueSeparate) {
 
1118
        int startValue = -1;
 
1119
        int style = RecogniseErrorListLine(lineBuffer, lengthLine, startValue);
 
1120
        if (valueSeparate && (startValue >= 0)) {
 
1121
                styler.ColourTo(endPos - (lengthLine - startValue), style);
 
1122
                styler.ColourTo(endPos, SCE_ERR_VALUE);
 
1123
        } else {
 
1124
                styler.ColourTo(endPos, style);
 
1125
        }
983
1126
}
984
1127
 
985
1128
static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
987
1130
        styler.StartAt(startPos);
988
1131
        styler.StartSegment(startPos);
989
1132
        unsigned int linePos = 0;
 
1133
 
 
1134
        // property lexer.errorlist.value.separate 
 
1135
        //      For lines in the output pane that are matches from Find in Files or GCC-style 
 
1136
        //      diagnostics, style the path and line number separately from the rest of the 
 
1137
        //      line with style 21 used for the rest of the line. 
 
1138
        //      This allows matched text to be more easily distinguished from its location. 
 
1139
        bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
990
1140
        for (unsigned int i = startPos; i < startPos + length; i++) {
991
1141
                lineBuffer[linePos++] = styler[i];
992
1142
                if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
993
1143
                        // End of line (or of line buffer) met, colourise it
994
1144
                        lineBuffer[linePos] = '\0';
995
 
                        ColouriseErrorListLine(lineBuffer, linePos, i, styler);
 
1145
                        ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate);
996
1146
                        linePos = 0;
997
1147
                }
998
1148
        }
999
1149
        if (linePos > 0) {      // Last line does not have ending characters
1000
 
                ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler);
 
1150
                ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate);
1001
1151
        }
1002
1152
}
1003
1153
 
1103
1253
}
1104
1254
 
1105
1255
static const char * const batchWordListDesc[] = {
1106
 
        "Keywords",
 
1256
        "Internal Commands",
 
1257
        "External Commands",
1107
1258
        0
1108
1259
};
1109
1260
 
1123
1274
 
1124
1275
LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
1125
1276
LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
 
1277
LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
1126
1278
LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
1127
1279
LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
1128
1280
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);