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