Initial commit of newLISP.
[newlisp.git] / guiserver / java / SyntaxHighlighterC.java
blobb14646dee25cc39cd02d3e14efe3b8799d879d55
1 //
2 // SyntaxHighlighterC.java
3 // guiserver
4 //
5 // Created by Lutz Mueller on 8/4/07.
6 //
7 // Copyright (C) 2007 Lutz Mueller
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 import java.awt.*;
24 import java.util.*;
25 import java.util.regex.Pattern;
26 import javax.swing.*;
27 import javax.swing.text.*;
29 @SuppressWarnings("unchecked")
30 public class SyntaxHighlighterC {
32 static String reservedC[] = {
33 "auto", "break", "byte", "case", "char", "const", "continue", "default", "do",
34 "double", "else", "enum", "extern", "float", "for", "goto", "if", "inline", "int",
35 "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch",
36 "typedef", "union", "unsigned", "void", "volatil", "while"
39 static String reservedCPP[] = {
40 "bool", "catch", "class", "delete", "friend", "inline", "new", "namespace",
41 "operator", "private", "protected", "public", "this", "throw", "try", "template"
42 };
44 static String reservedJava[] = {
45 "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
46 "class", "const", "continue", "default", "do", "double", "else", "enum",
47 "extends", "final", "finally", "float", "for", "goto", "if", "implements",
48 "import", "instanceof", "int", "interface", "long", "native", "new", "package",
49 "private", "protected", "public", "return", "short", "static", "strictfp",
50 "super", "switch", "synchronized", "this", "throw", "throws", "transient",
51 "try", "void", "volatile", "while"
54 static String reservedPHP[] = {
55 "abstract", "and", "array", "as", "break", "case", "catch", "cfunction",
56 "class", "clone", "const", "continue", "declare", "default", "die", "do",
57 "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach",
58 "endif", "endswitch", "endwhile", "eval", "exception", "exit", "extends",
59 "extends", "final", "for", "foreach", "function", "global", "if", "implements",
60 "include", "include_once", "interface", "isset", "list", "new", "old_function",
61 "or", "php_user_filter", "print", "private", "protected", "public", "require",
62 "require_once", "return", "static", "switch", "this", "throw", "try", "unset",
63 "use", "var", "while", "xor"
66 static SimpleAttributeSet comment;
67 static SimpleAttributeSet keyword;
68 static SimpleAttributeSet string;
69 static SimpleAttributeSet number;
70 static SimpleAttributeSet paren;
71 static SimpleAttributeSet quoted;
72 static SimpleAttributeSet normal;
74 static String numberPattern = "^-?\\d+$|^-?\\d+\\.\\d+$|^0x[0-9a-fA-F]+$";
75 static Pattern compiledPattern;
77 static StyledDocument doc;
78 static String text;
79 static String token;
80 static Vector topLevels;
82 static HashSet keys = null;
84 static HashSet keysC;
85 static HashSet keysCPP;
86 static HashSet keysJava;
87 static HashSet keysPHP;
89 @SuppressWarnings("unchecked")
90 static public void color(TextPaneWidget widget, int offset, int length)
92 int parenCount = 0;
93 int curlCount = 0;
94 int startToken;
95 int idx = offset;
96 char chr;
98 SyntaxHighlighter.active = true;
101 doc = widget.styledDoc;
102 topLevels = widget.shTopLevels;
104 normal = new SimpleAttributeSet();
105 StyleConstants.setForeground(normal, widget.foreground);
107 try { text = doc.getText(0, widget.documentLength); }
108 catch (Exception e) {text = null;}
110 //if(keys == null) init();
112 while(idx < length)
114 chr = text.charAt(idx++);
115 while(chr <= ' ' && idx < length) chr = text.charAt(idx++);
116 switch(chr)
118 case '#':
119 startToken = idx - 1;
120 while(chr != '\n' && idx < length) chr = text.charAt(idx++);
121 doc.setCharacterAttributes(startToken, idx - startToken, quoted, false);
122 continue;
123 case '{':
124 ++parenCount;
125 doc.setCharacterAttributes(idx - 1, 1, paren, false);
126 continue;
127 case '}':
128 --parenCount;
129 doc.setCharacterAttributes(idx - 1, 1, paren, false);
130 if(parenCount == 0) // top level
132 topLevels.addElement(offset);
133 offset = idx;
135 continue;
136 case '(':
137 doc.setCharacterAttributes(idx - 1, 1, paren, false);
138 continue;
139 case ')':
140 doc.setCharacterAttributes(idx - 1, 1, paren, false);
141 continue;
142 case '"':
143 startToken = idx - 1;
144 while(idx < length)
146 chr = text.charAt(idx++);
147 if(chr == '"')
149 doc.setCharacterAttributes(startToken, idx - startToken, string, false);
150 break;
152 if(chr == '\\')
154 idx++;
155 continue;
158 continue;
159 case '\'':
160 startToken = idx - 1;
161 while(idx < length)
163 chr = text.charAt(idx++);
164 if(chr == '\'')
166 doc.setCharacterAttributes(startToken, idx - startToken, string, false);
167 break;
169 if(chr == '\\')
171 idx++;
172 continue;
175 case '/':
176 startToken = idx - 1;
177 if(text.startsWith("/*", startToken))
179 idx = text.indexOf("*/", startToken + 2);
180 if(idx < 0) idx = length;
181 else idx = idx + 2;
182 doc.setCharacterAttributes(startToken, idx - startToken, comment, false);
184 else if(text.startsWith("//", startToken))
186 while(chr != '\n' && idx < length) chr = text.charAt(idx++);
187 doc.setCharacterAttributes(startToken, idx - startToken, comment, false);
189 continue;
190 default:
191 startToken = idx - 1;
192 while(chr > ' ' && chr != '(' && chr != ')' &&
193 chr != '\'' && chr != '"' &&
194 chr != ':' && chr != ';' && chr != ',' &&
195 chr != '{' && chr != '}' && chr != '[' && chr != ']' &&
196 idx < length) chr = text.charAt(idx++);
197 token = text.substring(startToken, idx - 1);
199 if(keys.contains(token))
200 doc.setCharacterAttributes(startToken, idx - startToken - 1, keyword, false);
201 else
203 //if(token.matches(numberPattern))
204 if(compiledPattern.matcher(token).matches())
205 doc.setCharacterAttributes(startToken, idx - startToken - 1, number, false);
206 else
207 doc.setCharacterAttributes(startToken, idx - startToken - 1, normal, false);
210 switch(chr)
212 case '(':
213 case ')':
214 case '[':
215 case ']':
216 doc.setCharacterAttributes(idx - 1, 1, paren, false);
217 continue;
218 case '{':
219 ++parenCount;
220 doc.setCharacterAttributes(idx - 1, 1, paren, false);
221 continue;
222 case '}':
223 --parenCount;
224 doc.setCharacterAttributes(idx - 1, 1, paren, false);
225 if(parenCount == 0) // top level
227 topLevels.addElement(offset);
228 offset = idx;
230 continue;
231 case ':':
232 case ';':
233 case ',':
234 doc.setCharacterAttributes(idx - 1, 1, normal, false);
235 continue;
236 case '"':
237 case '\'':
238 --idx;
239 continue;
244 SyntaxHighlighter.active = false;
247 static void setFlavor(int flavor)
249 if(keys == null) init();
250 switch(flavor)
252 case TextPaneWidget.SYNTAX_C:
253 keys = keysC;
254 break;
255 case TextPaneWidget.SYNTAX_CPP:
256 keys = keysCPP;
257 break;
258 case TextPaneWidget.SYNTAX_JAVA:
259 keys = keysJava;
260 break;
261 case TextPaneWidget.SYNTAX_PHP:
262 keys = keysPHP;
263 break;
267 static void init()
269 if(keys == null)
271 keysC = new HashSet();
272 for(int idx = 0; idx < reservedC.length; idx++)
273 keysC.add(reservedC[idx]);
275 keysCPP = new HashSet();
276 for(int idx = 0; idx < reservedC.length; idx++)
277 keysCPP.add(reservedC[idx]);
278 for(int idx = 0; idx < reservedCPP.length; idx++)
279 keysCPP.add(reservedCPP[idx]);
281 keysJava = new HashSet();
282 for(int idx = 0; idx < reservedJava.length; idx++)
283 keysJava.add(reservedJava[idx]);
285 keysPHP = new HashSet();
286 for(int idx = 0; idx < reservedPHP.length; idx++)
287 keysPHP.add(reservedPHP[idx]);
289 keys = keysC;
292 compiledPattern = Pattern.compile(numberPattern);
294 comment = new SimpleAttributeSet();
295 StyleConstants.setForeground(comment, SyntaxHighlighter.commentColor);
297 keyword = new SimpleAttributeSet();
298 StyleConstants.setForeground(keyword, SyntaxHighlighter.keywordColor);
300 string = new SimpleAttributeSet();
301 StyleConstants.setForeground(string, SyntaxHighlighter.stringColor);
303 number = new SimpleAttributeSet();
304 StyleConstants.setForeground(number, SyntaxHighlighter.numberColor);
306 quoted = new SimpleAttributeSet();
307 StyleConstants.setForeground(quoted, SyntaxHighlighter.quotedColor);
309 paren = new SimpleAttributeSet();
310 StyleConstants.setForeground(paren, SyntaxHighlighter.parenColor);
314 // eof