/libraries/jnaerator/ochafik-swing/src/main/java/com/ochafik/swing/syntaxcoloring/CTokenMarker.java

https://github.com/AndreiSochirca/nativelibs4java · Java · 271 lines · 242 code · 14 blank · 15 comment · 20 complexity · 42e1ba34cb8544acc43ad6d5b0a613c6 MD5 · raw file

  1. /*
  2. * CTokenMarker.java - C token marker
  3. * Copyright (C) 1998, 1999 Slava Pestov
  4. *
  5. * You may use and modify this package for any purpose. Redistribution is
  6. * permitted, in both source and binary form, provided that this notice
  7. * remains intact in all source distributions of this package.
  8. */
  9. package com.ochafik.swing.syntaxcoloring;
  10. import javax.swing.text.Segment;
  11. /**
  12. * C token marker.
  13. *
  14. * @author Slava Pestov
  15. * @version $Id: CTokenMarker.java,v 1.34 1999/12/13 03:40:29 sp Exp $
  16. */
  17. public class CTokenMarker extends TokenMarker
  18. {
  19. public CTokenMarker()
  20. {
  21. this(true,getKeywords());
  22. }
  23. public CTokenMarker(boolean cpp, KeywordMap keywords)
  24. {
  25. this.cpp = cpp;
  26. this.keywords = keywords;
  27. }
  28. public byte markTokensImpl(byte token, Segment line, int lineIndex)
  29. {
  30. char[] array = line.array;
  31. int offset = line.offset;
  32. lastOffset = offset;
  33. lastKeyword = offset;
  34. int length = line.count + offset;
  35. boolean backslash = false;
  36. loop: for(int i = offset; i < length; i++)
  37. {
  38. int i1 = (i+1);
  39. char c = array[i];
  40. if(c == '\\')
  41. {
  42. backslash = !backslash;
  43. continue;
  44. }
  45. switch(token)
  46. {
  47. case Token.NULL:
  48. switch(c)
  49. {
  50. case '#':
  51. if(backslash)
  52. backslash = false;
  53. else if(cpp)
  54. {
  55. if(doKeyword(line,i,c))
  56. break;
  57. addToken(i - lastOffset,token);
  58. addToken(length - i,Token.KEYWORD2);
  59. lastOffset = lastKeyword = length;
  60. break loop;
  61. }
  62. break;
  63. case '"':
  64. doKeyword(line,i,c);
  65. if(backslash)
  66. backslash = false;
  67. else
  68. {
  69. addToken(i - lastOffset,token);
  70. token = Token.LITERAL1;
  71. lastOffset = lastKeyword = i;
  72. }
  73. break;
  74. case '\'':
  75. doKeyword(line,i,c);
  76. if(backslash)
  77. backslash = false;
  78. else
  79. {
  80. addToken(i - lastOffset,token);
  81. token = Token.LITERAL2;
  82. lastOffset = lastKeyword = i;
  83. }
  84. break;
  85. case ':':
  86. if(lastKeyword == offset)
  87. {
  88. if(doKeyword(line,i,c))
  89. break;
  90. backslash = false;
  91. addToken(i1 - lastOffset,Token.LABEL);
  92. lastOffset = lastKeyword = i1;
  93. }
  94. else if(doKeyword(line,i,c))
  95. break;
  96. break;
  97. case '/':
  98. backslash = false;
  99. doKeyword(line,i,c);
  100. if(length - i > 1)
  101. {
  102. switch(array[i1])
  103. {
  104. case '*':
  105. addToken(i - lastOffset,token);
  106. lastOffset = lastKeyword = i;
  107. if(length - i > 2 && array[i+2] == '*')
  108. token = Token.COMMENT2;
  109. else
  110. token = Token.COMMENT1;
  111. break;
  112. case '/':
  113. addToken(i - lastOffset,token);
  114. addToken(length - i,Token.COMMENT1);
  115. lastOffset = lastKeyword = length;
  116. break loop;
  117. }
  118. }
  119. break;
  120. default:
  121. backslash = false;
  122. if(!Character.isLetterOrDigit(c)
  123. && c != '_')
  124. doKeyword(line,i,c);
  125. break;
  126. }
  127. break;
  128. case Token.COMMENT1:
  129. case Token.COMMENT2:
  130. backslash = false;
  131. if(c == '*' && length - i > 1)
  132. {
  133. if(array[i1] == '/')
  134. {
  135. i++;
  136. addToken((i+1) - lastOffset,token);
  137. token = Token.NULL;
  138. lastOffset = lastKeyword = i+1;
  139. }
  140. }
  141. break;
  142. case Token.LITERAL1:
  143. if(backslash)
  144. backslash = false;
  145. else if(c == '"')
  146. {
  147. addToken(i1 - lastOffset,token);
  148. token = Token.NULL;
  149. lastOffset = lastKeyword = i1;
  150. }
  151. break;
  152. case Token.LITERAL2:
  153. if(backslash)
  154. backslash = false;
  155. else if(c == '\'')
  156. {
  157. addToken(i1 - lastOffset,Token.LITERAL1);
  158. token = Token.NULL;
  159. lastOffset = lastKeyword = i1;
  160. }
  161. break;
  162. default:
  163. throw new InternalError("Invalid state: "
  164. + token);
  165. }
  166. }
  167. if(token == Token.NULL)
  168. doKeyword(line,length,'\0');
  169. switch(token)
  170. {
  171. case Token.LITERAL1:
  172. case Token.LITERAL2:
  173. addToken(length - lastOffset,Token.INVALID);
  174. token = Token.NULL;
  175. break;
  176. case Token.KEYWORD2:
  177. addToken(length - lastOffset,token);
  178. if(!backslash)
  179. token = Token.NULL;
  180. default:
  181. addToken(length - lastOffset,token);
  182. break;
  183. }
  184. return token;
  185. }
  186. public static KeywordMap getKeywords()
  187. {
  188. if(cKeywords == null)
  189. {
  190. cKeywords = new KeywordMap(false);
  191. cKeywords.add("char",Token.KEYWORD3);
  192. cKeywords.add("double",Token.KEYWORD3);
  193. cKeywords.add("enum",Token.KEYWORD3);
  194. cKeywords.add("float",Token.KEYWORD3);
  195. cKeywords.add("int",Token.KEYWORD3);
  196. cKeywords.add("long",Token.KEYWORD3);
  197. cKeywords.add("short",Token.KEYWORD3);
  198. cKeywords.add("signed",Token.KEYWORD3);
  199. cKeywords.add("struct",Token.KEYWORD3);
  200. cKeywords.add("typedef",Token.KEYWORD3);
  201. cKeywords.add("union",Token.KEYWORD3);
  202. cKeywords.add("unsigned",Token.KEYWORD3);
  203. cKeywords.add("void",Token.KEYWORD3);
  204. cKeywords.add("auto",Token.KEYWORD1);
  205. cKeywords.add("const",Token.KEYWORD1);
  206. cKeywords.add("extern",Token.KEYWORD1);
  207. cKeywords.add("register",Token.KEYWORD1);
  208. cKeywords.add("static",Token.KEYWORD1);
  209. cKeywords.add("volatile",Token.KEYWORD1);
  210. cKeywords.add("break",Token.KEYWORD1);
  211. cKeywords.add("case",Token.KEYWORD1);
  212. cKeywords.add("continue",Token.KEYWORD1);
  213. cKeywords.add("default",Token.KEYWORD1);
  214. cKeywords.add("do",Token.KEYWORD1);
  215. cKeywords.add("else",Token.KEYWORD1);
  216. cKeywords.add("for",Token.KEYWORD1);
  217. cKeywords.add("goto",Token.KEYWORD1);
  218. cKeywords.add("if",Token.KEYWORD1);
  219. cKeywords.add("return",Token.KEYWORD1);
  220. cKeywords.add("sizeof",Token.KEYWORD1);
  221. cKeywords.add("switch",Token.KEYWORD1);
  222. cKeywords.add("while",Token.KEYWORD1);
  223. cKeywords.add("asm",Token.KEYWORD2);
  224. cKeywords.add("asmlinkage",Token.KEYWORD2);
  225. cKeywords.add("far",Token.KEYWORD2);
  226. cKeywords.add("huge",Token.KEYWORD2);
  227. cKeywords.add("inline",Token.KEYWORD2);
  228. cKeywords.add("near",Token.KEYWORD2);
  229. cKeywords.add("pascal",Token.KEYWORD2);
  230. cKeywords.add("true",Token.LITERAL2);
  231. cKeywords.add("false",Token.LITERAL2);
  232. cKeywords.add("NULL",Token.LITERAL2);
  233. }
  234. return cKeywords;
  235. }
  236. // private members
  237. private static KeywordMap cKeywords;
  238. private boolean cpp;
  239. private KeywordMap keywords;
  240. private int lastOffset;
  241. private int lastKeyword;
  242. private boolean doKeyword(Segment line, int i, char c)
  243. {
  244. int i1 = i+1;
  245. int len = i - lastKeyword;
  246. byte id = keywords.lookup(line,lastKeyword,len);
  247. if(id != Token.NULL)
  248. {
  249. if(lastKeyword != lastOffset)
  250. addToken(lastKeyword - lastOffset,Token.NULL);
  251. addToken(len,id);
  252. lastOffset = i;
  253. }
  254. lastKeyword = i1;
  255. return false;
  256. }
  257. }