KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > AutoconfFormatter


1 /*
2  * AutoconfFormatter.java
3  *
4  * Copyright (C) 2000-2003 Peter Graves
5  * $Id: AutoconfFormatter.java,v 1.2 2003/10/21 18:30:01 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 public final class AutoconfFormatter extends Formatter
25 {
26     private static final int STATE_BACKQUOTE = STATE_LAST + 1;
27
28     // Formats.
29
private static final int AUTOCONF_FORMAT_TEXT = 0;
30     private static final int AUTOCONF_FORMAT_COMMENT = 1;
31     private static final int AUTOCONF_FORMAT_STRING = 2;
32     private static final int AUTOCONF_FORMAT_KEYWORD = 3;
33     private static final int AUTOCONF_FORMAT_FUNCTION = 4;
34
35     private static StringSet keywords;
36     private static StringSet functions;
37
38     private FastStringBuffer sb = new FastStringBuffer();
39     private String JavaDoc token;
40
41     public AutoconfFormatter(Buffer buffer)
42     {
43         this.buffer = buffer;
44         if (functions == null)
45             functions = new StringSet(autoconfFunctions);
46     }
47
48     public LineSegmentList formatLine(Line line)
49     {
50         clearSegmentList();
51         if (line == null || line.length() == 0) {
52             addSegment("", AUTOCONF_FORMAT_TEXT);
53             return segmentList;
54         }
55         parseLine(line);
56         for (int i = 0; i < segmentList.size(); i++) {
57             LineSegment segment = segmentList.getSegment(i);
58             if (segment.getFormat() >= 0)
59                 continue;
60             String JavaDoc s = segment.getText();
61             if (isKeyword(s))
62                 segment.setFormat(AUTOCONF_FORMAT_KEYWORD);
63             else if (isFunction(s))
64                 segment.setFormat(AUTOCONF_FORMAT_FUNCTION);
65             else
66                 segment.setFormat(AUTOCONF_FORMAT_TEXT);
67         }
68         return segmentList;
69     }
70
71     private void endToken(int state)
72     {
73         if (sb.length() > 0) {
74             int format = -1;
75             switch (state) {
76                 case STATE_NEUTRAL:
77                     break;
78                 case STATE_QUOTE:
79                 case STATE_BACKQUOTE:
80                     format = AUTOCONF_FORMAT_STRING;
81                     break;
82                 case STATE_IDENTIFIER:
83                     break;
84                 case STATE_COMMENT:
85                     format = AUTOCONF_FORMAT_COMMENT;
86                     break;
87             }
88             token = sb.toString();
89             addSegment(token, format);
90             sb.setLength(0);
91         }
92     }
93
94     private void parseLine(Line line)
95     {
96         String JavaDoc text = line.getText();
97         if (Editor.tabsAreVisible())
98             text = Utilities.makeTabsVisible(text, buffer.getTabWidth());
99         else
100             text = Utilities.detab(text, buffer.getTabWidth());
101         sb.setLength(0);
102         int i = 0;
103         int state = STATE_NEUTRAL;
104         final int limit = text.length();
105         // Skip whitespace at start of line.
106
while (i < limit) {
107             char c = text.charAt(i);
108             if (Character.isWhitespace(c)) {
109                 sb.append(c);
110                 ++i;
111             } else {
112                 endToken(state);
113                 break;
114             }
115         }
116         while (i < limit) {
117             char c = text.charAt(i);
118             if (state == STATE_QUOTE) {
119                 if (c == '"') {
120                     sb.append(c);
121                     endToken(state);
122                     state = STATE_NEUTRAL;
123                 } else {
124                     sb.append(c);
125
126                     if (c == '\\' && i < limit - 1)
127                     {
128                         // Escape char.
129
sb.append(text.charAt(++i));
130                     }
131                 }
132                 ++i;
133                 continue;
134             }
135             if (state == STATE_BACKQUOTE) {
136                 sb.append(c);
137                 if (c == '`') {
138                     endToken(state);
139                     state = STATE_NEUTRAL;
140                 }
141                 ++i;
142                 continue;
143             }
144             // Reaching here, we're not in a quoted string.
145
if (c == '\\') {
146                 // Escape.
147
sb.append(c);
148                 if (++i < limit) {
149                     sb.append(text.charAt(i));
150                     ++i;
151                 }
152                 continue;
153             }
154             if (c == '"') {
155                 endToken(state);
156                 sb.append(c);
157                 state = STATE_QUOTE;
158                 ++i;
159                 continue;
160             }
161             if (c == '`') {
162                 endToken(state);
163                 sb.append(c);
164                 state = STATE_BACKQUOTE;
165                 ++i;
166                 continue;
167             }
168             if (state == STATE_IDENTIFIER) {
169                 if (buffer.mode.isIdentifierPart(c))
170                     sb.append(c);
171                 else {
172                     // End of identifier.
173
endToken(state);
174                     if (token.equals("dnl")) {
175                         state = STATE_COMMENT;
176                         sb.append(text.substring(i));
177                         endToken(state);
178                         return;
179                     }
180                     state = STATE_NEUTRAL;
181                     sb.append(c);
182                 }
183                 ++i;
184                 continue;
185             }
186             if (state == STATE_NEUTRAL) {
187                 if (c == '#') {
188                     boolean isComment = false;
189                     if (i == limit-1) {
190                         // '#' is last or only character.
191
isComment = true;
192                     } else {
193                         // Ignore "#include", "#define", etc. (AC_TRY_COMPILE)
194
char nextChar = text.charAt(i + 1);
195                         if (nextChar == ' ' || nextChar == '\t' ||
196                             nextChar == '#' || nextChar == '!')
197                             isComment = true;
198                     }
199                     if (isComment) {
200                         state = STATE_COMMENT;
201                         sb.append(text.substring(i));
202                         endToken(state);
203                         return; // We're finished with this line.
204
}
205                     // Not really the start of a comment.
206
sb.append(c);
207                 } else if (buffer.mode.isIdentifierStart(c)) {
208                     endToken(state);
209                     sb.append(c);
210                     state = STATE_IDENTIFIER;
211                 } else // Still neutral...
212
sb.append(c);
213             }
214             ++i;
215         }
216         endToken(state);
217     }
218
219     public FormatTable getFormatTable()
220     {
221         if (formatTable == null) {
222             formatTable = new FormatTable("AutoconfMode");
223             formatTable.addEntryFromPrefs(AUTOCONF_FORMAT_TEXT, "text");
224             formatTable.addEntryFromPrefs(AUTOCONF_FORMAT_COMMENT, "comment");
225             formatTable.addEntryFromPrefs(AUTOCONF_FORMAT_STRING, "string" );
226             formatTable.addEntryFromPrefs(AUTOCONF_FORMAT_KEYWORD, "keyword");
227             formatTable.addEntryFromPrefs(AUTOCONF_FORMAT_FUNCTION, "function");
228         }
229         return formatTable;
230     }
231
232     private final boolean isFunction(String JavaDoc s)
233     {
234         if (functions == null)
235             return false;
236         return functions.contains(s);
237     }
238
239     private static final String JavaDoc[] autoconfFunctions = {
240         "AC_AIX",
241         "AC_ALLOCA",
242         "AC_ARG_ARRAY",
243         "AC_ARG_ENABLE",
244         "AC_ARG_PROGRAM",
245         "AC_ARG_WITH",
246         "AC_BEFORE",
247         "AC_C_BIGENDIAN",
248         "AC_C_CHAR_UNSIGNED",
249         "AC_C_CONST",
250         "AC_C_CROSS",
251         "AC_C_INLINE",
252         "AC_C_LONG_DOUBLE",
253         "AC_C_STRINGIZE",
254         "AC_CACHE_CHECK",
255         "AC_CACHE_LOAD",
256         "AC_CACHE_SAVE",
257         "AC_CACHE_VAL",
258         "AC_CANONICAL_HOST",
259         "AC_CANONICAL_SYSTEM",
260         "AC_CHAR_UNSIGNED",
261         "AC_CHECK_FILE",
262         "AC_CHECK_FILES",
263         "AC_CHECK_FUNC",
264         "AC_CHECK_FUNCS",
265         "AC_CHECK_HEADER",
266         "AC_CHECK_HEADERS",
267         "AC_CHECK_LIB",
268         "AC_CHECK_PROG",
269         "AC_CHECK_PROGS",
270         "AC_CHECK_SIZEOF",
271         "AC_CHECK_TOOL",
272         "AC_CHECK_TYPE",
273         "AC_CHECKING",
274         "AC_COMPILE_CHECK",
275         "AC_CONFIG_AUX_DIR",
276         "AC_CONFIG_COMMANDS",
277         "AC_CONFIG_FILES",
278         "AC_CONFIG_HEADER",
279         "AC_CONFIG_SUBDIRS",
280         "AC_CONST",
281         "AC_CROSS_CHECK",
282         "AC_CYGWIN",
283         "AC_DECL_SYS_SIGLIST",
284         "AC_DECL_YYTEXT",
285         "AC_DEFINE",
286         "AC_DEFINE_UNQUOTED",
287         "AC_DEFUN",
288         "AC_DIR_HEADER",
289         "AC_DYNIX_SEQ",
290         "AC_EGREP_CPP",
291         "AC_EGREP_HEADER",
292         "AC_ENABLE",
293         "AC_ERROR",
294         "AC_EXEEXT",
295         "AC_F77_LIBRARY_LDFLAGS",
296         "AC_FIND_X",
297         "AC_FIND_XTRA",
298         "AC_FUNC_ALLOCA",
299         "AC_FUNC_CHECK",
300         "AC_FUNC_CLOSEDIR_VOID",
301         "AC_FUNC_FNMATCH",
302         "AC_FUNC_GETLOADAVG",
303         "AC_FUNC_GETMNTENT",
304         "AC_FUNC_GETPGRP",
305         "AC_FUNC_MEMCMP",
306         "AC_FUNC_MMAP",
307         "AC_FUNC_SELECT_ARGTYPES",
308         "AC_FUNC_SETPGRP",
309         "AC_FUNC_SETVBUF_REVERSED",
310         "AC_FUNC_STRCOLL",
311         "AC_FUNC_STRFTIME",
312         "AC_FUNC_UTIME_NULL",
313         "AC_FUNC_VFORK",
314         "AC_FUNC_VPRINTF",
315         "AC_FUNC_WAIT3",
316         "AC_GCC_TRADITIONAL",
317         "AC_GETGROUPS_T",
318         "AC_GETLOADAVG",
319         "AC_HAVE_FUNCS",
320         "AC_HAVE_HEADERS",
321         "AC_HAVE_LIBRARY",
322         "AC_HAVE_POUNDBANG",
323         "AC_HEADER_CHECK",
324         "AC_HEADER_DIRENT",
325         "AC_HEADER_EGREP",
326         "AC_HEADER_MAJOR",
327         "AC_HEADER_STAT",
328         "AC_HEADER_STDC",
329         "AC_HEADER_SYS_WAIT",
330         "AC_HEADER_TIME",
331         "AC_INIT",
332         "AC_INLINE",
333         "AC_INT_16_BITS",
334         "AC_IRIX_SUN",
335         "AC_ISC_POSIX",
336         "AC_LANG_C",
337         "AC_LANG_CPLUSPLUS",
338         "AC_LANG_FORTRAN77",
339         "AC_LANG_RESTORE",
340         "AC_LANG_SAVE",
341         "AC_LINK_FILES",
342         "AC_LN_S",
343         "AC_LONG_64_BITS",
344         "AC_LONG_DOUBLE",
345         "AC_LONG_FILE_NAMES",
346         "AC_MAJOR_HEADER",
347         "AC_MEMORY_H",
348         "AC_MINGW32",
349         "AC_MINIX",
350         "AC_MINUS_C_MINUS_O",
351         "AC_MMAP",
352         "AC_MODE_T",
353         "AC_MSG_CHECKING",
354         "AC_MSG_ERROR",
355         "AC_MSG_RESULT",
356         "AC_MSG_WARN",
357         "AC_OBJEXT",
358         "AC_OBSOLETE",
359         "AC_OFF_T",
360         "AC_OUTPUT",
361         "AC_OUTPUT_COMMANDS",
362         "AC_PATH_PROG",
363         "AC_PATH_PROGS",
364         "AC_PATH_X",
365         "AC_PATH_XTRA",
366         "AC_PID_T",
367         "AC_PREFIX",
368         "AC_PREFIX_PROGRAM",
369         "AC_PREREQ",
370         "AC_PROG_AWK",
371         "AC_PROG_CC",
372         "AC_PROG_CC_C_O",
373         "AC_PROG_CPP",
374         "AC_PROG_CXX",
375         "AC_PROG_CXXCPP",
376         "AC_PROG_F77_C_O",
377         "AC_PROG_FORTRAN",
378         "AC_PROG_GCC_TRADITIONAL",
379         "AC_PROG_INSTALL",
380         "AC_PROG_LEX",
381         "AC_PROG_LN_S",
382         "AC_PROG_MAKE_SET",
383         "AC_PROG_RANLIB",
384         "AC_PROG_YACC",
385         "AC_PROGRAM_CHECK",
386         "AC_PROGRAM_EGREP",
387         "AC_PROGRAM_PATH",
388         "AC_PROGRAMS_CHECK",
389         "AC_PROGRAMS_PATH",
390         "AC_PROVIDE",
391         "AC_REMOTE_TAPE",
392         "AC_REPLACE_FUNCS",
393         "AC_REQUIRE",
394         "AC_REQUIRE_CPP",
395         "AC_RESTARTABLE_SYSCALLS",
396         "AC_RETSIGTYPE",
397         "AC_REVISION",
398         "AC_RSH",
399         "AC_SCO_INTL",
400         "AC_SEARCH_LIBS",
401         "AC_SET_MAKE",
402         "AC_SETVBUF_REVERSED",
403         "AC_SIZE_T",
404         "AC_SIZEOF_TYPE",
405         "AC_ST_BLKSIZE",
406         "AC_ST_BLOCKS",
407         "AC_ST_RDEV",
408         "AC_STAT_MACROS_BROKEN",
409         "AC_STDC_HEADERS",
410         "AC_STRCOLL",
411         "AC_STRUCT_ST_BLKSIZE",
412         "AC_STRUCT_ST_BLOCKS",
413         "AC_STRUCT_ST_RDEV",
414         "AC_STRUCT_TIMEZONE",
415         "AC_STRUCT_TM",
416         "AC_SUBST",
417         "AC_SUBST_FILE",
418         "AC_SYS_INTERPRETER",
419         "AC_SYS_LONG_FILE_NAMES",
420         "AC_SYS_RESTARTABLE_SYSCALLS",
421         "AC_SYS_SIGLIST_DECLARED",
422         "AC_TEST_CPP",
423         "AC_TEST_PROGRAM",
424         "AC_TIME_WITH_SYS_TIME",
425         "AC_TIMEZONE",
426         "AC_TRY_COMPILE",
427         "AC_TRY_CPP",
428         "AC_TRY_LINK",
429         "AC_TRY_LINK_FUNC",
430         "AC_TRY_RUN",
431         "AC_TYPE_GETGROUPS",
432         "AC_TYPE_MODE_T",
433         "AC_TYPE_OFF_T",
434         "AC_TYPE_PID_T",
435         "AC_TYPE_SIGNAL",
436         "AC_TYPE_SIZE_T",
437         "AC_TYPE_UID_T",
438         "AC_UID_T",
439         "AC_UNISTD_H",
440         "AC_USG",
441         "AC_UTIME_NULL",
442         "AC_VALIDATE_CACHED_SYSTEM_TUPLE",
443         "AC_VERBOSE",
444         "AC_VFORK",
445         "AC_VPRINTF",
446         "AC_WAIT3",
447         "AC_WARN",
448         "AC_WITH",
449         "AC_WORDS_BIGENDIAN",
450         "AC_XENIX_DIR",
451         "AC_YYTEXT_POINTER",
452
453         // Automake.
454
"AM_CONDITIONAL",
455         "AM_CONFIG_HEADER",
456         "AM_INIT_AUTOMAKE",
457         "AM_MAINTAINER_MODE",
458     };
459 }
460
Popular Tags