|
|
1.1 root 1: static char *sccsid = "@(#)errormain.c 1.2 (Berkeley) 10/16/80";
2: #include <stdio.h>
3: #include <ctype.h>
4: #include <signal.h>
5: #include "error.h"
6:
7: int nerrors = 0;
8: struct error_desc *er_head;
9: struct error_desc **errors;
10:
11: int nfiles = 0;
12: struct error_desc ***files; /* array of pointers into errors*/
13: int language = INCC;
14:
15: char *currentfilename = "????";
16: char *processname;
17: char *im_on; /* my tty name */
18:
19: boolean query = FALSE; /* query the operator if touch files */
20: boolean notouch = FALSE; /* don't touch ANY files */
21: boolean piflag = FALSE; /* this is not pi */
22:
23: char *suffixlist = ".*"; /* initially, can touch any file */
24:
25: int errorsort();
26: int onintr();
27: /*
28: * error [-I ignorename] [-n] [-q] [-t suffixlist] [-s] [-v] [infile]
29: *
30: * -I: the following name, `ignorename' contains a list of
31: * function names that are not to be treated as hard errors.
32: * Default: ~/.errorsrc
33: *
34: * -n: don't touch ANY files!
35: *
36: * -q: The user is to be queried before touching each
37: * file; if not specified, all files with hard, non
38: * ignorable errors are touched (assuming they can be).
39: *
40: * -t: touch only files ending with the list of suffices, each
41: * suffix preceded by a dot.
42: * eg, -t .c.y.l
43: * will touch only files ending with .c, .y or .l
44: *
45: * -s: print a summary of the error's categories.
46: *
47: * -v: after touching all files, overlay vi(1), ex(1) or ed(1)
48: * on top of error, entered in the first file with
49: * an error in it, with the appropriate editor
50: * set up to use the "next" command to get the other
51: * files containing errors.
52: *
53: * -p: (obsolete: for older versions of pi without bug
54: * fix regarding printing out the name of the main file
55: * with an error in it)
56: * Take the following argument and use it as the name of
57: * the pascal source file, suffix .p
58: *
59: * -E: show the errors in sorted order; intended for
60: * debugging.
61: *
62: * -S: show the errors in unsorted order
63: * (as they come from the error file)
64: *
65: * infile: The error messages come from this file.
66: * Default: stdin
67: */
68: main(argc, argv)
69: int argc;
70: char *argv[];
71: {
72: char *cp;
73: char *ignorename = 0;
74: int ed_argc;
75: char **ed_argv; /*return from touchfiles*/
76: boolean show_errors = FALSE;
77: boolean Show_Errors = FALSE;
78: boolean pr_summary = FALSE;
79: boolean edit_files = FALSE;
80:
81: processname = argv[0];
82:
83: errorfile = stdin;
84: if (argc > 1){
85: for(; (argc > 1) && (argv[1][0] == '-'); argc--, argv++){
86: for (cp = argv[1] + 1; *cp; cp++){
87: switch(*cp){
88: default:
89: fprintf(stderr, "%s: -%c: Unknown flag\n",
90: processname, *cp);
91: break;
92: case 'n': /* no touch */
93: notouch = TRUE;
94: break;
95: case 'q': /* query */
96: query = TRUE;
97: break;
98: case 'S':
99: Show_Errors = TRUE;
100: break;
101: case 's': /* show summary */
102: pr_summary = TRUE;
103: break;
104: case 'v': /* edit files */
105: edit_files = TRUE;
106: break;
107: #ifndef ERNIE
108: case 'p':
109: *cp-- = 0; argv++; argc--;
110: if (argc > 1){
111: currentfilename=argv[1];
112: piflag = TRUE;
113: }
114: break;
115: #endif
116: case 't':
117: *cp-- = 0; argv++; argc--;
118: if (argc > 1){
119: suffixlist = argv[1];
120: }
121: break;
122: case 'I': /*ignore file name*/
123: *cp-- = 0; argv++; argc--;
124: if (argc > 1)
125: ignorename = argv[1];
126: break;
127: } /*end of the argument switch*/
128: } /*end of loop to consume characters after '-'*/
129: }
130: } /* end of being at least one argument */
131: if (notouch)
132: suffixlist = 0;
133: if (argc > 1){
134: if (argc > 3){
135: fprintf(stderr, "%s: Only takes 0 or 1 arguments\n",
136: processname);
137: exit(3);
138: }
139: if ( (errorfile = fopen(argv[1], "r")) == NULL){
140: fprintf(stderr, "%s: %s: No such file or directory for reading errors.\n",
141: processname, argv[1]);
142: exit(4);
143: }
144: }
145: im_on = "/dev/tty";
146: if ( (queryfile = fopen(im_on, "r")) == NULL){
147: fprintf(stderr,"%s: Can't open \"%s\" to query the user.\n",
148: processname, im_on);
149: exit(9);
150: }
151: if (signal(SIGINT, onintr) == SIG_IGN)
152: signal(SIGINT, SIG_IGN);
153: if (signal(SIGTERM, onintr) == SIG_IGN)
154: signal(SIGTERM, SIG_IGN);
155: getignored(ignorename);
156: eaterrors(&nerrors, &errors);
157: if (Show_Errors)
158: printerrors(TRUE, nerrors, errors);
159: qsort(errors, nerrors, sizeof (struct error_desc *), errorsort);
160: if (show_errors)
161: printerrors(FALSE, nerrors, errors);
162: findfiles(nerrors, errors, &nfiles, &files);
163: #define P(msg, arg) fprintf(stdout, msg, arg)
164: if (pr_summary){
165: if (nunknown)
166: P("%d Errors are unclassifiable.\n", nunknown);
167: if (nignore)
168: P("%d Errors are classifiable, but totally discarded.\n",nignore);
169: if (nsyncerrors)
170: P("%d Errors are synchronization errors.\n", nsyncerrors);
171: if (nignore)
172: P("%d Errors are discarded because they refer to sacrosinct files.\n", ndiscard);
173: if (nnulled)
174: P("%d Errors are nulled because they refer to specific functions.\n", nnulled);
175: if (nnonspec)
176: P("%d Errors are not specific to any file.\n", nnonspec);
177: if (nthisfile)
178: P("%d Errors are specific to a given file, but not to a line.\n", nthisfile);
179: if (ntrue)
180: P("%d Errors are true errors, and can be inserted into the files.\n", ntrue);
181: }
182: filenames(nfiles, files);
183: fflush(stdout);
184: if (touchfiles(nfiles, files, &ed_argc, &ed_argv) && edit_files){
185: if (!query ||
186: inquire("Do you still want to edit the files you touched? ")){
187: /*
188: * ed_agument's first argument is
189: * a vi/ex compatabile search argument
190: * to find the first occurance of ###
191: */
192: try("vi", ed_argc, ed_argv);
193: try("ex", ed_argc, ed_argv);
194: try("ed", ed_argc-1, ed_argv+1);
195: fprintf(stdout, "Can't find any editors.\n");
196: }
197: }
198: }
199:
200: try(name, argc, argv)
201: char *name;
202: int argc;
203: char **argv;
204: {
205: argv[0] = name;
206: wordvprint(stdout, argc, argv);
207: fprintf(stdout, "\n");
208: fflush(stderr);
209: fflush(stdout);
210: sleep(2);
211: if (freopen(im_on, "r", stdin) == NULL)
212: return;
213: if (freopen(im_on, "w", stdout) == NULL)
214: return;
215: execvp(name, argv);
216: }
217:
218: int errorsort(epp1, epp2)
219: struct error_desc **epp1, **epp2;
220: {
221: register struct error_desc *ep1, *ep2;
222: int order;
223: /*
224: * Sort by:
225: * 1) synchronization, non specific, discarded errors first;
226: * 2) nulled and true errors last
227: * a) grouped by similar file names
228: * 1) grouped in ascending line number
229: */
230: ep1 = *epp1; ep2 = *epp2;
231: if (ep1 == 0 || ep2 == 0)
232: return(0);
233: if ( (NOTSORTABLE(ep1->error_e_class)) ^ (NOTSORTABLE(ep2->error_e_class))){
234: return(NOTSORTABLE(ep1->error_e_class) ? -1 : 1);
235: }
236: if (NOTSORTABLE(ep1->error_e_class)) /* then both are */
237: return(ep1->error_no - ep2->error_no);
238: order = strcmp(ep1->error_text[0], ep2->error_text[0]);
239: if (order == 0){
240: return(ep1->error_line - ep2->error_line);
241: }
242: return(order);
243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.