1 /* 2 * Copyright (c) 1980 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 35 char copyright[] = 36 "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 37 All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 static char sccsid[] = "@(#)main.c 5.6 (Berkeley) 2/26/91"; 42 #endif /* not lint */ 43 44 #include <signal.h> 45 #include <unistd.h> 46 #include <stdio.h> 47 #include <ctype.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include "error.h" 51 #include "pathnames.h" 52 53 int nerrors = 0; 54 Eptr er_head; 55 Eptr *errors; 56 57 int nfiles = 0; 58 Eptr **files; /* array of pointers into errors*/ 59 int language = INCC; 60 61 char *currentfilename = "????"; 62 char *processname; 63 char im_on[] = _PATH_TTY; /* my tty name */ 64 65 boolean query = FALSE; /* query the operator if touch files */ 66 boolean notouch = FALSE; /* don't touch ANY files */ 67 boolean piflag = FALSE; /* this is not pi */ 68 boolean terse = FALSE; /* Terse output */ 69 70 char *suffixlist = ".*"; /* initially, can touch any file */ 71 72 int errorsort(); 73 void onintr(); 74 /* 75 * error [-I ignorename] [-n] [-q] [-t suffixlist] [-s] [-v] [infile] 76 * 77 * -T: terse output 78 * 79 * -I: the following name, `ignorename' contains a list of 80 * function names that are not to be treated as hard errors. 81 * Default: ~/.errorsrc 82 * 83 * -n: don't touch ANY files! 84 * 85 * -q: The user is to be queried before touching each 86 * file; if not specified, all files with hard, non 87 * ignorable errors are touched (assuming they can be). 88 * 89 * -t: touch only files ending with the list of suffices, each 90 * suffix preceded by a dot. 91 * eg, -t .c.y.l 92 * will touch only files ending with .c, .y or .l 93 * 94 * -s: print a summary of the error's categories. 95 * 96 * -v: after touching all files, overlay vi(1), ex(1) or ed(1) 97 * on top of error, entered in the first file with 98 * an error in it, with the appropriate editor 99 * set up to use the "next" command to get the other 100 * files containing errors. 101 * 102 * -p: (obsolete: for older versions of pi without bug 103 * fix regarding printing out the name of the main file 104 * with an error in it) 105 * Take the following argument and use it as the name of 106 * the pascal source file, suffix .p 107 * 108 * -E: show the errors in sorted order; intended for 109 * debugging. 110 * 111 * -S: show the errors in unsorted order 112 * (as they come from the error file) 113 * 114 * infile: The error messages come from this file. 115 * Default: stdin 116 */ 117 main(argc, argv) 118 int argc; 119 char *argv[]; 120 { 121 char *cp; 122 char *ignorename = 0; 123 int ed_argc; 124 char **ed_argv; /*return from touchfiles*/ 125 boolean show_errors = FALSE; 126 boolean Show_Errors = FALSE; 127 boolean pr_summary = FALSE; 128 boolean edit_files = FALSE; 129 130 processname = argv[0]; 131 132 errorfile = stdin; 133 if (argc > 1) for(; (argc > 1) && (argv[1][0] == '-'); argc--, argv++){ 134 for (cp = argv[1] + 1; *cp; cp++) switch(*cp){ 135 default: 136 fprintf(stderr, "%s: -%c: Unknown flag\n", 137 processname, *cp); 138 break; 139 140 case 'n': notouch = TRUE; break; 141 case 'q': query = TRUE; break; 142 case 'S': Show_Errors = TRUE; break; 143 case 's': pr_summary = TRUE; break; 144 case 'v': edit_files = TRUE; break; 145 case 'T': terse = TRUE; break; 146 case 't': 147 *cp-- = 0; argv++; argc--; 148 if (argc > 1){ 149 suffixlist = argv[1]; 150 } 151 break; 152 case 'I': /*ignore file name*/ 153 *cp-- = 0; argv++; argc--; 154 if (argc > 1) 155 ignorename = argv[1]; 156 break; 157 } 158 } 159 if (notouch) 160 suffixlist = 0; 161 if (argc > 1){ 162 if (argc > 3){ 163 fprintf(stderr, "%s: Only takes 0 or 1 arguments\n", 164 processname); 165 exit(3); 166 } 167 if ( (errorfile = fopen(argv[1], "r")) == NULL){ 168 fprintf(stderr, "%s: %s: No such file or directory for reading errors.\n", 169 processname, argv[1]); 170 exit(4); 171 } 172 } 173 if ( (queryfile = fopen(im_on, "r")) == NULL){ 174 if (query){ 175 fprintf(stderr, 176 "%s: Can't open \"%s\" to query the user.\n", 177 processname, im_on); 178 exit(9); 179 } 180 } 181 if (signal(SIGINT, onintr) == SIG_IGN) 182 signal(SIGINT, SIG_IGN); 183 if (signal(SIGTERM, onintr) == SIG_IGN) 184 signal(SIGTERM, SIG_IGN); 185 getignored(ignorename); 186 eaterrors(&nerrors, &errors); 187 if (Show_Errors) 188 printerrors(TRUE, nerrors, errors); 189 qsort(errors, nerrors, sizeof(Eptr), errorsort); 190 if (show_errors) 191 printerrors(FALSE, nerrors, errors); 192 findfiles(nerrors, errors, &nfiles, &files); 193 #define P(msg, arg) fprintf(stdout, msg, arg) 194 if (pr_summary){ 195 if (nunknown) 196 P("%d Errors are unclassifiable.\n", nunknown); 197 if (nignore) 198 P("%d Errors are classifiable, but totally discarded.\n",nignore); 199 if (nsyncerrors) 200 P("%d Errors are synchronization errors.\n", nsyncerrors); 201 if (nignore) 202 P("%d Errors are discarded because they refer to sacrosinct files.\n", ndiscard); 203 if (nnulled) 204 P("%d Errors are nulled because they refer to specific functions.\n", nnulled); 205 if (nnonspec) 206 P("%d Errors are not specific to any file.\n", nnonspec); 207 if (nthisfile) 208 P("%d Errors are specific to a given file, but not to a line.\n", nthisfile); 209 if (ntrue) 210 P("%d Errors are true errors, and can be inserted into the files.\n", ntrue); 211 } 212 filenames(nfiles, files); 213 fflush(stdout); 214 if (touchfiles(nfiles, files, &ed_argc, &ed_argv) && edit_files) 215 forkvi(ed_argc, ed_argv); 216 } 217 218 forkvi(argc, argv) 219 int argc; 220 char **argv; 221 { 222 if (query){ 223 switch(inquire(terse 224 ? "Edit? " 225 : "Do you still want to edit the files you touched? ")){ 226 case Q_NO: 227 case Q_no: 228 return; 229 default: 230 break; 231 } 232 } 233 /* 234 * ed_agument's first argument is 235 * a vi/ex compatabile search argument 236 * to find the first occurance of ### 237 */ 238 try("vi", argc, argv); 239 try("ex", argc, argv); 240 try("ed", argc-1, argv+1); 241 fprintf(stdout, "Can't find any editors.\n"); 242 } 243 244 try(name, argc, argv) 245 char *name; 246 int argc; 247 char **argv; 248 { 249 argv[0] = name; 250 wordvprint(stdout, argc, argv); 251 fprintf(stdout, "\n"); 252 fflush(stderr); 253 fflush(stdout); 254 sleep(2); 255 if (freopen(im_on, "r", stdin) == NULL) 256 return; 257 if (freopen(im_on, "w", stdout) == NULL) 258 return; 259 execvp(name, argv); 260 } 261 262 int errorsort(epp1, epp2) 263 Eptr *epp1, *epp2; 264 { 265 reg Eptr ep1, ep2; 266 int order; 267 /* 268 * Sort by: 269 * 1) synchronization, non specific, discarded errors first; 270 * 2) nulled and true errors last 271 * a) grouped by similar file names 272 * 1) grouped in ascending line number 273 */ 274 ep1 = *epp1; ep2 = *epp2; 275 if (ep1 == 0 || ep2 == 0) 276 return(0); 277 if ( (NOTSORTABLE(ep1->error_e_class)) ^ (NOTSORTABLE(ep2->error_e_class))){ 278 return(NOTSORTABLE(ep1->error_e_class) ? -1 : 1); 279 } 280 if (NOTSORTABLE(ep1->error_e_class)) /* then both are */ 281 return(ep1->error_no - ep2->error_no); 282 order = strcmp(ep1->error_text[0], ep2->error_text[0]); 283 if (order == 0){ 284 return(ep1->error_line - ep2->error_line); 285 } 286 return(order); 287 } 288