Commit | Line | Data |
---|---|---|
c30ca4f4 | 1 | /* |
45b3d3fb | 2 | * Copyright (c) 1987, 1993, 1994, 1995 |
374464e3 | 3 | * The Regents of the University of California. All rights reserved. |
5b56324c | 4 | * |
3317ec65 | 5 | * %sccs.include.redist.c% |
c30ca4f4 KB |
6 | */ |
7 | ||
8 | #ifndef lint | |
374464e3 | 9 | static char copyright[] = |
45b3d3fb | 10 | "@(#) Copyright (c) 1987, 1993, 1994, 1995\n\ |
374464e3 | 11 | The Regents of the University of California. All rights reserved.\n"; |
5b56324c | 12 | #endif /* not lint */ |
c30ca4f4 KB |
13 | |
14 | #ifndef lint | |
45b3d3fb | 15 | static char sccsid[] = "@(#)ctags.c 8.4 (Berkeley) %G%"; |
5b56324c | 16 | #endif /* not lint */ |
2e314d68 | 17 | |
d3acad8d JSP |
18 | #include <err.h> |
19 | #include <limits.h> | |
6c2ce1d3 | 20 | #include <stdio.h> |
ebf8ef61 | 21 | #include <string.h> |
6c2ce1d3 | 22 | #include <stdlib.h> |
d3acad8d JSP |
23 | #include <unistd.h> |
24 | ||
6c2ce1d3 | 25 | #include "ctags.h" |
16bc359f KB |
26 | |
27 | /* | |
9927b527 | 28 | * ctags: create a tags file |
16bc359f KB |
29 | */ |
30 | ||
e99c8356 | 31 | NODE *head; /* head of the sorted binary tree */ |
16bc359f | 32 | |
e99c8356 | 33 | /* boolean "func" (see init()) */ |
d3acad8d | 34 | bool _wht[256], _etk[256], _itk[256], _btk[256], _gd[256]; |
16bc359f | 35 | |
d3acad8d JSP |
36 | FILE *inf; /* ioptr for current input file */ |
37 | FILE *outf; /* ioptr for tags file */ | |
16bc359f | 38 | |
e99c8356 | 39 | long lineftell; /* ftell after getc( inf ) == '\n' */ |
16bc359f | 40 | |
d3acad8d JSP |
41 | int lineno; /* line number of current line */ |
42 | int dflag; /* -d: non-macro defines */ | |
43 | int tflag; /* -t: create tags for typedefs */ | |
44 | int vflag; /* -v: vgrind style index output */ | |
45 | int wflag; /* -w: suppress warnings */ | |
46 | int xflag; /* -x: cxref style output */ | |
47 | ||
48 | char *curfile; /* current input file name */ | |
49 | char searchar = '/'; /* use /.../ searches by default */ | |
50 | char lbuf[LINE_MAX]; | |
16bc359f | 51 | |
d3acad8d JSP |
52 | void init __P((void)); |
53 | void find_entries __P((char *)); | |
16bc359f | 54 | |
d3acad8d JSP |
55 | int |
56 | main(argc, argv) | |
e99c8356 KB |
57 | int argc; |
58 | char **argv; | |
16bc359f | 59 | { |
e99c8356 | 60 | static char *outfile = "tags"; /* output file */ |
d3acad8d JSP |
61 | int aflag; /* -a: append to tags */ |
62 | int uflag; /* -u: update tags */ | |
63 | int exit_val; /* exit value */ | |
64 | int step; /* step through args */ | |
65 | int ch; /* getopts char */ | |
5b56324c | 66 | char cmd[100]; /* too ugly to explain */ |
16bc359f | 67 | |
5b56324c | 68 | aflag = uflag = NO; |
d3acad8d JSP |
69 | while ((ch = getopt(argc, argv, "BFadf:tuwvx")) != EOF) |
70 | switch(ch) { | |
71 | case 'B': | |
72 | searchar = '?'; | |
73 | break; | |
74 | case 'F': | |
75 | searchar = '/'; | |
76 | break; | |
77 | case 'a': | |
78 | aflag++; | |
79 | break; | |
80 | case 'd': | |
81 | dflag++; | |
82 | break; | |
83 | case 'f': | |
84 | outfile = optarg; | |
85 | break; | |
86 | case 't': | |
87 | tflag++; | |
88 | break; | |
89 | case 'u': | |
90 | uflag++; | |
91 | break; | |
92 | case 'w': | |
93 | wflag++; | |
94 | break; | |
95 | case 'v': | |
96 | vflag++; | |
97 | case 'x': | |
98 | xflag++; | |
99 | break; | |
100 | case '?': | |
101 | default: | |
102 | goto usage; | |
16bc359f | 103 | } |
e99c8356 KB |
104 | argv += optind; |
105 | argc -= optind; | |
106 | if (!argc) { | |
d3acad8d | 107 | usage: (void)fprintf(stderr, |
45b3d3fb | 108 | "usage: ctags [-BFadtuwvx] [-f tagsfile] file ...\n"); |
16bc359f KB |
109 | exit(1); |
110 | } | |
111 | ||
e99c8356 | 112 | init(); |
16bc359f | 113 | |
d3acad8d JSP |
114 | for (exit_val = step = 0; step < argc; ++step) |
115 | if (!(inf = fopen(argv[step], "r"))) { | |
116 | warn("%s", argv[step]); | |
e99c8356 | 117 | exit_val = 1; |
16bc359f | 118 | } |
5b56324c KB |
119 | else { |
120 | curfile = argv[step]; | |
e99c8356 | 121 | find_entries(argv[step]); |
5b56324c KB |
122 | (void)fclose(inf); |
123 | } | |
16bc359f | 124 | |
5b56324c KB |
125 | if (head) |
126 | if (xflag) | |
127 | put_entries(head); | |
128 | else { | |
129 | if (uflag) { | |
d3acad8d JSP |
130 | for (step = 0; step < argc; step++) { |
131 | (void)sprintf(cmd, | |
132 | "mv %s OTAGS; fgrep -v '\t%s\t' OTAGS >%s; rm OTAGS", | |
133 | outfile, argv[step], | |
134 | outfile); | |
5b56324c KB |
135 | system(cmd); |
136 | } | |
137 | ++aflag; | |
138 | } | |
d3acad8d JSP |
139 | if (!(outf = fopen(outfile, aflag ? "a" : "w"))) |
140 | err(exit_val, "%s", outfile); | |
5b56324c KB |
141 | put_entries(head); |
142 | (void)fclose(outf); | |
143 | if (uflag) { | |
d3acad8d JSP |
144 | (void)sprintf(cmd, "sort -o %s %s", |
145 | outfile, outfile); | |
5b56324c KB |
146 | system(cmd); |
147 | } | |
16bc359f | 148 | } |
e99c8356 | 149 | exit(exit_val); |
16bc359f KB |
150 | } |
151 | ||
152 | /* | |
e99c8356 KB |
153 | * init -- |
154 | * this routine sets up the boolean psuedo-functions which work by | |
155 | * setting boolean flags dependent upon the corresponding character. | |
156 | * Every char which is NOT in that string is false with respect to | |
157 | * the pseudo-function. Therefore, all of the array "_wht" is NO | |
158 | * by default and then the elements subscripted by the chars in | |
159 | * CWHITE are set to YES. Thus, "_wht" of a char is YES if it is in | |
160 | * the string CWHITE, else NO. | |
16bc359f | 161 | */ |
d3acad8d | 162 | void |
e99c8356 | 163 | init() |
16bc359f | 164 | { |
d3acad8d JSP |
165 | int i; |
166 | unsigned char *sp; | |
16bc359f | 167 | |
d3acad8d | 168 | for (i = 0; i < 256; i++) { |
e99c8356 KB |
169 | _wht[i] = _etk[i] = _itk[i] = _btk[i] = NO; |
170 | _gd[i] = YES; | |
171 | } | |
172 | #define CWHITE " \f\t\n" | |
173 | for (sp = CWHITE; *sp; sp++) /* white space chars */ | |
174 | _wht[*sp] = YES; | |
175 | #define CTOKEN " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?" | |
176 | for (sp = CTOKEN; *sp; sp++) /* token ending chars */ | |
177 | _etk[*sp] = YES; | |
178 | #define CINTOK "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789" | |
179 | for (sp = CINTOK; *sp; sp++) /* valid in-token chars */ | |
180 | _itk[*sp] = YES; | |
181 | #define CBEGIN "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" | |
182 | for (sp = CBEGIN; *sp; sp++) /* token starting chars */ | |
183 | _btk[*sp] = YES; | |
184 | #define CNOTGD ",;" | |
185 | for (sp = CNOTGD; *sp; sp++) /* invalid after-function chars */ | |
186 | _gd[*sp] = NO; | |
16bc359f KB |
187 | } |
188 | ||
c30ca4f4 | 189 | /* |
e99c8356 KB |
190 | * find_entries -- |
191 | * this routine opens the specified file and calls the function | |
192 | * which searches the file. | |
c30ca4f4 | 193 | */ |
d3acad8d | 194 | void |
e99c8356 KB |
195 | find_entries(file) |
196 | char *file; | |
c30ca4f4 | 197 | { |
d3acad8d | 198 | char *cp; |
c30ca4f4 | 199 | |
e99c8356 | 200 | lineno = 0; /* should be 1 ?? KB */ |
d3acad8d | 201 | if (cp = strrchr(file, '.')) { |
e99c8356 | 202 | if (cp[1] == 'l' && !cp[2]) { |
d3acad8d | 203 | int c; |
5b56324c KB |
204 | |
205 | for (;;) { | |
d3acad8d | 206 | if (GETC(==, EOF)) |
5b56324c KB |
207 | return; |
208 | if (!iswhite(c)) { | |
209 | rewind(inf); | |
210 | break; | |
211 | } | |
212 | } | |
213 | #define LISPCHR ";([" | |
d3acad8d | 214 | /* lisp */ if (strchr(LISPCHR, c)) { |
5b56324c KB |
215 | l_entries(); |
216 | return; | |
16bc359f | 217 | } |
e99c8356 | 218 | /* lex */ else { |
5b56324c KB |
219 | /* |
220 | * we search all 3 parts of a lex file | |
221 | * for C references. This may be wrong. | |
222 | */ | |
96d022f7 | 223 | toss_yysec(); |
d3acad8d JSP |
224 | (void)strcpy(lbuf, "%%$"); |
225 | pfnote("yylex", lineno); | |
5b56324c | 226 | rewind(inf); |
f5c61c07 | 227 | } |
f5c61c07 | 228 | } |
5b56324c | 229 | /* yacc */ else if (cp[1] == 'y' && !cp[2]) { |
e99c8356 | 230 | /* |
5b56324c KB |
231 | * we search only the 3rd part of a yacc file |
232 | * for C references. This may be wrong. | |
e99c8356 | 233 | */ |
5b56324c | 234 | toss_yysec(); |
d3acad8d JSP |
235 | (void)strcpy(lbuf, "%%$"); |
236 | pfnote("yyparse", lineno); | |
5b56324c | 237 | y_entries(); |
0404816e | 238 | } |
5b56324c KB |
239 | /* fortran */ else if ((cp[1] != 'c' && cp[1] != 'h') && !cp[2]) { |
240 | if (PF_funcs()) | |
0404816e | 241 | return; |
5b56324c | 242 | rewind(inf); |
0404816e | 243 | } |
c30ca4f4 | 244 | } |
5b56324c | 245 | /* C */ c_entries(); |
c30ca4f4 | 246 | } |