|
|
1.1 ! root 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 are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: static char sccsid[] = "@(#)errorinput.c 5.3 (Berkeley) 6/29/88"; ! 20: #endif /* not lint */ ! 21: ! 22: #include <stdio.h> ! 23: #include <ctype.h> ! 24: #include "error.h" ! 25: ! 26: int wordc; /* how long the current error message is */ ! 27: char **wordv; /* the actual error message */ ! 28: ! 29: int nerrors; ! 30: int language; ! 31: ! 32: Errorclass onelong(); ! 33: Errorclass cpp(); ! 34: Errorclass pccccom(); /* Portable C Compiler C Compiler */ ! 35: Errorclass richieccom(); /* Richie Compiler for 11 */ ! 36: Errorclass lint0(); ! 37: Errorclass lint1(); ! 38: Errorclass lint2(); ! 39: Errorclass lint3(); ! 40: Errorclass make(); ! 41: Errorclass f77(); ! 42: Errorclass pi(); ! 43: Errorclass ri(); ! 44: Errorclass troff(); ! 45: Errorclass mod2(); ! 46: /* ! 47: * Eat all of the lines in the input file, attempting to categorize ! 48: * them by their various flavors ! 49: */ ! 50: static char inbuffer[BUFSIZ]; ! 51: ! 52: eaterrors(r_errorc, r_errorv) ! 53: int *r_errorc; ! 54: Eptr **r_errorv; ! 55: { ! 56: extern boolean piflag; ! 57: Errorclass errorclass = C_SYNC; ! 58: ! 59: for (;;){ ! 60: if (fgets(inbuffer, BUFSIZ, errorfile) == NULL) ! 61: break; ! 62: wordvbuild(inbuffer, &wordc, &wordv); ! 63: /* ! 64: * for convience, convert wordv to be 1 based, instead ! 65: * of 0 based. ! 66: */ ! 67: wordv -= 1; ! 68: if ( wordc > 0 && ! 69: ((( errorclass = onelong() ) != C_UNKNOWN) ! 70: || (( errorclass = cpp() ) != C_UNKNOWN) ! 71: || (( errorclass = pccccom() ) != C_UNKNOWN) ! 72: || (( errorclass = richieccom() ) != C_UNKNOWN) ! 73: || (( errorclass = lint0() ) != C_UNKNOWN) ! 74: || (( errorclass = lint1() ) != C_UNKNOWN) ! 75: || (( errorclass = lint2() ) != C_UNKNOWN) ! 76: || (( errorclass = lint3() ) != C_UNKNOWN) ! 77: || (( errorclass = make() ) != C_UNKNOWN) ! 78: || (( errorclass = f77() ) != C_UNKNOWN) ! 79: || ((errorclass = pi() ) != C_UNKNOWN) ! 80: || (( errorclass = ri() )!= C_UNKNOWN) ! 81: || (( errorclass = mod2() )!= C_UNKNOWN) ! 82: || (( errorclass = troff() )!= C_UNKNOWN)) ! 83: ) ; ! 84: else ! 85: errorclass = catchall(); ! 86: if (wordc) ! 87: erroradd(wordc, wordv+1, errorclass, C_UNKNOWN); ! 88: } ! 89: #ifdef FULLDEBUG ! 90: printf("%d errorentrys\n", nerrors); ! 91: #endif ! 92: arrayify(r_errorc, r_errorv, er_head); ! 93: } ! 94: ! 95: /* ! 96: * create a new error entry, given a zero based array and count ! 97: */ ! 98: erroradd(errorlength, errorv, errorclass, errorsubclass) ! 99: int errorlength; ! 100: char **errorv; ! 101: Errorclass errorclass; ! 102: Errorclass errorsubclass; ! 103: { ! 104: reg Eptr newerror; ! 105: reg char *cp; ! 106: ! 107: if (errorclass == C_TRUE){ ! 108: /* check canonicalization of the second argument*/ ! 109: for(cp = errorv[1]; *cp && isdigit(*cp); cp++) ! 110: continue; ! 111: errorclass = (*cp == '\0') ? C_TRUE : C_NONSPEC; ! 112: #ifdef FULLDEBUG ! 113: if (errorclass != C_TRUE) ! 114: printf("The 2nd word, \"%s\" is not a number.\n", ! 115: errorv[1]); ! 116: #endif ! 117: } ! 118: if (errorlength > 0){ ! 119: newerror = (Eptr)Calloc(1, sizeof(Edesc)); ! 120: newerror->error_language = language; /* language is global */ ! 121: newerror->error_text = errorv; ! 122: newerror->error_lgtext = errorlength; ! 123: if (errorclass == C_TRUE) ! 124: newerror->error_line = atoi(errorv[1]); ! 125: newerror->error_e_class = errorclass; ! 126: newerror->error_s_class = errorsubclass; ! 127: switch(newerror->error_e_class = discardit(newerror)){ ! 128: case C_SYNC: nsyncerrors++; break; ! 129: case C_DISCARD: ndiscard++; break; ! 130: case C_NULLED: nnulled++; break; ! 131: case C_NONSPEC: nnonspec++; break; ! 132: case C_THISFILE: nthisfile++; break; ! 133: case C_TRUE: ntrue++; break; ! 134: case C_UNKNOWN: nunknown++; break; ! 135: case C_IGNORE: nignore++; break; ! 136: } ! 137: newerror->error_next = er_head; ! 138: er_head = newerror; ! 139: newerror->error_no = nerrors++; ! 140: } /* length > 0 */ ! 141: } ! 142: ! 143: Errorclass onelong() ! 144: { ! 145: char **nwordv; ! 146: if ( (wordc == 1) && (language != INLD) ){ ! 147: /* ! 148: * We have either: ! 149: * a) file name from cc ! 150: * b) Assembler telling world that it is complaining ! 151: * c) Noise from make ("Stop.") ! 152: * c) Random noise ! 153: */ ! 154: wordc = 0; ! 155: if (strcmp(wordv[1], "Stop.") == 0){ ! 156: language = INMAKE; return(C_SYNC); ! 157: } ! 158: if (strcmp(wordv[1], "Assembler:") == 0){ ! 159: /* assembler always alerts us to what happened*/ ! 160: language = INAS; return(C_SYNC); ! 161: } else ! 162: if (strcmp(wordv[1], "Undefined:") == 0){ ! 163: /* loader complains about unknown symbols*/ ! 164: language = INLD; return(C_SYNC); ! 165: } ! 166: if (lastchar(wordv[1]) == ':'){ ! 167: /* cc tells us what file we are in */ ! 168: currentfilename = wordv[1]; ! 169: (void)substitute(currentfilename, ':', '\0'); ! 170: language = INCC; return(C_SYNC); ! 171: } ! 172: } else ! 173: if ( (wordc == 1) && (language == INLD) ){ ! 174: nwordv = (char **)Calloc(4, sizeof(char *)); ! 175: nwordv[0] = "ld:"; ! 176: nwordv[1] = wordv[1]; ! 177: nwordv[2] = "is"; ! 178: nwordv[3] = "undefined."; ! 179: wordc = 4; ! 180: wordv = nwordv - 1; ! 181: return(C_NONSPEC); ! 182: } else ! 183: if (wordc == 1){ ! 184: return(C_SYNC); ! 185: } ! 186: return(C_UNKNOWN); ! 187: } /* end of one long */ ! 188: ! 189: Errorclass cpp() ! 190: { ! 191: /* ! 192: * Now attempt a cpp error message match ! 193: * Examples: ! 194: * ./morse.h: 23: undefined control ! 195: * morsesend.c: 229: MAGNIBBL: argument mismatch ! 196: * morsesend.c: 237: MAGNIBBL: argument mismatch ! 197: * test1.c: 6: undefined control ! 198: */ ! 199: if ( (language != INLD) /* loader errors have almost same fmt*/ ! 200: && (lastchar(wordv[1]) == ':') ! 201: && (isdigit(firstchar(wordv[2]))) ! 202: && (lastchar(wordv[2]) == ':') ){ ! 203: language = INCPP; ! 204: clob_last(wordv[1], '\0'); ! 205: clob_last(wordv[2], '\0'); ! 206: return(C_TRUE); ! 207: } ! 208: return(C_UNKNOWN); ! 209: } /*end of cpp*/ ! 210: ! 211: Errorclass pccccom() ! 212: { ! 213: /* ! 214: * Now attempt a ccom error message match: ! 215: * Examples: ! 216: * "morsesend.c", line 237: operands of & have incompatible types ! 217: * "test.c", line 7: warning: old-fashioned initialization: use = ! 218: * "subdir.d/foo2.h", line 1: illegal initialization ! 219: */ ! 220: if ( (firstchar(wordv[1]) == '"') ! 221: && (lastchar(wordv[1]) == ',') ! 222: && (next_lastchar(wordv[1]) == '"') ! 223: && (strcmp(wordv[2],"line") == 0) ! 224: && (isdigit(firstchar(wordv[3]))) ! 225: && (lastchar(wordv[3]) == ':') ){ ! 226: clob_last(wordv[1], '\0'); /* drop last , */ ! 227: clob_last(wordv[1], '\0'); /* drop last " */ ! 228: wordv[1]++; /* drop first " */ ! 229: clob_last(wordv[3], '\0'); /* drop : on line number */ ! 230: wordv[2] = wordv[1]; /* overwrite "line" */ ! 231: wordv++; /*compensate*/ ! 232: wordc--; ! 233: currentfilename = wordv[1]; ! 234: language = INCC; ! 235: return(C_TRUE); ! 236: } ! 237: return(C_UNKNOWN); ! 238: } /* end of ccom */ ! 239: /* ! 240: * Do the error message from the Richie C Compiler for the PDP11, ! 241: * which has this source: ! 242: * ! 243: * if (filename[0]) ! 244: * fprintf(stderr, "%s:", filename); ! 245: * fprintf(stderr, "%d: ", line); ! 246: * ! 247: */ ! 248: Errorclass richieccom() ! 249: { ! 250: reg char *cp; ! 251: reg char **nwordv; ! 252: char *file; ! 253: ! 254: if (lastchar(wordv[1]) == ':'){ ! 255: cp = wordv[1] + strlen(wordv[1]) - 1; ! 256: while (isdigit(*--cp)) ! 257: continue; ! 258: if (*cp == ':'){ ! 259: clob_last(wordv[1], '\0'); /* last : */ ! 260: *cp = '\0'; /* first : */ ! 261: file = wordv[1]; ! 262: nwordv = wordvsplice(1, wordc, wordv+1); ! 263: nwordv[0] = file; ! 264: nwordv[1] = cp + 1; ! 265: wordc += 1; ! 266: wordv = nwordv - 1; ! 267: language = INCC; ! 268: currentfilename = wordv[1]; ! 269: return(C_TRUE); ! 270: } ! 271: } ! 272: return(C_UNKNOWN); ! 273: } ! 274: ! 275: Errorclass lint0() ! 276: { ! 277: reg char **nwordv; ! 278: char *line, *file; ! 279: /* ! 280: * Attempt a match for the new lint style normal compiler ! 281: * error messages, of the form ! 282: * ! 283: * printf("%s(%d): %s\n", filename, linenumber, message); ! 284: */ ! 285: if (wordc >= 2){ ! 286: if ( (lastchar(wordv[1]) == ':') ! 287: && (next_lastchar(wordv[1]) == ')') ! 288: ) { ! 289: clob_last(wordv[1], '\0'); /* colon */ ! 290: if (persperdexplode(wordv[1], &line, &file)){ ! 291: nwordv = wordvsplice(1, wordc, wordv+1); ! 292: nwordv[0] = file; /* file name */ ! 293: nwordv[1] = line; /* line number */ ! 294: wordc += 1; ! 295: wordv = nwordv - 1; ! 296: language = INLINT; ! 297: return(C_TRUE); ! 298: } ! 299: wordv[1][strlen(wordv[1])] = ':'; ! 300: } ! 301: } ! 302: return (C_UNKNOWN); ! 303: } ! 304: ! 305: Errorclass lint1() ! 306: { ! 307: char *line1, *line2; ! 308: char *file1, *file2; ! 309: char **nwordv1, **nwordv2; ! 310: ! 311: /* ! 312: * Now, attempt a match for the various errors that lint ! 313: * can complain about. ! 314: * ! 315: * Look first for type 1 lint errors ! 316: */ ! 317: if (wordc > 1 && strcmp(wordv[wordc-1], "::") == 0){ ! 318: /* ! 319: * %.7s, arg. %d used inconsistently %s(%d) :: %s(%d) ! 320: * %.7s value used inconsistently %s(%d) :: %s(%d) ! 321: * %.7s multiply declared %s(%d) :: %s(%d) ! 322: * %.7s value declared inconsistently %s(%d) :: %s(%d) ! 323: * %.7s function value type must be declared before use %s(%d) :: %s(%d) ! 324: */ ! 325: language = INLINT; ! 326: if (wordc > 2 ! 327: && (persperdexplode(wordv[wordc], &line2, &file2)) ! 328: && (persperdexplode(wordv[wordc-2], &line1, &file1)) ){ ! 329: nwordv1 = wordvsplice(2, wordc, wordv+1); ! 330: nwordv2 = wordvsplice(2, wordc, wordv+1); ! 331: nwordv1[0] = file1; nwordv1[1] = line1; ! 332: erroradd(wordc+2, nwordv1, C_TRUE, C_DUPL); /* takes 0 based*/ ! 333: nwordv2[0] = file2; nwordv2[1] = line2; ! 334: wordc = wordc + 2; ! 335: wordv = nwordv2 - 1; /* 1 based */ ! 336: return(C_TRUE); ! 337: } ! 338: } ! 339: return(C_UNKNOWN); ! 340: } /* end of lint 1*/ ! 341: ! 342: Errorclass lint2() ! 343: { ! 344: char *file; ! 345: char *line; ! 346: char **nwordv; ! 347: /* ! 348: * Look for type 2 lint errors ! 349: * ! 350: * %.7s used( %s(%d) ), but not defined ! 351: * %.7s defined( %s(%d) ), but never used ! 352: * %.7s declared( %s(%d) ), but never used or defined ! 353: * ! 354: * bufp defined( "./metric.h"(10) ), but never used ! 355: */ ! 356: if ( (lastchar(wordv[2]) == '(' /* ')' */ ) ! 357: && (strcmp(wordv[4], "),") == 0) ){ ! 358: language = INLINT; ! 359: if (persperdexplode(wordv[3], &line, &file)){ ! 360: nwordv = wordvsplice(2, wordc, wordv+1); ! 361: nwordv[0] = file; nwordv[1] = line; ! 362: wordc = wordc + 2; ! 363: wordv = nwordv - 1; /* 1 based */ ! 364: return(C_TRUE); ! 365: } ! 366: } ! 367: return(C_UNKNOWN); ! 368: } /* end of lint 2*/ ! 369: ! 370: char *Lint31[4] = {"returns", "value", "which", "is"}; ! 371: char *Lint32[6] = {"value", "is", "used,", "but", "none", "returned"}; ! 372: Errorclass lint3() ! 373: { ! 374: if ( (wordvcmp(wordv+2, 4, Lint31) == 0) ! 375: || (wordvcmp(wordv+2, 6, Lint32) == 0) ){ ! 376: language = INLINT; ! 377: return(C_NONSPEC); ! 378: } ! 379: return(C_UNKNOWN); ! 380: } ! 381: ! 382: /* ! 383: * Special word vectors for use by F77 recognition ! 384: */ ! 385: char *F77_fatal[3] = {"Compiler", "error", "line"}; ! 386: char *F77_error[3] = {"Error", "on", "line"}; ! 387: char *F77_warning[3] = {"Warning", "on", "line"}; ! 388: char *F77_no_ass[3] = {"Error.","No","assembly."}; ! 389: f77() ! 390: { ! 391: char **nwordv; ! 392: /* ! 393: * look for f77 errors: ! 394: * Error messages from /usr/src/cmd/f77/error.c, with ! 395: * these printf formats: ! 396: * ! 397: * Compiler error line %d of %s: %s ! 398: * Error on line %d of %s: %s ! 399: * Warning on line %d of %s: %s ! 400: * Error. No assembly. ! 401: */ ! 402: if (wordc == 3 && wordvcmp(wordv+1, 3, F77_no_ass) == 0) { ! 403: wordc = 0; ! 404: return(C_SYNC); ! 405: } ! 406: if (wordc < 6) ! 407: return(C_UNKNOWN); ! 408: if ( (lastchar(wordv[6]) == ':') ! 409: &&( ! 410: (wordvcmp(wordv+1, 3, F77_fatal) == 0) ! 411: || (wordvcmp(wordv+1, 3, F77_error) == 0) ! 412: || (wordvcmp(wordv+1, 3, F77_warning) == 0) ) ! 413: ){ ! 414: language = INF77; ! 415: nwordv = wordvsplice(2, wordc, wordv+1); ! 416: nwordv[0] = wordv[6]; ! 417: clob_last(nwordv[0],'\0'); ! 418: nwordv[1] = wordv[4]; ! 419: wordc += 2; ! 420: wordv = nwordv - 1; /* 1 based */ ! 421: return(C_TRUE); ! 422: } ! 423: return(C_UNKNOWN); ! 424: } /* end of f77 */ ! 425: ! 426: char *Make_Croak[3] = {"***", "Error", "code"}; ! 427: char *Make_NotRemade[5] = {"not", "remade", "because", "of", "errors"}; ! 428: Errorclass make() ! 429: { ! 430: if (wordvcmp(wordv+1, 3, Make_Croak) == 0){ ! 431: language = INMAKE; ! 432: return(C_SYNC); ! 433: } ! 434: if (wordvcmp(wordv+2, 5, Make_NotRemade) == 0){ ! 435: language = INMAKE; ! 436: return(C_SYNC); ! 437: } ! 438: return(C_UNKNOWN); ! 439: } ! 440: Errorclass ri() ! 441: { ! 442: /* ! 443: * Match an error message produced by ri; here is the ! 444: * procedure yanked from the distributed version of ri ! 445: * April 24, 1980. ! 446: * ! 447: * serror(str, x1, x2, x3) ! 448: * char str[]; ! 449: * char *x1, *x2, *x3; ! 450: * { ! 451: * extern int yylineno; ! 452: * ! 453: * putc('"', stdout); ! 454: * fputs(srcfile, stdout); ! 455: * putc('"', stdout); ! 456: * fprintf(stdout, " %d: ", yylineno); ! 457: * fprintf(stdout, str, x1, x2, x3); ! 458: * fprintf(stdout, "\n"); ! 459: * synerrs++; ! 460: * } ! 461: */ ! 462: if ( (firstchar(wordv[1]) == '"') ! 463: &&(lastchar(wordv[1]) == '"') ! 464: &&(lastchar(wordv[2]) == ':') ! 465: &&(isdigit(firstchar(wordv[2]))) ){ ! 466: clob_last(wordv[1], '\0'); /* drop the last " */ ! 467: wordv[1]++; /* skip over the first " */ ! 468: clob_last(wordv[2], '\0'); ! 469: language = INRI; ! 470: return(C_TRUE); ! 471: } ! 472: return(C_UNKNOWN); ! 473: } ! 474: ! 475: Errorclass catchall() ! 476: { ! 477: /* ! 478: * Catches random things. ! 479: */ ! 480: language = INUNKNOWN; ! 481: return(C_NONSPEC); ! 482: } /* end of catch all*/ ! 483: ! 484: Errorclass troff() ! 485: { ! 486: /* ! 487: * troff source error message, from eqn, bib, tbl... ! 488: * Just like pcc ccom, except uses `' ! 489: */ ! 490: if ( (firstchar(wordv[1]) == '`') ! 491: && (lastchar(wordv[1]) == ',') ! 492: && (next_lastchar(wordv[1]) == '\'') ! 493: && (strcmp(wordv[2],"line") == 0) ! 494: && (isdigit(firstchar(wordv[3]))) ! 495: && (lastchar(wordv[3]) == ':') ){ ! 496: clob_last(wordv[1], '\0'); /* drop last , */ ! 497: clob_last(wordv[1], '\0'); /* drop last " */ ! 498: wordv[1]++; /* drop first " */ ! 499: clob_last(wordv[3], '\0'); /* drop : on line number */ ! 500: wordv[2] = wordv[1]; /* overwrite "line" */ ! 501: wordv++; /*compensate*/ ! 502: currentfilename = wordv[1]; ! 503: language = INTROFF; ! 504: return(C_TRUE); ! 505: } ! 506: return(C_UNKNOWN); ! 507: } ! 508: Errorclass mod2() ! 509: { ! 510: /* ! 511: * for decwrl modula2 compiler (powell) ! 512: */ ! 513: if ( ( (strcmp(wordv[1], "!!!") == 0) /* early version */ ! 514: ||(strcmp(wordv[1], "File") == 0)) /* later version */ ! 515: && (lastchar(wordv[2]) == ',') /* file name */ ! 516: && (strcmp(wordv[3], "line") == 0) ! 517: && (isdigit(firstchar(wordv[4]))) /* line number */ ! 518: && (lastchar(wordv[4]) == ':') /* line number */ ! 519: ){ ! 520: clob_last(wordv[2], '\0'); /* drop last , on file name */ ! 521: clob_last(wordv[4], '\0'); /* drop last : on line number */ ! 522: wordv[3] = wordv[2]; /* file name on top of "line" */ ! 523: wordv += 2; ! 524: wordc -= 2; ! 525: currentfilename = wordv[1]; ! 526: language = INMOD2; ! 527: return(C_TRUE); ! 528: } ! 529: return(C_UNKNOWN); ! 530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.