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