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

« back to all changes in this revision

Viewing changes to src/sdk/wxscintilla/src/scintilla/src/LexHTML.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:
19
19
#include "KeyWords.h"
20
20
#include "Scintilla.h"
21
21
#include "SciLexer.h"
 
22
#include "CharacterSet.h"
 
23
 
 
24
#ifdef SCI_NAMESPACE
 
25
using namespace Scintilla;
 
26
#endif
22
27
 
23
28
#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
24
29
#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
25
30
#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
26
31
 
27
 
enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock };
 
32
enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment };
28
33
enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };
29
34
 
30
35
static inline bool IsAWordChar(const int ch) {
35
40
        return (ch < 0x80) && (isalnum(ch) || ch == '_');
36
41
}
37
42
 
 
43
inline bool IsOperator(int ch) {
 
44
        if (isascii(ch) && isalnum(ch))
 
45
                return false;
 
46
        // '.' left out as it is used to make up numbers
 
47
        if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
 
48
                ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
 
49
                ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
 
50
                ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
 
51
                ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
 
52
                ch == '?' || ch == '!' || ch == '.' || ch == '~')
 
53
                return true;
 
54
        return false;
 
55
}
 
56
 
38
57
static inline int MakeLowerCase(int ch) {
39
58
        if (ch < 'A' || ch > 'Z')
40
59
                return ch;
50
69
        s[i] = '\0';
51
70
}
52
71
 
 
72
static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
 
73
 
 
74
        size_t i = 0;
 
75
        for (; i < sLen-1; i++) {
 
76
                char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
 
77
                if ((i == 0) && !IsAWordStart(ch))
 
78
                        break;
 
79
                if ((i > 0) && !IsAWordChar(ch)) 
 
80
                        break;
 
81
                s[i] = ch;
 
82
        }
 
83
        s[i] = '\0';
 
84
        
 
85
        return s;
 
86
}
 
87
 
53
88
static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
54
89
        char s[100];
55
90
        GetTextSegment(styler, start, end, s, sizeof(s));
66
101
                return eScriptJS;
67
102
        if (strstr(s, "php"))
68
103
                return eScriptPHP;
69
 
        if (strstr(s, "xml"))
 
104
        if (strstr(s, "xml")) {
 
105
                const char *xml = strstr(s, "xml");
 
106
                for (const char *t=s; t<xml; t++) {
 
107
                        if (!IsASpace(*t)) {
 
108
                                return prevValue;
 
109
                        }
 
110
                }
70
111
                return eScriptXML;
 
112
        }
71
113
 
72
114
        return prevValue;
73
115
}
102
144
}
103
145
 
104
146
static int statePrintForState(int state, script_mode inScriptType) {
105
 
        int StateToPrint;
 
147
        int StateToPrint = state;
106
148
 
107
 
        if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
108
 
                StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);
109
 
        } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
110
 
                StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);
111
 
        } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
112
 
                StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);
113
 
        } else {
114
 
                StateToPrint = state;
 
149
        if (state >= SCE_HJ_START) {
 
150
                if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
 
151
                        StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);
 
152
                } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
 
153
                        StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);
 
154
                } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
 
155
                        StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);
 
156
                }
115
157
        }
116
158
 
117
159
        return StateToPrint;
149
191
        case SCE_HB_STRING:
150
192
        case SCE_HBA_STRING:
151
193
        case SCE_HP_STRING:
 
194
        case SCE_HP_CHARACTER:
 
195
        case SCE_HP_TRIPLE:
 
196
        case SCE_HP_TRIPLEDOUBLE:
152
197
        case SCE_HPA_STRING:
 
198
        case SCE_HPA_CHARACTER:
 
199
        case SCE_HPA_TRIPLE:
 
200
        case SCE_HPA_TRIPLEDOUBLE:
153
201
        case SCE_HPHP_HSTRING:
154
202
        case SCE_HPHP_SIMPLESTRING:
155
203
        case SCE_HPHP_HSTRING_VARIABLE:
163
211
        return bResult;
164
212
}
165
213
 
 
214
static inline bool stateAllowsTermination(int state) {
 
215
        bool allowTermination = !isStringState(state);
 
216
        if (allowTermination) {
 
217
                switch (state) {
 
218
                case SCE_HB_COMMENTLINE:
 
219
                case SCE_HPHP_COMMENT:
 
220
                case SCE_HP_COMMENTLINE:
 
221
                case SCE_HPA_COMMENTLINE:
 
222
                        allowTermination = false;
 
223
                }
 
224
        }
 
225
        return allowTermination;
 
226
}
 
227
 
166
228
// not really well done, since it's only comments that should lex the %> and <%
167
229
static inline bool isCommentASPState(int state) {
168
230
        bool bResult;
203
265
 
204
266
static int classifyTagHTML(unsigned int start, unsigned int end,
205
267
                           WordList &keywords, Accessor &styler, bool &tagDontFold,
206
 
                           bool caseSensitive) {
 
268
                           bool caseSensitive, bool isXml, bool allowScripts) {
207
269
        char s[30 + 2];
208
270
        // Copy after the '<'
209
271
        unsigned int i = 0;
219
281
        s[i] = ' ';
220
282
        s[i+1] = '\0';
221
283
 
 
284
        // if the current language is XML, I can fold any tag
 
285
        // if the current language is HTML, I don't want to fold certain tags (input, meta, etc.)
222
286
        //...to find it in the list of no-container-tags
223
 
        // (There are many more. We will need a keywordlist in the property file for this)
224
 
        tagDontFold = (NULL != strstr("meta link img area br hr input ",s));
 
287
        tagDontFold = (!isXml) && (NULL != strstr("meta link img area br hr input ", s));
225
288
 
226
289
        //now we can remove the trailing space
227
290
        s[i] = '\0';
228
291
 
229
 
        bool isScript = false;
 
292
        // No keywords -> all are known
230
293
        char chAttr = SCE_H_TAGUNKNOWN;
231
294
        if (s[0] == '!') {
232
295
                chAttr = SCE_H_SGML_DEFAULT;
233
 
        } else if (s[0] == '/') {       // Closing tag
234
 
                if (keywords.InList(s + 1))
235
 
                        chAttr = SCE_H_TAG;
236
 
        } else {
237
 
                if (keywords.InList(s)) {
238
 
                        chAttr = SCE_H_TAG;
239
 
                        isScript = 0 == strcmp(s, "script");
240
 
                }
241
 
        }
242
 
        if ((chAttr == SCE_H_TAGUNKNOWN) && !keywords) {
243
 
                // No keywords -> all are known
 
296
        } else if (!keywords || keywords.InList(s)) {
244
297
                chAttr = SCE_H_TAG;
245
 
                isScript = 0 == strcmp(s, "script");
246
298
        }
247
299
        styler.ColourTo(end, chAttr);
248
 
        return isScript ? SCE_H_SCRIPT : chAttr;
 
300
        if (chAttr == SCE_H_TAG) {
 
301
                if (allowScripts && 0 == strcmp(s, "script")) {
 
302
                        // check to see if this is a self-closing tag by sniffing ahead
 
303
                        bool isSelfClose = false;
 
304
                        for (unsigned int cPos = end; cPos <= end + 100; cPos++) {
 
305
                                char ch = styler.SafeGetCharAt(cPos, '\0');
 
306
                                if (ch == '\0' || ch == '>')
 
307
                                        break;
 
308
                                else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') {
 
309
                                        isSelfClose = true;
 
310
                                        break;
 
311
                                }
 
312
                        }
 
313
 
 
314
                        // do not enter a script state if the tag self-closed
 
315
                        if (!isSelfClose)
 
316
                                chAttr = SCE_H_SCRIPT;
 
317
                } else if (!isXml && 0 == strcmp(s, "comment")) {
 
318
                        chAttr = SCE_H_COMMENT;
 
319
                }
 
320
        }
 
321
        return chAttr;
249
322
}
250
323
 
251
324
static void classifyWordHTJS(unsigned int start, unsigned int end,
364
437
        case eScriptSGML:
365
438
                Result = SCE_H_SGML_DEFAULT;
366
439
                break;
 
440
        case eScriptComment:
 
441
                Result = SCE_H_COMMENT;
 
442
                break;
367
443
        default :
368
444
                Result = SCE_HJ_START;
369
445
                break;
371
447
        return Result;
372
448
}
373
449
 
374
 
static inline bool ishtmlwordchar(char ch) {
 
450
static inline bool ishtmlwordchar(int ch) {
375
451
        return !isascii(ch) ||
376
452
                (isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
377
453
}
378
454
 
379
 
static inline bool issgmlwordchar(char ch) {
 
455
static inline bool issgmlwordchar(int ch) {
380
456
        return !isascii(ch) ||
381
457
                (isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
382
458
}
383
459
 
384
 
static inline bool IsPhpWordStart(const unsigned char ch) {
 
460
static inline bool IsPhpWordStart(int ch) {
385
461
        return (isascii(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f);
386
462
}
387
463
 
388
 
static inline bool IsPhpWordChar(char ch) {
 
464
static inline bool IsPhpWordChar(int ch) {
389
465
        return IsADigit(ch) || IsPhpWordStart(ch);
390
466
}
391
467
 
406
482
                   state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;
407
483
}
408
484
 
409
 
static bool isLineEnd(char ch) {
 
485
static bool isLineEnd(int ch) {
410
486
        return ch == '\r' || ch == '\n';
411
487
}
412
488
 
413
 
static bool isOKBeforeRE(char ch) {
 
489
static bool isOKBeforeRE(int ch) {
414
490
        return (ch == '(') || (ch == '=') || (ch == ',');
415
491
}
416
492
 
 
493
static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
 
494
        if (strlen(blockType) == 0) {
 
495
                return ((ch == '%') && (chNext == '>'));
 
496
        } else if ((0 == strcmp(blockType, "inherit")) ||
 
497
                           (0 == strcmp(blockType, "namespace")) || 
 
498
                           (0 == strcmp(blockType, "include")) ||
 
499
                           (0 == strcmp(blockType, "page"))) {
 
500
                return ((ch == '/') && (chNext == '>'));
 
501
        } else if (0 == strcmp(blockType, "%")) {
 
502
                return isLineEnd(ch);
 
503
        } else if (0 == strcmp(blockType, "{")) {
 
504
                return ch == '}';
 
505
        } else {
 
506
                return (ch == '>');
 
507
        }
 
508
}
 
509
 
417
510
static bool isPHPStringState(int state) {
418
511
        return
419
512
            (state == SCE_HPHP_HSTRING) ||
422
515
            (state == SCE_HPHP_COMPLEX_VARIABLE);
423
516
}
424
517
 
425
 
static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) {
 
518
static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler, bool &isSimpleString) {
426
519
        int j;
 
520
        const int beginning = i - 1;
 
521
        bool isValidSimpleString = false;
 
522
 
427
523
        while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
428
524
                i++;
429
 
        phpStringDelimiter[0] = '\n';
430
 
        for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) {
 
525
 
 
526
        char ch = styler.SafeGetCharAt(i);
 
527
        const char chNext = styler.SafeGetCharAt(i + 1);
 
528
        if (!IsPhpWordStart(ch)) {
 
529
                if (ch == '\'' && IsPhpWordStart(chNext)) {
 
530
                        i++;
 
531
                        ch = chNext;
 
532
                        isSimpleString = true;
 
533
                } else {
 
534
                        phpStringDelimiter[0] = '\0';
 
535
                        return beginning;
 
536
                }
 
537
        }
 
538
        phpStringDelimiter[0] = ch;
 
539
        i++;
 
540
 
 
541
        for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) {
 
542
                if (!IsPhpWordChar(styler[j])) {
 
543
                        if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) {
 
544
                                isValidSimpleString = true;
 
545
                                j++;
 
546
                                break;
 
547
                        } else {
 
548
                                phpStringDelimiter[0] = '\0';
 
549
                                return beginning;
 
550
                        }
 
551
                }
431
552
                if (j - i < phpStringDelimiterSize - 2)
432
553
                        phpStringDelimiter[j-i+1] = styler[j];
433
554
                else
434
555
                        i++;
435
556
        }
436
 
        phpStringDelimiter[j-i+1] = '\0';
437
 
        return j;
 
557
        if (isSimpleString && !isValidSimpleString) {
 
558
                phpStringDelimiter[0] = '\0';
 
559
                return beginning;
 
560
        }
 
561
        phpStringDelimiter[j-i+1 - (isSimpleString ? 1 : 0)] = '\0';
 
562
        return j - 1;
438
563
}
439
564
 
440
565
static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
441
 
                                  Accessor &styler) {
 
566
                                  Accessor &styler, bool isXml) {
442
567
        WordList &keywords = *keywordlists[0];
443
568
        WordList &keywords2 = *keywordlists[1];
444
569
        WordList &keywords3 = *keywordlists[2];
446
571
        WordList &keywords5 = *keywordlists[4];
447
572
        WordList &keywords6 = *keywordlists[5]; // SGML (DTD) keywords
448
573
 
449
 
        // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
450
 
        styler.StartAt(startPos, STYLE_MAX);
 
574
        // Lexer for HTML requires more lexical states (8 bits worth) than most lexers
 
575
        styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
451
576
        char prevWord[200];
452
577
        prevWord[0] = '\0';
 
578
        char nextWord[200];
 
579
        nextWord[0] = '\0';
453
580
        char phpStringDelimiter[200]; // PHP is not limited in length, we are
454
581
        phpStringDelimiter[0] = '\0';
455
582
        int StateToPrint = initStyle;
456
583
        int state = stateForPrintState(StateToPrint);
 
584
        char makoBlockType[200];
 
585
        makoBlockType[0] = '\0';
457
586
 
458
587
        // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
459
588
        if (InTagState(state)) {
463
592
                }
464
593
                state = SCE_H_DEFAULT;
465
594
        }
466
 
        // String can be heredoc, must find a delimiter first
467
 
        while (startPos > 0 && isPHPStringState(state) && state != SCE_HPHP_SIMPLESTRING) {
468
 
                startPos--;
469
 
                length++;
470
 
                state = styler.StyleAt(startPos);
 
595
        // String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
 
596
        if (isPHPStringState(state)) {
 
597
                while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) {
 
598
                        startPos--;
 
599
                        length++;
 
600
                        state = styler.StyleAt(startPos);
 
601
                }
 
602
                if (startPos == 0)
 
603
                        state = SCE_H_DEFAULT;
471
604
        }
472
 
        styler.StartAt(startPos, STYLE_MAX);
 
605
        styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
473
606
 
474
607
        int lineCurrent = styler.GetLine(startPos);
475
608
        int lineState;
478
611
        } else {
479
612
                // Default client and ASP scripting language is JavaScript
480
613
                lineState = eScriptJS << 8;
 
614
 
 
615
                // property asp.default.language 
 
616
                //      Script in ASP code is initially assumed to be in JavaScript. 
 
617
                //      To change this to VBScript set asp.default.language to 2. Python is 3.
481
618
                lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
482
619
        }
483
620
        script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
489
626
        int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
490
627
 
491
628
        script_type scriptLanguage = ScriptOfState(state);
 
629
        // If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
 
630
        if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {
 
631
                scriptLanguage = eScriptComment;
 
632
        }
492
633
 
 
634
        // property fold.html 
 
635
        //      Folding is turned on or off for HTML and XML files with this option. 
 
636
        //      The fold option must also be on for folding to occur.
493
637
        const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
 
638
 
494
639
        const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
 
640
 
 
641
        // property fold.html.preprocessor 
 
642
        //      Folding is turned on or off for scripts embedded in HTML files with this option. 
 
643
        //      The default is on.
495
644
        const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
 
645
 
496
646
        const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 
647
 
 
648
        // property fold.hypertext.comment 
 
649
        //      Allow folding for comments in scripts embedded in HTML. 
 
650
        //      The default is off. 
 
651
        const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0;
 
652
 
 
653
        // property fold.hypertext.heredoc 
 
654
        //      Allow folding for heredocs in scripts embedded in HTML. 
 
655
        //      The default is off.  
 
656
        const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0;
 
657
 
 
658
        // property html.tags.case.sensitive 
 
659
        //      For XML and HTML, setting this property to 1 will make tags match in a case 
 
660
        //      sensitive way which is the expected behaviour for XML and XHTML. 
497
661
        const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
498
662
 
 
663
        // property lexer.xml.allow.scripts 
 
664
        //      Set to 0 to disable scripts in XML.  
 
665
        const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
 
666
 
 
667
        // property lexer.html.mako 
 
668
        //      Set to 1 to enable the mako template language.  
 
669
        const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
 
670
 
 
671
        const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
 
672
        const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
 
673
        const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
 
674
 
499
675
        int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
500
676
        int levelCurrent = levelPrev;
501
677
        int visibleChars = 0;
 
678
        int lineStartVisibleChars = 0;
502
679
 
503
 
        char chPrev = ' ';
504
 
        char ch = ' ';
505
 
        char chPrevNonWhite = ' ';
 
680
        int chPrev = ' ';
 
681
        int ch = ' ';
 
682
        int chPrevNonWhite = ' ';
506
683
        // look back to set chPrevNonWhite properly for better regex colouring
507
684
        if (scriptLanguage == eScriptJS && startPos > 0) {
508
685
                int back = startPos;
514
691
                                break;
515
692
                }
516
693
                if (style == SCE_HJ_SYMBOLS) {
517
 
                        chPrevNonWhite = styler.SafeGetCharAt(back);
 
694
                        chPrevNonWhite = static_cast<unsigned char>(styler.SafeGetCharAt(back));
518
695
                }
519
696
        }
520
697
 
521
698
        styler.StartSegment(startPos);
522
699
        const int lengthDoc = startPos + length;
523
700
        for (int i = startPos; i < lengthDoc; i++) {
524
 
                const char chPrev2 = chPrev;
 
701
                const int chPrev2 = chPrev;
525
702
                chPrev = ch;
526
 
                if (!isspacechar(ch) && state != SCE_HJ_COMMENT &&
 
703
                if (!IsASpace(ch) && state != SCE_HJ_COMMENT &&
527
704
                        state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)
528
705
                        chPrevNonWhite = ch;
529
 
                ch = styler[i];
530
 
                char chNext = styler.SafeGetCharAt(i + 1);
531
 
                const char chNext2 = styler.SafeGetCharAt(i + 2);
 
706
                ch = static_cast<unsigned char>(styler[i]);
 
707
                int chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
 
708
                const int chNext2 = static_cast<unsigned char>(styler.SafeGetCharAt(i + 2));
532
709
 
533
710
                // Handle DBCS codepages
534
 
                if (styler.IsLeadByte(ch)) {
 
711
                if (styler.IsLeadByte(static_cast<char>(ch))) {
535
712
                        chPrev = ' ';
536
713
                        i += 1;
537
714
                        continue;
538
715
                }
539
716
 
540
 
                if ((!isspacechar(ch) || !foldCompact) && fold)
 
717
                if ((!IsASpace(ch) || !foldCompact) && fold)
541
718
                        visibleChars++;
 
719
                if (!IsASpace(ch))
 
720
                        lineStartVisibleChars++;
542
721
 
543
722
                // decide what is the current state to print (depending of the script tag)
544
723
                StateToPrint = statePrintForState(state, inScriptType);
553
732
                                if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
554
733
                                //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
555
734
                                //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
556
 
                                        if ((ch == '{') || (ch == '}')) {
557
 
                                                levelCurrent += (ch == '{') ? 1 : -1;
 
735
                                        if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
 
736
                                                levelCurrent += ((ch == '{') || (ch == '/')) ? 1 : -1;
558
737
                                        }
 
738
                                } else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
 
739
                                        levelCurrent--;
559
740
                                }
560
741
                                break;
561
742
                        case eScriptPython:
605
786
                                levelPrev = levelCurrent;
606
787
                        }
607
788
                        lineCurrent++;
 
789
                        lineStartVisibleChars = 0;
608
790
                        styler.SetLineState(lineCurrent,
609
791
                                            ((inScriptType & 0x03) << 0) |
610
792
                                            ((tagOpened & 0x01) << 2) |
614
796
                                            ((beforePreProc & 0xFF) << 12));
615
797
                }
616
798
 
 
799
                // Allow falling through to mako handling code if newline is going to end a block
 
800
                if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
 
801
                        (!isMako || (0 != strcmp(makoBlockType, "%")))) {
 
802
                }
 
803
                
617
804
                // generic end of script processing
618
805
                else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
619
806
                        // Check if it's the end of the script tag (or any other HTML tag)
625
812
                        case SCE_HJ_COMMENTDOC:
626
813
                        //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
627
814
                        // the end of script marker from some JS interpreters.
 
815
                        case SCE_HB_COMMENTLINE:
 
816
                        case SCE_HBA_COMMENTLINE:
628
817
                        case SCE_HJ_DOUBLESTRING:
629
818
                        case SCE_HJ_SINGLESTRING:
630
819
                        case SCE_HJ_REGEX:
631
820
                        case SCE_HB_STRING:
 
821
                        case SCE_HBA_STRING:
632
822
                        case SCE_HP_STRING:
633
823
                        case SCE_HP_TRIPLE:
634
824
                        case SCE_HP_TRIPLEDOUBLE:
 
825
                        case SCE_HPHP_HSTRING:
 
826
                        case SCE_HPHP_SIMPLESTRING:
 
827
                        case SCE_HPHP_COMMENT:
 
828
                        case SCE_HPHP_COMMENTLINE:
635
829
                                break;
636
830
                        default :
637
831
                                // check if the closing tag is a script tag
638
 
                                if (state == SCE_HJ_COMMENTLINE) {
639
 
                                        char tag[7]; // room for the <script> tag
640
 
                                        char chr;       // current char
641
 
                                        int j=0;
642
 
                                        chr = styler.SafeGetCharAt(i+2);
643
 
                                        while (j < 6 && !isspacechar(chr)) {
644
 
                                                tag[j++] = static_cast<char>(MakeLowerCase(chr));
645
 
                                                chr = styler.SafeGetCharAt(i+2+j);
646
 
                                        }
647
 
                                        tag[j] = '\0';
648
 
                                        if (strcmp(tag, "script") != 0) break;
 
832
                                if (const char *tag =
 
833
                                                state == SCE_HJ_COMMENTLINE || isXml ? "script" :
 
834
                                                state == SCE_H_COMMENT ? "comment" : 0) {
 
835
                                        int j = i + 2;
 
836
                                        int chr;
 
837
                                        do {
 
838
                                                chr = static_cast<int>(*tag++);
 
839
                                        } while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++)));
 
840
                                        if (chr != 0) break;
649
841
                                }
650
842
                                // closing tag of the script (it's a closing HTML tag anyway)
651
843
                                styler.ColourTo(i - 1, StateToPrint);
668
860
                         (ch == '<') &&
669
861
                         (chNext == '?') &&
670
862
                                 !IsScriptCommentState(state) ) {
671
 
                        scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment() + 2, i + 10, eScriptPHP);
 
863
                        scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
672
864
                        if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
673
865
                        styler.ColourTo(i - 1, StateToPrint);
674
866
                        beforePreProc = state;
675
867
                        i++;
676
868
                        visibleChars++;
677
 
                        i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 10);
 
869
                        i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6);
678
870
                        if (scriptLanguage == eScriptXML)
679
871
                                styler.ColourTo(i, SCE_H_XMLSTART);
680
872
                        else
689
881
                                levelCurrent++;
690
882
                        }
691
883
                        // should be better
692
 
                        ch = styler.SafeGetCharAt(i);
 
884
                        ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
 
885
                        continue;
 
886
                }
 
887
 
 
888
                // handle the start Mako template Python code
 
889
                else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') || 
 
890
                                                                                                                         (lineStartVisibleChars == 1 && ch == '%') ||
 
891
                                                                                                                         (ch == '$' && chNext == '{') ||
 
892
                                                                                                                         (ch == '<' && chNext == '/' && chNext2 == '%'))) {
 
893
                        if (ch == '%')
 
894
                                strcpy(makoBlockType, "%");
 
895
                        else if (ch == '$') 
 
896
                                strcpy(makoBlockType, "{");
 
897
                        else if (chNext == '/')
 
898
                                GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
 
899
                        else
 
900
                                GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType));
 
901
                        styler.ColourTo(i - 1, StateToPrint);
 
902
                        beforePreProc = state;
 
903
                        if (inScriptType == eNonHtmlScript)
 
904
                                inScriptType = eNonHtmlScriptPreProc;
 
905
                        else
 
906
                                inScriptType = eNonHtmlPreProc;
 
907
 
 
908
                        if (chNext == '/') {
 
909
                                i += 2;
 
910
                                visibleChars += 2;
 
911
                        } else if (ch != '%') {
 
912
                                i++;
 
913
                                visibleChars++;
 
914
                        }
 
915
                        state = SCE_HP_START;
 
916
                        scriptLanguage = eScriptPython;
 
917
                        styler.ColourTo(i, SCE_H_ASP);
 
918
                        if (foldHTMLPreprocessor && ch == '<')
 
919
                                levelCurrent++;
 
920
                                
 
921
                        if (ch != '%' && ch != '$') {
 
922
                                i += strlen(makoBlockType);
 
923
                                visibleChars += strlen(makoBlockType);
 
924
                                if (keywords4.InList(makoBlockType))
 
925
                                        styler.ColourTo(i, SCE_HP_WORD);
 
926
                                else
 
927
                                        styler.ColourTo(i, SCE_H_TAGUNKNOWN);
 
928
                        }
 
929
 
 
930
                        ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
693
931
                        continue;
694
932
                }
695
933
 
696
934
                // handle the start of ASP pre-processor = Non-HTML
697
 
                else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
 
935
                else if (!isMako && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
698
936
                        styler.ColourTo(i - 1, StateToPrint);
699
937
                        beforePreProc = state;
700
938
                        if (inScriptType == eNonHtmlScript)
728
966
                        if (foldHTMLPreprocessor)
729
967
                                levelCurrent++;
730
968
                        // should be better
731
 
                        ch = styler.SafeGetCharAt(i);
 
969
                        ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
732
970
                        continue;
733
971
                }
734
972
 
754
992
                                state = SCE_H_SGML_COMMAND; // wait for a pending command
755
993
                        }
756
994
                        // fold whole tag (-- when closing the tag)
757
 
                        if (foldHTMLPreprocessor)
 
995
                        if (foldHTMLPreprocessor || (state == SCE_H_COMMENT))
758
996
                                levelCurrent++;
759
997
                        continue;
760
998
                }
761
999
 
 
1000
                // handle the end of Mako Python code
 
1001
                else if (isMako && 
 
1002
                             ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && 
 
1003
                                 (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
 
1004
                                 isMakoBlockEnd(ch, chNext, makoBlockType)) {
 
1005
                        if (state == SCE_H_ASPAT) {
 
1006
                                aspScript = segIsScriptingIndicator(styler,
 
1007
                                                                    styler.GetStartSegment(), i - 1, aspScript);
 
1008
                        }
 
1009
                        if (state == SCE_HP_WORD) {
 
1010
                                classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
 
1011
                        } else {
 
1012
                                styler.ColourTo(i - 1, StateToPrint);
 
1013
                        }
 
1014
                        if (0 != strcmp(makoBlockType, "%") && (0 != strcmp(makoBlockType, "{")) && ch != '>') {
 
1015
                                i++;
 
1016
                                visibleChars++;
 
1017
                    }
 
1018
                        if (0 != strcmp(makoBlockType, "%")) {
 
1019
                                styler.ColourTo(i, SCE_H_ASP);
 
1020
                        }
 
1021
                        state = beforePreProc;
 
1022
                        if (inScriptType == eNonHtmlScriptPreProc)
 
1023
                                inScriptType = eNonHtmlScript;
 
1024
                        else
 
1025
                                inScriptType = eHtml;
 
1026
                        if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
 
1027
                                levelCurrent--;
 
1028
                        }
 
1029
                        scriptLanguage = eScriptNone;
 
1030
                        continue;
 
1031
                }
 
1032
 
762
1033
                // handle the end of a pre-processor = Non-HTML
763
 
                else if ((
764
 
                             ((inScriptType == eNonHtmlPreProc)
765
 
                              || (inScriptType == eNonHtmlScriptPreProc)) && (
766
 
                                 ((scriptLanguage == eScriptPHP) && (ch == '?') && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT)) ||
767
 
                                 ((scriptLanguage != eScriptNone) && !isStringState(state) &&
768
 
                                  ((ch == '%') || (ch == '?')))
769
 
                             ) && (chNext == '>')) ||
 
1034
                else if ((!isMako && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
 
1035
                                  (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
 
1036
                                  (((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
770
1037
                         ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
771
1038
                        if (state == SCE_H_ASPAT) {
772
1039
                                aspScript = segIsScriptingIndicator(styler,
845
1112
                                styler.ColourTo(i - 1, StateToPrint);
846
1113
                                state = SCE_H_SGML_SIMPLESTRING;
847
1114
                        } else if ((ch == '-') && (chPrev == '-')) {
848
 
                                styler.ColourTo(i - 2, StateToPrint);
 
1115
                                if (static_cast<int>(styler.GetStartSegment()) <= (i - 2)) {
 
1116
                                        styler.ColourTo(i - 2, StateToPrint);
 
1117
                                }
849
1118
                                state = SCE_H_SGML_COMMENT;
850
1119
                        } else if (isascii(ch) && isalpha(ch) && (chPrev == '%')) {
851
1120
                                styler.ColourTo(i - 2, StateToPrint);
907
1176
                                }
908
1177
                                // find the length of the word
909
1178
                                int size = 1;
910
 
                                while (ishtmlwordchar(styler.SafeGetCharAt(i + size)))
 
1179
                                while (setHTMLWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(i + size))))
911
1180
                                        size++;
912
1181
                                styler.ColourTo(i + size - 1, StateToPrint);
913
1182
                                i += size - 1;
914
1183
                                visibleChars += size - 1;
915
 
                                ch = styler.SafeGetCharAt(i);
 
1184
                                ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
916
1185
                                if (scriptLanguage == eScriptSGMLblock) {
917
1186
                                        state = SCE_H_SGML_BLOCK_DEFAULT;
918
1187
                                } else {
952
1221
                        }
953
1222
                        break;
954
1223
                case SCE_H_COMMENT:
955
 
                        if ((chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
 
1224
                        if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
956
1225
                                styler.ColourTo(i, StateToPrint);
957
1226
                                state = SCE_H_DEFAULT;
958
1227
                                levelCurrent--;
990
1259
                        }
991
1260
                        if (ch != '#' && !(isascii(ch) && isalnum(ch))  // Should check that '#' follows '&', but it is unlikely anyway...
992
1261
                                && ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML
993
 
                                styler.ColourTo(i, SCE_H_TAGUNKNOWN);
 
1262
                                if (!isascii(ch))       // Possibly start of a multibyte character so don't allow this byte to be in entity style
 
1263
                                        styler.ColourTo(i-1, SCE_H_TAGUNKNOWN);
 
1264
                                else
 
1265
                                        styler.ColourTo(i, SCE_H_TAGUNKNOWN);
994
1266
                                state = SCE_H_DEFAULT;
995
1267
                        }
996
1268
                        break;
997
1269
                case SCE_H_TAGUNKNOWN:
998
 
                        if (!ishtmlwordchar(ch) && !((ch == '/') && (chPrev == '<')) && ch != '[') {
 
1270
                        if (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) {
999
1271
                                int eClass = classifyTagHTML(styler.GetStartSegment(),
1000
 
                                        i - 1, keywords, styler, tagDontFold, caseSensitive);
1001
 
                                if (eClass == SCE_H_SCRIPT) {
 
1272
                                        i - 1, keywords, styler, tagDontFold, caseSensitive, isXml, allowScripts);
 
1273
                                if (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) {
1002
1274
                                        if (!tagClosing) {
1003
1275
                                                inScriptType = eNonHtmlScript;
1004
 
                                                scriptLanguage = clientScript;
1005
 
                                                eClass = SCE_H_TAG;
 
1276
                                                scriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment;
1006
1277
                                        } else {
1007
1278
                                                scriptLanguage = eScriptNone;
1008
 
                                                eClass = SCE_H_TAG;
1009
1279
                                        }
 
1280
                                        eClass = SCE_H_TAG;
1010
1281
                                }
1011
1282
                                if (ch == '>') {
1012
1283
                                        styler.ColourTo(i, eClass);
1016
1287
                                                state = SCE_H_DEFAULT;
1017
1288
                                        }
1018
1289
                                        tagOpened = false;
1019
 
                                        if (!tagDontFold){
 
1290
                                        if (!tagDontFold) {
1020
1291
                                                if (tagClosing) {
1021
1292
                                                        levelCurrent--;
1022
1293
                                                } else {
1047
1318
                        }
1048
1319
                        break;
1049
1320
                case SCE_H_ATTRIBUTE:
1050
 
                        if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') {
 
1321
                        if (!setAttributeContinue.Contains(ch)) {
1051
1322
                                if (inScriptType == eNonHtmlScript) {
1052
1323
                                        int scriptLanguagePrev = scriptLanguage;
1053
1324
                                        clientScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, scriptLanguage);
1064
1335
                                                state = SCE_H_DEFAULT;
1065
1336
                                        }
1066
1337
                                        tagOpened = false;
1067
 
                                        if (!tagDontFold){
1068
 
                                                if (tagClosing){
 
1338
                                        if (!tagDontFold) {
 
1339
                                                if (tagClosing) {
1069
1340
                                                        levelCurrent--;
1070
1341
                                                } else {
1071
1342
                                                        levelCurrent++;
1090
1361
                                        state = SCE_H_DEFAULT;
1091
1362
                                }
1092
1363
                                tagOpened = false;
1093
 
                                if (!tagDontFold){
1094
 
                                        if (tagClosing){
 
1364
                                if (!tagDontFold) {
 
1365
                                        if (tagClosing) {
1095
1366
                                                levelCurrent--;
1096
1367
                                        } else {
1097
1368
                                                levelCurrent++;
1120
1391
                                i++;
1121
1392
                                ch = chNext;
1122
1393
                                state = SCE_H_DEFAULT;
1123
 
                        } else if (ishtmlwordchar(ch)) {
 
1394
                        } else if (setHTMLWord.Contains(ch)) {
1124
1395
                                styler.ColourTo(i - 1, StateToPrint);
1125
1396
                                state = SCE_H_ATTRIBUTE;
1126
1397
                        }
1144
1415
                        }
1145
1416
                        break;
1146
1417
                case SCE_H_VALUE:
1147
 
                        if (!ishtmlwordchar(ch)) {
 
1418
                        if (!setHTMLWord.Contains(ch)) {
1148
1419
                                if (ch == '\"' && chPrev == '=') {
1149
1420
                                        // Should really test for being first character
1150
1421
                                        state = SCE_H_DOUBLESTRING;
1164
1435
                                                        state = SCE_H_DEFAULT;
1165
1436
                                                }
1166
1437
                                                tagOpened = false;
1167
 
                                                if (!tagDontFold){
1168
 
                                                        if (tagClosing){
 
1438
                                                if (!tagDontFold) {
 
1439
                                                        if (tagClosing) {
1169
1440
                                                                levelCurrent--;
1170
1441
                                                        } else {
1171
1442
                                                                levelCurrent++;
1181
1452
                case SCE_HJ_DEFAULT:
1182
1453
                case SCE_HJ_START:
1183
1454
                case SCE_HJ_SYMBOLS:
1184
 
                        if (iswordstart(ch)) {
 
1455
                        if (IsAWordStart(ch)) {
1185
1456
                                styler.ColourTo(i - 1, StateToPrint);
1186
1457
                                state = SCE_HJ_WORD;
1187
1458
                        } else if (ch == '/' && chNext == '*') {
1210
1481
                                styler.ColourTo(i - 1, StateToPrint);
1211
1482
                                state = SCE_HJ_COMMENTLINE;
1212
1483
                                i += 2;
1213
 
                        } else if (isoperator(ch)) {
 
1484
                        } else if (IsOperator(ch)) {
1214
1485
                                styler.ColourTo(i - 1, StateToPrint);
1215
1486
                                styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
1216
1487
                                state = SCE_HJ_DEFAULT;
1222
1493
                        }
1223
1494
                        break;
1224
1495
                case SCE_HJ_WORD:
1225
 
                        if (!iswordchar(ch)) {
 
1496
                        if (!IsAWordChar(ch)) {
1226
1497
                                classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType);
1227
1498
                                //styler.ColourTo(i - 1, eHTJSKeyword);
1228
1499
                                state = SCE_HJ_DEFAULT;
1241
1512
                                        styler.ColourTo(i - 1, StateToPrint);
1242
1513
                                        state = SCE_HJ_COMMENTLINE;
1243
1514
                                        i += 2;
1244
 
                                } else if (isoperator(ch)) {
 
1515
                                } else if (IsOperator(ch)) {
1245
1516
                                        styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
1246
1517
                                        state = SCE_HJ_DEFAULT;
1247
1518
                                }
1311
1582
                                        while (isascii(chNext) && islower(chNext)) {   // gobble regex flags
1312
1583
                                                i++;
1313
1584
                                                ch = chNext;
1314
 
                                                chNext = styler.SafeGetCharAt(i + 1);
 
1585
                                                chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1315
1586
                                        }
1316
1587
                                }
1317
1588
                                styler.ColourTo(i, StateToPrint);
1321
1592
                                if (chNext == '\\' || chNext == '/') {
1322
1593
                                        i++;
1323
1594
                                        ch = chNext;
1324
 
                                        chNext = styler.SafeGetCharAt(i + 1);
 
1595
                                        chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1325
1596
                                }
1326
1597
                        }
1327
1598
                        break;
1328
1599
                case SCE_HB_DEFAULT:
1329
1600
                case SCE_HB_START:
1330
 
                        if (iswordstart(ch)) {
 
1601
                        if (IsAWordStart(ch)) {
1331
1602
                                styler.ColourTo(i - 1, StateToPrint);
1332
1603
                                state = SCE_HB_WORD;
1333
1604
                        } else if (ch == '\'') {
1340
1611
                                   styler.SafeGetCharAt(i + 3) == '-') {
1341
1612
                                styler.ColourTo(i - 1, StateToPrint);
1342
1613
                                state = SCE_HB_COMMENTLINE;
1343
 
                        } else if (isoperator(ch)) {
 
1614
                        } else if (IsOperator(ch)) {
1344
1615
                                styler.ColourTo(i - 1, StateToPrint);
1345
1616
                                styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
1346
1617
                                state = SCE_HB_DEFAULT;
1352
1623
                        }
1353
1624
                        break;
1354
1625
                case SCE_HB_WORD:
1355
 
                        if (!iswordchar(ch)) {
 
1626
                        if (!IsAWordChar(ch)) {
1356
1627
                                state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
1357
1628
                                if (state == SCE_HB_DEFAULT) {
1358
1629
                                        if (ch == '\"') {
1359
1630
                                                state = SCE_HB_STRING;
1360
1631
                                        } else if (ch == '\'') {
1361
1632
                                                state = SCE_HB_COMMENTLINE;
1362
 
                                        } else if (isoperator(ch)) {
 
1633
                                        } else if (IsOperator(ch)) {
1363
1634
                                                styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
1364
1635
                                                state = SCE_HB_DEFAULT;
1365
1636
                                        }
1392
1663
                        break;
1393
1664
                case SCE_HP_DEFAULT:
1394
1665
                case SCE_HP_START:
1395
 
                        if (iswordstart(ch)) {
 
1666
                        if (IsAWordStart(ch)) {
1396
1667
                                styler.ColourTo(i - 1, StateToPrint);
1397
1668
                                state = SCE_HP_WORD;
1398
1669
                        } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
1409
1680
                                        state = SCE_HP_TRIPLEDOUBLE;
1410
1681
                                        ch = ' ';
1411
1682
                                        chPrev = ' ';
1412
 
                                        chNext = styler.SafeGetCharAt(i + 1);
 
1683
                                        chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1413
1684
                                } else {
1414
1685
                                        //                                      state = statePrintForState(SCE_HP_STRING,inScriptType);
1415
1686
                                        state = SCE_HP_STRING;
1421
1692
                                        state = SCE_HP_TRIPLE;
1422
1693
                                        ch = ' ';
1423
1694
                                        chPrev = ' ';
1424
 
                                        chNext = styler.SafeGetCharAt(i + 1);
 
1695
                                        chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1425
1696
                                } else {
1426
1697
                                        state = SCE_HP_CHARACTER;
1427
1698
                                }
1428
 
                        } else if (isoperator(ch)) {
 
1699
                        } else if (IsOperator(ch)) {
1429
1700
                                styler.ColourTo(i - 1, StateToPrint);
1430
1701
                                styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
1431
1702
                        } else if ((ch == ' ') || (ch == '\t')) {
1436
1707
                        }
1437
1708
                        break;
1438
1709
                case SCE_HP_WORD:
1439
 
                        if (!iswordchar(ch)) {
 
1710
                        if (!IsAWordChar(ch)) {
1440
1711
                                classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
1441
1712
                                state = SCE_HP_DEFAULT;
1442
1713
                                if (ch == '#') {
1447
1718
                                                state = SCE_HP_TRIPLEDOUBLE;
1448
1719
                                                ch = ' ';
1449
1720
                                                chPrev = ' ';
1450
 
                                                chNext = styler.SafeGetCharAt(i + 1);
 
1721
                                                chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1451
1722
                                        } else {
1452
1723
                                                state = SCE_HP_STRING;
1453
1724
                                        }
1457
1728
                                                state = SCE_HP_TRIPLE;
1458
1729
                                                ch = ' ';
1459
1730
                                                chPrev = ' ';
1460
 
                                                chNext = styler.SafeGetCharAt(i + 1);
 
1731
                                                chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1461
1732
                                        } else {
1462
1733
                                                state = SCE_HP_CHARACTER;
1463
1734
                                        }
1464
 
                                } else if (isoperator(ch)) {
 
1735
                                } else if (IsOperator(ch)) {
1465
1736
                                        styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
1466
1737
                                }
1467
1738
                        }
1477
1748
                                if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
1478
1749
                                        i++;
1479
1750
                                        ch = chNext;
1480
 
                                        chNext = styler.SafeGetCharAt(i + 1);
 
1751
                                        chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1481
1752
                                }
1482
1753
                        } else if (ch == '\"') {
1483
1754
                                styler.ColourTo(i, StateToPrint);
1489
1760
                                if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
1490
1761
                                        i++;
1491
1762
                                        ch = chNext;
1492
 
                                        chNext = styler.SafeGetCharAt(i + 1);
 
1763
                                        chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
1493
1764
                                }
1494
1765
                        } else if (ch == '\'') {
1495
1766
                                styler.ColourTo(i, StateToPrint);
1510
1781
                        break;
1511
1782
                        ///////////// start - PHP state handling
1512
1783
                case SCE_HPHP_WORD:
1513
 
                        if (!iswordchar(ch)) {
 
1784
                        if (!IsAWordChar(ch)) {
1514
1785
                                classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
1515
1786
                                if (ch == '/' && chNext == '*') {
1516
1787
                                        i++;
1524
1795
                                        state = SCE_HPHP_HSTRING;
1525
1796
                                        strcpy(phpStringDelimiter, "\"");
1526
1797
                                } else if (styler.Match(i, "<<<")) {
1527
 
                                        state = SCE_HPHP_HSTRING;
1528
 
                                        i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler);
 
1798
                                        bool isSimpleString = false;
 
1799
                                        i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
 
1800
                                        if (strlen(phpStringDelimiter)) {
 
1801
                                                state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
 
1802
                                                if (foldHeredoc) levelCurrent++;
 
1803
                                        }
1529
1804
                                } else if (ch == '\'') {
1530
1805
                                        state = SCE_HPHP_SIMPLESTRING;
 
1806
                                        strcpy(phpStringDelimiter, "\'");
1531
1807
                                } else if (ch == '$' && IsPhpWordStart(chNext)) {
1532
1808
                                        state = SCE_HPHP_VARIABLE;
1533
 
                                } else if (isoperator(ch)) {
 
1809
                                } else if (IsOperator(ch)) {
1534
1810
                                        state = SCE_HPHP_OPERATOR;
1535
1811
                                } else {
1536
1812
                                        state = SCE_HPHP_DEFAULT;
1543
1819
                                && strchr(".xXabcdefABCDEF", ch) == NULL
1544
1820
                                && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) {
1545
1821
                                styler.ColourTo(i - 1, SCE_HPHP_NUMBER);
1546
 
                                if (isoperator(ch))
 
1822
                                if (IsOperator(ch))
1547
1823
                                        state = SCE_HPHP_OPERATOR;
1548
1824
                                else
1549
1825
                                        state = SCE_HPHP_DEFAULT;
1550
1826
                        }
1551
1827
                        break;
1552
1828
                case SCE_HPHP_VARIABLE:
1553
 
                        if (!IsPhpWordChar(ch)) {
1554
 
                                styler.ColourTo(i - 1, SCE_HPHP_VARIABLE);
1555
 
                                if (isoperator(ch))
1556
 
                                        state = SCE_HPHP_OPERATOR;
1557
 
                                else
1558
 
                                        state = SCE_HPHP_DEFAULT;
 
1829
                        if (!IsPhpWordChar(chNext)) {
 
1830
                                styler.ColourTo(i, SCE_HPHP_VARIABLE);
 
1831
                                state = SCE_HPHP_DEFAULT;
1559
1832
                        }
1560
1833
                        break;
1561
1834
                case SCE_HPHP_COMMENT:
1582
1855
                                styler.ColourTo(i - 1, StateToPrint);
1583
1856
                                state = SCE_HPHP_HSTRING_VARIABLE;
1584
1857
                        } else if (styler.Match(i, phpStringDelimiter)) {
1585
 
                                if (strlen(phpStringDelimiter) > 1)
1586
 
                                        i += strlen(phpStringDelimiter) - 1;
1587
 
                                styler.ColourTo(i, StateToPrint);
1588
 
                                state = SCE_HPHP_DEFAULT;
 
1858
                                if (phpStringDelimiter[0] == '\"') {
 
1859
                                        styler.ColourTo(i, StateToPrint);
 
1860
                                        state = SCE_HPHP_DEFAULT;
 
1861
                                } else if (isLineEnd(chPrev)) {
 
1862
                                const int psdLength = strlen(phpStringDelimiter);
 
1863
                                        const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
 
1864
                                        const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
 
1865
                                        if (isLineEnd(chAfterPsd) ||
 
1866
                                                (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
 
1867
                                                        i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
 
1868
                                                styler.ColourTo(i, StateToPrint);
 
1869
                                                state = SCE_HPHP_DEFAULT;
 
1870
                                                if (foldHeredoc) levelCurrent--;
 
1871
                                        }
 
1872
                                }
1589
1873
                        }
1590
1874
                        break;
1591
1875
                case SCE_HPHP_SIMPLESTRING:
1592
 
                        if (ch == '\\') {
1593
 
                                // skip the next char
1594
 
                                i++;
1595
 
                        } else if (ch == '\'') {
1596
 
                                styler.ColourTo(i, StateToPrint);
1597
 
                                state = SCE_HPHP_DEFAULT;
 
1876
                        if (phpStringDelimiter[0] == '\'') {
 
1877
                                if (ch == '\\') {
 
1878
                                        // skip the next char
 
1879
                                        i++;
 
1880
                                } else if (ch == '\'') {
 
1881
                                        styler.ColourTo(i, StateToPrint);
 
1882
                                        state = SCE_HPHP_DEFAULT;
 
1883
                                }
 
1884
                        } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
 
1885
                                const int psdLength = strlen(phpStringDelimiter);
 
1886
                                const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
 
1887
                                const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
 
1888
                                if (isLineEnd(chAfterPsd) ||
 
1889
                                (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
 
1890
                                        i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
 
1891
                                        styler.ColourTo(i, StateToPrint);
 
1892
                                        state = SCE_HPHP_DEFAULT;
 
1893
                                        if (foldHeredoc) levelCurrent--;
 
1894
                                }
1598
1895
                        }
1599
1896
                        break;
1600
1897
                case SCE_HPHP_HSTRING_VARIABLE:
1601
 
                        if (!IsPhpWordChar(ch)) {
1602
 
                                styler.ColourTo(i - 1, StateToPrint);
1603
 
                                i--; // strange but it works
 
1898
                        if (!IsPhpWordChar(chNext)) {
 
1899
                                styler.ColourTo(i, StateToPrint);
1604
1900
                                state = SCE_HPHP_HSTRING;
1605
1901
                        }
1606
1902
                        break;
1615
1911
                        styler.ColourTo(i - 1, StateToPrint);
1616
1912
                        if (IsADigit(ch) || (ch == '.' && IsADigit(chNext))) {
1617
1913
                                state = SCE_HPHP_NUMBER;
1618
 
                        } else if (iswordstart(ch)) {
 
1914
                        } else if (IsAWordStart(ch)) {
1619
1915
                                state = SCE_HPHP_WORD;
1620
1916
                        } else if (ch == '/' && chNext == '*') {
1621
1917
                                i++;
1629
1925
                                state = SCE_HPHP_HSTRING;
1630
1926
                                strcpy(phpStringDelimiter, "\"");
1631
1927
                        } else if (styler.Match(i, "<<<")) {
1632
 
                                state = SCE_HPHP_HSTRING;
1633
 
                                i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler);
 
1928
                                bool isSimpleString = false;
 
1929
                                i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
 
1930
                                if (strlen(phpStringDelimiter)) {
 
1931
                                        state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
 
1932
                                        if (foldHeredoc) levelCurrent++;
 
1933
                                }
1634
1934
                        } else if (ch == '\'') {
1635
1935
                                state = SCE_HPHP_SIMPLESTRING;
 
1936
                                strcpy(phpStringDelimiter, "\'");
1636
1937
                        } else if (ch == '$' && IsPhpWordStart(chNext)) {
1637
1938
                                state = SCE_HPHP_VARIABLE;
1638
 
                        } else if (isoperator(ch)) {
 
1939
                        } else if (IsOperator(ch)) {
1639
1940
                                state = SCE_HPHP_OPERATOR;
1640
 
                        } else if ((state == SCE_HPHP_OPERATOR) && (isspacechar(ch))) {
 
1941
                        } else if ((state == SCE_HPHP_OPERATOR) && (IsASpace(ch))) {
1641
1942
                                state = SCE_HPHP_DEFAULT;
1642
1943
                        }
1643
1944
                        break;
1653
1954
                                state = SCE_HB_STRING;
1654
1955
                        } else if (ch == '\'') {
1655
1956
                                state = SCE_HB_COMMENTLINE;
1656
 
                        } else if (iswordstart(ch)) {
 
1957
                        } else if (IsAWordStart(ch)) {
1657
1958
                                state = SCE_HB_WORD;
1658
 
                        } else if (isoperator(ch)) {
 
1959
                        } else if (IsOperator(ch)) {
1659
1960
                                styler.ColourTo(i, SCE_HB_DEFAULT);
1660
1961
                        }
1661
1962
                } else if (state == SCE_HBA_DEFAULT) {    // One of the above succeeded
1663
1964
                                state = SCE_HBA_STRING;
1664
1965
                        } else if (ch == '\'') {
1665
1966
                                state = SCE_HBA_COMMENTLINE;
1666
 
                        } else if (iswordstart(ch)) {
 
1967
                        } else if (IsAWordStart(ch)) {
1667
1968
                                state = SCE_HBA_WORD;
1668
 
                        } else if (isoperator(ch)) {
 
1969
                        } else if (IsOperator(ch)) {
1669
1970
                                styler.ColourTo(i, SCE_HBA_DEFAULT);
1670
1971
                        }
1671
1972
                } else if (state == SCE_HJ_DEFAULT) {    // One of the above succeeded
1680
1981
                                state = SCE_HJ_DOUBLESTRING;
1681
1982
                        } else if ((ch == '\'') && (nonEmptySegment)) {
1682
1983
                                state = SCE_HJ_SINGLESTRING;
1683
 
                        } else if (iswordstart(ch)) {
 
1984
                        } else if (IsAWordStart(ch)) {
1684
1985
                                state = SCE_HJ_WORD;
1685
 
                        } else if (isoperator(ch)) {
 
1986
                        } else if (IsOperator(ch)) {
1686
1987
                                styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
1687
1988
                        }
1688
1989
                }
1689
1990
        }
1690
1991
 
1691
 
        StateToPrint = statePrintForState(state, inScriptType);
 
1992
        switch (state) {
 
1993
        case SCE_HJ_WORD:
 
1994
                classifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywords2, styler, inScriptType);
 
1995
                break;
 
1996
        case SCE_HB_WORD:
 
1997
                classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
 
1998
                break;
 
1999
        case SCE_HP_WORD:
 
2000
                classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType);
 
2001
                break;
 
2002
        case SCE_HPHP_WORD:
 
2003
                classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);
 
2004
                break;
 
2005
        default:
 
2006
                StateToPrint = statePrintForState(state, inScriptType);
1692
2007
                styler.ColourTo(lengthDoc - 1, StateToPrint);
 
2008
                break;
 
2009
        }
1693
2010
 
1694
2011
        // Fill in the real level of the next line, keeping the current flags as they will be filled in later
1695
2012
        if (fold) {
1698
2015
        }
1699
2016
}
1700
2017
 
1701
 
static bool isASPScript(int state) {
1702
 
        return
1703
 
                (state >= SCE_HJA_START && state <= SCE_HJA_REGEX) ||
1704
 
                (state >= SCE_HBA_START && state <= SCE_HBA_STRINGEOL) ||
1705
 
                (state >= SCE_HPA_DEFAULT && state <= SCE_HPA_IDENTIFIER);
1706
 
}
1707
 
 
1708
 
static void ColouriseHBAPiece(StyleContext &sc, WordList *keywordlists[]) {
1709
 
        WordList &keywordsVBS = *keywordlists[2];
1710
 
        if (sc.state == SCE_HBA_WORD) {
1711
 
                if (!IsAWordChar(sc.ch)) {
1712
 
                        char s[100];
1713
 
                        sc.GetCurrentLowered(s, sizeof(s));
1714
 
                        if (keywordsVBS.InList(s)) {
1715
 
                                if (strcmp(s, "rem") == 0) {
1716
 
                                        sc.ChangeState(SCE_HBA_COMMENTLINE);
1717
 
                                        if (sc.atLineEnd) {
1718
 
                                                sc.SetState(SCE_HBA_DEFAULT);
1719
 
                                        }
1720
 
                                } else {
1721
 
                                        sc.SetState(SCE_HBA_DEFAULT);
1722
 
                                }
1723
 
                        } else {
1724
 
                                sc.ChangeState(SCE_HBA_IDENTIFIER);
1725
 
                                sc.SetState(SCE_HBA_DEFAULT);
1726
 
                        }
1727
 
                }
1728
 
        } else if (sc.state == SCE_HBA_NUMBER) {
1729
 
                if (!IsAWordChar(sc.ch)) {
1730
 
                        sc.SetState(SCE_HBA_DEFAULT);
1731
 
                }
1732
 
        } else if (sc.state == SCE_HBA_STRING) {
1733
 
                if (sc.ch == '\"') {
1734
 
                        sc.ForwardSetState(SCE_HBA_DEFAULT);
1735
 
                } else if (sc.ch == '\r' || sc.ch == '\n') {
1736
 
                        sc.ChangeState(SCE_HBA_STRINGEOL);
1737
 
                        sc.ForwardSetState(SCE_HBA_DEFAULT);
1738
 
                }
1739
 
        } else if (sc.state == SCE_HBA_COMMENTLINE) {
1740
 
                if (sc.ch == '\r' || sc.ch == '\n') {
1741
 
                        sc.SetState(SCE_HBA_DEFAULT);
1742
 
                }
1743
 
        }
1744
 
 
1745
 
        if (sc.state == SCE_HBA_DEFAULT) {
1746
 
                if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
1747
 
                        sc.SetState(SCE_HBA_NUMBER);
1748
 
                } else if (IsAWordStart(sc.ch)) {
1749
 
                        sc.SetState(SCE_HBA_WORD);
1750
 
                } else if (sc.ch == '\'') {
1751
 
                        sc.SetState(SCE_HBA_COMMENTLINE);
1752
 
                } else if (sc.ch == '\"') {
1753
 
                        sc.SetState(SCE_HBA_STRING);
1754
 
                }
1755
 
        }
1756
 
}
1757
 
 
1758
 
static void ColouriseHTMLPiece(StyleContext &sc, WordList *keywordlists[]) {
1759
 
        WordList &keywordsTags = *keywordlists[0];
1760
 
        if (sc.state == SCE_H_COMMENT) {
1761
 
                if (sc.Match("-->")) {
1762
 
                        sc.Forward();
1763
 
                        sc.Forward();
1764
 
                        sc.ForwardSetState(SCE_H_DEFAULT);
1765
 
                }
1766
 
        } else if (sc.state == SCE_H_ENTITY) {
1767
 
                if (sc.ch == ';') {
1768
 
                        sc.ForwardSetState(SCE_H_DEFAULT);
1769
 
                } else if (sc.ch != '#' && (sc.ch < 0x80) && !isalnum(sc.ch)    // Should check that '#' follows '&', but it is unlikely anyway...
1770
 
                        && sc.ch != '.' && sc.ch != '-' && sc.ch != '_' && sc.ch != ':') { // valid in XML
1771
 
                        sc.ChangeState(SCE_H_TAGUNKNOWN);
1772
 
                        sc.SetState(SCE_H_DEFAULT);
1773
 
                }
1774
 
        } else if (sc.state == SCE_H_TAGUNKNOWN) {
1775
 
                if (!ishtmlwordchar(static_cast<char>(sc.ch)) && !((sc.ch == '/') && (sc.chPrev == '<')) && sc.ch != '[') {
1776
 
                        char s[100];
1777
 
                        sc.GetCurrentLowered(s, sizeof(s));
1778
 
                        if (s[1] == '/') {
1779
 
                                if (keywordsTags.InList(s + 2)) {
1780
 
                                        sc.ChangeState(SCE_H_TAG);
1781
 
                                }
1782
 
                        } else {
1783
 
                                if (keywordsTags.InList(s + 1)) {
1784
 
                                        sc.ChangeState(SCE_H_TAG);
1785
 
                                }
1786
 
                        }
1787
 
                        if (sc.ch == '>') {
1788
 
                                sc.ForwardSetState(SCE_H_DEFAULT);
1789
 
                        } else if (sc.Match('/', '>')) {
1790
 
                                sc.SetState(SCE_H_TAGEND);
1791
 
                                sc.Forward();
1792
 
                                sc.ForwardSetState(SCE_H_DEFAULT);
1793
 
                        } else {
1794
 
                                sc.SetState(SCE_H_OTHER);
1795
 
                        }
1796
 
                }
1797
 
        } else if (sc.state == SCE_H_ATTRIBUTE) {
1798
 
                if (!ishtmlwordchar(static_cast<char>(sc.ch))) {
1799
 
                        char s[100];
1800
 
                        sc.GetCurrentLowered(s, sizeof(s));
1801
 
                        if (!keywordsTags.InList(s)) {
1802
 
                                sc.ChangeState(SCE_H_ATTRIBUTEUNKNOWN);
1803
 
                        }
1804
 
                        sc.SetState(SCE_H_OTHER);
1805
 
                }
1806
 
        } else if (sc.state == SCE_H_OTHER) {
1807
 
                if (sc.ch == '>') {
1808
 
                        sc.SetState(SCE_H_TAG);
1809
 
                        sc.ForwardSetState(SCE_H_DEFAULT);
1810
 
                } else if (sc.Match('/', '>')) {
1811
 
                        sc.SetState(SCE_H_TAG);
1812
 
                        sc.Forward();
1813
 
                        sc.ForwardSetState(SCE_H_DEFAULT);
1814
 
                } else if (sc.chPrev == '=') {
1815
 
                        sc.SetState(SCE_H_VALUE);
1816
 
                }
1817
 
        } else if (sc.state == SCE_H_DOUBLESTRING) {
1818
 
                if (sc.ch == '\"') {
1819
 
                        sc.ForwardSetState(SCE_H_OTHER);
1820
 
                }
1821
 
        } else if (sc.state == SCE_H_SINGLESTRING) {
1822
 
                if (sc.ch == '\'') {
1823
 
                        sc.ForwardSetState(SCE_H_OTHER);
1824
 
                }
1825
 
        } else if (sc.state == SCE_H_NUMBER) {
1826
 
                if (!IsADigit(sc.ch)) {
1827
 
                        sc.SetState(SCE_H_OTHER);
1828
 
                }
1829
 
        }
1830
 
 
1831
 
        if (sc.state == SCE_H_DEFAULT) {
1832
 
                if (sc.ch == '<') {
1833
 
                        if (sc.Match("<!--"))
1834
 
                                sc.SetState(SCE_H_COMMENT);
1835
 
                        else
1836
 
                                sc.SetState(SCE_H_TAGUNKNOWN);
1837
 
                } else if (sc.ch == '&') {
1838
 
                        sc.SetState(SCE_H_ENTITY);
1839
 
                }
1840
 
        } else if ((sc.state == SCE_H_OTHER) || (sc.state == SCE_H_VALUE)) {
1841
 
                if (sc.ch == '\"' && sc.chPrev == '=') {
1842
 
                        sc.SetState(SCE_H_DOUBLESTRING);
1843
 
                } else if (sc.ch == '\'' && sc.chPrev == '=') {
1844
 
                        sc.SetState(SCE_H_SINGLESTRING);
1845
 
                } else if (IsADigit(sc.ch)) {
1846
 
                        sc.SetState(SCE_H_NUMBER);
1847
 
                } else if (sc.ch == '>') {
1848
 
                        sc.SetState(SCE_H_TAG);
1849
 
                        sc.ForwardSetState(SCE_H_DEFAULT);
1850
 
                } else if (ishtmlwordchar(static_cast<char>(sc.ch))) {
1851
 
                        sc.SetState(SCE_H_ATTRIBUTE);
1852
 
                }
1853
 
        }
1854
 
}
1855
 
 
1856
 
static void ColouriseASPPiece(StyleContext &sc, WordList *keywordlists[]) {
1857
 
        // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1858
 
        if ((sc.state == SCE_H_ASPAT || isASPScript(sc.state)) && sc.Match('%', '>')) {
1859
 
                sc.SetState(SCE_H_ASP);
1860
 
                sc.Forward();
1861
 
                sc.ForwardSetState(SCE_H_DEFAULT);
1862
 
        }
1863
 
 
1864
 
        // Handle some ASP script
1865
 
        if (sc.state >= SCE_HBA_START && sc.state <= SCE_HBA_STRINGEOL) {
1866
 
                ColouriseHBAPiece(sc, keywordlists);
1867
 
        } else if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
1868
 
                ColouriseHTMLPiece(sc, keywordlists);
1869
 
        }
1870
 
 
1871
 
        // Enter new sc.state
1872
 
        if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
1873
 
                if (sc.Match('<', '%')) {
1874
 
                        if (sc.state == SCE_H_TAGUNKNOWN)
1875
 
                                sc.ChangeState(SCE_H_ASP);
1876
 
                        else
1877
 
                                sc.SetState(SCE_H_ASP);
1878
 
                        sc.Forward();
1879
 
                        sc.Forward();
1880
 
                        if (sc.ch == '@') {
1881
 
                                sc.ForwardSetState(SCE_H_ASPAT);
1882
 
                        } else {
1883
 
                                if (sc.ch == '=') {
1884
 
                                        sc.Forward();
1885
 
                                }
1886
 
                                sc.SetState(SCE_HBA_DEFAULT);
1887
 
                        }
1888
 
                }
1889
 
        }
1890
 
}
1891
 
 
1892
 
static void ColouriseASPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
1893
 
                                  Accessor &styler) {
1894
 
        // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
1895
 
        StyleContext sc(startPos, length, initStyle, styler, 0x7f);
1896
 
        for (; sc.More(); sc.Forward()) {
1897
 
                ColouriseASPPiece(sc, keywordlists);
1898
 
        }
1899
 
        sc.Complete();
1900
 
}
1901
 
 
1902
 
static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
1903
 
        // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1904
 
        if (sc.state >= SCE_HPHP_DEFAULT && sc.state <= SCE_HPHP_OPERATOR) {
1905
 
                if (!isPHPStringState(sc.state) &&
1906
 
                        (sc.state != SCE_HPHP_COMMENT) &&
1907
 
                        (sc.Match('?', '>'))) {
1908
 
                        sc.SetState(SCE_H_QUESTION);
1909
 
                        sc.Forward();
1910
 
                        sc.ForwardSetState(SCE_H_DEFAULT);
1911
 
                }
1912
 
        }
1913
 
 
1914
 
        if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
1915
 
                ColouriseHTMLPiece(sc, keywordlists);
1916
 
        }
1917
 
 
1918
 
        // Handle some PHP script
1919
 
        if (sc.state == SCE_HPHP_WORD) {
1920
 
                if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
1921
 
                        sc.SetState(SCE_HPHP_DEFAULT);
1922
 
                }
1923
 
        } else if (sc.state == SCE_HPHP_COMMENTLINE) {
1924
 
                if (sc.ch == '\r' || sc.ch == '\n') {
1925
 
                        sc.SetState(SCE_HPHP_DEFAULT);
1926
 
                }
1927
 
        } else if (sc.state == SCE_HPHP_COMMENT) {
1928
 
                if (sc.Match('*', '/')) {
1929
 
                        sc.Forward();
1930
 
                        sc.Forward();
1931
 
                        sc.SetState(SCE_HPHP_DEFAULT);
1932
 
                }
1933
 
        } else if (sc.state == SCE_HPHP_HSTRING) {
1934
 
                if (sc.ch == '\"') {
1935
 
                        sc.ForwardSetState(SCE_HPHP_DEFAULT);
1936
 
                }
1937
 
        } else if (sc.state == SCE_HPHP_SIMPLESTRING) {
1938
 
                if (sc.ch == '\'') {
1939
 
                        sc.ForwardSetState(SCE_HPHP_DEFAULT);
1940
 
                }
1941
 
        } else if (sc.state == SCE_HPHP_VARIABLE) {
1942
 
                if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
1943
 
                        sc.SetState(SCE_HPHP_DEFAULT);
1944
 
                }
1945
 
        } else if (sc.state == SCE_HPHP_OPERATOR) {
1946
 
                sc.SetState(SCE_HPHP_DEFAULT);
1947
 
        }
1948
 
 
1949
 
        // Enter new sc.state
1950
 
        if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
1951
 
                if (sc.Match("<?php")) {
1952
 
                        sc.SetState(SCE_H_QUESTION);
1953
 
                        sc.Forward();
1954
 
                        sc.Forward();
1955
 
                        sc.Forward();
1956
 
                        sc.Forward();
1957
 
                        sc.Forward();
1958
 
                        sc.SetState(SCE_HPHP_DEFAULT);
1959
 
                }
1960
 
        }
1961
 
        if (sc.state == SCE_HPHP_DEFAULT) {
1962
 
                if (IsPhpWordStart(static_cast<char>(sc.ch))) {
1963
 
                        sc.SetState(SCE_HPHP_WORD);
1964
 
                } else if (sc.ch == '#') {
1965
 
                        sc.SetState(SCE_HPHP_COMMENTLINE);
1966
 
                } else if (sc.Match("<!--")) {
1967
 
                        sc.SetState(SCE_HPHP_COMMENTLINE);
1968
 
                } else if (sc.Match('/', '/')) {
1969
 
                        sc.SetState(SCE_HPHP_COMMENTLINE);
1970
 
                } else if (sc.Match('/', '*')) {
1971
 
                        sc.SetState(SCE_HPHP_COMMENT);
1972
 
                } else if (sc.ch == '\"') {
1973
 
                        sc.SetState(SCE_HPHP_HSTRING);
1974
 
                } else if (sc.ch == '\'') {
1975
 
                        sc.SetState(SCE_HPHP_SIMPLESTRING);
1976
 
                } else if (sc.ch == '$' && IsPhpWordStart(static_cast<char>(sc.chNext))) {
1977
 
                        sc.SetState(SCE_HPHP_VARIABLE);
1978
 
                } else if (isoperator(static_cast<char>(sc.ch))) {
1979
 
                        sc.SetState(SCE_HPHP_OPERATOR);
1980
 
                }
1981
 
        }
1982
 
}
1983
 
 
1984
 
static void ColourisePHPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
1985
 
                                  Accessor &styler) {
1986
 
        // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
1987
 
        StyleContext sc(startPos, length, initStyle, styler, 0x7f);
1988
 
        for (; sc.More(); sc.Forward()) {
1989
 
                ColourisePHPPiece(sc, keywordlists);
1990
 
        }
1991
 
        sc.Complete();
 
2018
static void ColouriseXMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 
2019
                                  Accessor &styler) {
 
2020
        // Passing in true because we're lexing XML
 
2021
        ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, true);
 
2022
}
 
2023
 
 
2024
static void ColouriseHTMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 
2025
                                  Accessor &styler) {
 
2026
        // Passing in false because we're notlexing XML
 
2027
        ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false);
1992
2028
}
1993
2029
 
1994
2030
static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
1995
 
                                               Accessor &styler) {
1996
 
        if(startPos == 0) initStyle = SCE_HPHP_DEFAULT;
1997
 
                ColouriseHyperTextDoc(startPos,length,initStyle,keywordlists,styler);
 
2031
        Accessor &styler) {
 
2032
        if (startPos == 0)
 
2033
                initStyle = SCE_HPHP_DEFAULT;
 
2034
        ColouriseHTMLDoc(startPos, length, initStyle, keywordlists, styler);
1998
2035
}
1999
2036
 
2000
2037
static const char * const htmlWordListDesc[] = {
2017
2054
        0,
2018
2055
};
2019
2056
 
2020
 
LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc, 7);
2021
 
LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc, 7);
2022
 
// SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead.
2023
 
LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc, 7);
2024
 
LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc, 7);
2025
 
LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 7);
 
2057
LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc, 8);
 
2058
LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc, 8);
 
2059
LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 8);