Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.utils / src / main / java / org / gvsig / utils / console / jedit / CTokenMarker.java @ 40561

History | View | Annotate | Download (7.22 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.utils.console.jedit;
25
/*
26
 * CTokenMarker.java - C token marker
27
 * Copyright (C) 1998, 1999 Slava Pestov
28
 *
29
 * You may use and modify this package for any purpose. Redistribution is
30
 * permitted, in both source and binary form, provided that this notice
31
 * remains intact in all source distributions of this package.
32
 */
33

    
34
import javax.swing.text.Segment;
35

    
36
/**
37
 * C token marker.
38
 *
39
 * @author Slava Pestov
40
 * @version $Id$
41
 */
42
public class CTokenMarker extends TokenMarker
43
{
44
        public CTokenMarker()
45
        {
46
                this(true,getKeywords());
47
        }
48

    
49
        public CTokenMarker(boolean cpp, KeywordMap keywords)
50
        {
51
                this.cpp = cpp;
52
                this.keywords = keywords;
53
        }
54

    
55
        public byte markTokensImpl(byte token, Segment line, int lineIndex)
56
        {
57
                char[] array = line.array;
58
                int offset = line.offset;
59
                lastOffset = offset;
60
                lastKeyword = offset;
61
                int length = line.count + offset;
62
                boolean backslash = false;
63

    
64
loop:                for(int i = offset; i < length; i++)
65
                {
66
                        int i1 = (i+1);
67

    
68
                        char c = array[i];
69
                        if(c == '\\')
70
                        {
71
                                backslash = !backslash;
72
                                continue;
73
                        }
74

    
75
                        switch(token)
76
                        {
77
                        case Token.NULL:
78
                                switch(c)
79
                                {
80
                                case '#':
81
                                        if(backslash)
82
                                                backslash = false;
83
                                        else if(cpp)
84
                                        {
85
                                                if(doKeyword(line,i,c))
86
                                                        break;
87
                                                addToken(i - lastOffset,token);
88
                                                addToken(length - i,Token.KEYWORD2);
89
                                                lastOffset = lastKeyword = length;
90
                                                break loop;
91
                                        }
92
                                        break;
93
                                case '"':
94
                                        doKeyword(line,i,c);
95
                                        if(backslash)
96
                                                backslash = false;
97
                                        else
98
                                        {
99
                                                addToken(i - lastOffset,token);
100
                                                token = Token.LITERAL1;
101
                                                lastOffset = lastKeyword = i;
102
                                        }
103
                                        break;
104
                                case '\'':
105
                                        doKeyword(line,i,c);
106
                                        if(backslash)
107
                                                backslash = false;
108
                                        else
109
                                        {
110
                                                addToken(i - lastOffset,token);
111
                                                token = Token.LITERAL2;
112
                                                lastOffset = lastKeyword = i;
113
                                        }
114
                                        break;
115
                                case ':':
116
                                        if(lastKeyword == offset)
117
                                        {
118
                                                if(doKeyword(line,i,c))
119
                                                        break;
120
                                                backslash = false;
121
                                                addToken(i1 - lastOffset,Token.LABEL);
122
                                                lastOffset = lastKeyword = i1;
123
                                        }
124
                                        else if(doKeyword(line,i,c))
125
                                                break;
126
                                        break;
127
                                case '/':
128
                                        backslash = false;
129
                                        doKeyword(line,i,c);
130
                                        if(length - i > 1)
131
                                        {
132
                                                switch(array[i1])
133
                                                {
134
                                                case '*':
135
                                                        addToken(i - lastOffset,token);
136
                                                        lastOffset = lastKeyword = i;
137
                                                        if(length - i > 2 && array[i+2] == '*')
138
                                                                token = Token.COMMENT2;
139
                                                        else
140
                                                                token = Token.COMMENT1;
141
                                                        break;
142
                                                case '/':
143
                                                        addToken(i - lastOffset,token);
144
                                                        addToken(length - i,Token.COMMENT1);
145
                                                        lastOffset = lastKeyword = length;
146
                                                        break loop;
147
                                                }
148
                                        }
149
                                        break;
150
                                default:
151
                                        backslash = false;
152
                                        if(!Character.isLetterOrDigit(c)
153
                                                && c != '_')
154
                                                doKeyword(line,i,c);
155
                                        break;
156
                                }
157
                                break;
158
                        case Token.COMMENT1:
159
                        case Token.COMMENT2:
160
                                backslash = false;
161
                                if(c == '*' && length - i > 1)
162
                                {
163
                                        if(array[i1] == '/')
164
                                        {
165
                                                i++;
166
                                                addToken((i+1) - lastOffset,token);
167
                                                token = Token.NULL;
168
                                                lastOffset = lastKeyword = i+1;
169
                                        }
170
                                }
171
                                break;
172
                        case Token.LITERAL1:
173
                                if(backslash)
174
                                        backslash = false;
175
                                else if(c == '"')
176
                                {
177
                                        addToken(i1 - lastOffset,token);
178
                                        token = Token.NULL;
179
                                        lastOffset = lastKeyword = i1;
180
                                }
181
                                break;
182
                        case Token.LITERAL2:
183
                                if(backslash)
184
                                        backslash = false;
185
                                else if(c == '\'')
186
                                {
187
                                        addToken(i1 - lastOffset,Token.LITERAL1);
188
                                        token = Token.NULL;
189
                                        lastOffset = lastKeyword = i1;
190
                                }
191
                                break;
192
                        default:
193
                                throw new InternalError("Invalid state: "
194
                                        + token);
195
                        }
196
                }
197

    
198
                if(token == Token.NULL)
199
                        doKeyword(line,length,'\0');
200

    
201
                switch(token)
202
                {
203
                case Token.LITERAL1:
204
                case Token.LITERAL2:
205
                        addToken(length - lastOffset,Token.INVALID);
206
                        token = Token.NULL;
207
                        break;
208
                case Token.KEYWORD2:
209
                        addToken(length - lastOffset,token);
210
                        if(!backslash)
211
                                token = Token.NULL;
212
                default:
213
                        addToken(length - lastOffset,token);
214
                        break;
215
                }
216

    
217
                return token;
218
        }
219

    
220
        public static KeywordMap getKeywords()
221
        {
222
                if(cKeywords == null)
223
                {
224
                        cKeywords = new KeywordMap(false);
225
                        cKeywords.add("char",Token.KEYWORD3);
226
                        cKeywords.add("double",Token.KEYWORD3);
227
                        cKeywords.add("enum",Token.KEYWORD3);
228
                        cKeywords.add("float",Token.KEYWORD3);
229
                        cKeywords.add("int",Token.KEYWORD3);
230
                        cKeywords.add("long",Token.KEYWORD3);
231
                        cKeywords.add("short",Token.KEYWORD3);
232
                        cKeywords.add("signed",Token.KEYWORD3);
233
                        cKeywords.add("struct",Token.KEYWORD3);
234
                        cKeywords.add("typedef",Token.KEYWORD3);
235
                        cKeywords.add("union",Token.KEYWORD3);
236
                        cKeywords.add("unsigned",Token.KEYWORD3);
237
                        cKeywords.add("void",Token.KEYWORD3);
238
                        cKeywords.add("auto",Token.KEYWORD1);
239
                        cKeywords.add("const",Token.KEYWORD1);
240
                        cKeywords.add("extern",Token.KEYWORD1);
241
                        cKeywords.add("register",Token.KEYWORD1);
242
                        cKeywords.add("static",Token.KEYWORD1);
243
                        cKeywords.add("volatile",Token.KEYWORD1);
244
                        cKeywords.add("break",Token.KEYWORD1);
245
                        cKeywords.add("case",Token.KEYWORD1);
246
                        cKeywords.add("continue",Token.KEYWORD1);
247
                        cKeywords.add("default",Token.KEYWORD1);
248
                        cKeywords.add("do",Token.KEYWORD1);
249
                        cKeywords.add("else",Token.KEYWORD1);
250
                        cKeywords.add("for",Token.KEYWORD1);
251
                        cKeywords.add("goto",Token.KEYWORD1);
252
                        cKeywords.add("if",Token.KEYWORD1);
253
                        cKeywords.add("return",Token.KEYWORD1);
254
                        cKeywords.add("sizeof",Token.KEYWORD1);
255
                        cKeywords.add("switch",Token.KEYWORD1);
256
                        cKeywords.add("while",Token.KEYWORD1);
257
                        cKeywords.add("asm",Token.KEYWORD2);
258
                        cKeywords.add("asmlinkage",Token.KEYWORD2);
259
                        cKeywords.add("far",Token.KEYWORD2);
260
                        cKeywords.add("huge",Token.KEYWORD2);
261
                        cKeywords.add("inline",Token.KEYWORD2);
262
                        cKeywords.add("near",Token.KEYWORD2);
263
                        cKeywords.add("pascal",Token.KEYWORD2);
264
                        cKeywords.add("true",Token.LITERAL2);
265
                        cKeywords.add("false",Token.LITERAL2);
266
                        cKeywords.add("NULL",Token.LITERAL2);
267
                }
268
                return cKeywords;
269
        }
270

    
271
        // private members
272
        private static KeywordMap cKeywords;
273

    
274
        private boolean cpp;
275
        private KeywordMap keywords;
276
        private int lastOffset;
277
        private int lastKeyword;
278

    
279
        private boolean doKeyword(Segment line, int i, char c)
280
        {
281
                int i1 = i+1;
282

    
283
                int len = i - lastKeyword;
284
                byte id = keywords.lookup(line,lastKeyword,len);
285
                if(id != Token.NULL)
286
                {
287
                        if(lastKeyword != lastOffset)
288
                                addToken(lastKeyword - lastOffset,Token.NULL);
289
                        addToken(len,id);
290
                        lastOffset = i;
291
                }
292
                lastKeyword = i1;
293
                return false;
294
        }
295
}