Highlight.cpp

* "isFloat" variable name instead of "f" - Zbigniew Rebacz, 09/14/2013 12:59 AM

Download (27.3 KB)

 
1
#include "CodeEditor.h"
2

    
3
NAMESPACE_UPP
4

    
5
#define LTIMING(x)  // RTIMING(x)
6

    
7
bool cmps(const wchar *q, const char *s, int& n) {
8
        const wchar *t = q;
9
        while(*q)
10
                if(*q++ != *s++)
11
                        return false;
12
        n += int(q - t);
13
        return *q == *s;
14
}
15

    
16
bool IsUpperString(const char *q)
17
{
18
        while(*q)
19
        {
20
                if(*q != '_' && (*q < '0' || *q > '9') && !IsUpper(*q))
21
                        return false;
22
                q++;
23
    }
24
        return true;
25
}
26

    
27
#define UVSALERT      Color(255, 240, 240)
28
#define UVSREPINSERT  Color(240, 240, 255)
29
#define UVSYOUINSERT  Color(240, 255, 240)
30
#define UVSDELETE     Color(240, 240, 240)
31

    
32
Color GetUvsHighlight(const wchar *text, int& n) {
33
        n = 0;
34
        if(text[0] != '$' || text[1] != 'u' || text[2] != 'v' || text[3] != 's' || text[4] != ':' || text[5] != ' ')
35
                return Null;
36
        n = 6;
37
        const wchar *q = text + 6;
38
        if(cmps(q, "PENDING CONFLICT", n))
39
                return Null;
40
        if(cmps(q, "YOUR DELETE (REPOSITORY DELETE)", n))
41
                return UVSALERT;
42
        if(cmps(q, "END YOUR DELETE (REPOSITORY DELETE)", n))
43
                return UVSDELETE;
44
        if(cmps(q, "YOUR INSERT (REPOSITORY DELETE)", n))
45
                return UVSALERT;
46
        if(cmps(q, "END YOUR INSERT (REPOSITORY DELETE)", n))
47
                return UVSDELETE;
48
        if(cmps(q, "REPOSITORY DELETE (YOUR DELETE)", n))
49
                return UVSALERT;
50
        if(cmps(q, "END REPOSITORY DELETE (YOUR DELETE)", n))
51
                return UVSDELETE;
52
        if(cmps(q, "REPOSITORY INSERT (YOUR DELETE)", n))
53
                return UVSALERT;
54
        if(cmps(q, "END REPOSITORY INSERT (YOUR DELETE)", n))
55
                return UVSDELETE;
56
        if(cmps(q, "YOUR INSERT", n))
57
                return UVSYOUINSERT;
58
        if(cmps(q, "END YOUR INSERT", n))
59
                return Null;
60
        if(cmps(q, "YOUR DELETE", n))
61
                return UVSDELETE;
62
        if(cmps(q, "END YOUR DELETE", n))
63
                return Null;
64
        if(cmps(q, "REPOSITORY DELETE", n))
65
                return UVSDELETE;
66
        if(cmps(q, "END REPOSITORY DELETE", n))
67
                return Null;
68
        if(cmps(q, "REPOSITORY INSERT", n))
69
                return UVSREPINSERT;
70
        if(cmps(q, "END REPOSITORY INSERT", n))
71
                return Null;
72
        n = 0;
73
        return Null;
74
}
75

    
76
struct CodeEditor::HlSt {
77
        Vector<LineEdit::Highlight>& v;
78
        LineEdit::Highlight          def;
79
        int                          pos;
80

    
81
        void Set(int pos, int count, const HlStyle& ink);
82
        void SetFont(int pos, int count, const HlStyle& f);
83
        void SetPaper(int pos, int count, Color paper);
84
        void SetInk(int pos, int count, Color ink);
85
        void Put(int count, const HlStyle& ink)                  { Set(pos, count, ink); pos += count; }
86
        void Put(const HlStyle& ink)                             { Put(1, ink); }
87

    
88
        HlSt(Vector<LineEdit::Highlight>& v) : v(v) {
89
                pos = 0;
90
                def = v[0];
91
                def.chr = ' ';
92
                v.Top().chr = ' ';
93
        }
94

    
95
        ~HlSt() {
96
                for(int i = 0; i < v.GetCount(); i++)
97
                        if(v[i].chr == '_') {
98
                                v[i].font.NoBold();
99
                                v[i].font.NoItalic();
100
                        }
101
        }
102
};
103

    
104
void CodeEditor::HlSt::Set(int pos, int count, const HlStyle& ink)
105
{
106
        if(pos + count > v.GetCount())
107
                v.At(pos + count - 1, def);
108
        while(count-- > 0) {
109
                LineEdit::Highlight& x = v[pos++];
110
                x.ink = ink.color;
111
                if(ink.bold)
112
                        x.font.Bold();
113
                if(ink.italic)
114
                        x.font.Italic();
115
                if(ink.underline)
116
                        x.font.Underline();
117
        }
118
}
119

    
120
void CodeEditor::HlSt::SetFont(int pos, int count, const HlStyle& f)
121
{
122
        if(pos + count > v.GetCount())
123
                v.At(pos + count - 1, def);
124
        while(count-- > 0) {
125
                LineEdit::Highlight& x = v[pos++];
126
                if(f.bold)
127
                        x.font.Bold();
128
                if(f.italic)
129
                        x.font.Italic();
130
                if(f.underline)
131
                        x.font.Underline();
132
        }
133
}
134

    
135
void CodeEditor::HlSt::SetPaper(int pos, int count, Color paper)
136
{
137
        if(pos + count > v.GetCount())
138
                v.At(pos + count - 1, def);
139
        while(count-- > 0)
140
                v[pos++].paper = paper;
141
}
142

    
143
void CodeEditor::HlSt::SetInk(int pos, int count, Color ink)
144
{
145
        if(pos + count > v.GetCount())
146
                v.At(pos + count - 1, def);
147
        while(count-- > 0)
148
                v[pos++].ink = ink;
149
}
150

    
151
const wchar *CodeEditor::HlString(HlSt& hls, const wchar *p)
152
{
153
        hls.Put(hl_style[INK_CONST_STRING]);
154
        const wchar delim = *p;
155
        p++;
156
        while(*p && *p != delim)
157
                if(*p == '\\') {
158
                        const wchar *t = p++;
159
                        if(*p == 'x' || *p == 'X') {
160
                                p++;
161
                                if(IsXDigit(*p))
162
                                        p++;
163
                                if(IsXDigit(*p))
164
                                        p++;
165
                                hls.Put(int(p - t), hl_style[INK_CONST_STRINGOP]);
166
                        }
167
                        else
168
                        if(*p >= '0' && *p <= '7') {
169
                                p++;
170
                                if(*p >= '0' && *p <= '7') p++;
171
                                if(*p >= '0' && *p <= '7') p++;
172
                                hls.Put(int(p - t), hl_style[INK_CONST_STRINGOP]);
173
                        }
174
                        else {
175
                                hls.Put(hl_style[INK_CONST_STRINGOP]);
176
                                if(*p) {
177
                                        hls.Put(hl_style[INK_CONST_STRINGOP]);
178
                                        p++;
179
                                }
180
                        }
181
                }
182
                else
183
                if(*p == '%')
184
                        if(p[1] == '%') {
185
                                hls.Put(2, hl_style[INK_CONST_STRING]);
186
                                p += 2;
187
                        }
188
                        else {
189
                                const wchar *t = p++;
190
                                while(!IsAlpha(*p) && *p && *p != '`' && *p != '\"' && *p != '\'' && *p != '\\')
191
                                        p++;
192
                                while(IsAlpha(*p) && *p)
193
                                        p++;
194
                                hls.Put(int(p - t), hl_style[INK_CONST_STRINGOP]);
195
                        }
196
                else {
197
                        hls.Put(hl_style[INK_CONST_STRING]);
198
                        p++;
199
                }
200
        if(*p == delim)        {
201
                hls.Put(hl_style[INK_CONST_STRING]);
202
                p++;
203
        }
204
        return p;
205
}
206

    
207
Color CodeEditor::BlockColor(int level)
208
{
209
        if(hilite_scope == 1)
210
                return  GetHlStyle(level & 1 ? PAPER_BLOCK1 : PAPER_NORMAL).color;
211
        if(hilite_scope == 2) {
212
                int q = level % 5;
213
                return  GetHlStyle(q ? PAPER_BLOCK1 + q - 1 : PAPER_NORMAL).color;
214
        }
215
        return GetHlStyle(PAPER_NORMAL).color;
216
}
217

    
218
void CodeEditor::Bracket(int pos, HlSt& hls)
219
{
220
        if(pos == highlight_bracket_pos0 && hilite_bracket
221
           || pos == highlight_bracket_pos && (hilite_bracket == 1 || hilite_bracket == 2 && bracket_flash)) {
222
                        HlStyle& h = hl_style[pos == highlight_bracket_pos0 ? PAPER_BRACKET0 : PAPER_BRACKET];
223
                        hls.SetPaper(hls.pos, 1, h.color);
224
                        hls.SetFont(hls.pos, 1, h);
225
        }
226
}
227

    
228
Vector <Index<String> > CodeEditor::keyword;
229
Vector <Index<String> > CodeEditor::name;
230
Index<String> CodeEditor::kw_upp;
231
int CodeEditor::kw_macros;
232
int CodeEditor::kw_logs;
233
int CodeEditor::kw_sql_base;
234
int CodeEditor::kw_sql_func;
235

    
236
const Index<String>& CodeEditor::CppKeywords()
237
{
238
        return keyword[0];
239
}
240

    
241
int CodeEditor::InitUpp(const char **q)
242
{
243
        while(*q)
244
                kw_upp.Add(*q++);
245
        return kw_upp.GetCount();
246
}
247

    
248
void CodeEditor::InitKeywords()
249
{
250
        static const char *cpp[] = {
251
                "namespace", "asm", "__asm", "else", "struct",
252
                "enum", "switch", "auto", "__except", "template",
253
                "explicit", "this",
254
                "bool", "extern", "mutable", "thread",
255
                "break", "false", "throw",
256
                "case", "__fastcall", "true",
257
                "catch", "__finally", "new", "try",
258
                "__cdecl", "float", "__try",
259
                "char", "for", "operator", "typedef",
260
                "class", "friend", "private", "typeid",
261
                "const", "goto", "protected", "typename",
262
                "const_cast", "if", "public", "union",
263
                "continue", "inline", "register", "unsigned",
264
                "__declspec", "__inline", "reinterpret_cast", "using",
265
                "using", "default", "int", "return",
266
                "delete", "__int8", "short", "__uuidof",
267
                "dllexport", "__int16", "signed", "virtual",
268
                "dllimport", "__int32", "sizeof", "void",
269
                "do", "__int64", "static", "volatile",
270
                "double", "__leave", "static_cast",
271
                "dynamic_cast", "long", "__stdcall", "while",
272
                "force_inline",
273
                "and", "bitor", "or", "xor", 
274
                "compl", "bitand", "and_eq", "or_eq",
275
                "xor_eq", "not", "not_eq",
276
                "char16_t", "char32_t", "constexpr", "decltype",
277
                "noexcept", "nullptr", "static_assert",
278
                "override", "final",
279
                NULL
280
        };
281
        static const char *cs[] = {
282
                "abstract", "event", "new", "struct",
283
                "as", "explicit", "null", "switch",
284
                "base", "extern", "object", "this",
285
                "bool", "false", "operator", "throw",
286
                "break", "finally", "out", "true",
287
                "byte", "fixed", "override", "try",
288
                "case", "float", "params", "typeof",
289
                "catch", "for", "private", "uint",
290
                "char", "foreach", "protected", "ulong",
291
                "checked", "goto", "public", "unchecked",
292
                "class", "if", "readonly", "unsafe",
293
                "const", "implicit", "ref", "ushort",
294
                "continue", "in", "return", "using",
295
                "decimal", "int", "sbyte", "virtual",
296
                "default", "interface", "sealed", "volatile",
297
                "delegate", "internal", "short", "void",
298
                "do", "is", "sizeof", "while",
299
                "double", "lock", "stackalloc",
300
                "else", "long", "static",
301
                "enum", "namespace", "string",
302
                "await", "async", "throws", "awaits",
303
                NULL
304
        };
305
        static const char *upp[] = {
306
                "byte", "word", "dword", "__countof", "pick_", "wchar", "NULL", "Null",
307
                "int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", "qword",
308
                "INTERLOCKED_", "INTERLOCKED", "ONCELOCK", "ONCELOCK_", "INITBLOCK", "EXITBLOCK",
309
                NULL
310
        };
311
        static const char *usc[] = {
312
                "void", "self", "if", "else", "while", "do", "case",
313
                "default", "break", "return", "switch", "operator", "for",
314
                "fn", "group", "ctrl", "subctrl", "template", "enum_property",
315
                "raw", "int", "double", "String", "bool",
316
                "Text", "Qtf", "Doc", "Font", "Color", "macro",
317
                NULL
318
        };
319
        static const char *usclib[] = {
320
                "Color", "Point", "Size", "Rect", "RectC",
321
                "StdFont", "Arial", "Roman", "Courier", "GetImageSize",
322
                "GetTextSize", "print", "Black", "Gray", "LtGray",
323
                "WhiteGray", "White", "Red", "Green", "Brown", "Blue",
324
                "Magenta", "Cyan", "Yellow", "LtRed", "LtGreen", "LtYellow",
325
                "LtBlue", "LtMagenta", "LtCyan", "SBlack", "SGray", "SLtGray",
326
                "SWhiteGray", "SWhite", "SRed", "SGreen", "SBrown", "SBlue",
327
                "SMagenta", "SCyan", "SYellow", "SLtRed", "SLtGreen", "SLtYellow",
328
                "SLtBlue", "SLtMagenta", "SLtCyan", "IntNull", "DblNullLim",
329
                "DrawRect", "DrawText", "DrawSmartText", "DrawImage", "is_number",
330
                "GetSmartTextSize", "GetQtfHeight", "DrawQtf",
331
                "is_array", "is_map", "is_void", "int", "to_string", "count",
332
                "len", "remove", "insert", "mid", "keys", "values", "exists",
333
                "erase", "rand", "OpenFileOut", "OpenFileAppend", "OpenFileIn",
334
                "GetMinSize", "GetStdSize",
335
                NULL
336
        };
337
        static const char *java[] = {
338
                "abstract", "boolean", "break", "byte", "case",
339
                "catch", "char", "class", "const", "continue",
340
                "default", "do", "double", "else", "extends",
341
                "false", "final", "finally", "float", "for",
342
                "goto", "if", "implements", "import", "instanceof",
343
                "int", "interface", "long", "native", "new",
344
                "null", "package", "private", "protected", "public",
345
                "return", "short", "static", "super", "switch",
346
                "synchronized", "this", "throw", "throws", "transient",
347
                "true", "try", "void", "volatile", "while",
348
                NULL
349
        };
350
        static const char *javascript[] = {
351
                "break", "continue", "do", "for", "import", "new", "this", "void",
352
                "case", "default", "else", "function", "in", "return", "typeof", "while",
353
                "comment", "delete", "export", "if", "label", "switch", "var", "with",
354
                "catch", "enum", "throw", "class", "extends", "try", "const", "finally",
355
                "debugger", "super", "true", "false", "undefined",
356
                NULL
357
        };
358
        static const char *css[] = {
359
                "azimuth", "background-attachment", "background-color", "background-image", "background-position",
360
                "background-repeat", "background", "border-collapse", "border-color", "border-spacing", "border-style",
361
                "border-top", "border-right", "border-bottom", "border-left", "border-top-color", "border-right-color",
362
                "border-bottom-color", "border-left-color", "border-top-style", "border-right-style", "border-bottom-style",
363
                "border-left-style", "border-top-width", "border-right-width", "border-bottom-width", "border-left-width",
364
                "border-width", "border", "bottom", "caption-side", "clear", "clip", "color", "content", "counter-increment",
365
                "counter-reset", "cue-after", "cue-before", "cue", "cursor", "direction", "display", "elevation", "empty-cells",
366
                "float", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "height", "left",
367
                "letter-spacing", "line-height", "list-style-image", "list-style-position", "list-style-type", "list-style",
368
                "margin-right", "margin-left", "margin-top", "margin-bottom", "margin", "max-height", "max-width", "min-height",
369
                "min-width", "orphans", "outline-color", "outline-style", "outline-width", "outline", "overflow", "padding-top",
370
                "padding-right", "padding-bottom", "padding-left", "padding", "page-break-after", "page-break-before",
371
                "page-break-inside", "pause-after", "pause-before", "pause", "pitch-range", "pitch", "play-during", "position",
372
                "quotes", "richness", "right", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate",
373
                "stress", "table-layout", "text-align", "text-decoration", "text-indent", "text-transform", "top",
374
                "unicode-bidi", "vertical-align", "visibility", "voice-family", "volume", "white-space", "widows", "width",
375
                "word-spacing", "z-index",
376
                NULL
377
        };
378
        static const char *cssn[] = {
379
                "em", "px", "pt",
380
                "left-side", "far-left", "left", "center-left", "center", "center-right", "right", "far-right", "right-side",
381
                "behind", "leftwards", "rightwards", "inherit", "scroll", "fixed", "transparent", "none", "top", "bottom",
382
                "repeat", "repeat-x", "repeat-y", "no-repeat", "background-color", "background-image", "background-repeat",
383
                "background-attachment", "background-position", "collapse", "separate", "border-top-color", "auto", "both",
384
                "normal", "attr", "open-quote", "close-quote", "no-open-quote", "no-close-quote", "cue-before", "cue-after",
385
                "crosshair", "default", "pointer", "move", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize",
386
                "sw-resize", "s-resize", "w-resize", "text", "wait", "help", "progress", "ltr", "rtl", "inline", "block",
387
                "list-item", "inline-block", "table", "inline-table", "table-row-group", "table-header-group",
388
                "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption",
389
                "below", "level", "above", "higher", "lower", "show", "hide", "italic", "oblique", "small-caps", "bold",
390
                "bolder", "lighter", "font-style",
391
                "font-variant", "font-weight", "font-size", "line-height", "font-family", "caption", "icon", "menu",
392
                "message-box", "small-caption", "status-bar", "inside", "outside", "disc", "circle", "square", "decimal",
393
                "decimal-leading-zero", "lower-roman", "upper-roman", "lower-greek", "lower-latin", "upper-latin", "armenian",
394
                "georgian", "lower-alpha", "upper-alpha", "list-style-type", "list-style-position", "list-style-image",
395
                "invert", "outline-color", "outline-style", "outline-width", "visible", "hidden", "always", "avoid",
396
                "x-low", "low", "medium", "high", "x-high", "mix", "static", "relative", "absolute", "once", "digits",
397
                "continuous", "code", "spell-out", "x-slow", "slow", "fast", "x-fast", "faster", "slower", "justify",
398
                "underline", "overline", "line-through", "blink", "capitalize", "uppercase", "lowercase", "embed",
399
                "bidi-override", "baseline", "sub", "super", "text-top", "middle", "text-bottom", "silent", "x-soft", "soft",
400
                "loud", "x-loud", "pre", "nowrap", "pre-wrap", "pre-line", 
401
                NULL
402
        };
403
        static const char *upp_macros[] = {
404
                "CLASSNAME", "THISBACK", "THISBACK1", "THISBACK2", "THISBACK3", "THISBACK4",
405
                "PTEBACK", "PTEBACK1", "PTEBACK2",  "PTEBACK3",  "PTEBACK4", 
406
                "QUOTE", "XASSERT", "NEVER", "XNEVER", "CHECK", "XCHECK", "ASSERT", "ASSERT_",
407
                "NAMESPACE_UPP", "END_UPP_NAMESPACE", "NEVER_", "SKYLARK", "RPC_METHOD", "RPC_GMETHOD",
408
                NULL
409
        };
410
        static const char *upp_logs[] = {
411
                "LOG", "LOGF", "DUMP", "DUMPC", "DUMPCC", "DUMPCCC", "DUMPM",
412
                "LLOG", "LLOGF", "LDUMP", "LDUMPC", "LDUMPCC", "LDUMPCCC", "LDUMPM",
413
                "DLOG", "DLOGF", "DDUMP", "DDUMPC", "DDUMPCC", "DDUMPCCC", "DDUMPM",
414
                "RLOG", "RLOGF", "RDUMP", "RDUMPC", "RDUMPCC", "RDUMPCCC", "RDUMPM",
415
                "LOGBEGIN", "LOGEND", "LOGBLOCK", "LOGHEXDUMP", "LOGSRCPOS", 
416
                "RLOGBEGIN", "RLOGEND", "RLOGBLOCK", "RLOGHEXDUMP", "RLOGSRCPOS", "RQUOTE",
417
                "RTIMING", "TIMING", "LTIMING", "DTIMING",
418
                "LOGHEX", "DUMPHEX", "DLOGHEX", "DDUMPHEX", "RLOGHEX", "RDUMPHEX", "LLOGHEX", "LDUMPHEX",
419
                "DEBUGCODE",                        
420
                NULL
421
        };
422
        static const char *sql_base[] = {
423
                "Select", "Update", "Insert", "Delete", "From",
424
                "Join", "InnerJoin", "LeftJoin", "RightJoin", "FullJoin", "OuterJoin",
425
                "Where", "On", "OrderBy", "GroupBy",
426
                "Of", "As", "StartWith", "ConnectBy", "Having", "ForUpdate", "NoWait", "Limit",
427
                "Offset", "Hint", "SQL",
428
                NULL
429
        };
430
        static const char *sql_func[] = {
431
                "Decode", "Distinct", "All", "SqlAll", "Count", "Descending",
432
                "SqlMax", "SqlMin", "SqlSum", "Avg", "Stddev", "Variance",
433
                "Greatest", "Least", "ConvertCharset", "ConvertAscii",
434
                "Upper", "Lower", "Substr", "Instr", "Wild", "SqlDate", "AddMonths", "LastDay",
435
                "MonthsBetween", "NextDay", "SqlNvl", "Prior", "NextVal", "CurrVal", "SqlArg",
436
                NULL
437
        };
438
        static const char *sql_bool[] = {
439
                "SqlIsNull", "NotNull", "Like", "LikeUpperAscii", "NotLike", "Between",
440
                "NotBetween", "In", "NotIn", "Exists", "NotExists",
441
                NULL
442
        };
443
        static const char *tfile[] = {
444
                "T_",
445
                NULL,
446
        };
447
        static const char *tlng[] = {
448
                "enUS", "enGB", "enAU", "enCA", "enNZ", "enIE", "enZA", "enJM", "enCB", "enBZ",
449
                "enTT", "bgBG", "csCZ", "daDK", "deDE", "deCH", "deAT", "deLU", "deLI", "elGR",
450
                "esES", "esMX", "esES", "esGT", "esCR", "esPA", "esDO", "esVE", "esCO", "esPE",
451
                "esAR", "esEC", "esCL", "esUY", "esPY", "esBO", "esSV", "esHN", "esNI", "esPR",
452
                "fiFI", "frFR", "frBE", "frCA", "frCH", "frLU", "huHU", "isIS", "itIT", "itCH",
453
                "nlNL", "nlBE", "noNO", "noNO", "plPL", "ptBR", "ptPT", "roRO", "ruRU", "hrHR",
454
                "srSP", "srSP", "skSK", "svSE", "svFI", "trTR", "slSI", "afZA", "sqAL", "euES",
455
                "beBY", "caES", "etEE", "foFO", "idID", "lvLV", "ltLT", "ukUA", "zhCN", "zhTW",
456
                "koKR", "jaJP",
457
                NULL
458
        };
459
        static const char *lay[] = {
460
                "LAYOUT", "ITEM", "UNTYPED", "END_LAYOUT",
461
                NULL
462
        };
463
        static const char *sch[] = {
464
                "BIT", "BIT_ARRAY", "BIT_", "BIT_ARRAY_",
465
                "BOOL", "BOOL_ARRAY", "BOOL_", "BOOL_ARRAY_",
466
                "INT", "INT_ARRAY", "INT_", "INT_ARRAY_",
467
                "DOUBLE", "DOUBLE_ARRAY", "DOUBLE_", "DOUBLE_ARRAY_",
468
                "DATE", "DATE_ARRAY", "DATE_", "DATE_ARRAY_",
469
                "DATETIME", "DATETIME_ARRAY", "DATETIME_", "DATETIME_ARRAY_",
470
                "TIME", "TIME_ARRAY", "TIME_", "TIME_ARRAY_",
471
                "STRING", "STRING_ARRAY", "STRING_", "STRING_ARRAY_",
472
                "LONG", "LONG_", "LONGRAW", "LONGRAW_", "BLOB", "BLOB_", "CLOB", "CLOB_",
473
                "AUTO_INCREMENT", "KEY", "NOT_NULL", "TIMESTAMP", "COMMENT", "SEQUENCE", "SEQUENCE_",
474
                "PRIMARY_KEY", "INDEX", "PARTIAL_INDEX", "UNIQUE", "SQLDEFAULT", "REFERENCES", "REFERENCES_",
475
                "REFERENCES_CASCADE", "REFERENCES_CASCADE_", "DUAL_PRIMARY_KEY", "DUAL_UNIQUE",
476
                "UNIQUE_LIST", "SQLCHECK",
477
                "TABLE", "TABLE_", "END_TABLE", "TABLE_I", "TABLE_I_", "TABLE_II",
478
                "TABLE_II_", "TABLE_III", "TABLE_III_", "VAR", "VAR_",
479
                "COLUMN", "COLUMN_ARRAY", "ATTRIBUTE", "INLINE_ATTRIBUTE",
480
                "TYPE", "TYPE_I", "TYPE_II", "TYPE_III", "END_TYPE",
481
                "TYPE_", "TYPE_I_", "TYPE_II_", "TYPE_III_", "SERIAL", "ISERIAL",
482
                NULL
483
        };
484
        static const char *sql[] = {
485
                "ABORT", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", "ATTACH",
486
                "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", "CASCADE", "CASE", "CHECK",
487
                "COLLATE", "COLUMN", "COMMIT", "CONFLICT", "CONSTRAINT", "CREATE", "CROSS",
488
                "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT",
489
                "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", "END", "EXCEPT",
490
                "EXCLUSIVE", "EXISTS", "FOREIGN", "FROM", "FULL", "GROUP", "HAVING",
491
                "IN", "INDEX", "INITIALLY", "INNER", "INSERT", "INSTEAD", "INTERSECT", "INTO",
492
                "IS", "ISNULL", "JOIN", "KEY", "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NOT",
493
                "NOTNULL", "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PRIMARY", "RAISE",
494
                "REFERENCES", "REPLACE", "RESTRICT", "UPDATE", "SET", "WHERE", "NEW", "OLD", "TRIGGER",
495
                "SELECT",
496
                NULL
497
        };
498
        static const char *javan[] = {
499
                NULL
500
        };
501
        static const char *javascriptn[] = {
502
                "alert", "eval", "toString", "valueOf", "length",
503
                NULL
504
        };
505
        static const char **kw[HIGHLIGHT_COUNT] = {
506
                cpp, usc, java, tfile, usc, lay, sch, sql, cs, javascript, css,
507
        };
508
        static const char **nm[HIGHLIGHT_COUNT] = {
509
                upp, usclib, javan, tlng, usclib, javan, javan, javan, javan, javascriptn, cssn
510
        };
511

    
512
        for(int i = 0; i < HIGHLIGHT_COUNT; i++) 
513
                LoadSyntax(kw[i], nm[i]);
514

    
515
        kw_macros = InitUpp(upp_macros);
516
        kw_logs = InitUpp(upp_logs);
517
        kw_sql_base = InitUpp(sql_base);
518
        kw_sql_func = InitUpp(sql_func);
519
        InitUpp(sql_bool);
520
}
521

    
522
int CodeEditor::LoadSyntax(const char *keywords[], const char *names[])        // Changed
523
{
524
        Index <String> &key = keyword.Add()        ;
525
        while(*keywords)
526
                key.Add(*keywords++);
527
        Index <String> &nam = name.Add();
528
        while(*names)
529
                nam.Add(*names++);        
530
        return keyword.GetCount() - 1;
531
}
532

    
533
void CodeEditor::HighlightLine(int line, Vector<LineEdit::Highlight>& hl, int pos)
534
{
535
        LTIMING("HighlightLine");
536
        if(highlight < 0 || highlight >= keyword.GetCount())
537
                return;
538
        WString text = GetWLine(line);
539
        SyntaxState ss = ScanSyntax(line);
540
        ss.Grounding(text.Begin(), text.End());
541
        SyntaxState sm = ScanSyntax(line + 1);
542
        HlSt hls(hl);
543
        const wchar *p = text;
544
        const wchar *e = text.End();
545
        int uvsn;
546
        GetUvsHighlight(text, uvsn);
547
        if(uvsn) {
548
                hls.SetInk(0, text.GetLength() + 1, Yellow);
549
                hls.SetPaper(0, text.GetLength() + 1, Gray);
550
                hls.pos += uvsn;
551
                p += uvsn;
552
                return;
553
        }
554
        else
555
        if(highlight == HIGHLIGHT_CALC) {
556
                if(line == GetLineCount() - 1 || *p == '$')
557
                        hls.SetPaper(0, text.GetLength() + 1, hl_style[PAPER_BLOCK1].color);
558
        }
559
        else
560
                hls.SetPaper(0, text.GetLength() + 1,
561
                             Nvl(ss.uvscolor, sm.macro ? hl_style[PAPER_MACRO].color : hl_style[PAPER_NORMAL].color));
562
        int block_level = ss.bid.GetCount() - 1;
563
        String cppid;
564
        if(IsNull(ss.uvscolor) && !uvsn && !ss.comment && highlight != HIGHLIGHT_CALC) {
565
                if(!sm.macro) {
566
                        int i = 0, bid = 0, pos = 0, tabsz = GetTabSize();
567
                        while(bid < ss.bid.GetCount() - 1
568
                        && (i >= text.GetLength() || text[i] == ' ' || text[i] == '\t')) {
569
                                hls.SetPaper(i, 1, BlockColor(bid));
570
                                if(i < text.GetLength() && text[i] == '\t' || ++pos >= tabsz) {
571
                                        pos = 0;
572
                                        bid++;
573
                                }
574
                                i++;
575
                        }
576
                        hls.SetPaper(i, 1 + max(0, text.GetLength() - i), BlockColor(ss.bid.GetCount() - 1));
577
                }
578
                while(*p == ' ' || *p == '\t') {
579
                        p++;
580
                        hls.Put(hl_style[INK_NORMAL]);
581
                }
582
                if(*p == '#' && highlight != HIGHLIGHT_JAVASCRIPT && highlight != HIGHLIGHT_CSS) {
583
                        static const char *pd[] = {
584
                                "define", "error", "if", "elif", "else", "endif",
585
                                "ifdef", "ifndef", "include", "line", "undef", "pragma",
586
                                // CLR
587
                                "using"
588
                        };
589
                        static Index<String> macro;
590
                        if(macro.GetCount() == 0)
591
                                for(int i = 0; i < __countof(pd); i++)
592
                                        macro.Add(pd[i]);
593
                        const wchar *q = p + 1;
594
                        while(*q == ' ' || *q == '\t')
595
                                q++;
596
                        StringBuffer id;
597
                        while(IsAlpha(*q))
598
                                id.Cat(*q++);
599
                        cppid = id;
600
                        hls.Put(macro.Find(cppid) < 0 ? 1 : int(q - p), hl_style[INK_MACRO]);
601
                        p = q;
602
                }
603
        }
604
        int lindent = int(p - ~text);
605
        int lbrace = -1;
606
        int lbclose = -1;
607
        Color lbcolor = Null;
608
        bool is_comment = false;
609
        while(p < e) {
610
                int pair = MAKELONG(p[0], p[1]);
611
                if(ss.linecomment && ss.linecont || pair == MAKELONG('/', '/') && highlight != HIGHLIGHT_CSS) {
612
                        hls.Put(text.GetLength() + 1 - hls.pos, hl_style[INK_COMMENT]);
613
                        is_comment = true;
614
                        break;
615
                }
616
                else
617
                if(ss.comment)
618
                        if(pair == MAKELONG('*', '/')) {
619
                                hls.Put(2, hl_style[INK_COMMENT]);
620
                                p += 2;
621
                                ss.comment = false;
622
                        }
623
                        else {
624
                                hls.Put(hl_style[INK_COMMENT]);
625
                                p++;
626
                        }
627
                else
628
                if((*p == '\"' || *p == '\'') || ss.linecont && ss.string)
629
                        p = HlString(hls, p);
630
                else
631
                if(pair == MAKELONG('/', '*')) {
632
                        hls.Put(2, hl_style[INK_COMMENT]);
633
                        p += 2;
634
                        ss.comment = true;
635
                        is_comment = true;
636
                }
637
                else
638
                if(*p == '(') {
639
                        ss.brk.Add(')');
640
                        Bracket(int(p - text) + pos, hls);
641
                        hls.Put(hl_style[INK_PAR0 + max(ss.pl++, 0) % 4]);
642
                        p++;
643
                }
644
                else
645
                if(*p == '{') {
646
                        ss.brk.Add(ss.was_namespace ? 0 : '}');
647
                        Bracket(int(p - text) + pos, hls);
648
                        hls.Put(hl_style[INK_PAR0 + max(ss.cl, 0) % 4]);
649
                        if(ss.was_namespace)
650
                                ss.was_namespace = false;
651
                        else {
652
                                ++block_level;
653
                                ++ss.cl;
654
                        }
655
                        if(hls.pos < text.GetCount())
656
                                hls.SetPaper(hls.pos, text.GetCount() - hls.pos + 1, BlockColor(block_level));
657
                        p++;
658
                }
659
                else
660
                if(*p == '[') {
661
                        ss.brk.Add(']');
662
                        Bracket(int(p - text) + pos, hls);
663
                        hls.Put(hl_style[INK_PAR0 + max(ss.bl++, 0) % 4]);
664
                        p++;
665
                }
666
                else
667
                if(*p == ')' || *p == '}' || *p == ']') {
668
                        int bl = ss.brk.GetCount();
669
                        int bc = bl ? ss.brk.Pop() : 0;
670
                        if(*p == '}' && hilite_scope && block_level > 0 && bc)
671
                                hls.SetPaper(hls.pos, text.GetLength() + 1 - hls.pos, BlockColor(--block_level));
672
                        Bracket(int(p - text) + pos, hls);
673
                        int& l = *p == ')' ? ss.pl : *p == '}' ? ss.cl : ss.bl;
674
                        if(bc && (bc != *p || l <= 0) || bc == 0 && *p != '}') {
675
                                hls.Put(p == ~text ? hl_style[INK_PAR0] : hl_style[INK_ERROR]);
676
                                ss.brk.Clear();
677
                                ss.cl = ss.bl = ss.pl = 0;
678
                        }
679
                        else {
680
                                if(bc) --l;
681
                                hls.Put(1, hl_style[INK_PAR0 + l % 4]);
682
                        }
683
                        p++;
684
                }
685
                else
686
                if(highlight == HIGHLIGHT_CSS ? *p == '#' : pair == MAKELONG('0', 'x') || pair == MAKELONG('0', 'X')) {
687
                        hls.Put(2, hl_style[INK_CONST_HEX]);
688
                        p += 2;
689
                        const wchar *t = p;
690
                        while(IsXDigit(*p))
691
                                p++;
692
                        hls.Put(int(p - t), hl_style[INK_CONST_HEX]);
693
                }
694
                else
695
                if(IsDigit(*p)) {
696
                        const wchar *t = p;
697
                        int c = INK_CONST_INT;
698
                        bool isDot, isFloat = false;
699
                        if(*p == '0') c = INK_CONST_OCT;
700
                        while(IsDigit(*p)) p++; 
701
                        if(*p == '.' || (*p == 'e' || *p == 'E') && highlight != HIGHLIGHT_CSS) {
702
                                if(*p == '.')
703
                                        isDot = true;
704
                                c = INK_CONST_FLOAT;
705
                                p++;
706
                                if(*p == '-')
707
                                        p++;
708
                        }
709
                        while((IsDigit(*p) || (isDot && *p == 'f')) && (isFloat == false)) {
710
                                if(*p == 'f')
711
                                        isFloat = true;
712
                                p++;
713
                        }
714
                        if(c == INK_CONST_OCT && p - t == 1)
715
                                c = INK_CONST_INT;
716
                        if(p - t > 0)
717
                                hls.Put(int(p - t), hl_style[c]);
718
                }
719
                else
720
                if(pair == MAKELONG('t', '_') && p[2] == '(' && p[3] == '\"') {
721
                        int pos0 = hls.pos;
722
                        hls.Put(3, hl_style[INK_UPP]);
723
                        p = HlString(hls, p + 3);
724
                        if(*p == ')') {
725
                                hls.Put(hl_style[INK_UPP]);
726
                                p++;
727
                        }
728
                        hls.SetPaper(pos0, hls.pos - pos0, hl_style[PAPER_LNG].color);
729
                }
730
                else
731
                if(pair == MAKELONG('t', 't') && p[3] == '(' && p[4] == '\"') {
732
                        int pos0 = hls.pos;
733
                        hls.Put(4, hl_style[INK_UPP]);
734
                        p = HlString(hls, p + 4);
735
                        if(*p == ')') {
736
                                hls.Put(hl_style[INK_UPP]);
737
                                p++;
738
                        }
739
                        hls.SetPaper(pos0, hls.pos - pos0, hl_style[PAPER_LNG].color);
740
                }
741
                else
742
                if(iscib(*p)) {
743
                        const wchar *q = p;
744
                        StringBuffer id;
745
                        while((iscidl(*q) || highlight == HIGHLIGHT_CSS && *q == '-') && q < e)
746
                                id.Cat(*q++);
747
                        String iid = id;
748
                        if(highlight == HIGHLIGHT_SQL)
749
                                iid = ToUpper(iid);
750
                        int uq = kw_upp.Find(iid);
751
                        int nq;
752
                        hls.Put(int(q - p), (nq = keyword[highlight].Find(iid)) >= 0 ? hl_style[INK_KEYWORD] :
753
                                            name[highlight].Find(iid) >= 0 ? hl_style[INK_UPP] :
754
                                            uq >= 0 ? uq < kw_macros ? hl_style[INK_UPPMACROS] :
755
                                                      uq < kw_logs ? hl_style[INK_UPPLOGS] :
756
                                                      uq < kw_sql_base ? hl_style[INK_SQLBASE] : 
757
                                                      uq < kw_sql_func ? hl_style[INK_SQLFUNC] :
758
                                                      hl_style[INK_SQLBOOL] :
759
                                            IsUpperString(iid) && !sm.macro ? hl_style[INK_UPPER] :
760
                                            hl_style[INK_NORMAL]);
761
                        p = q;
762
                        if(nq == 0)
763
                                ss.was_namespace = true;
764
                }
765
                else {
766
                        if(*p == ';')
767
                                ss.was_namespace = false;
768
                        hls.Put(strchr("!+-*^/%~&|=[]:?<>.", *p) ? hl_style[INK_OPERATOR] : hl_style[INK_NORMAL]);
769
                        p++;
770
                }
771
        }
772
        if(hilite_ifdef && !IsNull(cppid) && !is_comment) {
773
                if((cppid == "else" || cppid == "elif" || cppid == "endif") && !ss.ifstack.IsEmpty()) {
774
                        WStringBuffer ifln;
775
                        ifln.Cat(" // ");
776
                        ifln.Cat(ss.ifstack.Top().iftext);
777
                        if(ss.ifstack.Top().ifline && hilite_ifdef == 2) {
778
                                ifln.Cat(", line ");
779
                                ifln.Cat(FormatInt(ss.ifstack.Top().ifline));
780
                        }
781
                        ifln.Cat('\t');
782
                        int start = text.GetLength();
783
                        WString ifs(ifln);
784
                        hls.Set(start, ifs.GetLength(), hl_style[INK_IFDEF]);
785
                        for(int i = 0; i < ifs.GetCount(); i++)
786
                                hl[start + i].chr = ifs[i];
787
                }
788
        }
789
        if(hilite_scope) {
790
                if(lbrace >= 0 && lbclose < 0 && lbrace > lindent)
791
                        hls.SetPaper(lindent, lbrace - lindent, lbcolor);
792
                if(lbrace < 0 && lbclose >= 0)
793
                        hls.SetPaper(lbclose, text.GetLength() + 1 - lbclose, lbcolor);
794
        }
795
        if(!IsNull(cppid) && (cppid == "else" || cppid == "elif" || cppid == "endif" || cppid == "if"
796
                              || cppid == "ifdef" || cppid == "ifndef"))
797
           hls.SetPaper(0, hls.v.GetCount(), hl_style[PAPER_IFDEF].color);
798
}
799

    
800
INITBLOCK {
801
        CodeEditor::InitKeywords();
802
}
803

    
804
END_UPP_NAMESPACE