Annotation of src/usr.bin/error/main.c, Revision 1.9
1.9 ! millert 1: /* $OpenBSD: main.c,v 1.8 2002/06/14 21:35:00 todd Exp $ */
1.1 deraadt 2: /* $NetBSD: main.c,v 1.3 1995/09/02 06:15:37 jtc Exp $ */
3:
4: /*
5: * Copyright (c) 1980, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
1.9 ! millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
33: #ifndef lint
34: static char copyright[] =
35: "@(#) Copyright (c) 1980, 1993\n\
36: The Regents of the University of California. All rights reserved.\n";
37: #endif /* not lint */
38:
39: #ifndef lint
40: #if 0
41: static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
42: #endif
1.9 ! millert 43: static char rcsid[] = "$OpenBSD: main.c,v 1.8 2002/06/14 21:35:00 todd Exp $";
1.1 deraadt 44: #endif /* not lint */
45:
46: #include <signal.h>
47: #include <unistd.h>
48: #include <stdio.h>
49: #include <ctype.h>
50: #include <stdlib.h>
51: #include <string.h>
1.6 deraadt 52: #include <err.h>
1.1 deraadt 53: #include "error.h"
54: #include "pathnames.h"
55:
56: int nerrors = 0;
57: Eptr er_head;
58: Eptr *errors;
59:
60: int nfiles = 0;
61: Eptr **files; /* array of pointers into errors*/
62: int language = INCC;
63:
64: char *currentfilename = "????";
65: char im_on[] = _PATH_TTY; /* my tty name */
66:
67: boolean query = FALSE; /* query the operator if touch files */
68: boolean notouch = FALSE; /* don't touch ANY files */
69: boolean piflag = FALSE; /* this is not pi */
70: boolean terse = FALSE; /* Terse output */
71:
72: char *suffixlist = ".*"; /* initially, can touch any file */
73:
74: int errorsort();
75: void onintr();
1.5 aaron 76: void usage();
77:
1.1 deraadt 78: /*
79: * error [-I ignorename] [-n] [-q] [-t suffixlist] [-s] [-v] [infile]
80: *
81: * -T: terse output
82: *
83: * -I: the following name, `ignorename' contains a list of
84: * function names that are not to be treated as hard errors.
85: * Default: ~/.errorsrc
86: *
87: * -n: don't touch ANY files!
88: *
89: * -q: The user is to be queried before touching each
90: * file; if not specified, all files with hard, non
91: * ignorable errors are touched (assuming they can be).
92: *
93: * -t: touch only files ending with the list of suffices, each
94: * suffix preceded by a dot.
95: * eg, -t .c.y.l
96: * will touch only files ending with .c, .y or .l
97: *
98: * -s: print a summary of the error's categories.
99: *
100: * -v: after touching all files, overlay vi(1), ex(1) or ed(1)
101: * on top of error, entered in the first file with
102: * an error in it, with the appropriate editor
103: * set up to use the "next" command to get the other
104: * files containing errors.
105: *
106: * -p: (obsolete: for older versions of pi without bug
107: * fix regarding printing out the name of the main file
108: * with an error in it)
109: * Take the following argument and use it as the name of
110: * the pascal source file, suffix .p
111: *
112: * -S: show the errors in unsorted order
113: * (as they come from the error file)
114: *
115: * infile: The error messages come from this file.
116: * Default: stdin
117: */
1.5 aaron 118: int
1.1 deraadt 119: main(argc, argv)
1.5 aaron 120: int argc;
121: char *argv[];
1.1 deraadt 122: {
1.5 aaron 123: char *ignorename = 0;
124: char **ed_argv; /* return from touchfiles */
125: int ch, ed_argc;
1.1 deraadt 126: boolean show_errors = FALSE;
127: boolean Show_Errors = FALSE;
128: boolean pr_summary = FALSE;
129: boolean edit_files = FALSE;
130:
131: errorfile = stdin;
1.5 aaron 132: while ((ch = getopt(argc, argv, "STnqsvI:t:")) != -1)
133: switch (ch) {
134: case 'S':
135: Show_Errors = TRUE;
136: break;
137: case 'T':
138: terse = TRUE;
139: break;
140: case 'n':
141: notouch = TRUE;
142: break;
143: case 'q':
144: query = TRUE;
145: break;
146: case 's':
147: pr_summary = TRUE;
148: break;
149: case 'v':
150: edit_files = TRUE;
151: break;
152: case 'I':
153: ignorename = optarg;
1.1 deraadt 154: break;
155: case 't':
1.5 aaron 156: suffixlist = optarg;
1.1 deraadt 157: break;
1.5 aaron 158: default:
159: usage();
1.1 deraadt 160: }
1.5 aaron 161:
162: argc -= optind;
163: argv += optind;
164:
1.1 deraadt 165: if (notouch)
1.5 aaron 166: suffixlist = NULL;
167:
168: if (argc > 1) {
1.3 mickey 169: if (argc > 3)
1.7 mpech 170: errx(3, "Only takes 0 or 1 arguments.");
1.5 aaron 171: if ((errorfile = fopen(argv[1], "r")) == NULL)
1.4 millert 172: err(4, "%s", argv[1]);
1.1 deraadt 173: }
1.5 aaron 174:
175: if ((queryfile = fopen(im_on, "r")) == NULL) {
176: if (query) {
1.3 mickey 177: errx(9, "Can't open \"%s\" to query the user.", im_on);
1.1 deraadt 178: exit(9);
179: }
180: }
1.5 aaron 181:
1.1 deraadt 182: if (signal(SIGINT, onintr) == SIG_IGN)
183: signal(SIGINT, SIG_IGN);
184: if (signal(SIGTERM, onintr) == SIG_IGN)
185: signal(SIGTERM, SIG_IGN);
1.5 aaron 186:
1.1 deraadt 187: getignored(ignorename);
188: eaterrors(&nerrors, &errors);
1.5 aaron 189:
1.1 deraadt 190: if (Show_Errors)
191: printerrors(TRUE, nerrors, errors);
1.5 aaron 192:
1.1 deraadt 193: qsort(errors, nerrors, sizeof(Eptr), errorsort);
1.5 aaron 194:
1.1 deraadt 195: if (show_errors)
196: printerrors(FALSE, nerrors, errors);
1.5 aaron 197:
1.1 deraadt 198: findfiles(nerrors, errors, &nfiles, &files);
1.5 aaron 199:
1.1 deraadt 200: #define P(msg, arg) fprintf(stdout, msg, arg)
1.5 aaron 201:
202: if (pr_summary) {
203: if (nunknown)
204: P("%d Errors are unclassifiable.\n", nunknown);
205: if (nignore)
206: P("%d Errors are classifiable, but totally discarded.\n",nignore);
207: if (nsyncerrors)
208: P("%d Errors are synchronization errors.\n", nsyncerrors);
209: if (nignore)
210: P("%d Errors are discarded because they refer to sacrosinct files.\n", ndiscard);
211: if (nnulled)
212: P("%d Errors are nulled because they refer to specific functions.\n", nnulled);
213: if (nnonspec)
214: P("%d Errors are not specific to any file.\n", nnonspec);
215: if (nthisfile)
216: P("%d Errors are specific to a given file, but not to a line.\n", nthisfile);
217: if (ntrue)
218: P("%d Errors are true errors, and can be inserted into the files.\n", ntrue);
1.1 deraadt 219: }
1.5 aaron 220:
1.1 deraadt 221: filenames(nfiles, files);
222: fflush(stdout);
1.5 aaron 223:
1.1 deraadt 224: if (touchfiles(nfiles, files, &ed_argc, &ed_argv) && edit_files)
225: forkvi(ed_argc, ed_argv);
1.6 deraadt 226: exit(0);
1.1 deraadt 227: }
228:
1.6 deraadt 229: void
1.1 deraadt 230: forkvi(argc, argv)
231: int argc;
232: char **argv;
233: {
1.5 aaron 234: if (query) {
235: switch (inquire(terse ? "Edit? " :
236: "Do you still want to edit the files you touched? ")) {
1.1 deraadt 237: case Q_NO:
238: case Q_no:
239: return;
240: default:
241: break;
242: }
243: }
1.5 aaron 244:
1.1 deraadt 245: /*
246: * ed_agument's first argument is
1.8 todd 247: * a vi/ex compatible search argument
1.1 deraadt 248: * to find the first occurance of ###
249: */
250: try("vi", argc, argv);
251: try("ex", argc, argv);
1.5 aaron 252: try("ed", argc - 1, argv + 1);
1.1 deraadt 253: fprintf(stdout, "Can't find any editors.\n");
254: }
255:
1.6 deraadt 256: void
1.1 deraadt 257: try(name, argc, argv)
1.5 aaron 258: char *name;
259: int argc;
260: char **argv;
1.1 deraadt 261: {
262: argv[0] = name;
263: wordvprint(stdout, argc, argv);
264: fprintf(stdout, "\n");
265: fflush(stderr);
266: fflush(stdout);
267: sleep(2);
1.5 aaron 268:
1.1 deraadt 269: if (freopen(im_on, "r", stdin) == NULL)
270: return;
271: if (freopen(im_on, "w", stdout) == NULL)
272: return;
1.5 aaron 273:
1.1 deraadt 274: execvp(name, argv);
275: }
276:
277: int errorsort(epp1, epp2)
1.5 aaron 278: Eptr *epp1, *epp2;
1.1 deraadt 279: {
1.5 aaron 280: reg Eptr ep1, ep2;
281: int order;
282:
1.1 deraadt 283: /*
284: * Sort by:
1.5 aaron 285: * 1) synchronization, non specific, discarded errors first;
286: * 2) nulled and true errors last
287: * a) grouped by similar file names
288: * b) grouped in ascending line number
1.1 deraadt 289: */
290: ep1 = *epp1; ep2 = *epp2;
291: if (ep1 == 0 || ep2 == 0)
1.5 aaron 292: return (0);
293:
294: if ((NOTSORTABLE(ep1->error_e_class)) ^
295: (NOTSORTABLE(ep2->error_e_class))) {
296: return (NOTSORTABLE(ep1->error_e_class) ? -1 : 1);
1.1 deraadt 297: }
1.5 aaron 298:
1.1 deraadt 299: if (NOTSORTABLE(ep1->error_e_class)) /* then both are */
1.5 aaron 300: return (ep1->error_no - ep2->error_no);
301:
1.1 deraadt 302: order = strcmp(ep1->error_text[0], ep2->error_text[0]);
1.5 aaron 303: if (order == 0)
304: return (ep1->error_line - ep2->error_line);
305:
306: return (order);
307: }
308:
309: void
310: usage()
311: {
312: extern char *__progname;
313:
314: (void)fprintf(stderr,
315: "usage: %s [-STnsqv] [-I ignorefile] [-t suffixlist] [name]\n",
316: __progname);
317: exit(1);
1.1 deraadt 318: }