1 1.21 rillig /* $NetBSD: input.c,v 1.21 2023/08/26 15:18:27 rillig Exp $ */ 2 1.3 jtc 3 1.1 cgd /* 4 1.3 jtc * Copyright (c) 1980, 1993 5 1.3 jtc * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.10 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.5 lukem #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.3 jtc #if 0 35 1.3 jtc static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/6/93"; 36 1.3 jtc #endif 37 1.21 rillig __RCSID("$NetBSD: input.c,v 1.21 2023/08/26 15:18:27 rillig Exp $"); 38 1.1 cgd #endif /* not lint */ 39 1.1 cgd 40 1.1 cgd #include <stdio.h> 41 1.1 cgd #include <ctype.h> 42 1.1 cgd #include <stdlib.h> 43 1.1 cgd #include <string.h> 44 1.1 cgd #include "error.h" 45 1.1 cgd 46 1.15 dholland int cur_wordc; /* how long the current error message is */ 47 1.15 dholland char **cur_wordv; /* the actual error message */ 48 1.1 cgd 49 1.12 dholland static Errorclass catchall(void); 50 1.12 dholland static Errorclass cpp(void); 51 1.12 dholland static Errorclass f77(void); 52 1.12 dholland static Errorclass lint0(void); 53 1.12 dholland static Errorclass lint1(void); 54 1.12 dholland static Errorclass lint2(void); 55 1.12 dholland static Errorclass lint3(void); 56 1.12 dholland static Errorclass make(void); 57 1.12 dholland static Errorclass mod2(void); 58 1.12 dholland static Errorclass onelong(void); 59 1.12 dholland static Errorclass pccccom(void); /* Portable C Compiler C Compiler */ 60 1.12 dholland static Errorclass ri(void); 61 1.12 dholland static Errorclass richieccom(void); /* Richie Compiler for 11 */ 62 1.17 christos static Errorclass gcc45ccom(void); /* gcc45+ */ 63 1.12 dholland static Errorclass troff(void); 64 1.5 lukem 65 1.1 cgd /* 66 1.13 dholland * Eat all of the lines in the input file, attempting to categorize 67 1.13 dholland * them by their various flavors 68 1.1 cgd */ 69 1.5 lukem void 70 1.9 wiz eaterrors(int *r_errorc, Eptr **r_errorv) 71 1.1 cgd { 72 1.13 dholland Errorclass errorclass = C_SYNC; 73 1.4 christos char *line; 74 1.4 christos size_t inbuflen; 75 1.1 cgd 76 1.13 dholland for (;;) { 77 1.18 christos line = NULL; 78 1.18 christos inbuflen = 0; 79 1.18 christos if (getline(&line, &inbuflen, errorfile) == -1) 80 1.1 cgd break; 81 1.15 dholland wordvbuild(line, &cur_wordc, &cur_wordv); 82 1.13 dholland 83 1.1 cgd /* 84 1.15 dholland * for convenience, convert cur_wordv to be 1 based, instead 85 1.13 dholland * of 0 based. 86 1.1 cgd */ 87 1.15 dholland cur_wordv -= 1; 88 1.15 dholland if (cur_wordc > 0 && 89 1.1 cgd ((( errorclass = onelong() ) != C_UNKNOWN) 90 1.1 cgd || (( errorclass = cpp() ) != C_UNKNOWN) 91 1.17 christos || (( errorclass = gcc45ccom() ) != C_UNKNOWN) 92 1.1 cgd || (( errorclass = pccccom() ) != C_UNKNOWN) 93 1.1 cgd || (( errorclass = richieccom() ) != C_UNKNOWN) 94 1.1 cgd || (( errorclass = lint0() ) != C_UNKNOWN) 95 1.1 cgd || (( errorclass = lint1() ) != C_UNKNOWN) 96 1.1 cgd || (( errorclass = lint2() ) != C_UNKNOWN) 97 1.1 cgd || (( errorclass = lint3() ) != C_UNKNOWN) 98 1.1 cgd || (( errorclass = make() ) != C_UNKNOWN) 99 1.1 cgd || (( errorclass = f77() ) != C_UNKNOWN) 100 1.1 cgd || ((errorclass = pi() ) != C_UNKNOWN) 101 1.1 cgd || (( errorclass = ri() )!= C_UNKNOWN) 102 1.1 cgd || (( errorclass = mod2() )!= C_UNKNOWN) 103 1.1 cgd || (( errorclass = troff() )!= C_UNKNOWN)) 104 1.1 cgd ) ; 105 1.1 cgd else 106 1.1 cgd errorclass = catchall(); 107 1.20 rillig if (cur_wordc > 0) 108 1.15 dholland erroradd(cur_wordc, cur_wordv+1, errorclass, C_UNKNOWN); 109 1.1 cgd } 110 1.1 cgd #ifdef FULLDEBUG 111 1.1 cgd printf("%d errorentrys\n", nerrors); 112 1.1 cgd #endif 113 1.1 cgd arrayify(r_errorc, r_errorv, er_head); 114 1.1 cgd } 115 1.1 cgd 116 1.1 cgd /* 117 1.13 dholland * create a new error entry, given a zero based array and count 118 1.1 cgd */ 119 1.5 lukem void 120 1.9 wiz erroradd(int errorlength, char **errorv, Errorclass errorclass, 121 1.9 wiz Errorclass errorsubclass) 122 1.1 cgd { 123 1.13 dholland Eptr newerror; 124 1.14 dholland const char *cp; 125 1.1 cgd 126 1.13 dholland if (errorclass == C_TRUE) { 127 1.1 cgd /* check canonicalization of the second argument*/ 128 1.20 rillig for (cp = errorv[1]; 129 1.20 rillig *cp != '\0' && isdigit((unsigned char)*cp); cp++) 130 1.1 cgd continue; 131 1.1 cgd errorclass = (*cp == '\0') ? C_TRUE : C_NONSPEC; 132 1.1 cgd #ifdef FULLDEBUG 133 1.1 cgd if (errorclass != C_TRUE) 134 1.1 cgd printf("The 2nd word, \"%s\" is not a number.\n", 135 1.1 cgd errorv[1]); 136 1.1 cgd #endif 137 1.1 cgd } 138 1.13 dholland if (errorlength > 0) { 139 1.15 dholland newerror = Calloc(1, sizeof(Edesc)); 140 1.1 cgd newerror->error_language = language; /* language is global */ 141 1.1 cgd newerror->error_text = errorv; 142 1.1 cgd newerror->error_lgtext = errorlength; 143 1.1 cgd if (errorclass == C_TRUE) 144 1.1 cgd newerror->error_line = atoi(errorv[1]); 145 1.1 cgd newerror->error_e_class = errorclass; 146 1.1 cgd newerror->error_s_class = errorsubclass; 147 1.13 dholland switch (newerror->error_e_class = discardit(newerror)) { 148 1.1 cgd case C_SYNC: nsyncerrors++; break; 149 1.1 cgd case C_DISCARD: ndiscard++; break; 150 1.1 cgd case C_NULLED: nnulled++; break; 151 1.1 cgd case C_NONSPEC: nnonspec++; break; 152 1.1 cgd case C_THISFILE: nthisfile++; break; 153 1.1 cgd case C_TRUE: ntrue++; break; 154 1.1 cgd case C_UNKNOWN: nunknown++; break; 155 1.1 cgd case C_IGNORE: nignore++; break; 156 1.1 cgd } 157 1.1 cgd newerror->error_next = er_head; 158 1.1 cgd er_head = newerror; 159 1.1 cgd newerror->error_no = nerrors++; 160 1.1 cgd } /* length > 0 */ 161 1.1 cgd } 162 1.1 cgd 163 1.12 dholland static Errorclass 164 1.9 wiz onelong(void) 165 1.1 cgd { 166 1.13 dholland char **nwordv; 167 1.13 dholland 168 1.15 dholland if (cur_wordc == 1 && language != INLD) { 169 1.1 cgd /* 170 1.13 dholland * We have either: 171 1.13 dholland * a) file name from cc 172 1.13 dholland * b) Assembler telling world that it is complaining 173 1.13 dholland * c) Noise from make ("Stop.") 174 1.13 dholland * c) Random noise 175 1.1 cgd */ 176 1.15 dholland cur_wordc = 0; 177 1.15 dholland if (strcmp(cur_wordv[1], "Stop.") == 0) { 178 1.13 dholland language = INMAKE; 179 1.19 rillig return C_SYNC; 180 1.1 cgd } 181 1.15 dholland if (strcmp(cur_wordv[1], "Assembler:") == 0) { 182 1.1 cgd /* assembler always alerts us to what happened*/ 183 1.13 dholland language = INAS; 184 1.19 rillig return C_SYNC; 185 1.13 dholland } else 186 1.15 dholland if (strcmp(cur_wordv[1], "Undefined:") == 0) { 187 1.1 cgd /* loader complains about unknown symbols*/ 188 1.13 dholland language = INLD; 189 1.19 rillig return C_SYNC; 190 1.1 cgd } 191 1.15 dholland if (lastchar(cur_wordv[1]) == ':') { 192 1.1 cgd /* cc tells us what file we are in */ 193 1.15 dholland currentfilename = cur_wordv[1]; 194 1.1 cgd (void)substitute(currentfilename, ':', '\0'); 195 1.13 dholland language = INCC; 196 1.19 rillig return C_SYNC; 197 1.1 cgd } 198 1.1 cgd } else 199 1.15 dholland if (cur_wordc == 1 && language == INLD) { 200 1.15 dholland nwordv = Calloc(4, sizeof(char *)); 201 1.16 dholland nwordv[0] = Strdup("ld:"); /* XXX leaked */ 202 1.15 dholland nwordv[1] = cur_wordv[1]; 203 1.16 dholland nwordv[2] = Strdup("is"); /* XXX leaked */ 204 1.16 dholland nwordv[3] = Strdup("undefined.");/* XXX leaked */ 205 1.15 dholland cur_wordc = 4; 206 1.15 dholland cur_wordv = nwordv - 1; 207 1.19 rillig return C_NONSPEC; 208 1.1 cgd } else 209 1.15 dholland if (cur_wordc == 1) { 210 1.19 rillig return C_SYNC; 211 1.1 cgd } 212 1.19 rillig return C_UNKNOWN; 213 1.1 cgd } /* end of one long */ 214 1.1 cgd 215 1.12 dholland static Errorclass 216 1.9 wiz cpp(void) 217 1.1 cgd { 218 1.13 dholland /* 219 1.13 dholland * Now attempt a cpp error message match 220 1.13 dholland * Examples: 221 1.13 dholland * ./morse.h: 23: undefined control 222 1.13 dholland * morsesend.c: 229: MAGNIBBL: argument mismatch 223 1.13 dholland * morsesend.c: 237: MAGNIBBL: argument mismatch 224 1.13 dholland * test1.c: 6: undefined control 225 1.1 cgd */ 226 1.15 dholland if (cur_wordc < 3) 227 1.19 rillig return C_UNKNOWN; 228 1.15 dholland if (language != INLD /* loader errors have almost same fmt */ 229 1.15 dholland && lastchar(cur_wordv[1]) == ':' 230 1.15 dholland && isdigit((unsigned char)firstchar(cur_wordv[2])) 231 1.15 dholland && lastchar(cur_wordv[2]) == ':') { 232 1.1 cgd language = INCPP; 233 1.15 dholland clob_last(cur_wordv[1], '\0'); 234 1.15 dholland clob_last(cur_wordv[2], '\0'); 235 1.19 rillig return C_TRUE; 236 1.1 cgd } 237 1.19 rillig return C_UNKNOWN; 238 1.1 cgd } /*end of cpp*/ 239 1.1 cgd 240 1.12 dholland static Errorclass 241 1.9 wiz pccccom(void) 242 1.1 cgd { 243 1.1 cgd /* 244 1.13 dholland * Now attempt a ccom error message match: 245 1.13 dholland * Examples: 246 1.13 dholland * "morsesend.c", line 237: operands of & have incompatible types 247 1.13 dholland * "test.c", line 7: warning: old-fashioned initialization: use = 248 1.13 dholland * "subdir.d/foo2.h", line 1: illegal initialization 249 1.1 cgd */ 250 1.15 dholland if (cur_wordc < 4) 251 1.19 rillig return C_UNKNOWN; 252 1.15 dholland if (firstchar(cur_wordv[1]) == '"' 253 1.15 dholland && lastchar(cur_wordv[1]) == ',' 254 1.15 dholland && next_lastchar(cur_wordv[1]) == '"' 255 1.15 dholland && strcmp(cur_wordv[2], "line") == 0 256 1.15 dholland && isdigit((unsigned char)firstchar(cur_wordv[3])) 257 1.15 dholland && lastchar(cur_wordv[3]) == ':') { 258 1.15 dholland clob_last(cur_wordv[1], '\0'); /* drop last , */ 259 1.15 dholland clob_last(cur_wordv[1], '\0'); /* drop last " */ 260 1.15 dholland cur_wordv[1]++; /* drop first " */ 261 1.15 dholland clob_last(cur_wordv[3], '\0'); /* drop : on line number */ 262 1.15 dholland cur_wordv[2] = cur_wordv[1]; /* overwrite "line" */ 263 1.15 dholland cur_wordv++; /*compensate*/ 264 1.15 dholland cur_wordc--; 265 1.15 dholland currentfilename = cur_wordv[1]; 266 1.1 cgd language = INCC; 267 1.19 rillig return C_TRUE; 268 1.1 cgd } 269 1.19 rillig return C_UNKNOWN; 270 1.1 cgd } /* end of ccom */ 271 1.13 dholland 272 1.1 cgd /* 273 1.17 christos * Do the error message from gcc 4.5+ which prints: 274 1.17 christos * 275 1.17 christos * fprintf(stderr, "%s:%d:%d: ", filename, line, column); 276 1.17 christos */ 277 1.17 christos 278 1.17 christos static Errorclass 279 1.17 christos gcc45ccom(void) 280 1.17 christos { 281 1.17 christos char *cp, *ccp; 282 1.17 christos char **nwordv; 283 1.17 christos char *file; 284 1.17 christos 285 1.17 christos if (cur_wordc < 2) 286 1.17 christos return C_UNKNOWN; 287 1.17 christos 288 1.17 christos if (lastchar(cur_wordv[1]) != ':') 289 1.17 christos return C_UNKNOWN; 290 1.17 christos 291 1.17 christos cp = cur_wordv[1] + strlen(cur_wordv[1]) - 1; 292 1.17 christos while (isdigit((unsigned char)*--cp)) 293 1.17 christos continue; 294 1.17 christos if (*cp != ':') 295 1.17 christos return C_UNKNOWN; 296 1.17 christos 297 1.17 christos ccp = cp; 298 1.17 christos while (isdigit((unsigned char)*--cp)) 299 1.17 christos continue; 300 1.17 christos if (*cp != ':') 301 1.17 christos return C_UNKNOWN; 302 1.17 christos 303 1.17 christos clob_last(cur_wordv[1], '\0'); /* last : */ 304 1.17 christos *ccp = '\0'; /* middle : */ 305 1.17 christos *cp = '\0'; /* first : */ 306 1.17 christos file = cur_wordv[1]; 307 1.17 christos #ifdef notyet 308 1.17 christos #define EHEAD 2 309 1.17 christos #else 310 1.17 christos #define EHEAD 1 /* Nothing to do with column info yet */ 311 1.17 christos #endif 312 1.17 christos nwordv = wordvsplice(EHEAD, cur_wordc, cur_wordv + 1); 313 1.17 christos nwordv[0] = file; 314 1.17 christos nwordv[1] = cp + 1; 315 1.17 christos #ifdef notyet 316 1.17 christos nwordv[2] = ccp + 1; 317 1.17 christos #endif 318 1.17 christos cur_wordc += 1; 319 1.17 christos cur_wordv = nwordv - 1; 320 1.17 christos language = INCC; 321 1.17 christos currentfilename = cur_wordv[1]; 322 1.17 christos return C_TRUE; 323 1.17 christos } 324 1.17 christos 325 1.17 christos /* 326 1.13 dholland * Do the error message from the Richie C Compiler for the PDP11, 327 1.13 dholland * which has this source: 328 1.1 cgd * 329 1.1 cgd * if (filename[0]) 330 1.1 cgd * fprintf(stderr, "%s:", filename); 331 1.1 cgd * fprintf(stderr, "%d: ", line); 332 1.1 cgd * 333 1.1 cgd */ 334 1.5 lukem 335 1.12 dholland static Errorclass 336 1.9 wiz richieccom(void) 337 1.1 cgd { 338 1.13 dholland char *cp; 339 1.13 dholland char **nwordv; 340 1.13 dholland char *file; 341 1.1 cgd 342 1.15 dholland if (cur_wordc < 2) 343 1.19 rillig return C_UNKNOWN; 344 1.8 christos 345 1.15 dholland if (lastchar(cur_wordv[1]) == ':') { 346 1.15 dholland cp = cur_wordv[1] + strlen(cur_wordv[1]) - 1; 347 1.7 christos while (isdigit((unsigned char)*--cp)) 348 1.1 cgd continue; 349 1.13 dholland if (*cp == ':') { 350 1.15 dholland clob_last(cur_wordv[1], '\0'); /* last : */ 351 1.1 cgd *cp = '\0'; /* first : */ 352 1.15 dholland file = cur_wordv[1]; 353 1.15 dholland nwordv = wordvsplice(1, cur_wordc, cur_wordv+1); 354 1.1 cgd nwordv[0] = file; 355 1.1 cgd nwordv[1] = cp + 1; 356 1.15 dholland cur_wordc += 1; 357 1.15 dholland cur_wordv = nwordv - 1; 358 1.1 cgd language = INCC; 359 1.15 dholland currentfilename = cur_wordv[1]; 360 1.19 rillig return C_TRUE; 361 1.1 cgd } 362 1.1 cgd } 363 1.19 rillig return C_UNKNOWN; 364 1.1 cgd } 365 1.1 cgd 366 1.12 dholland static Errorclass 367 1.9 wiz lint0(void) 368 1.1 cgd { 369 1.13 dholland char **nwordv; 370 1.13 dholland char *line, *file; 371 1.13 dholland 372 1.1 cgd /* 373 1.13 dholland * Attempt a match for the new lint style normal compiler 374 1.13 dholland * error messages, of the form 375 1.13 dholland * 376 1.1 cgd * printf("%s(%d): %s\n", filename, linenumber, message); 377 1.1 cgd */ 378 1.15 dholland if (cur_wordc < 2) 379 1.19 rillig return C_UNKNOWN; 380 1.8 christos 381 1.15 dholland if (lastchar(cur_wordv[1]) == ':' 382 1.15 dholland && next_lastchar(cur_wordv[1]) == ')') { 383 1.15 dholland clob_last(cur_wordv[1], '\0'); /* colon */ 384 1.15 dholland if (persperdexplode(cur_wordv[1], &line, &file)) { 385 1.15 dholland nwordv = wordvsplice(1, cur_wordc, cur_wordv+1); 386 1.8 christos nwordv[0] = file; /* file name */ 387 1.8 christos nwordv[1] = line; /* line number */ 388 1.15 dholland cur_wordc += 1; 389 1.15 dholland cur_wordv = nwordv - 1; 390 1.8 christos language = INLINT; 391 1.19 rillig return C_TRUE; 392 1.1 cgd } 393 1.15 dholland cur_wordv[1][strlen(cur_wordv[1])] = ':'; 394 1.1 cgd } 395 1.19 rillig return C_UNKNOWN; 396 1.1 cgd } 397 1.1 cgd 398 1.12 dholland static Errorclass 399 1.9 wiz lint1(void) 400 1.1 cgd { 401 1.13 dholland char *line1 = NULL, *line2 = NULL; 402 1.13 dholland char *file1 = NULL, *file2 = NULL; 403 1.13 dholland char **nwordv1, **nwordv2; 404 1.1 cgd 405 1.1 cgd /* 406 1.13 dholland * Now, attempt a match for the various errors that lint 407 1.13 dholland * can complain about. 408 1.1 cgd * 409 1.13 dholland * Look first for type 1 lint errors 410 1.1 cgd */ 411 1.15 dholland if (cur_wordc > 1 && strcmp(cur_wordv[cur_wordc-1], "::") == 0) { 412 1.1 cgd /* 413 1.1 cgd * %.7s, arg. %d used inconsistently %s(%d) :: %s(%d) 414 1.1 cgd * %.7s value used inconsistently %s(%d) :: %s(%d) 415 1.1 cgd * %.7s multiply declared %s(%d) :: %s(%d) 416 1.1 cgd * %.7s value declared inconsistently %s(%d) :: %s(%d) 417 1.1 cgd * %.7s function value type must be declared before use %s(%d) :: %s(%d) 418 1.1 cgd */ 419 1.1 cgd language = INLINT; 420 1.15 dholland if (cur_wordc > 2 421 1.15 dholland && persperdexplode(cur_wordv[cur_wordc], &line2, &file2) 422 1.15 dholland && persperdexplode(cur_wordv[cur_wordc-2], &line1, &file1)) { 423 1.15 dholland nwordv1 = wordvsplice(2, cur_wordc, cur_wordv+1); 424 1.15 dholland nwordv2 = wordvsplice(2, cur_wordc, cur_wordv+1); 425 1.15 dholland nwordv1[0] = file1; 426 1.15 dholland nwordv1[1] = line1; 427 1.15 dholland erroradd(cur_wordc+2, nwordv1, C_TRUE, C_DUPL); /* takes 0 based*/ 428 1.15 dholland nwordv2[0] = file2; 429 1.15 dholland nwordv2[1] = line2; 430 1.15 dholland cur_wordc = cur_wordc + 2; 431 1.15 dholland cur_wordv = nwordv2 - 1; /* 1 based */ 432 1.19 rillig return C_TRUE; 433 1.1 cgd } 434 1.1 cgd } 435 1.20 rillig free(file2); 436 1.20 rillig free(file1); 437 1.20 rillig free(line2); 438 1.20 rillig free(line1); 439 1.19 rillig return C_UNKNOWN; 440 1.1 cgd } /* end of lint 1*/ 441 1.1 cgd 442 1.12 dholland static Errorclass 443 1.9 wiz lint2(void) 444 1.1 cgd { 445 1.13 dholland char *file; 446 1.13 dholland char *line; 447 1.13 dholland char **nwordv; 448 1.13 dholland 449 1.1 cgd /* 450 1.13 dholland * Look for type 2 lint errors 451 1.1 cgd * 452 1.1 cgd * %.7s used( %s(%d) ), but not defined 453 1.1 cgd * %.7s defined( %s(%d) ), but never used 454 1.1 cgd * %.7s declared( %s(%d) ), but never used or defined 455 1.1 cgd * 456 1.1 cgd * bufp defined( "./metric.h"(10) ), but never used 457 1.1 cgd */ 458 1.15 dholland if (cur_wordc < 5) 459 1.19 rillig return C_UNKNOWN; 460 1.8 christos 461 1.15 dholland if (lastchar(cur_wordv[2]) == '(' /* ')' */ 462 1.15 dholland && strcmp(cur_wordv[4], "),") == 0) { 463 1.1 cgd language = INLINT; 464 1.15 dholland if (persperdexplode(cur_wordv[3], &line, &file)) { 465 1.15 dholland nwordv = wordvsplice(2, cur_wordc, cur_wordv+1); 466 1.15 dholland nwordv[0] = file; 467 1.15 dholland nwordv[1] = line; 468 1.15 dholland cur_wordc = cur_wordc + 2; 469 1.15 dholland cur_wordv = nwordv - 1; /* 1 based */ 470 1.19 rillig return C_TRUE; 471 1.1 cgd } 472 1.1 cgd } 473 1.19 rillig return C_UNKNOWN; 474 1.1 cgd } /* end of lint 2*/ 475 1.1 cgd 476 1.16 dholland #if 0 /* not const-correct */ 477 1.12 dholland static char *Lint31[4] = {"returns", "value", "which", "is"}; 478 1.12 dholland static char *Lint32[6] = {"value", "is", "used,", "but", "none", "returned"}; 479 1.16 dholland #else 480 1.16 dholland DECL_STRINGS_4(static, Lint31, 481 1.16 dholland "returns", "value", "which", "is"); 482 1.16 dholland DECL_STRINGS_6(static, Lint32, 483 1.16 dholland "value", "is", "used,", "but", "none", "returned"); 484 1.16 dholland #endif 485 1.5 lukem 486 1.12 dholland static Errorclass 487 1.9 wiz lint3(void) 488 1.1 cgd { 489 1.15 dholland if (cur_wordc < 3) 490 1.19 rillig return C_UNKNOWN; 491 1.21 rillig if (wordv_eq(cur_wordv+2, 4, Lint31) 492 1.21 rillig || wordv_eq(cur_wordv+2, 6, Lint32)) { 493 1.1 cgd language = INLINT; 494 1.19 rillig return C_NONSPEC; 495 1.1 cgd } 496 1.19 rillig return C_UNKNOWN; 497 1.1 cgd } 498 1.1 cgd 499 1.1 cgd /* 500 1.13 dholland * Special word vectors for use by F77 recognition 501 1.1 cgd */ 502 1.16 dholland #if 0 /* not const-correct */ 503 1.12 dholland static char *F77_fatal[3] = {"Compiler", "error", "line"}; 504 1.12 dholland static char *F77_error[3] = {"Error", "on", "line"}; 505 1.12 dholland static char *F77_warning[3] = {"Warning", "on", "line"}; 506 1.12 dholland static char *F77_no_ass[3] = {"Error.","No","assembly."}; 507 1.16 dholland #else 508 1.16 dholland DECL_STRINGS_3(static, F77_fatal, "Compiler", "error", "line"); 509 1.16 dholland DECL_STRINGS_3(static, F77_error, "Error", "on", "line"); 510 1.16 dholland DECL_STRINGS_3(static, F77_warning, "Warning", "on", "line"); 511 1.16 dholland DECL_STRINGS_3(static, F77_no_ass, "Error.", "No", "assembly."); 512 1.16 dholland #endif 513 1.5 lukem 514 1.13 dholland static Errorclass 515 1.9 wiz f77(void) 516 1.1 cgd { 517 1.13 dholland char **nwordv; 518 1.13 dholland 519 1.1 cgd /* 520 1.13 dholland * look for f77 errors: 521 1.13 dholland * Error messages from /usr/src/cmd/f77/error.c, with 522 1.13 dholland * these printf formats: 523 1.1 cgd * 524 1.13 dholland * Compiler error line %d of %s: %s 525 1.13 dholland * Error on line %d of %s: %s 526 1.13 dholland * Warning on line %d of %s: %s 527 1.13 dholland * Error. No assembly. 528 1.1 cgd */ 529 1.21 rillig if (cur_wordc == 3 && wordv_eq(cur_wordv+1, 3, F77_no_ass)) { 530 1.15 dholland cur_wordc = 0; 531 1.19 rillig return C_SYNC; 532 1.1 cgd } 533 1.15 dholland if (cur_wordc < 6) 534 1.19 rillig return C_UNKNOWN; 535 1.15 dholland if (lastchar(cur_wordv[6]) == ':' 536 1.13 dholland && ( 537 1.21 rillig wordv_eq(cur_wordv+1, 3, F77_fatal) 538 1.21 rillig || wordv_eq(cur_wordv+1, 3, F77_error) 539 1.21 rillig || wordv_eq(cur_wordv+1, 3, F77_warning) 540 1.15 dholland ) 541 1.13 dholland ) { 542 1.1 cgd language = INF77; 543 1.15 dholland nwordv = wordvsplice(2, cur_wordc, cur_wordv+1); 544 1.15 dholland nwordv[0] = cur_wordv[6]; 545 1.1 cgd clob_last(nwordv[0],'\0'); 546 1.15 dholland nwordv[1] = cur_wordv[4]; 547 1.15 dholland cur_wordc += 2; 548 1.15 dholland cur_wordv = nwordv - 1; /* 1 based */ 549 1.19 rillig return C_TRUE; 550 1.1 cgd } 551 1.19 rillig return C_UNKNOWN; 552 1.1 cgd } /* end of f77 */ 553 1.1 cgd 554 1.16 dholland #if 0 /* not const-correct */ 555 1.12 dholland static char *Make_Croak[3] = {"***", "Error", "code"}; 556 1.12 dholland static char *Make_NotRemade[5] = {"not", "remade", "because", "of", "errors"}; 557 1.16 dholland #else 558 1.16 dholland DECL_STRINGS_3(static, Make_Croak, "***", "Error", "code"); 559 1.16 dholland DECL_STRINGS_5(static, Make_NotRemade, 560 1.16 dholland "not", "remade", "because", "of", "errors"); 561 1.16 dholland #endif 562 1.5 lukem 563 1.12 dholland static Errorclass 564 1.9 wiz make(void) 565 1.1 cgd { 566 1.21 rillig if (wordv_eq(cur_wordv+1, 3, Make_Croak)) { 567 1.1 cgd language = INMAKE; 568 1.19 rillig return C_SYNC; 569 1.1 cgd } 570 1.21 rillig if (wordv_eq(cur_wordv+2, 5, Make_NotRemade)) { 571 1.1 cgd language = INMAKE; 572 1.19 rillig return C_SYNC; 573 1.1 cgd } 574 1.19 rillig return C_UNKNOWN; 575 1.1 cgd } 576 1.5 lukem 577 1.12 dholland static Errorclass 578 1.9 wiz ri(void) 579 1.1 cgd { 580 1.1 cgd /* 581 1.13 dholland * Match an error message produced by ri; here is the 582 1.13 dholland * procedure yanked from the distributed version of ri 583 1.13 dholland * April 24, 1980. 584 1.13 dholland * 585 1.1 cgd * serror(str, x1, x2, x3) 586 1.1 cgd * char str[]; 587 1.1 cgd * char *x1, *x2, *x3; 588 1.1 cgd * { 589 1.1 cgd * extern int yylineno; 590 1.13 dholland * 591 1.1 cgd * putc('"', stdout); 592 1.1 cgd * fputs(srcfile, stdout); 593 1.1 cgd * putc('"', stdout); 594 1.1 cgd * fprintf(stdout, " %d: ", yylineno); 595 1.1 cgd * fprintf(stdout, str, x1, x2, x3); 596 1.1 cgd * fprintf(stdout, "\n"); 597 1.1 cgd * synerrs++; 598 1.1 cgd * } 599 1.1 cgd */ 600 1.15 dholland if (cur_wordc < 3) 601 1.19 rillig return C_UNKNOWN; 602 1.15 dholland if (firstchar(cur_wordv[1]) == '"' 603 1.15 dholland && lastchar(cur_wordv[1]) == '"' 604 1.15 dholland && lastchar(cur_wordv[2]) == ':' 605 1.15 dholland && isdigit((unsigned char)firstchar(cur_wordv[2]))) { 606 1.15 dholland clob_last(cur_wordv[1], '\0'); /* drop the last " */ 607 1.15 dholland cur_wordv[1]++; /* skip over the first " */ 608 1.15 dholland clob_last(cur_wordv[2], '\0'); 609 1.1 cgd language = INRI; 610 1.19 rillig return C_TRUE; 611 1.1 cgd } 612 1.19 rillig return C_UNKNOWN; 613 1.1 cgd } 614 1.1 cgd 615 1.12 dholland static Errorclass 616 1.9 wiz catchall(void) 617 1.1 cgd { 618 1.1 cgd /* 619 1.13 dholland * Catches random things. 620 1.1 cgd */ 621 1.1 cgd language = INUNKNOWN; 622 1.19 rillig return C_NONSPEC; 623 1.1 cgd } /* end of catch all*/ 624 1.1 cgd 625 1.12 dholland static Errorclass 626 1.9 wiz troff(void) 627 1.1 cgd { 628 1.1 cgd /* 629 1.13 dholland * troff source error message, from eqn, bib, tbl... 630 1.13 dholland * Just like pcc ccom, except uses `' 631 1.1 cgd */ 632 1.15 dholland if (cur_wordc < 4) 633 1.19 rillig return C_UNKNOWN; 634 1.13 dholland 635 1.15 dholland if (firstchar(cur_wordv[1]) == '`' 636 1.15 dholland && lastchar(cur_wordv[1]) == ',' 637 1.15 dholland && next_lastchar(cur_wordv[1]) == '\'' 638 1.15 dholland && strcmp(cur_wordv[2], "line") == 0 639 1.15 dholland && isdigit((unsigned char)firstchar(cur_wordv[3])) 640 1.15 dholland && lastchar(cur_wordv[3]) == ':') { 641 1.15 dholland clob_last(cur_wordv[1], '\0'); /* drop last , */ 642 1.15 dholland clob_last(cur_wordv[1], '\0'); /* drop last " */ 643 1.15 dholland cur_wordv[1]++; /* drop first " */ 644 1.15 dholland clob_last(cur_wordv[3], '\0'); /* drop : on line number */ 645 1.15 dholland cur_wordv[2] = cur_wordv[1]; /* overwrite "line" */ 646 1.15 dholland cur_wordv++; /*compensate*/ 647 1.15 dholland currentfilename = cur_wordv[1]; 648 1.1 cgd language = INTROFF; 649 1.19 rillig return C_TRUE; 650 1.1 cgd } 651 1.19 rillig return C_UNKNOWN; 652 1.1 cgd } 653 1.5 lukem 654 1.12 dholland static Errorclass 655 1.9 wiz mod2(void) 656 1.1 cgd { 657 1.1 cgd /* 658 1.13 dholland * for decwrl modula2 compiler (powell) 659 1.1 cgd */ 660 1.15 dholland if (cur_wordc < 5) 661 1.19 rillig return C_UNKNOWN; 662 1.15 dholland if ((strcmp(cur_wordv[1], "!!!") == 0 /* early version */ 663 1.15 dholland || strcmp(cur_wordv[1], "File") == 0) /* later version */ 664 1.15 dholland && lastchar(cur_wordv[2]) == ',' /* file name */ 665 1.15 dholland && strcmp(cur_wordv[3], "line") == 0 666 1.15 dholland && isdigit((unsigned char)firstchar(cur_wordv[4])) /* line number */ 667 1.15 dholland && lastchar(cur_wordv[4]) == ':' /* line number */ 668 1.13 dholland ) { 669 1.15 dholland clob_last(cur_wordv[2], '\0'); /* drop last , on file name */ 670 1.15 dholland clob_last(cur_wordv[4], '\0'); /* drop last : on line number */ 671 1.15 dholland cur_wordv[3] = cur_wordv[2]; /* file name on top of "line" */ 672 1.15 dholland cur_wordv += 2; 673 1.15 dholland cur_wordc -= 2; 674 1.15 dholland currentfilename = cur_wordv[1]; 675 1.1 cgd language = INMOD2; 676 1.19 rillig return C_TRUE; 677 1.1 cgd } 678 1.19 rillig return C_UNKNOWN; 679 1.1 cgd } 680