PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/LexMSSQL.cxx

https://bitbucket.org/CaptainOz/ogre
C++ | 359 lines | 319 code | 27 blank | 13 comment | 128 complexity | 70da7ca864adbbde380103dfb0f54d80 MD5 | raw file
Possible License(s): LGPL-2.1, MIT
  1. // Scintilla source code edit control
  2. /** @file LexMSSQL.cxx
  3. ** Lexer for MSSQL.
  4. **/
  5. // By Filip Yaghob <fyaghob@gmail.com>
  6. // The License.txt file describes the conditions under which this software may be distributed.
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #include "Platform.h"
  13. #include "PropSet.h"
  14. #include "Accessor.h"
  15. #include "KeyWords.h"
  16. #include "Scintilla.h"
  17. #include "SciLexer.h"
  18. #define KW_MSSQL_STATEMENTS 0
  19. #define KW_MSSQL_DATA_TYPES 1
  20. #define KW_MSSQL_SYSTEM_TABLES 2
  21. #define KW_MSSQL_GLOBAL_VARIABLES 3
  22. #define KW_MSSQL_FUNCTIONS 4
  23. #define KW_MSSQL_STORED_PROCEDURES 5
  24. #define KW_MSSQL_OPERATORS 6
  25. static bool isMSSQLOperator(char ch) {
  26. if (isascii(ch) && isalnum(ch))
  27. return false;
  28. // '.' left out as it is used to make up numbers
  29. if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
  30. ch == '-' || ch == '+' || ch == '=' || ch == '|' ||
  31. ch == '<' || ch == '>' || ch == '/' ||
  32. ch == '!' || ch == '~' || ch == '(' || ch == ')' ||
  33. ch == ',')
  34. return true;
  35. return false;
  36. }
  37. static char classifyWordSQL(unsigned int start,
  38. unsigned int end,
  39. WordList *keywordlists[],
  40. Accessor &styler,
  41. unsigned int actualState,
  42. unsigned int prevState) {
  43. char s[256];
  44. bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
  45. WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
  46. WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
  47. WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
  48. WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
  49. WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
  50. WordList &kwStoredProcedures = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
  51. WordList &kwOperators = *keywordlists[KW_MSSQL_OPERATORS];
  52. for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) {
  53. s[i] = static_cast<char>(tolower(styler[start + i]));
  54. s[i + 1] = '\0';
  55. }
  56. char chAttr = SCE_MSSQL_IDENTIFIER;
  57. if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {
  58. if (kwGlobalVariables.InList(&s[2]))
  59. chAttr = SCE_MSSQL_GLOBAL_VARIABLE;
  60. } else if (wordIsNumber) {
  61. chAttr = SCE_MSSQL_NUMBER;
  62. } else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
  63. // Look first in datatypes
  64. if (kwDataTypes.InList(s))
  65. chAttr = SCE_MSSQL_DATATYPE;
  66. else if (kwOperators.InList(s))
  67. chAttr = SCE_MSSQL_OPERATOR;
  68. else if (kwStatements.InList(s))
  69. chAttr = SCE_MSSQL_STATEMENT;
  70. else if (kwSystemTables.InList(s))
  71. chAttr = SCE_MSSQL_SYSTABLE;
  72. else if (kwFunctions.InList(s))
  73. chAttr = SCE_MSSQL_FUNCTION;
  74. else if (kwStoredProcedures.InList(s))
  75. chAttr = SCE_MSSQL_STORED_PROCEDURE;
  76. } else {
  77. if (kwOperators.InList(s))
  78. chAttr = SCE_MSSQL_OPERATOR;
  79. else if (kwStatements.InList(s))
  80. chAttr = SCE_MSSQL_STATEMENT;
  81. else if (kwSystemTables.InList(s))
  82. chAttr = SCE_MSSQL_SYSTABLE;
  83. else if (kwFunctions.InList(s))
  84. chAttr = SCE_MSSQL_FUNCTION;
  85. else if (kwStoredProcedures.InList(s))
  86. chAttr = SCE_MSSQL_STORED_PROCEDURE;
  87. else if (kwDataTypes.InList(s))
  88. chAttr = SCE_MSSQL_DATATYPE;
  89. }
  90. styler.ColourTo(end, chAttr);
  91. return chAttr;
  92. }
  93. static void ColouriseMSSQLDoc(unsigned int startPos, int length,
  94. int initStyle, WordList *keywordlists[], Accessor &styler) {
  95. styler.StartAt(startPos);
  96. bool fold = styler.GetPropertyInt("fold") != 0;
  97. int lineCurrent = styler.GetLine(startPos);
  98. int spaceFlags = 0;
  99. int state = initStyle;
  100. int prevState = initStyle;
  101. char chPrev = ' ';
  102. char chNext = styler[startPos];
  103. styler.StartSegment(startPos);
  104. unsigned int lengthDoc = startPos + length;
  105. for (unsigned int i = startPos; i < lengthDoc; i++) {
  106. char ch = chNext;
  107. chNext = styler.SafeGetCharAt(i + 1);
  108. if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
  109. int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
  110. int lev = indentCurrent;
  111. if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
  112. // Only non whitespace lines can be headers
  113. int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
  114. if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
  115. lev |= SC_FOLDLEVELHEADERFLAG;
  116. }
  117. }
  118. if (fold) {
  119. styler.SetLevel(lineCurrent, lev);
  120. }
  121. }
  122. if (styler.IsLeadByte(ch)) {
  123. chNext = styler.SafeGetCharAt(i + 2);
  124. chPrev = ' ';
  125. i += 1;
  126. continue;
  127. }
  128. // When the last char isn't part of the state (have to deal with it too)...
  129. if ( (state == SCE_MSSQL_IDENTIFIER) ||
  130. (state == SCE_MSSQL_STORED_PROCEDURE) ||
  131. (state == SCE_MSSQL_DATATYPE) ||
  132. //~ (state == SCE_MSSQL_COLUMN_NAME) ||
  133. (state == SCE_MSSQL_FUNCTION) ||
  134. //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
  135. (state == SCE_MSSQL_VARIABLE)) {
  136. if (!iswordchar(ch)) {
  137. int stateTmp;
  138. if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
  139. styler.ColourTo(i - 1, state);
  140. stateTmp = state;
  141. } else
  142. stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
  143. prevState = state;
  144. if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
  145. state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
  146. else
  147. state = SCE_MSSQL_DEFAULT;
  148. }
  149. } else if (state == SCE_MSSQL_LINE_COMMENT) {
  150. if (ch == '\r' || ch == '\n') {
  151. styler.ColourTo(i - 1, state);
  152. prevState = state;
  153. state = SCE_MSSQL_DEFAULT;
  154. }
  155. } else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
  156. if ((ch != '@') && !iswordchar(ch)) {
  157. classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
  158. prevState = state;
  159. state = SCE_MSSQL_DEFAULT;
  160. }
  161. }
  162. // If is the default or one of the above succeeded
  163. if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
  164. if (iswordstart(ch)) {
  165. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  166. prevState = state;
  167. state = SCE_MSSQL_IDENTIFIER;
  168. } else if (ch == '/' && chNext == '*') {
  169. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  170. prevState = state;
  171. state = SCE_MSSQL_COMMENT;
  172. } else if (ch == '-' && chNext == '-') {
  173. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  174. prevState = state;
  175. state = SCE_MSSQL_LINE_COMMENT;
  176. } else if (ch == '\'') {
  177. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  178. prevState = state;
  179. state = SCE_MSSQL_STRING;
  180. } else if (ch == '"') {
  181. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  182. prevState = state;
  183. state = SCE_MSSQL_COLUMN_NAME;
  184. } else if (ch == '[') {
  185. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  186. prevState = state;
  187. state = SCE_MSSQL_COLUMN_NAME_2;
  188. } else if (isMSSQLOperator(ch)) {
  189. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  190. styler.ColourTo(i, SCE_MSSQL_OPERATOR);
  191. //~ style = SCE_MSSQL_DEFAULT;
  192. prevState = state;
  193. state = SCE_MSSQL_DEFAULT;
  194. } else if (ch == '@') {
  195. styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
  196. prevState = state;
  197. if (chNext == '@') {
  198. state = SCE_MSSQL_GLOBAL_VARIABLE;
  199. // i += 2;
  200. } else
  201. state = SCE_MSSQL_VARIABLE;
  202. }
  203. // When the last char is part of the state...
  204. } else if (state == SCE_MSSQL_COMMENT) {
  205. if (ch == '/' && chPrev == '*') {
  206. if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
  207. (styler.GetStartSegment() == startPos)))) {
  208. styler.ColourTo(i, state);
  209. //~ state = SCE_MSSQL_COMMENT;
  210. prevState = state;
  211. state = SCE_MSSQL_DEFAULT;
  212. }
  213. }
  214. } else if (state == SCE_MSSQL_STRING) {
  215. if (ch == '\'') {
  216. if ( chNext == '\'' ) {
  217. i++;
  218. ch = chNext;
  219. chNext = styler.SafeGetCharAt(i + 1);
  220. } else {
  221. styler.ColourTo(i, state);
  222. prevState = state;
  223. state = SCE_MSSQL_DEFAULT;
  224. //i++;
  225. }
  226. //ch = chNext;
  227. //chNext = styler.SafeGetCharAt(i + 1);
  228. }
  229. } else if (state == SCE_MSSQL_COLUMN_NAME) {
  230. if (ch == '"') {
  231. if (chNext == '"') {
  232. i++;
  233. ch = chNext;
  234. chNext = styler.SafeGetCharAt(i + 1);
  235. } else {
  236. styler.ColourTo(i, state);
  237. prevState = state;
  238. state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
  239. //i++;
  240. }
  241. }
  242. } else if (state == SCE_MSSQL_COLUMN_NAME_2) {
  243. if (ch == ']') {
  244. styler.ColourTo(i, state);
  245. prevState = state;
  246. state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
  247. //i++;
  248. }
  249. }
  250. chPrev = ch;
  251. }
  252. styler.ColourTo(lengthDoc - 1, state);
  253. }
  254. static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  255. bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
  256. bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  257. unsigned int endPos = startPos + length;
  258. int visibleChars = 0;
  259. int lineCurrent = styler.GetLine(startPos);
  260. int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  261. int levelCurrent = levelPrev;
  262. char chNext = styler[startPos];
  263. bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
  264. char s[10];
  265. for (unsigned int i = startPos; i < endPos; i++) {
  266. char ch = chNext;
  267. chNext = styler.SafeGetCharAt(i + 1);
  268. int style = styler.StyleAt(i);
  269. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  270. // Comment folding
  271. if (foldComment) {
  272. if (!inComment && (style == SCE_MSSQL_COMMENT))
  273. levelCurrent++;
  274. else if (inComment && (style != SCE_MSSQL_COMMENT))
  275. levelCurrent--;
  276. inComment = (style == SCE_MSSQL_COMMENT);
  277. }
  278. if (style == SCE_MSSQL_STATEMENT) {
  279. // Folding between begin and end
  280. if (ch == 'b' || ch == 'e') {
  281. for (unsigned int j = 0; j < 5; j++) {
  282. if (!iswordchar(styler[i + j])) {
  283. break;
  284. }
  285. s[j] = styler[i + j];
  286. s[j + 1] = '\0';
  287. }
  288. if (strcmp(s, "begin") == 0) {
  289. levelCurrent++;
  290. }
  291. if (strcmp(s, "end") == 0) {
  292. levelCurrent--;
  293. }
  294. }
  295. }
  296. if (atEOL) {
  297. int lev = levelPrev;
  298. if (visibleChars == 0 && foldCompact)
  299. lev |= SC_FOLDLEVELWHITEFLAG;
  300. if ((levelCurrent > levelPrev) && (visibleChars > 0))
  301. lev |= SC_FOLDLEVELHEADERFLAG;
  302. if (lev != styler.LevelAt(lineCurrent)) {
  303. styler.SetLevel(lineCurrent, lev);
  304. }
  305. lineCurrent++;
  306. levelPrev = levelCurrent;
  307. visibleChars = 0;
  308. }
  309. if (!isspacechar(ch))
  310. visibleChars++;
  311. }
  312. // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  313. int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  314. styler.SetLevel(lineCurrent, levelPrev | flagsNext);
  315. }
  316. static const char * const sqlWordListDesc[] = {
  317. "Statements",
  318. "Data Types",
  319. "System tables",
  320. "Global variables",
  321. "Functions",
  322. "System Stored Procedures",
  323. "Operators",
  324. 0,
  325. };
  326. LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);