PageRenderTime 90ms CodeModel.GetById 43ms RepoModel.GetById 2ms app.codeStats 0ms

/src/tools/lua_debug/scintilla/lexers/LexOthers.cxx

http://fengine.googlecode.com/
C++ | 1730 lines | 1498 code | 70 blank | 162 comment | 556 complexity | 9e15bb66ea31511864f9a26d60e61359 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. // Scintilla source code edit control
  2. /** @file LexOthers.cxx
  3. ** Lexers for batch files, diff results, properties files, make files and error lists.
  4. ** Also lexer for LaTeX documents.
  5. **/
  6. // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
  7. // The License.txt file describes the conditions under which this software may be distributed.
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #include <assert.h>
  13. #include <ctype.h>
  14. #include "ILexer.h"
  15. #include "Scintilla.h"
  16. #include "SciLexer.h"
  17. #include "PropSetSimple.h"
  18. #include "WordList.h"
  19. #include "LexAccessor.h"
  20. #include "Accessor.h"
  21. #include "StyleContext.h"
  22. #include "CharacterSet.h"
  23. #include "LexerModule.h"
  24. #ifdef SCI_NAMESPACE
  25. using namespace Scintilla;
  26. #endif
  27. static bool strstart(const char *haystack, const char *needle) {
  28. return strncmp(haystack, needle, strlen(needle)) == 0;
  29. }
  30. static bool Is0To9(char ch) {
  31. return (ch >= '0') && (ch <= '9');
  32. }
  33. static bool Is1To9(char ch) {
  34. return (ch >= '1') && (ch <= '9');
  35. }
  36. static bool IsAlphabetic(int ch) {
  37. return isascii(ch) && isalpha(ch);
  38. }
  39. static inline bool AtEOL(Accessor &styler, unsigned int i) {
  40. return (styler[i] == '\n') ||
  41. ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
  42. }
  43. // Tests for BATCH Operators
  44. static bool IsBOperator(char ch) {
  45. return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
  46. //! (ch == '|') || (ch == '?') || (ch == '*');
  47. (ch == '|') || (ch == '?') || (ch == '*') || (ch == '(') || (ch == ')'); //!-change-[BatchLexerImprovement]
  48. }
  49. // Tests for BATCH Separators
  50. static bool IsBSeparator(char ch) {
  51. return (ch == '\\') || (ch == '.') || (ch == ';') ||
  52. //! (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
  53. (ch == '\"') || (ch == '\'') || (ch == '/'); //!-change-[BatchLexerImprovement]
  54. }
  55. //!-start-[BatchLexerImprovement]
  56. // Tests for Environment Variable simbol
  57. static inline bool IsEnvironmentVar(char ch) {
  58. return isalpha(ch) || Is0To9(ch) || (ch == '_');
  59. }
  60. // Tests for BATCH Variable simbol
  61. static inline bool IsBatchVar(char ch) {
  62. return isalpha(ch) || Is0To9(ch);
  63. }
  64. // Find length of BATCH Variable with modifier (%~...) or return 0
  65. static unsigned int GetBatchVarLen(char *wordBuffer, unsigned int wbl)
  66. {
  67. if (wbl > 2 && wordBuffer[0] == '%' && wordBuffer[1] == '~') {
  68. wordBuffer += 2;
  69. if (wbl > 5 && wordBuffer[0] == '$' && isalpha(wordBuffer[1])) {
  70. unsigned int l = 2;
  71. while (IsEnvironmentVar(wordBuffer[l])) l++;
  72. if (wordBuffer[l] == ':' && IsBatchVar(wordBuffer[l+1]))
  73. return l + 4;
  74. } else
  75. if (wbl > 7 && 0 == CompareNCaseInsensitive(wordBuffer, "dp$", 3) &&
  76. isalpha(wordBuffer[3])) {
  77. unsigned int l = 4;
  78. while (IsEnvironmentVar(wordBuffer[l])) l++;
  79. if (wordBuffer[l] == ':' && IsBatchVar(wordBuffer[l+1]))
  80. return l + 4;
  81. } else
  82. if (wbl > 6 && 0 == CompareNCaseInsensitive(wordBuffer, "ftza", 4) &&
  83. IsBatchVar(wordBuffer[4])) {
  84. return 7;
  85. } else
  86. if (wbl > 4 &&
  87. (0 == CompareNCaseInsensitive(wordBuffer, "dp", 2) ||
  88. 0 == CompareNCaseInsensitive(wordBuffer, "nx", 2) ||
  89. 0 == CompareNCaseInsensitive(wordBuffer, "fs", 2)) &&
  90. IsBatchVar(wordBuffer[2])) {
  91. return 5;
  92. } else
  93. if (wbl > 3 &&
  94. (wordBuffer[0] == 'f' || wordBuffer[0] == 'F' ||
  95. wordBuffer[0] == 'd' || wordBuffer[0] == 'D' ||
  96. wordBuffer[0] == 'p' || wordBuffer[0] == 'P' ||
  97. wordBuffer[0] == 'n' || wordBuffer[0] == 'N' ||
  98. wordBuffer[0] == 'x' || wordBuffer[0] == 'X' ||
  99. wordBuffer[0] == 's' || wordBuffer[0] == 'S' ||
  100. wordBuffer[0] == 'a' || wordBuffer[0] == 'A' ||
  101. wordBuffer[0] == 't' || wordBuffer[0] == 'T' ||
  102. wordBuffer[0] == 'z' || wordBuffer[0] == 'Z') &&
  103. IsBatchVar(wordBuffer[1])) {
  104. return 4;
  105. } else
  106. if (IsBatchVar(wordBuffer[0])) {
  107. return 3;
  108. }
  109. }
  110. return 0;
  111. }
  112. /** similar to InList, but keyword can be a substring of word s.
  113. * eg. the keyword define is defined as def~ or def~e. This means the word must
  114. * start with def and finished with e to be a keyword, but also may have any
  115. * symbols instead of marker.
  116. * The marker is ~ in this case.
  117. * Returns in mainLen - the length of starting part and in finLen - final part.
  118. */
  119. static bool InListPartly(WordList &wl,const char *s, const char marker, int &mainLen, int &finLen) {
  120. if (0 == wl.words || !*s) {
  121. mainLen = finLen = 0;
  122. return false;
  123. }
  124. unsigned char firstChar = s[0];
  125. int j = wl.starts[firstChar];
  126. if (j >= 0) {
  127. while ((unsigned char)wl.words[j][0] == firstChar) {
  128. if (s[1] == wl.words[j][1]) {
  129. const char *a = wl.words[j] + 1;
  130. const char *b = s + 1;
  131. mainLen = finLen = 0;
  132. while (*a && *a != marker && *a == *b) {
  133. a++;
  134. b++;
  135. mainLen++;
  136. }
  137. if (!*a && !*b)
  138. return true;
  139. if (*a == marker) {
  140. while (*a) a++;
  141. while (*b) b++;
  142. finLen = -1;
  143. while (*a != marker && *a == *b) {
  144. a--;
  145. b--;
  146. finLen++;
  147. }
  148. if (*a == marker)
  149. return true;
  150. }
  151. }
  152. j++;
  153. }
  154. }
  155. j = wl.starts['^'];
  156. if (j >= 0) {
  157. while (wl.words[j][0] == '^') {
  158. const char *a = wl.words[j] + 1;
  159. const char *b = s;
  160. mainLen = finLen = 0;
  161. while (*a && *a == *b) {
  162. a++;
  163. b++;
  164. mainLen++;
  165. }
  166. if (!*a)
  167. return true;
  168. j++;
  169. }
  170. }
  171. mainLen = finLen = 0;
  172. return false;
  173. }
  174. //!-end-[BatchLexerImprovement]
  175. static void ColouriseBatchLine(
  176. char *lineBuffer,
  177. unsigned int lengthLine,
  178. unsigned int startLine,
  179. unsigned int endPos,
  180. WordList *keywordlists[],
  181. Accessor &styler) {
  182. unsigned int offset = 0; // Line Buffer Offset
  183. unsigned int cmdLoc; // External Command / Program Location
  184. char wordBuffer[81]; // Word Buffer - large to catch long paths
  185. unsigned int wbl; // Word Buffer Length
  186. unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
  187. WordList &keywords = *keywordlists[0]; // Internal Commands
  188. WordList &keywords2 = *keywordlists[1]; // External Commands (optional)
  189. bool isDelayedExpansion = styler.GetPropertyInt("lexer.batch.enabledelayedexpansion") != 0; //!-add-[BatchLexerImprovement]
  190. // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
  191. // Toggling Regular Keyword Checking off improves readability
  192. // Other Regular Keywords and External Commands / Programs might also benefit from toggling
  193. // Need a more robust algorithm to properly toggle Regular Keyword Checking
  194. bool continueProcessing = true; // Used to toggle Regular Keyword Checking
  195. // Special Keywords are those that allow certain characters without whitespace after the command
  196. // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
  197. bool inString = false; // Used for processing while "" //!-add-[BatchLexerImprovement]
  198. // Special Keyword Buffer used to determine if the first n characters is a Keyword
  199. char sKeywordBuffer[10]; // Special Keyword Buffer
  200. bool sKeywordFound; // Exit Special Keyword for-loop if found
  201. // Skip initial spaces
  202. while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
  203. offset++;
  204. }
  205. // Colorize Default Text
  206. styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
  207. // Set External Command / Program Location
  208. cmdLoc = offset;
  209. // Check for Fake Label (Comment) or Real Label - return if found
  210. if (lineBuffer[offset] == ':') {
  211. if (lineBuffer[offset + 1] == ':') {
  212. // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
  213. styler.ColourTo(endPos, SCE_BAT_COMMENT);
  214. } else {
  215. // Colorize Real Label
  216. styler.ColourTo(endPos, SCE_BAT_LABEL);
  217. }
  218. return;
  219. //!-start-[BatchLexerImprovement]
  220. // Check for Comment - return if found
  221. } else if (CompareNCaseInsensitive(lineBuffer+offset, "rem", 3) == 0 &&
  222. isspacechar(lineBuffer[offset + 3])) {
  223. styler.ColourTo(endPos, SCE_BAT_COMMENT);
  224. return;
  225. //!-end-[BatchLexerImprovement]
  226. // Check for Drive Change (Drive Change is internal command) - return if found
  227. } else if ((IsAlphabetic(lineBuffer[offset])) &&
  228. (lineBuffer[offset + 1] == ':') &&
  229. ((isspacechar(lineBuffer[offset + 2])) ||
  230. (((lineBuffer[offset + 2] == '\\')) &&
  231. (isspacechar(lineBuffer[offset + 3]))))) {
  232. // Colorize Regular Keyword
  233. styler.ColourTo(endPos, SCE_BAT_WORD);
  234. return;
  235. }
  236. // Check for Hide Command (@ECHO OFF/ON)
  237. if (lineBuffer[offset] == '@') {
  238. styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
  239. offset++;
  240. }
  241. // Skip next spaces
  242. while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
  243. offset++;
  244. }
  245. // Read remainder of line word-at-a-time or remainder-of-word-at-a-time
  246. while (offset < lengthLine) {
  247. if (offset > startLine) {
  248. // Colorize Default Text
  249. styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
  250. }
  251. // Copy word from Line Buffer into Word Buffer
  252. wbl = 0;
  253. for (; offset < lengthLine && wbl < 80 &&
  254. !isspacechar(lineBuffer[offset]); wbl++, offset++) {
  255. wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
  256. }
  257. wordBuffer[wbl] = '\0';
  258. wbo = 0;
  259. /*!-start-remove-[BatchLexerImprovement]
  260. // REM is comment only when it's a first word in line
  261. // Check for Comment - return if found
  262. if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
  263. styler.ColourTo(endPos, SCE_BAT_COMMENT);
  264. return;
  265. }
  266. */ //!-end-remove-[BatchLexerImprovement]
  267. // Check for Separator
  268. if (IsBSeparator(wordBuffer[0])) {
  269. // Check for External Command / Program
  270. if ((cmdLoc == offset - wbl) &&
  271. ((wordBuffer[0] == ':') ||
  272. (wordBuffer[0] == '\\') ||
  273. (wordBuffer[0] == '.'))) {
  274. // Reset Offset to re-process remainder of word
  275. offset -= (wbl - 1);
  276. // Colorize External Command / Program
  277. if (!keywords2) {
  278. styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
  279. } else if (keywords2.InList(wordBuffer)) {
  280. styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
  281. } else {
  282. styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
  283. }
  284. // Reset External Command / Program Location
  285. cmdLoc = offset;
  286. } else {
  287. // Reset Offset to re-process remainder of word
  288. offset -= (wbl - 1);
  289. // Colorize Default Text
  290. styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
  291. //!-start-[BatchLexerImprovement]
  292. if (wordBuffer[0] == '"')
  293. inString = !inString;
  294. //!-end-[BatchLexerImprovement]
  295. }
  296. //!-start-[BatchLexerImprovement]
  297. // Check for Labels in text (... :label)
  298. } else if (wordBuffer[0] == ':' && isspacechar(lineBuffer[offset - wbl - 1])) {
  299. // Colorize Default Text
  300. styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
  301. // Colorize Label
  302. styler.ColourTo(startLine + offset - 1, SCE_BAT_CLABEL);
  303. // No need to Reset Offset
  304. // Check for SetLocal Variable (!x...!)
  305. } else if (isDelayedExpansion && wordBuffer[0] == '!') {
  306. // Colorize Default Text
  307. styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
  308. wbo++;
  309. // Search to end of word for second !
  310. while ((wbo < wbl) &&
  311. (wordBuffer[wbo] != '!') &&
  312. (!IsBOperator(wordBuffer[wbo])) &&
  313. (!IsBSeparator(wordBuffer[wbo]))) {
  314. wbo++;
  315. }
  316. if (wordBuffer[wbo] == '!') {
  317. wbo++;
  318. // Colorize Environment Variable
  319. styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_EXPANSION);
  320. } else {
  321. wbo = 1;
  322. // Colorize Simbol
  323. styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_DEFAULT);
  324. }
  325. // Check for External Command / Program
  326. if (cmdLoc == offset - wbl) {
  327. cmdLoc = offset - (wbl - wbo);
  328. }
  329. // Reset Offset to re-process remainder of word
  330. offset -= (wbl - wbo);
  331. //!-end-[BatchLexerImprovement]
  332. // Check for Regular Keyword in list
  333. } else if ((keywords.InList(wordBuffer)) &&
  334. (!inString) && //!-add-[BatchLexerImprovement]
  335. (continueProcessing)) {
  336. // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
  337. if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
  338. (CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
  339. (CompareCaseInsensitive(wordBuffer, "prompt") == 0) ||
  340. (CompareCaseInsensitive(wordBuffer, "set") == 0)) {
  341. continueProcessing = false;
  342. }
  343. // Identify External Command / Program Location for ERRORLEVEL, and EXIST
  344. if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
  345. (CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
  346. // Reset External Command / Program Location
  347. cmdLoc = offset;
  348. // Skip next spaces
  349. while ((cmdLoc < lengthLine) &&
  350. (isspacechar(lineBuffer[cmdLoc]))) {
  351. cmdLoc++;
  352. }
  353. // Skip comparison
  354. while ((cmdLoc < lengthLine) &&
  355. (!isspacechar(lineBuffer[cmdLoc]))) {
  356. cmdLoc++;
  357. }
  358. // Skip next spaces
  359. while ((cmdLoc < lengthLine) &&
  360. (isspacechar(lineBuffer[cmdLoc]))) {
  361. cmdLoc++;
  362. }
  363. // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
  364. } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
  365. (CompareCaseInsensitive(wordBuffer, "do") == 0) ||
  366. (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
  367. (CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
  368. // Reset External Command / Program Location
  369. cmdLoc = offset;
  370. // Skip next spaces
  371. while ((cmdLoc < lengthLine) &&
  372. (isspacechar(lineBuffer[cmdLoc]))) {
  373. cmdLoc++;
  374. }
  375. }
  376. // Colorize Regular keyword
  377. styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
  378. // No need to Reset Offset
  379. // Check for Special Keyword in list, External Command / Program, or Default Text
  380. } else if ((wordBuffer[0] != '%') &&
  381. (wordBuffer[0] != '!') &&
  382. (!IsBOperator(wordBuffer[0])) &&
  383. (!inString) && //!-add-[BatchLexerImprovement]
  384. (continueProcessing)) {
  385. // Check for Special Keyword
  386. // Affected Commands are in Length range 2-6
  387. // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
  388. sKeywordFound = false;
  389. for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
  390. wbo = 0;
  391. // Copy Keyword Length from Word Buffer into Special Keyword Buffer
  392. for (; wbo < keywordLength; wbo++) {
  393. sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
  394. }
  395. sKeywordBuffer[wbo] = '\0';
  396. // Check for Special Keyword in list
  397. if ((keywords.InList(sKeywordBuffer)) &&
  398. ((IsBOperator(wordBuffer[wbo])) ||
  399. (IsBSeparator(wordBuffer[wbo])))) {
  400. sKeywordFound = true;
  401. // ECHO requires no further Regular Keyword Checking
  402. if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
  403. continueProcessing = false;
  404. }
  405. // Colorize Special Keyword as Regular Keyword
  406. styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
  407. // Reset Offset to re-process remainder of word
  408. offset -= (wbl - wbo);
  409. }
  410. }
  411. // Check for External Command / Program or Default Text
  412. if (!sKeywordFound) {
  413. wbo = 0;
  414. // Check for External Command / Program
  415. if (cmdLoc == offset - wbl) {
  416. // Read up to %, Operator or Separator
  417. while ((wbo < wbl) &&
  418. (wordBuffer[wbo] != '%') &&
  419. //! (wordBuffer[wbo] != '!') &&
  420. (!isDelayedExpansion || wordBuffer[wbo] != '!') && //!-change-[BatchLexerImprovement]
  421. (!IsBOperator(wordBuffer[wbo])) &&
  422. (!IsBSeparator(wordBuffer[wbo]))) {
  423. wbo++;
  424. }
  425. // Reset External Command / Program Location
  426. cmdLoc = offset - (wbl - wbo);
  427. // Reset Offset to re-process remainder of word
  428. offset -= (wbl - wbo);
  429. // CHOICE requires no further Regular Keyword Checking
  430. if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
  431. continueProcessing = false;
  432. }
  433. // Check for START (and its switches) - What follows is External Command \ Program
  434. if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
  435. // Reset External Command / Program Location
  436. cmdLoc = offset;
  437. // Skip next spaces
  438. while ((cmdLoc < lengthLine) &&
  439. (isspacechar(lineBuffer[cmdLoc]))) {
  440. cmdLoc++;
  441. }
  442. // Reset External Command / Program Location if command switch detected
  443. if (lineBuffer[cmdLoc] == '/') {
  444. // Skip command switch
  445. while ((cmdLoc < lengthLine) &&
  446. (!isspacechar(lineBuffer[cmdLoc]))) {
  447. cmdLoc++;
  448. }
  449. // Skip next spaces
  450. while ((cmdLoc < lengthLine) &&
  451. (isspacechar(lineBuffer[cmdLoc]))) {
  452. cmdLoc++;
  453. }
  454. }
  455. }
  456. // Colorize External Command / Program
  457. if (!keywords2) {
  458. styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
  459. } else if (keywords2.InList(wordBuffer)) {
  460. styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
  461. } else {
  462. styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
  463. }
  464. // No need to Reset Offset
  465. // Check for Default Text
  466. } else {
  467. // Read up to %, Operator or Separator
  468. while ((wbo < wbl) &&
  469. (wordBuffer[wbo] != '%') &&
  470. //! (wordBuffer[wbo] != '!') &&
  471. (!isDelayedExpansion || wordBuffer[wbo] != '!') && //!-change-[BatchLexerImprovement]
  472. (!IsBOperator(wordBuffer[wbo])) &&
  473. (!IsBSeparator(wordBuffer[wbo]))) {
  474. wbo++;
  475. }
  476. // Colorize Default Text
  477. styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
  478. // Reset Offset to re-process remainder of word
  479. offset -= (wbl - wbo);
  480. }
  481. }
  482. // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
  483. } else if (wordBuffer[0] == '%') {
  484. unsigned int varlen; //!-add-[BatchLexerImprovement]
  485. // Colorize Default Text
  486. styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
  487. wbo++;
  488. // Search to end of word for second % (can be a long path)
  489. while ((wbo < wbl) &&
  490. (wordBuffer[wbo] != '%') &&
  491. (!IsBOperator(wordBuffer[wbo])) &&
  492. (!IsBSeparator(wordBuffer[wbo]))) {
  493. wbo++;
  494. }
  495. // Check for Argument (%n) or (%*)
  496. if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
  497. (wordBuffer[wbo] != '%')) {
  498. // Check for External Command / Program
  499. if (cmdLoc == offset - wbl) {
  500. cmdLoc = offset - (wbl - 2);
  501. }
  502. // Colorize Argument
  503. styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
  504. // Reset Offset to re-process remainder of word
  505. offset -= (wbl - 2);
  506. // Check for Expanded Argument (%~...) / Variable (%%~...)
  507. } else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
  508. ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
  509. // Check for External Command / Program
  510. if (cmdLoc == offset - wbl) {
  511. cmdLoc = offset - (wbl - wbo);
  512. }
  513. // Colorize Expanded Argument / Variable
  514. styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
  515. // Reset Offset to re-process remainder of word
  516. offset -= (wbl - wbo);
  517. // Check for Environment Variable (%x...%)
  518. } else if ((wordBuffer[1] != '%') &&
  519. (wordBuffer[wbo] == '%')) {
  520. wbo++;
  521. // Check for External Command / Program
  522. if (cmdLoc == offset - wbl) {
  523. cmdLoc = offset - (wbl - wbo);
  524. }
  525. // Colorize Environment Variable
  526. //! styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
  527. styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_ENVIRONMENT); //!-change-[BatchLexerImprovement]
  528. // Reset Offset to re-process remainder of word
  529. offset -= (wbl - wbo);
  530. //!-start-[BatchLexerImprovement]
  531. // Check for Variable with modifiers (%~...)
  532. } else if ((varlen = GetBatchVarLen(wordBuffer, wbl)) != 0) {
  533. // Check for External Command / Program
  534. if (cmdLoc == offset - wbl) {
  535. cmdLoc = offset - (wbl - varlen);
  536. }
  537. // Colorize Variable
  538. styler.ColourTo(startLine + offset - 1 - (wbl - varlen), SCE_BAT_IDENTIFIER);
  539. // Reset Offset to re-process remainder of word
  540. offset -= (wbl - varlen);
  541. // Check for Local Variable with modifiers (%%~...)
  542. } else if ((wordBuffer[1] == '%') &&
  543. ((varlen = GetBatchVarLen(wordBuffer+1, wbl-1)) != 0)) {
  544. // Check for External Command / Program
  545. if (cmdLoc == offset - wbl) {
  546. cmdLoc = offset - (wbl - varlen - 1);
  547. }
  548. // Colorize Local Variable
  549. styler.ColourTo(startLine + offset - 1 - (wbl - varlen - 1), SCE_BAT_IDENTIFIER);
  550. // Reset Offset to re-process remainder of word
  551. offset -= (wbl - varlen - 1);
  552. //!-end-[BatchLexerImprovement]
  553. // Check for Local Variable (%%a)
  554. } else if (
  555. (wbl > 2) &&
  556. (wordBuffer[1] == '%') &&
  557. (wordBuffer[2] != '%') &&
  558. (!IsBOperator(wordBuffer[2])) &&
  559. (!IsBSeparator(wordBuffer[2]))) {
  560. // Check for External Command / Program
  561. if (cmdLoc == offset - wbl) {
  562. cmdLoc = offset - (wbl - 3);
  563. }
  564. // Colorize Local Variable
  565. styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
  566. // Reset Offset to re-process remainder of word
  567. offset -= (wbl - 3);
  568. //!-start-[BatchLexerImprovement]
  569. // Check for %%
  570. } else if (
  571. (wbl > 1) &&
  572. (wordBuffer[1] == '%')) {
  573. // Check for External Command / Program
  574. if (cmdLoc == offset - wbl) {
  575. cmdLoc = offset - (wbl - 2);
  576. }
  577. // Colorize Simbols
  578. styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_DEFAULT);
  579. // Reset Offset to re-process remainder of word
  580. offset -= (wbl - 2);
  581. } else {
  582. // Check for External Command / Program
  583. if (cmdLoc == offset - wbl) {
  584. cmdLoc = offset - (wbl - 1);
  585. }
  586. // Colorize Simbol
  587. styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_DEFAULT);
  588. // Reset Offset to re-process remainder of word
  589. offset -= (wbl - 1);
  590. //!-end-[BatchLexerImprovement]
  591. }
  592. // Check for Environment Variable (!x...!)
  593. } else if (wordBuffer[0] == '!') {
  594. // Colorize Default Text
  595. styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
  596. wbo++;
  597. // Search to end of word for second ! (can be a long path)
  598. while ((wbo < wbl) &&
  599. (wordBuffer[wbo] != '!') &&
  600. (!IsBOperator(wordBuffer[wbo])) &&
  601. (!IsBSeparator(wordBuffer[wbo]))) {
  602. wbo++;
  603. }
  604. if (wordBuffer[wbo] == '!') {
  605. wbo++;
  606. // Check for External Command / Program
  607. if (cmdLoc == offset - wbl) {
  608. cmdLoc = offset - (wbl - wbo);
  609. }
  610. // Colorize Environment Variable
  611. styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
  612. // Reset Offset to re-process remainder of word
  613. offset -= (wbl - wbo);
  614. }
  615. // Check for Operator
  616. } else if (IsBOperator(wordBuffer[0])) {
  617. // Colorize Default Text
  618. styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
  619. // Check for Comparison Operator
  620. if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
  621. // Identify External Command / Program Location for IF
  622. cmdLoc = offset;
  623. // Skip next spaces
  624. while ((cmdLoc < lengthLine) &&
  625. (isspacechar(lineBuffer[cmdLoc]))) {
  626. cmdLoc++;
  627. }
  628. // Colorize Comparison Operator
  629. styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
  630. // Reset Offset to re-process remainder of word
  631. offset -= (wbl - 2);
  632. // Check for Pipe Operator
  633. } else if (wordBuffer[0] == '|') {
  634. // Reset External Command / Program Location
  635. cmdLoc = offset - wbl + 1;
  636. // Skip next spaces
  637. while ((cmdLoc < lengthLine) &&
  638. (isspacechar(lineBuffer[cmdLoc]))) {
  639. cmdLoc++;
  640. }
  641. // Colorize Pipe Operator
  642. styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
  643. // Reset Offset to re-process remainder of word
  644. offset -= (wbl - 1);
  645. // Check for Other Operator
  646. } else {
  647. // Check for > Operator
  648. if (wordBuffer[0] == '>') {
  649. // Turn Keyword and External Command / Program checking back on
  650. continueProcessing = true;
  651. }
  652. // Colorize Other Operator
  653. if (!inString || !(wordBuffer[0] == '(' || wordBuffer[0] == ')')) //!-add-[BatchLexerImprovement]
  654. styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
  655. // Reset Offset to re-process remainder of word
  656. offset -= (wbl - 1);
  657. }
  658. // Check for Default Text
  659. } else {
  660. // Read up to %, Operator or Separator
  661. while ((wbo < wbl) &&
  662. (wordBuffer[wbo] != '%') &&
  663. //! (wordBuffer[wbo] != '!') &&
  664. (!isDelayedExpansion || wordBuffer[wbo] != '!') && //!-add-[BatchLexerImprovement]
  665. (!IsBOperator(wordBuffer[wbo])) &&
  666. (!IsBSeparator(wordBuffer[wbo]))) {
  667. wbo++;
  668. }
  669. // Colorize Default Text
  670. styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
  671. // Reset Offset to re-process remainder of word
  672. offset -= (wbl - wbo);
  673. }
  674. // Skip next spaces - nothing happens if Offset was Reset
  675. while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
  676. offset++;
  677. }
  678. }
  679. // Colorize Default Text for remainder of line - currently not lexed
  680. styler.ColourTo(endPos, SCE_BAT_DEFAULT);
  681. }
  682. static void ColouriseBatchDoc(
  683. unsigned int startPos,
  684. int length,
  685. int /*initStyle*/,
  686. WordList *keywordlists[],
  687. Accessor &styler) {
  688. char lineBuffer[1024];
  689. styler.StartAt(startPos);
  690. styler.StartSegment(startPos);
  691. unsigned int linePos = 0;
  692. unsigned int startLine = startPos;
  693. for (unsigned int i = startPos; i < startPos + length; i++) {
  694. lineBuffer[linePos++] = styler[i];
  695. if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
  696. // End of line (or of line buffer) met, colourise it
  697. lineBuffer[linePos] = '\0';
  698. ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler);
  699. linePos = 0;
  700. startLine = i + 1;
  701. }
  702. }
  703. if (linePos > 0) { // Last line does not have ending characters
  704. lineBuffer[linePos] = '\0';
  705. ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
  706. keywordlists, styler);
  707. }
  708. }
  709. //!-start-[BatchLexerImprovement]
  710. static void FoldBatchDoc(unsigned int startPos, int length, int,
  711. WordList *[], Accessor &styler)
  712. {
  713. int line = styler.GetLine(startPos);
  714. int level = styler.LevelAt(line);
  715. int levelIndent = 0;
  716. unsigned int endPos = startPos + length;
  717. // Scan for ( and )
  718. for (unsigned int i = startPos; i < endPos; i++) {
  719. int c = styler.SafeGetCharAt(i, '\n');
  720. int style = styler.StyleAt(i);
  721. if (style == SCE_BAT_OPERATOR) {
  722. // CheckFoldPoint
  723. if (c == '(') {
  724. levelIndent += 1;
  725. } else
  726. if (c == ')') {
  727. levelIndent -= 1;
  728. }
  729. }
  730. if (c == '\n') { // line end
  731. if (levelIndent > 0) {
  732. level |= SC_FOLDLEVELHEADERFLAG;
  733. }
  734. if (level != styler.LevelAt(line))
  735. styler.SetLevel(line, level);
  736. level += levelIndent;
  737. if ((level & SC_FOLDLEVELNUMBERMASK) < SC_FOLDLEVELBASE)
  738. level = SC_FOLDLEVELBASE;
  739. line++;
  740. // reset state
  741. levelIndent = 0;
  742. level &= ~SC_FOLDLEVELHEADERFLAG;
  743. level &= ~SC_FOLDLEVELWHITEFLAG;
  744. }
  745. }
  746. }
  747. //!-end-[BatchLexerImprovement]
  748. static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
  749. // It is needed to remember the current state to recognize starting
  750. // comment lines before the first "diff " or "--- ". If a real
  751. // difference starts then each line starting with ' ' is a whitespace
  752. // otherwise it is considered a comment (Only in..., Binary file...)
  753. if (0 == strncmp(lineBuffer, "diff ", 5)) {
  754. styler.ColourTo(endLine, SCE_DIFF_COMMAND);
  755. } else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff
  756. styler.ColourTo(endLine, SCE_DIFF_COMMAND);
  757. } else if (0 == strncmp(lineBuffer, "---", 3)) {
  758. // In a context diff, --- appears in both the header and the position markers
  759. if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
  760. styler.ColourTo(endLine, SCE_DIFF_POSITION);
  761. else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
  762. styler.ColourTo(endLine, SCE_DIFF_POSITION);
  763. else
  764. styler.ColourTo(endLine, SCE_DIFF_HEADER);
  765. } else if (0 == strncmp(lineBuffer, "+++ ", 4)) {
  766. // I don't know of any diff where "+++ " is a position marker, but for
  767. // consistency, do the same as with "--- " and "*** ".
  768. if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
  769. styler.ColourTo(endLine, SCE_DIFF_POSITION);
  770. else
  771. styler.ColourTo(endLine, SCE_DIFF_HEADER);
  772. } else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff
  773. styler.ColourTo(endLine, SCE_DIFF_HEADER);
  774. } else if (0 == strncmp(lineBuffer, "***", 3)) {
  775. // In a context diff, *** appears in both the header and the position markers.
  776. // Also ******** is a chunk header, but here it's treated as part of the
  777. // position marker since there is no separate style for a chunk header.
  778. if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
  779. styler.ColourTo(endLine, SCE_DIFF_POSITION);
  780. else if (lineBuffer[3] == '*')
  781. styler.ColourTo(endLine, SCE_DIFF_POSITION);
  782. else
  783. styler.ColourTo(endLine, SCE_DIFF_HEADER);
  784. } else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib
  785. styler.ColourTo(endLine, SCE_DIFF_HEADER);
  786. } else if (lineBuffer[0] == '@') {
  787. styler.ColourTo(endLine, SCE_DIFF_POSITION);
  788. } else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') {
  789. styler.ColourTo(endLine, SCE_DIFF_POSITION);
  790. } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
  791. styler.ColourTo(endLine, SCE_DIFF_DELETED);
  792. } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
  793. styler.ColourTo(endLine, SCE_DIFF_ADDED);
  794. } else if (lineBuffer[0] == '!') {
  795. styler.ColourTo(endLine, SCE_DIFF_CHANGED);
  796. } else if (lineBuffer[0] != ' ') {
  797. styler.ColourTo(endLine, SCE_DIFF_COMMENT);
  798. } else {
  799. styler.ColourTo(endLine, SCE_DIFF_DEFAULT);
  800. }
  801. }
  802. static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  803. char lineBuffer[1024];
  804. styler.StartAt(startPos);
  805. styler.StartSegment(startPos);
  806. unsigned int linePos = 0;
  807. for (unsigned int i = startPos; i < startPos + length; i++) {
  808. lineBuffer[linePos++] = styler[i];
  809. if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
  810. // End of line (or of line buffer) met, colourise it
  811. lineBuffer[linePos] = '\0';
  812. ColouriseDiffLine(lineBuffer, i, styler);
  813. linePos = 0;
  814. }
  815. }
  816. if (linePos > 0) { // Last line does not have ending characters
  817. ColouriseDiffLine(lineBuffer, startPos + length - 1, styler);
  818. }
  819. }
  820. static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  821. int curLine = styler.GetLine(startPos);
  822. int curLineStart = styler.LineStart(curLine);
  823. int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE;
  824. int nextLevel;
  825. do {
  826. int lineType = styler.StyleAt(curLineStart);
  827. if (lineType == SCE_DIFF_COMMAND)
  828. nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
  829. else if (lineType == SCE_DIFF_HEADER)
  830. nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
  831. else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-')
  832. nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
  833. else if (prevLevel & SC_FOLDLEVELHEADERFLAG)
  834. nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
  835. else
  836. nextLevel = prevLevel;
  837. if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
  838. styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
  839. styler.SetLevel(curLine, nextLevel);
  840. prevLevel = nextLevel;
  841. curLineStart = styler.LineStart(++curLine);
  842. } while (static_cast<int>(startPos) + length > curLineStart);
  843. }
  844. static void ColourisePoLine(
  845. char *lineBuffer,
  846. unsigned int lengthLine,
  847. unsigned int startLine,
  848. unsigned int endPos,
  849. Accessor &styler) {
  850. unsigned int i = 0;
  851. static unsigned int state = SCE_PO_DEFAULT;
  852. unsigned int state_start = SCE_PO_DEFAULT;
  853. while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
  854. i++;
  855. if (i < lengthLine) {
  856. if (lineBuffer[i] == '#') {
  857. // check if the comment contains any flags ("#, ") and
  858. // then whether the flags contain "fuzzy"
  859. if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
  860. styler.ColourTo(endPos, SCE_PO_FUZZY);
  861. else
  862. styler.ColourTo(endPos, SCE_PO_COMMENT);
  863. } else {
  864. if (lineBuffer[0] == '"') {
  865. // line continuation, use previous style
  866. styler.ColourTo(endPos, state);
  867. return;
  868. // this implicitly also matches "msgid_plural"
  869. } else if (strstart(lineBuffer, "msgid")) {
  870. state_start = SCE_PO_MSGID;
  871. state = SCE_PO_MSGID_TEXT;
  872. } else if (strstart(lineBuffer, "msgstr")) {
  873. state_start = SCE_PO_MSGSTR;
  874. state = SCE_PO_MSGSTR_TEXT;
  875. } else if (strstart(lineBuffer, "msgctxt")) {
  876. state_start = SCE_PO_MSGCTXT;
  877. state = SCE_PO_MSGCTXT_TEXT;
  878. }
  879. if (state_start != SCE_PO_DEFAULT) {
  880. // find the next space
  881. while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
  882. i++;
  883. styler.ColourTo(startLine + i - 1, state_start);
  884. styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
  885. styler.ColourTo(endPos, state);
  886. }
  887. }
  888. } else {
  889. styler.ColourTo(endPos, SCE_PO_DEFAULT);
  890. }
  891. }
  892. static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  893. char lineBuffer[1024];
  894. styler.StartAt(startPos);
  895. styler.StartSegment(startPos);
  896. unsigned int linePos = 0;
  897. unsigned int startLine = startPos;
  898. for (unsigned int i = startPos; i < startPos + length; i++) {
  899. lineBuffer[linePos++] = styler[i];
  900. if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
  901. // End of line (or of line buffer) met, colourise it
  902. lineBuffer[linePos] = '\0';
  903. ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
  904. linePos = 0;
  905. startLine = i + 1;
  906. }
  907. }
  908. if (linePos > 0) { // Last line does not have ending characters
  909. ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
  910. }
  911. }
  912. static inline bool isassignchar(unsigned char ch) {
  913. return (ch == '=') || (ch == ':');
  914. }
  915. //!-start-[PropsKeywords]
  916. static bool isprefix(const char *target, const char *prefix) {
  917. while (*target && *prefix) {
  918. if (*target != *prefix)
  919. return false;
  920. target++;
  921. prefix++;
  922. }
  923. if (*prefix)
  924. return false;
  925. else
  926. return true;
  927. }
  928. //!-end-[PropsKeywords]
  929. //!static void ColourisePropsLine(
  930. static char ColourisePropsLine( // return last style //!-change-[PropsColouriseFix]
  931. char *lineBuffer,
  932. unsigned int lengthLine,
  933. unsigned int startLine,
  934. unsigned int endPos,
  935. WordList *keywordlists[], //!-add-[PropsKeysSets]
  936. Accessor &styler,
  937. bool allowInitialSpaces) {
  938. unsigned int i = 0;
  939. if (allowInitialSpaces) {
  940. while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
  941. i++;
  942. } else {
  943. if (isspacechar(lineBuffer[i])) // don't allow initial spaces
  944. i = lengthLine;
  945. }
  946. if (i < lengthLine) {
  947. if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
  948. styler.ColourTo(endPos, SCE_PROPS_COMMENT);
  949. return SCE_PROPS_COMMENT; //!-add-[PropsColouriseFix]
  950. } else if (lineBuffer[i] == '[') {
  951. styler.ColourTo(endPos, SCE_PROPS_SECTION);
  952. return SCE_PROPS_SECTION; //!-add-[PropsColouriseFix]
  953. } else if (lineBuffer[i] == '@') {
  954. styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL);
  955. if (isassignchar(lineBuffer[i++]))
  956. styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
  957. styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
  958. //!-start-[PropsKeywords]
  959. } else if (isprefix(lineBuffer, "import ")) {
  960. styler.ColourTo(startLine + 6, SCE_PROPS_KEYWORD);
  961. styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
  962. } else if (isprefix(lineBuffer, "if ")) {
  963. styler.ColourTo(startLine + 2, SCE_PROPS_KEYWORD);
  964. styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
  965. //!-end-[PropsKeywords]
  966. } else {
  967. // Search for the '=' character
  968. while ((i < lengthLine) && !isassignchar(lineBuffer[i]))
  969. i++;
  970. if ((i < lengthLine) && isassignchar(lineBuffer[i])) {
  971. //! styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);
  972. //!-start-[PropsKeysSets]
  973. if (i > 0) {
  974. int chAttr;
  975. lineBuffer[i] = '\0';
  976. // remove trailing spaces
  977. int indent = 0;
  978. while (lineBuffer[0] == ' ' || lineBuffer[0] == '\t') {
  979. lineBuffer++;
  980. indent++;
  981. }
  982. int len=0, fin=0;
  983. if (InListPartly(*keywordlists[0],lineBuffer, '~', len, fin)) {
  984. chAttr = SCE_PROPS_KEYSSET0;
  985. } else if (InListPartly(*keywordlists[1],lineBuffer, '~', len, fin)) {
  986. chAttr = SCE_PROPS_KEYSSET1;
  987. } else if (InListPartly(*keywordlists[2],lineBuffer, '~', len, fin)) {
  988. chAttr = SCE_PROPS_KEYSSET2;
  989. } else if (InListPartly(*keywordlists[3],lineBuffer, '~', len, fin)) {
  990. chAttr = SCE_PROPS_KEYSSET3;
  991. } else {
  992. chAttr = SCE_PROPS_KEY;
  993. }
  994. styler.ColourTo(startLine + indent + len, chAttr);
  995. styler.ColourTo(startLine + i - 1 - fin, SCE_PROPS_KEY);
  996. styler.ColourTo(startLine + i - 1, chAttr);
  997. }
  998. //!-end-[PropsKeysSets]
  999. styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
  1000. styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
  1001. } else {
  1002. styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
  1003. }
  1004. }
  1005. } else {
  1006. styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
  1007. }
  1008. return SCE_PROPS_DEFAULT; //!-add-[PropsColouriseFix]
  1009. }
  1010. //!static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  1011. static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) { //!-change-[PropsKeysSets]
  1012. char lineBuffer[1024];
  1013. styler.StartAt(startPos);
  1014. styler.StartSegment(startPos);
  1015. unsigned int linePos = 0;
  1016. unsigned int startLine = startPos;
  1017. // property lexer.props.allow.initial.spaces
  1018. // For properties files, set to 0 to style all lines that start with whitespace in the default style.
  1019. // This is not suitable for SciTE .properties files which use indentation for flow control but
  1020. // can be used for RFC2822 text where indentation is used for continuation lines.
  1021. bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
  1022. //!-start-[PropsColouriseFix]
  1023. char style = 0;
  1024. bool continuation = false;
  1025. if (startPos >= 3)
  1026. continuation = styler.StyleAt(startPos-2) != SCE_PROPS_COMMENT && ((styler[startPos-2] == '\\')
  1027. || (styler[startPos-3] == '\\' && styler[startPos-2] == '\r'));
  1028. //!-end-[PropsColouriseFix]
  1029. for (unsigned int i = startPos; i < startPos + length; i++) {
  1030. lineBuffer[linePos++] = styler[i];
  1031. if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
  1032. // End of line (or of line buffer) met, colourise it
  1033. lineBuffer[linePos] = '\0';
  1034. //! ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces);
  1035. //!-start-[PropsColouriseFix][PropsKeysSets]
  1036. if (continuation)
  1037. styler.ColourTo(i, SCE_PROPS_DEFAULT);
  1038. else
  1039. style = ColourisePropsLine(lineBuffer, linePos, startLine, i, keywordlists, styler, allowInitialSpaces);
  1040. // test: is next a continuation of line
  1041. continuation = (linePos >= sizeof(lineBuffer) - 1) ||
  1042. (style != SCE_PROPS_COMMENT && ((lineBuffer[linePos-2] == '\\')
  1043. || (lineBuffer[linePos-3] == '\\' && lineBuffer[linePos-2] == '\r')));
  1044. //!-end-[PropsColouriseFix][PropsKeysSets]
  1045. linePos = 0;
  1046. startLine = i + 1;
  1047. }
  1048. }
  1049. if (linePos > 0) { // Last line does not have ending characters
  1050. //!-start-[PropsColouriseFix]
  1051. if (continuation)
  1052. styler.ColourTo(startPos + length - 1, SCE_PROPS_DEFAULT);
  1053. else
  1054. //!-end-[PropsColouriseFix]
  1055. //! ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces);
  1056. ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, keywordlists, styler, allowInitialSpaces); //!-change-[PropsKeysSets]
  1057. }
  1058. }
  1059. // adaption by ksc, using the "} else {" trick of 1.53
  1060. // 030721
  1061. static void FoldPropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  1062. bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  1063. unsigned int endPos = startPos + length;
  1064. int visibleChars = 0;
  1065. int lineCurrent = styler.GetLine(startPos);
  1066. char chNext = styler[startPos];
  1067. int styleNext = styler.StyleAt(startPos);
  1068. bool headerPoint = false;
  1069. int lev;
  1070. for (unsigned int i = startPos; i < endPos; i++) {
  1071. char ch = chNext;
  1072. chNext = styler[i+1];
  1073. int style = styleNext;
  1074. styleNext = styler.StyleAt(i + 1);
  1075. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  1076. if (style == SCE_PROPS_SECTION) {
  1077. headerPoint = true;
  1078. }
  1079. if (atEOL) {
  1080. lev = SC_FOLDLEVELBASE;
  1081. if (lineCurrent > 0) {
  1082. int levelPrevious = styler.LevelAt(lineCurrent - 1);
  1083. if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
  1084. lev = SC_FOLDLEVELBASE + 1;
  1085. } else {
  1086. lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
  1087. }
  1088. }
  1089. if (headerPoint) {
  1090. lev = SC_FOLDLEVELBASE;
  1091. }
  1092. if (visibleChars == 0 && foldCompact)
  1093. lev |= SC_FOLDLEVELWHITEFLAG;
  1094. if (headerPoint) {
  1095. lev |= SC_FOLDLEVELHEADERFLAG;
  1096. }
  1097. if (lev != styler.LevelAt(lineCurrent)) {
  1098. styler.SetLevel(lineCurrent, lev);
  1099. }
  1100. lineCurrent++;
  1101. visibleChars = 0;
  1102. headerPoint = false;
  1103. }
  1104. if (!isspacechar(ch))
  1105. visibleChars++;
  1106. }
  1107. if (lineCurrent > 0) {
  1108. int levelPrevious = styler.LevelAt(lineCurrent - 1);
  1109. if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
  1110. lev = SC_FOLDLEVELBASE + 1;
  1111. } else {
  1112. lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
  1113. }
  1114. } else {
  1115. lev = SC_FOLDLEVELBASE;
  1116. }
  1117. int flagsNext = styler.LevelAt(lineCurrent);
  1118. styler.SetLevel(lineCurrent, lev | (flagsNext & ~SC_FOLDLEVELNUMBERMASK));
  1119. }
  1120. static void ColouriseMakeLine(
  1121. char *lineBuffer,
  1122. unsigned int lengthLine,
  1123. unsigned int startLine,
  1124. unsigned int endPos,
  1125. Accessor &styler) {
  1126. unsigned int i = 0;
  1127. int lastNonSpace = -1;
  1128. unsigned int state = SCE_MAKE_DEFAULT;
  1129. bool bSpecial = false;
  1130. // check for a tab character in column 0 indicating a command
  1131. bool bCommand = false;
  1132. if ((lengthLine > 0) && (lineBuffer[0] == '\t'))
  1133. bCommand = true;
  1134. // Skip initial spaces
  1135. while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
  1136. i++;
  1137. }
  1138. if (lineBuffer[i] == '#') { // Comment
  1139. styler.ColourTo(endPos, SCE_MAKE_COMMENT);
  1140. return;
  1141. }
  1142. if (lineBuffer[i] == '!') { // Special directive
  1143. styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
  1144. return;
  1145. }
  1146. while (i < lengthLine) {
  1147. if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
  1148. styler.ColourTo(startLine + i - 1, state);
  1149. state = SCE_MAKE_IDENTIFIER;
  1150. } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
  1151. styler.ColourTo(startLine + i, state);
  1152. state = SCE_MAKE_DEFAULT;
  1153. }
  1154. // skip identifier and target styling if this is a command line
  1155. if (!bSpecial && !bCommand) {
  1156. if (lineBuffer[i] == ':') {
  1157. if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) {
  1158. // it's a ':=', so style as an identifier
  1159. if (lastNonSpace >= 0)
  1160. styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
  1161. styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
  1162. styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR);
  1163. } else {
  1164. // We should check that no colouring was made since the beginning of the line,
  1165. // to avoid colouring stuff like /OUT:file
  1166. if (lastNonSpace >= 0)
  1167. styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
  1168. styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
  1169. styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
  1170. }
  1171. bSpecial = true; // Only react to the first ':' of the line
  1172. state = SCE_MAKE_DEFAULT;
  1173. } else if (lineBuffer[i] == '=') {
  1174. if (lastNonSpace >= 0)
  1175. styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
  1176. styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
  1177. styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
  1178. bSpecial = true; // Only react to the first '=' of the line
  1179. state = SCE_MAKE_DEFAULT;
  1180. }
  1181. }
  1182. if (!isspacechar(lineBuffer[i])) {
  1183. lastNonSpace = i;
  1184. }
  1185. i++;
  1186. }
  1187. if (state == SCE_MAKE_IDENTIFIER) {
  1188. styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended
  1189. } else {
  1190. styler.ColourTo(endPos, SCE_MAKE_DEFAULT);
  1191. }
  1192. }
  1193. static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  1194. char lineBuffer[1024];
  1195. styler.StartAt(startPos);
  1196. styler.StartSegment(startPos);
  1197. unsigned int linePos = 0;
  1198. unsigned int startLine = startPos;
  1199. for (unsigned int i = startPos; i < startPos + length; i++) {
  1200. lineBuffer[linePos++] = styler[i];
  1201. if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
  1202. // End of line (or of line buffer) met, colourise it
  1203. lineBuffer[linePos] = '\0';
  1204. ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler);
  1205. linePos = 0;
  1206. startLine = i + 1;
  1207. }
  1208. }
  1209. if (linePos > 0) { // Last line does not have ending characters
  1210. ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
  1211. }
  1212. }
  1213. static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine, int &startValue) {
  1214. if (lineBuffer[0] == '>') {
  1215. // Command or return status
  1216. return SCE_ERR_CMD;
  1217. } else if (lineBuffer[0] == '<') {
  1218. // Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
  1219. return SCE_ERR_DEFAULT;
  1220. } else if (lineBuffer[0] == '!') {
  1221. return SCE_ERR_DIFF_CHANGED;
  1222. } else if (lineBuffer[0] == '+') {
  1223. if (strstart(lineBuffer, "+++ ")) {
  1224. return SCE_ERR_DIFF_MESSAGE;
  1225. } else {
  1226. return SCE_ERR_DIFF_ADDITION;
  1227. }
  1228. } else if (lineBuffer[0] == '-') {
  1229. if (strstart(lineBuffer, "--- ")) {
  1230. return SCE_ERR_DIFF_MESSAGE;
  1231. } else {
  1232. return SCE_ERR_DIFF_DELETION;
  1233. }
  1234. } else if (strstart(lineBuffer, "cf90-")) {
  1235. // Absoft Pro Fortran 90/95 v8.2 error and/or warning message
  1236. return SCE_ERR_ABSF;
  1237. } else if (strstart(lineBuffer, "fortcom:")) {
  1238. // Intel Fortran Compiler v8.0 error/warning message
  1239. return SCE_ERR_IFORT;
  1240. } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
  1241. return SCE_ERR_PYTHON;
  1242. } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
  1243. return SCE_ERR_PHP;
  1244. } else if ((strstart(lineBuffer, "Error ") ||
  1245. strstart(lineBuffer, "Warning ")) &&
  1246. strstr(lineBuffer, " at (") &&
  1247. strstr(lineBuffer, ") : ") &&
  1248. (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
  1249. // Intel Fortran Compiler error/warning message
  1250. return SCE_ERR_IFC;
  1251. } else if (strstart(lineBuffer, "Error ")) {
  1252. // Borland error message
  1253. return SCE_ERR_BORLAND;
  1254. } else if (strstart(lineBuffer, "Warning ")) {
  1255. // Borland warning message
  1256. return SCE_ERR_BORLAND;
  1257. } else if (strstr(lineBuffer, "at line ") &&
  1258. (strstr(lineBuffer, "at line ") < (lineBuffer + lengthLine)) &&
  1259. strstr(lineBuffer, "file ") &&
  1260. (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
  1261. // Lua 4 error message
  1262. return SCE_ERR_LUA;
  1263. } else if (strstr(lineBuffer, " at ") &&
  1264. (strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) &&
  1265. strstr(lineBuffer, " line ") &&
  1266. (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
  1267. (strstr(lineBuffer, " at ") < (strstr(lineBuffer, " line ")))) {
  1268. // perl error message
  1269. return SCE_ERR_PERL;
  1270. } else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
  1271. strstr(lineBuffer, ":line ")) {
  1272. // A .NET traceback
  1273. return SCE_ERR_NET;
  1274. } else if (strstart(lineBuffer, "Line ") &&
  1275. strstr(lineBuffer, ", file ")) {
  1276. // Essential Lahey Fortran error message
  1277. return SCE_ERR_ELF;
  1278. } else if (strstart(lineBuffer, "line ") &&
  1279. strstr(lineBuffer, " column ")) {
  1280. // HTML tidy style: line 42 column 1
  1281. return SCE_ERR_TIDY;
  1282. } else if (strstart(lineBuffer, "\tat ") &&
  1283. strstr(lineBuffer, "(") &&
  1284. strstr(lineBuffer, ".java:")) {
  1285. // Java stack back trace
  1286. return SCE_ERR_JAVA_STACK;
  1287. } else {
  1288. // Look for one of the following formats:
  1289. // GCC: <filename>:<line>:<message>
  1290. // Microsoft: <filename>(<line>) :<message>
  1291. // Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal
  1292. // Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal
  1293. // Microsoft: <filename>(<line>,<column>)<message>
  1294. // CTags: \t<message>
  1295. // Lua 5 traceback: \t<filename>:<line>:<message>
  1296. // Lua 5.1: <exe>: <filename>:<line>:<message>
  1297. bool initialTab = (lineBuffer[0] == '\t');
  1298. bool initialColonPart = false;
  1299. enum { stInitial,
  1300. stGccStart, stGccDigit, stGcc,
  1301. stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
  1302. stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags,
  1303. stUnrecognized
  1304. } state = stInitial;
  1305. for (unsigned int i = 0; i < lengthLine; i++) {
  1306. char ch = lineBuffer[i];
  1307. char chNext = ' ';
  1308. if ((i + 1) < lengthLine)
  1309. chNext = lineBuffer[i + 1];
  1310. if (state == stInitial) {
  1311. if (ch == ':') {
  1312. // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
  1313. if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) {
  1314. // This check is not completely accurate as may be on
  1315. // GTK+ with a file name that includes ':'.
  1316. state = stGccStart;
  1317. } else if (ch

Large files files are truncated, but you can click here to view the full file