PageRenderTime 80ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/CaptainOz/ogre
C++ | 369 lines | 316 code | 39 blank | 14 comment | 259 complexity | 175c544369c7224e5c546899bd43282e MD5 | raw file
Possible License(s): LGPL-2.1, MIT
  1. // Scintilla source code edit control
  2. /** @file LexPascal.cxx
  3. ** Lexer for Pascal.
  4. ** Written by Laurent le Tynevez
  5. ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
  6. ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
  7. **/
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <stdio.h>
  12. #include <stdarg.h>
  13. #include "Platform.h"
  14. #include "PropSet.h"
  15. #include "Accessor.h"
  16. #include "KeyWords.h"
  17. #include "Scintilla.h"
  18. #include "SciLexer.h"
  19. #include "StyleContext.h"
  20. static void getRange(unsigned int start,
  21. unsigned int end,
  22. Accessor &styler,
  23. char *s,
  24. unsigned int len) {
  25. unsigned int i = 0;
  26. while ((i < end - start + 1) && (i < len-1)) {
  27. s[i] = static_cast<char>(tolower(styler[start + i]));
  28. i++;
  29. }
  30. s[i] = '\0';
  31. }
  32. static bool IsStreamCommentStyle(int style) {
  33. return style == SCE_C_COMMENT ||
  34. style == SCE_C_COMMENTDOC ||
  35. style == SCE_C_COMMENTDOCKEYWORD ||
  36. style == SCE_C_COMMENTDOCKEYWORDERROR;
  37. }
  38. static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
  39. if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
  40. styler.ColourTo(end, SCE_C_REGEX);
  41. } else
  42. styler.ColourTo(end, attr);
  43. }
  44. // returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
  45. static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInClass, bool bInAsm) {
  46. int ret = 0;
  47. WordList& keywords = *keywordlists[0];
  48. WordList& classwords = *keywordlists[1];
  49. char s[100];
  50. getRange(start, end, styler, s, sizeof(s));
  51. char chAttr = SCE_C_IDENTIFIER;
  52. if (isdigit(s[0]) || (s[0] == '.') ||(s[0] == '$')) {
  53. chAttr = SCE_C_NUMBER;
  54. }
  55. else {
  56. if (s[0] == '#') {
  57. chAttr = SCE_C_CHARACTER;
  58. }
  59. else {
  60. if (keywords.InList(s)) {
  61. chAttr = SCE_C_WORD;
  62. if(strcmp(s, "class") == 0) {
  63. ret = 1;
  64. }
  65. else if (strcmp(s, "asm") == 0) {
  66. ret = 2;
  67. }
  68. else if (strcmp(s, "end") == 0) {
  69. ret = -1;
  70. }
  71. } else if (bInClass) {
  72. if (classwords.InList(s)) {
  73. chAttr = SCE_C_WORD;
  74. }
  75. }
  76. }
  77. }
  78. ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
  79. return ret;
  80. }
  81. static int classifyFoldPointPascal(const char* s) {
  82. int lev = 0;
  83. if (!(isdigit(s[0]) || (s[0] == '.'))) {
  84. if (strcmp(s, "begin") == 0 ||
  85. strcmp(s, "object") == 0 ||
  86. strcmp(s, "case") == 0 ||
  87. strcmp(s, "class") == 0 ||
  88. strcmp(s, "record") == 0 ||
  89. strcmp(s, "try") == 0) {
  90. lev=1;
  91. } else if (strcmp(s, "end") == 0) {
  92. lev=-1;
  93. }
  94. }
  95. return lev;
  96. }
  97. static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
  98. Accessor &styler) {
  99. styler.StartAt(startPos);
  100. int state = initStyle;
  101. if (state == SCE_C_CHARACTER) // Does not leak onto next line
  102. state = SCE_C_DEFAULT;
  103. char chPrev = ' ';
  104. char chNext = styler[startPos];
  105. unsigned int lengthDoc = startPos + length;
  106. bool bInClassDefinition;
  107. int currentLine = styler.GetLine(startPos);
  108. if (currentLine > 0) {
  109. styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
  110. bInClassDefinition = (styler.GetLineState(currentLine) == 1);
  111. } else {
  112. styler.SetLineState(currentLine, 0);
  113. bInClassDefinition = false;
  114. }
  115. bool bInAsm = (state == SCE_C_REGEX);
  116. if (bInAsm)
  117. state = SCE_C_DEFAULT;
  118. styler.StartSegment(startPos);
  119. for (unsigned int i = startPos; i < lengthDoc; i++) {
  120. char ch = chNext;
  121. chNext = styler.SafeGetCharAt(i + 1);
  122. if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
  123. // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
  124. // Avoid triggering two times on Dos/Win
  125. // End of line
  126. if (state == SCE_C_CHARACTER) {
  127. ColourTo(styler, i, state, bInAsm);
  128. state = SCE_C_DEFAULT;
  129. }
  130. currentLine++;
  131. styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
  132. }
  133. if (styler.IsLeadByte(ch)) {
  134. chNext = styler.SafeGetCharAt(i + 2);
  135. chPrev = ' ';
  136. i += 1;
  137. continue;
  138. }
  139. if (state == SCE_C_DEFAULT) {
  140. if (iswordstart(ch) || ch == '#' || ch == '$' || (ch == '@' && bInAsm)) {
  141. ColourTo(styler, i-1, state, bInAsm);
  142. state = SCE_C_IDENTIFIER;
  143. } else if (ch == '{' && chNext != '$' && chNext != '&') {
  144. ColourTo(styler, i-1, state, bInAsm);
  145. state = SCE_C_COMMENT;
  146. } else if (ch == '(' && chNext == '*'
  147. && styler.SafeGetCharAt(i + 2) != '$'
  148. && styler.SafeGetCharAt(i + 2) != '&') {
  149. ColourTo(styler, i-1, state, bInAsm);
  150. state = SCE_C_COMMENTDOC;
  151. } else if (ch == '/' && chNext == '/') {
  152. ColourTo(styler, i-1, state, bInAsm);
  153. state = SCE_C_COMMENTLINE;
  154. } else if (ch == '\'') {
  155. ColourTo(styler, i-1, state, bInAsm);
  156. state = SCE_C_CHARACTER;
  157. } else if (ch == '{' && (chNext == '$' || chNext=='&')) {
  158. ColourTo(styler, i-1, state, bInAsm);
  159. state = SCE_C_PREPROCESSOR;
  160. } else if (isoperator(ch)) {
  161. ColourTo(styler, i-1, state, bInAsm);
  162. ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
  163. }
  164. } else if (state == SCE_C_IDENTIFIER) {
  165. bool bDoublePoint = ((ch == '.') && (chPrev == '.'));
  166. if ((!iswordchar(ch) && ch != '$' && ch != '#' && (ch != '@' || !bInAsm)) || bDoublePoint) {
  167. if (bDoublePoint) i--;
  168. int lStateChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywordlists, styler, bInClassDefinition, bInAsm);
  169. if(lStateChange == 1) {
  170. styler.SetLineState(currentLine, 1);
  171. bInClassDefinition = true;
  172. } else if(lStateChange == 2) {
  173. bInAsm = true;
  174. } else if(lStateChange == -1) {
  175. styler.SetLineState(currentLine, 0);
  176. bInClassDefinition = false;
  177. bInAsm = false;
  178. }
  179. if (bDoublePoint) {
  180. i++;
  181. ColourTo(styler, i-1, SCE_C_DEFAULT, bInAsm);
  182. }
  183. state = SCE_C_DEFAULT;
  184. chNext = styler.SafeGetCharAt(i + 1);
  185. if (ch == '{' && chNext != '$' && chNext != '&') {
  186. state = SCE_C_COMMENT;
  187. } else if (ch == '(' && chNext == '*'
  188. && styler.SafeGetCharAt(i + 2) != '$'
  189. && styler.SafeGetCharAt(i + 2) != '&') {
  190. ColourTo(styler, i-1, state, bInAsm);
  191. state = SCE_C_COMMENTDOC;
  192. } else if (ch == '/' && chNext == '/') {
  193. state = SCE_C_COMMENTLINE;
  194. } else if (ch == '\'') {
  195. state = SCE_C_CHARACTER;
  196. } else if (isoperator(ch)) {
  197. ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
  198. }
  199. }
  200. } else {
  201. if (state == SCE_C_PREPROCESSOR) {
  202. if (ch=='}'){
  203. ColourTo(styler, i, state, bInAsm);
  204. state = SCE_C_DEFAULT;
  205. } else {
  206. if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
  207. ColourTo(styler, i-1, state, bInAsm);
  208. state = SCE_C_DEFAULT;
  209. }
  210. }
  211. } else if (state == SCE_C_COMMENT) {
  212. if (ch == '}' ) {
  213. ColourTo(styler, i, state, bInAsm);
  214. state = SCE_C_DEFAULT;
  215. }
  216. } else if (state == SCE_C_COMMENTDOC) {
  217. if (ch == ')' && chPrev == '*') {
  218. if (((i > styler.GetStartSegment() + 2) || (
  219. (initStyle == SCE_C_COMMENTDOC) &&
  220. (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
  221. ColourTo(styler, i, state, bInAsm);
  222. state = SCE_C_DEFAULT;
  223. }
  224. }
  225. } else if (state == SCE_C_COMMENTLINE) {
  226. if (ch == '\r' || ch == '\n') {
  227. ColourTo(styler, i-1, state, bInAsm);
  228. state = SCE_C_DEFAULT;
  229. }
  230. } else if (state == SCE_C_CHARACTER) {
  231. if (ch == '\'') {
  232. ColourTo(styler, i, state, bInAsm);
  233. state = SCE_C_DEFAULT;
  234. }
  235. }
  236. }
  237. chPrev = ch;
  238. }
  239. ColourTo(styler, lengthDoc - 1, state, bInAsm);
  240. }
  241. static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[],
  242. Accessor &styler) {
  243. bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
  244. bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
  245. bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  246. unsigned int endPos = startPos + length;
  247. int visibleChars = 0;
  248. int lineCurrent = styler.GetLine(startPos);
  249. int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  250. int levelCurrent = levelPrev;
  251. char chNext = styler[startPos];
  252. int styleNext = styler.StyleAt(startPos);
  253. int style = initStyle;
  254. int lastStart = 0;
  255. for (unsigned int i = startPos; i < endPos; i++) {
  256. char ch = chNext;
  257. chNext = styler.SafeGetCharAt(i + 1);
  258. int stylePrev = style;
  259. style = styleNext;
  260. styleNext = styler.StyleAt(i + 1);
  261. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  262. if (stylePrev == SCE_C_DEFAULT && style == SCE_C_WORD)
  263. {
  264. // Store last word start point.
  265. lastStart = i;
  266. }
  267. if (stylePrev == SCE_C_WORD) {
  268. if(iswordchar(ch) && !iswordchar(chNext)) {
  269. char s[100];
  270. getRange(lastStart, i, styler, s, sizeof(s));
  271. levelCurrent += classifyFoldPointPascal(s);
  272. }
  273. }
  274. if (foldComment && (style == SCE_C_COMMENTLINE)) {
  275. if ((ch == '/') && (chNext == '/')) {
  276. char chNext2 = styler.SafeGetCharAt(i + 2);
  277. if (chNext2 == '{') {
  278. levelCurrent++;
  279. } else if (chNext2 == '}') {
  280. levelCurrent--;
  281. }
  282. }
  283. }
  284. if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
  285. if (ch == '{' && chNext == '$') {
  286. unsigned int j=i+2; // skip {$
  287. while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
  288. j++;
  289. }
  290. if (styler.Match(j, "region") || styler.Match(j, "if")) {
  291. levelCurrent++;
  292. } else if (styler.Match(j, "end")) {
  293. levelCurrent--;
  294. }
  295. }
  296. }
  297. if (foldComment && IsStreamCommentStyle(style)) {
  298. if (!IsStreamCommentStyle(stylePrev)) {
  299. levelCurrent++;
  300. } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
  301. // Comments don't end at end of line and the next character may be unstyled.
  302. levelCurrent--;
  303. }
  304. }
  305. if (atEOL) {
  306. int lev = levelPrev;
  307. if (visibleChars == 0 && foldCompact)
  308. lev |= SC_FOLDLEVELWHITEFLAG;
  309. if ((levelCurrent > levelPrev) && (visibleChars > 0))
  310. lev |= SC_FOLDLEVELHEADERFLAG;
  311. if (lev != styler.LevelAt(lineCurrent)) {
  312. styler.SetLevel(lineCurrent, lev);
  313. }
  314. lineCurrent++;
  315. levelPrev = levelCurrent;
  316. visibleChars = 0;
  317. }
  318. if (!isspacechar(ch))
  319. visibleChars++;
  320. }
  321. // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  322. int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  323. styler.SetLevel(lineCurrent, levelPrev | flagsNext);
  324. }
  325. static const char * const pascalWordListDesc[] = {
  326. "Keywords",
  327. "Classwords",
  328. 0
  329. };
  330. LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc);