KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * CTagger.java
3  *
4  * Copyright (C) 1998-2002 Peter Graves
5  * $Id: CTagger.java,v 1.8 2003/12/30 19:27:59 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 import gnu.regexp.RE;
25 import gnu.regexp.UncheckedRE;
26 import java.util.ArrayList JavaDoc;
27
28 public final class CTagger extends JavaTagger
29 {
30     // States.
31
private static final int NEUTRAL = 0;
32     private static final int METHOD_NAME = 1;
33     private static final int PARAMETER_LIST = 2;
34
35     private static RE lynxArgsMacroRE = new UncheckedRE("ARGS[0-9][0-9]?");
36
37     private CMode mode = (CMode) CMode.getMode();
38
39     public CTagger(SystemBuffer buffer)
40     {
41         super(buffer);
42     }
43
44     public void run()
45     {
46         ArrayList JavaDoc tags = new ArrayList JavaDoc();
47         pos = new Position(buffer.getFirstLine(), 0);
48         token = null;
49         tokenStart = null;
50         int state = NEUTRAL;
51         while (!pos.atEnd()) {
52             char c = pos.getChar();
53             if (Character.isWhitespace(c)) {
54                 pos.skipWhitespace();
55                 continue;
56             }
57             if (c == '\'' || c == '"') {
58                 pos.skipQuote();
59                 continue;
60             }
61             if (pos.lookingAt("/*")) {
62                 skipComment(pos);
63                 continue;
64             }
65             if (pos.lookingAt("//")) {
66                 skipSingleLineComment(pos);
67                 continue;
68             }
69             if (c == '#' && pos.getOffset() == 0) {
70                 skipPreprocessor(pos);
71                 continue;
72             }
73             if (state == METHOD_NAME) {
74                 if (c == '{') {
75                     if (token != null && !mode.isKeyword(token))
76                         tags.add(new CTag(token, tokenStart));
77                     skipBrace();
78                     state = NEUTRAL;
79                     continue;
80                 } else if (mode.isIdentifierStart(c)) {
81                     state = PARAMETER_LIST;
82                     pos.next();
83                     continue;
84                 } else {
85                     state = NEUTRAL;
86                     pos.next();
87                     continue;
88                 }
89             }
90             if (state == PARAMETER_LIST) {
91                 if (c == '{') {
92                     if (token != null && !mode.isKeyword(token))
93                         tags.add(new CTag(token, tokenStart));
94                     skipBrace();
95                     state = NEUTRAL;
96                     continue;
97                 } else if (c == '(') {
98                     state = NEUTRAL;
99                     skipParen();
100                     continue;
101                 } else {
102                     pos.next();
103                     continue;
104                 }
105             }
106             if (c == '}') {
107                 pos.next();
108                 continue;
109             }
110             if (mode.isIdentifierStart(c)) {
111                 tokenStart = pos.copy();
112                 String JavaDoc s = gatherToken(pos);
113                 if (s.startsWith("ARGS") && lynxArgsMacroRE.isMatch(s)) {
114                     // Lynx "ARGSnn" macro.
115
;
116                 } else if (s.equals("NOARGS")) {
117                     // Lynx macro.
118
state = METHOD_NAME;
119                 } else if (isDefunStart(s)) {
120                     // Emacs macro.
121
while (true) {
122                         c = pos.getChar();
123                         if (c == '"') {
124                             pos.next();
125                             break;
126                         }
127                         if (!pos.next())
128                             break;
129                     }
130                     tokenStart = pos.copy();
131                     token = gatherDefunName(pos);
132                     tags.add(new CTag(token, tokenStart));
133                     while ((c = pos.getChar()) != '{') {
134                         if (c == '"' || c == '\'') {
135                             pos.skipQuote();
136                             continue;
137                         }
138                         if (c == '/' && pos.lookingAt("/*")) {
139                             skipComment(pos);
140                             continue;
141                         }
142                         if (!pos.next())
143                             break;
144                     }
145                     if (c == '{')
146                         skipBrace();
147                 } else
148                     token = s;
149                 continue;
150             }
151             if (c == '(') {
152                 skipParen();
153                 state = METHOD_NAME;
154                 continue;
155             }
156             pos.next();
157         }
158         buffer.setTags(tags);
159     }
160
161     private String JavaDoc gatherToken(Position pos)
162     {
163         FastStringBuffer sb = new FastStringBuffer();
164         char c;
165         while (mode.isIdentifierPart(c = pos.getChar())) {
166             sb.append(c);
167             if (!pos.next())
168                 break;
169         }
170         return sb.toString();
171     }
172
173     private static boolean isDefunStart(String JavaDoc s)
174     {
175         if (s.length() < 5)
176             return false;
177         char c = s.charAt(0);
178         if (c == 'D') {
179             if (s.equals("DEFUN")) // Emacs, rep
180
return true;
181             if (s.equals("DEFUN_INT")) // rep
182
return true;
183         } else if (c == 'S') {
184             if (s.equals("SCM_DEFINE")) // guile
185
return true;
186         }
187         return false;
188     }
189
190     private static String JavaDoc gatherDefunName(Position pos)
191     {
192         FastStringBuffer sb = new FastStringBuffer();
193         while (true) {
194             char c = pos.getChar();
195             if (c == '"') {
196                 pos.next(); // Skip past final quote char.
197
break;
198             }
199             if (c == EOL)
200                 break;
201             sb.append(c);
202             if (!pos.next())
203                 break;
204         }
205         return sb.toString();
206     }
207 }
208
Popular Tags