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