]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/global/gctags/java.c
Import Global v3_4_2 sources.
[FreeBSD/FreeBSD.git] / contrib / global / gctags / java.c
1 /*
2  * Copyright (c) 1998 Shigio Yamaguchi. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. All advertising materials mentioning features or use of this software
13  *    must display the following acknowledgement:
14  *      This product includes software developed by Shigio Yamaguchi.
15  * 4. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *      java.c                                  2-Sep-98
32  */
33
34 #include <ctype.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include "gctags.h"
40 #include "defined.h"
41 #include "die.h"
42 #include "java.h"
43 #include "token.h"
44
45 static int      reserved __P((char *));
46
47 /*
48  * java: read java file and pickup tag entries.
49  */
50 void
51 java()
52 {
53         int     c;
54         int     level;                                  /* brace level */
55         int     target;
56         int     startclass, startthrows, startequal;
57         char    classname[MAXTOKEN];
58         char    completename[MAXCOMPLETENAME];
59         int     classlevel;
60         struct {
61                 char *classname;
62                 char *terminate;
63                 int   level;
64         } stack[MAXCLASSSTACK];
65         const char *interested = "{}=;";
66
67         stack[0].terminate = completename;
68         stack[0].level = 0;
69         level = classlevel = 0;
70         target = (sflag) ? SYM : ((rflag) ? REF : DEF);
71         startclass = startthrows = startequal = 0;
72
73         while ((c = nexttoken(interested, reserved)) != EOF) {
74                 switch (c) {
75                 case SYMBOL:                                    /* symbol */
76                         for (; c == SYMBOL && peekc(1) == '.'; c = nexttoken(interested, reserved)) {
77                                 if (target == SYM)
78                                         PUT(token, lineno, sp);
79                         }
80                         if (c != SYMBOL)
81                                 break;
82                         if (startclass || startthrows) {
83                                 if (target == REF && defined(token))
84                                         PUT(token, lineno, sp);
85                         } else if (peekc(0) == '('/* ) */) {
86                                 if (target == DEF && level == stack[classlevel].level && !startequal)
87                                         /* ignore constructor */
88                                         if (strcmp(stack[classlevel].classname, token))
89                                                 PUT(token, lineno, sp);
90                                 if (target == REF && (level > stack[classlevel].level || startequal) && defined(token))
91                                         PUT(token, lineno, sp);
92                         } else {
93                                 if (target == SYM)
94                                         PUT(token, lineno, sp);
95                         }
96                         break;
97                 case '{': /* } */
98                         DBG_PRINT(level, "{");  /* } */
99
100                         ++level;
101                         if (startclass) {
102                                 char *p = stack[classlevel].terminate;
103                                 char *q = classname;
104
105                                 if (++classlevel >= MAXCLASSSTACK)
106                                         die1("class stack over flow.[%s]", curfile);
107                                 if (classlevel > 1)
108                                         *p++ = '.';
109                                 stack[classlevel].classname = p;
110                                 while (*q)
111                                         *p++ = *q++;
112                                 stack[classlevel].terminate = p;
113                                 stack[classlevel].level = level;
114                                 *p++ = 0;
115                         }
116                         startclass = startthrows = 0;
117                         break;
118                         /* { */
119                 case '}':
120                         if (--level < 0) {
121                                 if (wflag)
122                                         fprintf(stderr, "Warning: missing left '{' (at %d).\n", lineno); /* } */
123                                 level = 0;
124                         }
125                         if (level < stack[classlevel].level)
126                                 *(stack[--classlevel].terminate) = 0;
127                         /* { */
128                         DBG_PRINT(level, "}");
129                         break;
130                 case '=':
131                         startequal = 1;
132                         break;
133                 case ';':
134                         startclass = startthrows = startequal = 0;
135                         break;
136                 case J_CLASS:
137                 case J_INTERFACE:
138                         if ((c = nexttoken(interested, reserved)) == SYMBOL) {
139                                 strcpy(classname, token);
140                                 startclass = 1;
141                                 if (target == DEF)
142                                         PUT(token, lineno, sp);
143                         }
144                         break;
145                 case J_NEW:
146                 case J_INSTANCEOF:
147                         while ((c = nexttoken(interested, reserved)) == SYMBOL && peekc(1) == '.')
148                                 if (target == SYM)
149                                         PUT(token, lineno, sp);
150                         if (c == SYMBOL)
151                                 if (target == REF && defined(token))
152                                         PUT(token, lineno, sp);
153                         break;
154                 case J_THROWS:
155                         startthrows = 1;
156                         break;
157                 case J_BOOLEAN:
158                 case J_BYTE:
159                 case J_CHAR:
160                 case J_DOUBLE:
161                 case J_FLOAT:
162                 case J_INT:
163                 case J_LONG:
164                 case J_SHORT:
165                 case J_VOID:
166                         if (peekc(1) == '.' && (c = nexttoken(interested, reserved)) != J_CLASS)
167                                 pushbacktoken();
168                         break;
169                 default:
170                 }
171         }
172 }
173                 /* sorted by alphabet */
174 static struct words words[] = {
175         {"abstract",    J_ABSTRACT},
176         {"boolean",     J_BOOLEAN},
177         {"break",       J_BREAK},
178         {"byte",        J_BYTE},
179         {"case",        J_CASE},
180         {"catch",       J_CATCH},
181         {"char",        J_CHAR},
182         {"class",       J_CLASS},
183         {"const",       J_CONST},
184         {"continue",    J_CONTINUE},
185         {"default",     J_DEFAULT},
186         {"do",          J_DO},
187         {"double",      J_DOUBLE},
188         {"else",        J_ELSE},
189         {"extends",     J_EXTENDS},
190         {"false",       J_FALSE},
191         {"final",       J_FINAL},
192         {"finally",     J_FINALLY},
193         {"float",       J_FLOAT},
194         {"for",         J_FOR},
195         {"goto",        J_GOTO},
196         {"if",          J_IF},
197         {"implements",  J_IMPLEMENTS},
198         {"import",      J_IMPORT},
199         {"instanceof",  J_INSTANCEOF},
200         {"int",         J_INT},
201         {"interface",   J_INTERFACE},
202         {"long",        J_LONG},
203         {"native",      J_NATIVE},
204         {"new",         J_NEW},
205         {"null",        J_NULL},
206         {"package",     J_PACKAGE},
207         {"private",     J_PRIVATE},
208         {"protected",   J_PROTECTED},
209         {"public",      J_PUBLIC},
210         {"return",      J_RETURN},
211         {"short",       J_SHORT},
212         {"static",      J_STATIC},
213         {"strictfp",    J_STRICTFP},
214         {"super",       J_SUPER},
215         {"switch",      J_SWITCH},
216         {"synchronized",J_SYNCHRONIZED},
217         {"this",        J_THIS},
218         {"throw",       J_THROW},
219         {"throws",      J_THROWS},
220         {"union",       J_UNION},
221         {"transient",   J_TRANSIENT},
222         {"true",        J_TRUE},
223         {"try",         J_TRY},
224         {"void",        J_VOID},
225         {"volatile",    J_VOLATILE},
226         {"while",       J_WHILE},
227         {"widefp",      J_WIDEFP},
228 };
229
230 static int
231 reserved(word)
232         char *word;
233 {
234         struct words tmp;
235         struct words *result;
236
237         tmp.name = word;
238         result = (struct words *)bsearch(&tmp, words, sizeof(words)/sizeof(struct words), sizeof(struct words), cmp);
239         return (result != NULL) ? result->val : SYMBOL;
240 }