1 // Scintilla source code edit control
5 // Copyright 1998-2002 by Filip Yaghob <fy@eg.cz>
19 #include "Scintilla.h"
22 #define KW_MSSQL_STATEMENTS 0
23 #define KW_MSSQL_DATA_TYPES 1
24 #define KW_MSSQL_SYSTEM_TABLES 2
25 #define KW_MSSQL_GLOBAL_VARIABLES 3
26 #define KW_MSSQL_FUNCTIONS 4
27 #define KW_MSSQL_STORED_PROCEDURES 5
28 #define KW_MSSQL_OPERATORS 6
30 //~ val SCE_MSSQL_DEFAULT=0
31 //~ val SCE_MSSQL_COMMENT=1
32 //~ val SCE_MSSQL_LINE_COMMENT=2
33 //~ val SCE_MSSQL_NUMBER=3
34 //~ val SCE_MSSQL_STRING=4
35 //~ val SCE_MSSQL_OPERATOR=5
36 //~ val SCE_MSSQL_IDENTIFIER=6
37 //~ val SCE_MSSQL_VARIABLE=7
38 //~ val SCE_MSSQL_COLUMN_NAME=8
39 //~ val SCE_MSSQL_STATEMENT=9
40 //~ val SCE_MSSQL_DATATYPE=10
41 //~ val SCE_MSSQL_SYSTABLE=11
42 //~ val SCE_MSSQL_GLOBAL_VARIABLE=12
43 //~ val SCE_MSSQL_FUNCTION=13
44 //~ val SCE_MSSQL_STORED_PROCEDURE=14
45 //~ val SCE_MSSQL_DEFAULT_PREF_DATATYPE 15
46 //~ val SCE_MSSQL_COLUMN_NAME_2 16
48 static bool isMSSQLOperator(char ch
) {
49 if (isascii(ch
) && isalnum(ch
))
51 // '.' left out as it is used to make up numbers
52 if (ch
== '%' || ch
== '^' || ch
== '&' || ch
== '*' ||
53 ch
== '-' || ch
== '+' || ch
== '=' || ch
== '|' ||
54 ch
== '<' || ch
== '>' || ch
== '/' ||
55 ch
== '!' || ch
== '~' || ch
== '(' || ch
== ')' ||
61 static char classifyWordSQL(unsigned int start
,
63 WordList
*keywordlists
[],
65 unsigned int actualState
,
66 unsigned int prevState
) {
68 bool wordIsNumber
= isdigit(styler
[start
]) || (styler
[start
] == '.');
70 WordList
&kwStatements
= *keywordlists
[KW_MSSQL_STATEMENTS
];
71 WordList
&kwDataTypes
= *keywordlists
[KW_MSSQL_DATA_TYPES
];
72 WordList
&kwSystemTables
= *keywordlists
[KW_MSSQL_SYSTEM_TABLES
];
73 WordList
&kwGlobalVariables
= *keywordlists
[KW_MSSQL_GLOBAL_VARIABLES
];
74 WordList
&kwFunctions
= *keywordlists
[KW_MSSQL_FUNCTIONS
];
75 WordList
&kwStoredProcedures
= *keywordlists
[KW_MSSQL_STORED_PROCEDURES
];
76 WordList
&kwOperators
= *keywordlists
[KW_MSSQL_OPERATORS
];
78 for (unsigned int i
= 0; i
< end
- start
+ 1 && i
< 128; i
++) {
79 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
82 char chAttr
= SCE_MSSQL_IDENTIFIER
;
84 if (actualState
== SCE_MSSQL_GLOBAL_VARIABLE
) {
86 if (kwGlobalVariables
.InList(&s
[2]))
87 chAttr
= SCE_MSSQL_GLOBAL_VARIABLE
;
89 } else if (wordIsNumber
) {
90 chAttr
= SCE_MSSQL_NUMBER
;
92 } else if (prevState
== SCE_MSSQL_DEFAULT_PREF_DATATYPE
) {
93 // Look first in datatypes
94 if (kwDataTypes
.InList(s
))
95 chAttr
= SCE_MSSQL_DATATYPE
;
96 else if (kwOperators
.InList(s
))
97 chAttr
= SCE_MSSQL_OPERATOR
;
98 else if (kwStatements
.InList(s
))
99 chAttr
= SCE_MSSQL_STATEMENT
;
100 else if (kwSystemTables
.InList(s
))
101 chAttr
= SCE_MSSQL_SYSTABLE
;
102 else if (kwFunctions
.InList(s
))
103 chAttr
= SCE_MSSQL_FUNCTION
;
104 else if (kwStoredProcedures
.InList(s
))
105 chAttr
= SCE_MSSQL_STORED_PROCEDURE
;
108 if (kwOperators
.InList(s
))
109 chAttr
= SCE_MSSQL_OPERATOR
;
110 else if (kwStatements
.InList(s
))
111 chAttr
= SCE_MSSQL_STATEMENT
;
112 else if (kwSystemTables
.InList(s
))
113 chAttr
= SCE_MSSQL_SYSTABLE
;
114 else if (kwFunctions
.InList(s
))
115 chAttr
= SCE_MSSQL_FUNCTION
;
116 else if (kwStoredProcedures
.InList(s
))
117 chAttr
= SCE_MSSQL_STORED_PROCEDURE
;
118 else if (kwDataTypes
.InList(s
))
119 chAttr
= SCE_MSSQL_DATATYPE
;
122 styler
.ColourTo(end
, chAttr
);
127 static void ColouriseMSSQLDoc(unsigned int startPos
, int length
,
128 int initStyle
, WordList
*keywordlists
[], Accessor
&styler
) {
131 styler
.StartAt(startPos
);
133 bool fold
= styler
.GetPropertyInt("fold") != 0;
134 int lineCurrent
= styler
.GetLine(startPos
);
137 WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
138 WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
139 WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
140 WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
141 WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
145 s[0] = 's'; s[1] = 'e'; s[2] = 'l'; s[3] = 'e'; s[4] = 'c'; s[5] = 't'; s[6] = 0;
146 if (kwStatements.InList(s))
148 s[0] = 's'; s[1] = 'e'; s[2] = 'r'; s[3] = 'v'; s[4] = 'e'; s[5] = 'r'; s[6] = 'n'; s[7] = 'a'; s[8] = 'm'; s[9] = 'e'; s[10] = 0;
149 if (kwGlobalVariables.InList(s))
152 int state
= initStyle
;
153 int prevState
= initStyle
;
155 char chNext
= styler
[startPos
];
156 styler
.StartSegment(startPos
);
157 unsigned int lengthDoc
= startPos
+ length
;
158 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
160 chNext
= styler
.SafeGetCharAt(i
+ 1);
162 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n')) {
163 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
);
164 int lev
= indentCurrent
;
165 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
)) {
166 // Only non whitespace lines can be headers
167 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
);
168 if (indentCurrent
< (indentNext
& ~SC_FOLDLEVELWHITEFLAG
)) {
169 lev
|= SC_FOLDLEVELHEADERFLAG
;
173 styler
.SetLevel(lineCurrent
, lev
);
177 if (styler
.IsLeadByte(ch
)) {
178 chNext
= styler
.SafeGetCharAt(i
+ 2);
184 // When the last char isn't part of the state (have to deal with it too)...
185 if ( (state
== SCE_MSSQL_IDENTIFIER
) ||
186 (state
== SCE_MSSQL_STORED_PROCEDURE
) ||
187 (state
== SCE_MSSQL_DATATYPE
) ||
188 //~ (state == SCE_MSSQL_COLUMN_NAME) ||
189 (state
== SCE_MSSQL_FUNCTION
) ||
190 //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
191 (state
== SCE_MSSQL_VARIABLE
)) {
192 if (!iswordchar(ch
)) {
195 if ((state
== SCE_MSSQL_VARIABLE
) || (state
== SCE_MSSQL_COLUMN_NAME
)) {
196 styler
.ColourTo(i
- 1, state
);
199 stateTmp
= classifyWordSQL(styler
.GetStartSegment(), i
- 1, keywordlists
, styler
, state
, prevState
);
203 if (stateTmp
== SCE_MSSQL_IDENTIFIER
|| stateTmp
== SCE_MSSQL_VARIABLE
)
204 state
= SCE_MSSQL_DEFAULT_PREF_DATATYPE
;
206 state
= SCE_MSSQL_DEFAULT
;
208 } else if (state
== SCE_MSSQL_LINE_COMMENT
) {
209 if (ch
== '\r' || ch
== '\n') {
210 styler
.ColourTo(i
- 1, state
);
212 state
= SCE_MSSQL_DEFAULT
;
214 } else if (state
== SCE_MSSQL_GLOBAL_VARIABLE
) {
215 if ((ch
!= '@') && !iswordchar(ch
)) {
216 classifyWordSQL(styler
.GetStartSegment(), i
- 1, keywordlists
, styler
, state
, prevState
);
218 state
= SCE_MSSQL_DEFAULT
;
222 // If is the default or one of the above succeeded
223 if (state
== SCE_MSSQL_DEFAULT
|| state
== SCE_MSSQL_DEFAULT_PREF_DATATYPE
) {
224 if (iswordstart(ch
)) {
225 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
227 state
= SCE_MSSQL_IDENTIFIER
;
228 } else if (ch
== '/' && chNext
== '*') {
229 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
231 state
= SCE_MSSQL_COMMENT
;
232 } else if (ch
== '-' && chNext
== '-') {
233 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
235 state
= SCE_MSSQL_LINE_COMMENT
;
236 } else if (ch
== '\'') {
237 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
239 state
= SCE_MSSQL_STRING
;
240 } else if (ch
== '"') {
241 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
243 state
= SCE_MSSQL_COLUMN_NAME
;
244 } else if (ch
== '[') {
245 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
247 state
= SCE_MSSQL_COLUMN_NAME_2
;
248 } else if (isMSSQLOperator(ch
)) {
249 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
250 styler
.ColourTo(i
, SCE_MSSQL_OPERATOR
);
251 //~ style = SCE_MSSQL_DEFAULT;
253 state
= SCE_MSSQL_DEFAULT
;
254 } else if (ch
== '@') {
255 styler
.ColourTo(i
- 1, SCE_MSSQL_DEFAULT
);
258 state
= SCE_MSSQL_GLOBAL_VARIABLE
;
261 state
= SCE_MSSQL_VARIABLE
;
265 // When the last char is part of the state...
266 } else if (state
== SCE_MSSQL_COMMENT
) {
267 if (ch
== '/' && chPrev
== '*') {
268 if (((i
> (styler
.GetStartSegment() + 2)) || ((initStyle
== SCE_MSSQL_COMMENT
) &&
269 (styler
.GetStartSegment() == startPos
)))) {
270 styler
.ColourTo(i
, state
);
271 //~ state = SCE_MSSQL_COMMENT;
273 state
= SCE_MSSQL_DEFAULT
;
276 } else if (state
== SCE_MSSQL_STRING
) {
278 if ( chNext
== '\'' ) {
281 chNext
= styler
.SafeGetCharAt(i
+ 1);
283 styler
.ColourTo(i
, state
);
285 state
= SCE_MSSQL_DEFAULT
;
289 //chNext = styler.SafeGetCharAt(i + 1);
291 } else if (state
== SCE_MSSQL_COLUMN_NAME
) {
296 chNext
= styler
.SafeGetCharAt(i
+ 1);
298 styler
.ColourTo(i
, state
);
300 state
= SCE_MSSQL_DEFAULT_PREF_DATATYPE
;
304 } else if (state
== SCE_MSSQL_COLUMN_NAME_2
) {
306 styler
.ColourTo(i
, state
);
308 state
= SCE_MSSQL_DEFAULT_PREF_DATATYPE
;
315 styler
.ColourTo(lengthDoc
- 1, state
);
318 static const char * const sqlWordListDesc
[] = {
324 "System Stored Procedures",
329 LexerModule
lmMSSQL(SCLEX_MSSQL
, ColouriseMSSQLDoc
, "mssql", 0, sqlWordListDesc
);