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