Fix tputs affcnt according to termcap(5), affects terminals
[unix-history] / usr.bin / ctags / ctags.c
CommitLineData
15637ed4
RG
1/*
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, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35char copyright[] =
36"@(#) Copyright (c) 1987 The Regents of the University of California.\n\
37 All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)ctags.c 5.8 (Berkeley) 2/26/91";
42#endif /* not lint */
43
44#include <stdio.h>
45#include <string.h>
46#include <stdlib.h>
47#include "ctags.h"
48
49/*
50 * ctags: create a tags file
51 */
52
53NODE *head; /* head of the sorted binary tree */
54
55 /* boolean "func" (see init()) */
56bool _wht[0177],_etk[0177],_itk[0177],_btk[0177],_gd[0177];
57
58FILE *inf, /* ioptr for current input file */
59 *outf; /* ioptr for tags file */
60
61long lineftell; /* ftell after getc( inf ) == '\n' */
62
63int lineno, /* line number of current line */
64 dflag, /* -d: non-macro defines */
65 tflag, /* -t: create tags for typedefs */
66 wflag, /* -w: suppress warnings */
67 vflag, /* -v: vgrind style index output */
68 xflag; /* -x: cxref style output */
69
70char *curfile, /* current input file name */
71 searchar = '/', /* use /.../ searches by default */
72 lbuf[BUFSIZ];
73
74main(argc,argv)
75 int argc;
76 char **argv;
77{
78 extern char *optarg; /* getopt arguments */
79 extern int optind;
80 static char *outfile = "tags"; /* output file */
81 int aflag, /* -a: append to tags */
82 uflag, /* -u: update tags */
83 exit_val, /* exit value */
84 step, /* step through args */
85 ch; /* getopts char */
86 char cmd[100]; /* too ugly to explain */
87
88 aflag = uflag = NO;
89 while ((ch = getopt(argc,argv,"BFadf:tuwvx")) != EOF)
90 switch((char)ch) {
91 case 'B':
92 searchar = '?';
93 break;
94 case 'F':
95 searchar = '/';
96 break;
97 case 'a':
98 aflag++;
99 break;
100 case 'd':
101 dflag++;
102 break;
103 case 'f':
104 outfile = optarg;
105 break;
106 case 't':
107 tflag++;
108 break;
109 case 'u':
110 uflag++;
111 break;
112 case 'w':
113 wflag++;
114 break;
115 case 'v':
116 vflag++;
117 case 'x':
118 xflag++;
119 break;
120 case '?':
121 default:
122 goto usage;
123 }
124 argv += optind;
125 argc -= optind;
126 if (!argc) {
127usage: puts("Usage: ctags [-BFadtuwvx] [-f tagsfile] file ...");
128 exit(1);
129 }
130
131 init();
132
133 for (exit_val = step = 0;step < argc;++step)
134 if (!(inf = fopen(argv[step],"r"))) {
135 perror(argv[step]);
136 exit_val = 1;
137 }
138 else {
139 curfile = argv[step];
140 find_entries(argv[step]);
141 (void)fclose(inf);
142 }
143
144 if (head)
145 if (xflag)
146 put_entries(head);
147 else {
148 if (uflag) {
149 for (step = 0;step < argc;step++) {
150 (void)sprintf(cmd,"mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",outfile,argv[step],outfile);
151 system(cmd);
152 }
153 ++aflag;
154 }
155 if (!(outf = fopen(outfile, aflag ? "a" : "w"))) {
156 perror(outfile);
157 exit(exit_val);
158 }
159 put_entries(head);
160 (void)fclose(outf);
161 if (uflag) {
162 (void)sprintf(cmd,"sort %s -o %s",outfile,outfile);
163 system(cmd);
164 }
165 }
166 exit(exit_val);
167}
168
169/*
170 * init --
171 * this routine sets up the boolean psuedo-functions which work by
172 * setting boolean flags dependent upon the corresponding character.
173 * Every char which is NOT in that string is false with respect to
174 * the pseudo-function. Therefore, all of the array "_wht" is NO
175 * by default and then the elements subscripted by the chars in
176 * CWHITE are set to YES. Thus, "_wht" of a char is YES if it is in
177 * the string CWHITE, else NO.
178 */
179init()
180{
181 register int i;
182 register char *sp;
183
184 for (i = 0; i < 0177; i++) {
185 _wht[i] = _etk[i] = _itk[i] = _btk[i] = NO;
186 _gd[i] = YES;
187 }
188#define CWHITE " \f\t\n"
189 for (sp = CWHITE; *sp; sp++) /* white space chars */
190 _wht[*sp] = YES;
191#define CTOKEN " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?"
192 for (sp = CTOKEN; *sp; sp++) /* token ending chars */
193 _etk[*sp] = YES;
194#define CINTOK "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789"
195 for (sp = CINTOK; *sp; sp++) /* valid in-token chars */
196 _itk[*sp] = YES;
197#define CBEGIN "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
198 for (sp = CBEGIN; *sp; sp++) /* token starting chars */
199 _btk[*sp] = YES;
200#define CNOTGD ",;"
201 for (sp = CNOTGD; *sp; sp++) /* invalid after-function chars */
202 _gd[*sp] = NO;
203}
204
205/*
206 * find_entries --
207 * this routine opens the specified file and calls the function
208 * which searches the file.
209 */
210find_entries(file)
211 char *file;
212{
213 register char *cp;
214
215 lineno = 0; /* should be 1 ?? KB */
216 if (cp = rindex(file, '.')) {
217 if (cp[1] == 'l' && !cp[2]) {
218 register int c;
219
220 for (;;) {
221 if (GETC(==,EOF))
222 return;
223 if (!iswhite(c)) {
224 rewind(inf);
225 break;
226 }
227 }
228#define LISPCHR ";(["
229/* lisp */ if (index(LISPCHR,(char)c)) {
230 l_entries();
231 return;
232 }
233/* lex */ else {
234 /*
235 * we search all 3 parts of a lex file
236 * for C references. This may be wrong.
237 */
238 toss_yysec();
239 (void)strcpy(lbuf,"%%$");
240 pfnote("yylex",lineno);
241 rewind(inf);
242 }
243 }
244/* yacc */ else if (cp[1] == 'y' && !cp[2]) {
245 /*
246 * we search only the 3rd part of a yacc file
247 * for C references. This may be wrong.
248 */
249 toss_yysec();
250 (void)strcpy(lbuf,"%%$");
251 pfnote("yyparse",lineno);
252 y_entries();
253 }
254/* fortran */ else if ((cp[1] != 'c' && cp[1] != 'h') && !cp[2]) {
255 if (PF_funcs())
256 return;
257 rewind(inf);
258 }
259 }
260/* C */ c_entries();
261}