]>
Commit | Line | Data |
---|---|---|
65ec6247 RD |
1 | // Scintilla source code edit control |
2 | /** @file LexSQL.cxx | |
3 | ** Lexer for SQL. | |
4 | **/ | |
1a2fb4cd | 5 | // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> |
f6bcfd97 BP |
6 | // The License.txt file describes the conditions under which this software may be distributed. |
7 | ||
65ec6247 RD |
8 | #include <stdlib.h> |
9 | #include <string.h> | |
10 | #include <ctype.h> | |
11 | #include <stdio.h> | |
12 | #include <stdarg.h> | |
f6bcfd97 BP |
13 | |
14 | #include "Platform.h" | |
15 | ||
16 | #include "PropSet.h" | |
17 | #include "Accessor.h" | |
18 | #include "KeyWords.h" | |
19 | #include "Scintilla.h" | |
20 | #include "SciLexer.h" | |
21 | ||
22 | static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { | |
23 | char s[100]; | |
24 | bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); | |
25 | for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { | |
88a8b04e | 26 | s[i] = static_cast<char>(tolower(styler[start + i])); |
f6bcfd97 BP |
27 | s[i + 1] = '\0'; |
28 | } | |
29 | char chAttr = SCE_C_IDENTIFIER; | |
30 | if (wordIsNumber) | |
31 | chAttr = SCE_C_NUMBER; | |
32 | else { | |
33 | if (keywords.InList(s)) | |
34 | chAttr = SCE_C_WORD; | |
35 | } | |
36 | styler.ColourTo(end, chAttr); | |
37 | } | |
38 | ||
39 | static void ColouriseSQLDoc(unsigned int startPos, int length, | |
40 | int initStyle, WordList *keywordlists[], Accessor &styler) { | |
41 | ||
42 | WordList &keywords = *keywordlists[0]; | |
65ec6247 | 43 | |
f6bcfd97 BP |
44 | styler.StartAt(startPos); |
45 | ||
1a2fb4cd | 46 | bool fold = styler.GetPropertyInt("fold") != 0; |
591d01be | 47 | bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0; |
f6bcfd97 BP |
48 | int lineCurrent = styler.GetLine(startPos); |
49 | int spaceFlags = 0; | |
50 | ||
51 | int state = initStyle; | |
52 | char chPrev = ' '; | |
53 | char chNext = styler[startPos]; | |
54 | styler.StartSegment(startPos); | |
55 | unsigned int lengthDoc = startPos + length; | |
56 | for (unsigned int i = startPos; i < lengthDoc; i++) { | |
57 | char ch = chNext; | |
58 | chNext = styler.SafeGetCharAt(i + 1); | |
59 | ||
60 | if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { | |
61 | int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); | |
62 | int lev = indentCurrent; | |
63 | if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { | |
64 | // Only non whitespace lines can be headers | |
65 | int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags); | |
66 | if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) { | |
67 | lev |= SC_FOLDLEVELHEADERFLAG; | |
68 | } | |
69 | } | |
70 | if (fold) { | |
71 | styler.SetLevel(lineCurrent, lev); | |
72 | } | |
73 | } | |
74 | ||
75 | if (styler.IsLeadByte(ch)) { | |
76 | chNext = styler.SafeGetCharAt(i + 2); | |
77 | chPrev = ' '; | |
78 | i += 1; | |
79 | continue; | |
80 | } | |
81 | ||
82 | if (state == SCE_C_DEFAULT) { | |
83 | if (iswordstart(ch)) { | |
84 | styler.ColourTo(i - 1, state); | |
85 | state = SCE_C_WORD; | |
86 | } else if (ch == '/' && chNext == '*') { | |
87 | styler.ColourTo(i - 1, state); | |
88 | state = SCE_C_COMMENT; | |
89 | } else if (ch == '-' && chNext == '-') { | |
90 | styler.ColourTo(i - 1, state); | |
91 | state = SCE_C_COMMENTLINE; | |
591d01be RD |
92 | } else if (ch == '#') { |
93 | styler.ColourTo(i - 1, state); | |
94 | state = SCE_C_COMMENTLINEDOC; | |
8e54aaed RD |
95 | } else if (ch == '\'') { |
96 | styler.ColourTo(i - 1, state); | |
97 | state = SCE_C_CHARACTER; | |
98 | } else if (ch == '"') { | |
f6bcfd97 BP |
99 | styler.ColourTo(i - 1, state); |
100 | state = SCE_C_STRING; | |
101 | } else if (isoperator(ch)) { | |
102 | styler.ColourTo(i - 1, state); | |
103 | styler.ColourTo(i, SCE_C_OPERATOR); | |
104 | } | |
105 | } else if (state == SCE_C_WORD) { | |
106 | if (!iswordchar(ch)) { | |
107 | classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler); | |
108 | state = SCE_C_DEFAULT; | |
109 | if (ch == '/' && chNext == '*') { | |
110 | state = SCE_C_COMMENT; | |
111 | } else if (ch == '-' && chNext == '-') { | |
112 | state = SCE_C_COMMENTLINE; | |
591d01be RD |
113 | } else if (ch == '#') { |
114 | state = SCE_C_COMMENTLINEDOC; | |
8e54aaed RD |
115 | } else if (ch == '\'') { |
116 | state = SCE_C_CHARACTER; | |
117 | } else if (ch == '"') { | |
f6bcfd97 BP |
118 | state = SCE_C_STRING; |
119 | } else if (isoperator(ch)) { | |
120 | styler.ColourTo(i, SCE_C_OPERATOR); | |
121 | } | |
122 | } | |
123 | } else { | |
124 | if (state == SCE_C_COMMENT) { | |
125 | if (ch == '/' && chPrev == '*') { | |
126 | if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) && | |
127 | (styler.GetStartSegment() == startPos)))) { | |
128 | styler.ColourTo(i, state); | |
129 | state = SCE_C_DEFAULT; | |
130 | } | |
131 | } | |
591d01be | 132 | } else if (state == SCE_C_COMMENTLINE || state == SCE_C_COMMENTLINEDOC) { |
f6bcfd97 BP |
133 | if (ch == '\r' || ch == '\n') { |
134 | styler.ColourTo(i - 1, state); | |
135 | state = SCE_C_DEFAULT; | |
136 | } | |
8e54aaed | 137 | } else if (state == SCE_C_CHARACTER) { |
591d01be RD |
138 | if (sqlBackslashEscapes && ch == '\\') { |
139 | i++; | |
140 | ch = chNext; | |
141 | chNext = styler.SafeGetCharAt(i + 1); | |
142 | } else if (ch == '\'') { | |
143 | if (chNext == '\'') { | |
f6bcfd97 BP |
144 | i++; |
145 | } else { | |
146 | styler.ColourTo(i, state); | |
147 | state = SCE_C_DEFAULT; | |
148 | i++; | |
149 | } | |
150 | ch = chNext; | |
151 | chNext = styler.SafeGetCharAt(i + 1); | |
8e54aaed RD |
152 | } |
153 | } else if (state == SCE_C_STRING) { | |
154 | if (ch == '"') { | |
88a8b04e RD |
155 | if (chNext == '"') { |
156 | i++; | |
157 | } else { | |
158 | styler.ColourTo(i, state); | |
159 | state = SCE_C_DEFAULT; | |
160 | i++; | |
161 | } | |
162 | ch = chNext; | |
163 | chNext = styler.SafeGetCharAt(i + 1); | |
f6bcfd97 BP |
164 | } |
165 | } | |
166 | if (state == SCE_C_DEFAULT) { // One of the above succeeded | |
167 | if (ch == '/' && chNext == '*') { | |
168 | state = SCE_C_COMMENT; | |
169 | } else if (ch == '-' && chNext == '-') { | |
170 | state = SCE_C_COMMENTLINE; | |
591d01be RD |
171 | } else if (ch == '#') { |
172 | state = SCE_C_COMMENTLINEDOC; | |
8e54aaed RD |
173 | } else if (ch == '\'') { |
174 | state = SCE_C_CHARACTER; | |
175 | } else if (ch == '"') { | |
f6bcfd97 BP |
176 | state = SCE_C_STRING; |
177 | } else if (iswordstart(ch)) { | |
178 | state = SCE_C_WORD; | |
179 | } else if (isoperator(ch)) { | |
180 | styler.ColourTo(i, SCE_C_OPERATOR); | |
181 | } | |
182 | } | |
183 | } | |
184 | chPrev = ch; | |
185 | } | |
186 | styler.ColourTo(lengthDoc - 1, state); | |
187 | } | |
188 | ||
9e730a78 RD |
189 | static const char * const sqlWordListDesc[] = { |
190 | "Keywords", | |
191 | 0 | |
192 | }; | |
193 | ||
194 | LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc); |