1 /* $NetBSD: err.c,v 1.119 2021/05/16 11:11:36 rillig Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995 Jochen Pohl 5 * All Rights Reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Jochen Pohl for 18 * The NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #if HAVE_NBTOOL_CONFIG_H 35 #include "nbtool_config.h" 36 #endif 37 38 #include <sys/cdefs.h> 39 #if defined(__RCSID) && !defined(lint) 40 __RCSID("$NetBSD: err.c,v 1.119 2021/05/16 11:11:36 rillig Exp $"); 41 #endif 42 43 #include <sys/types.h> 44 #include <stdarg.h> 45 #include <stdlib.h> 46 47 #include "lint1.h" 48 49 /* number of errors found */ 50 int nerr; 51 52 /* number of syntax errors */ 53 int sytxerr; 54 55 56 const char *const msgs[] = { 57 "empty declaration", /* 0 */ 58 "old style declaration; add 'int'", /* 1 */ 59 "empty declaration", /* 2 */ 60 "'%s' declared in argument declaration list", /* 3 */ 61 "illegal type combination", /* 4 */ 62 "modifying typedef with '%s'; only qualifiers allowed", /* 5 */ 63 "use 'double' instead of 'long float'", /* 6 */ 64 "only one storage class allowed", /* 7 */ 65 "illegal storage class", /* 8 */ 66 "only register valid as formal parameter storage class", /* 9 */ 67 "duplicate '%s'", /* 10 */ 68 "bit-field initializer out of range", /* 11 */ 69 "compiler takes size of function", /* 12 */ 70 "incomplete enum type: %s", /* 13 */ 71 "compiler takes alignment of function", /* 14 */ 72 "function returns illegal type", /* 15 */ 73 "array of function is illegal", /* 16 */ 74 "null dimension", /* 17 */ 75 "illegal use of 'void'", /* 18 */ 76 "void type for '%s'", /* 19 */ 77 "negative array dimension (%d)", /* 20 */ 78 "redeclaration of formal parameter %s", /* 21 */ 79 "incomplete or misplaced function definition", /* 22 */ 80 "undefined label %s", /* 23 */ 81 "cannot initialize function: %s", /* 24 */ 82 "cannot initialize typedef: %s", /* 25 */ 83 "cannot initialize extern declaration: %s", /* 26 */ 84 "redeclaration of %s", /* 27 */ 85 "redefinition of %s", /* 28 */ 86 "previously declared extern, becomes static: %s", /* 29 */ 87 "redeclaration of %s; ANSI C requires static", /* 30 */ 88 "incomplete structure or union %s: %s", /* 31 */ 89 "argument type defaults to 'int': %s", /* 32 */ 90 "duplicate member name: %s", /* 33 */ 91 "nonportable bit-field type '%s'", /* 34 */ 92 "illegal bit-field type '%s'", /* 35 */ 93 "illegal bit-field size: %d", /* 36 */ 94 "zero size bit-field", /* 37 */ 95 "function illegal in structure or union", /* 38 */ 96 "zero sized array in struct is a C99 extension: %s", /* 39 */ 97 "unknown size: %s", /* 40 */ 98 "illegal use of bit-field", /* 41 */ 99 "forward reference to enum type", /* 42 */ 100 "redefinition hides earlier one: %s", /* 43 */ 101 "declaration introduces new type in ANSI C: %s %s", /* 44 */ 102 "base type is really '%s %s'", /* 45 */ 103 "(%s) tag redeclared", /* 46 */ 104 "zero sized %s is a C9X feature", /* 47 */ 105 "overflow in enumeration values: %s", /* 48 */ 106 "anonymous struct/union members is a C9X feature", /* 49 */ 107 "a function is declared as an argument: %s", /* 50 */ 108 "parameter mismatch: %d declared, %d defined", /* 51 */ 109 "cannot initialize parameter: %s", /* 52 */ 110 "declared argument %s is missing", /* 53 */ 111 "trailing ',' prohibited in enum declaration", /* 54 */ 112 "integral constant expression expected", /* 55 */ 113 "integral constant too large", /* 56 */ 114 "enumeration constant hides parameter: %s", /* 57 */ 115 "type does not match prototype: %s", /* 58 */ 116 "formal parameter lacks name: param #%d", /* 59 */ 117 "void must be sole parameter", /* 60 */ 118 "void parameter cannot have name: %s", /* 61 */ 119 "function prototype parameters must have types", /* 62 */ 120 "prototype does not match old-style definition", /* 63 */ 121 "()-less function definition", /* 64 */ 122 "%s has no named members", /* 65 */ 123 "syntax requires ';' after last struct/union member", /* 66 */ 124 "cannot return incomplete type", /* 67 */ 125 "typedef already qualified with '%s'", /* 68 */ 126 "inappropriate qualifiers with 'void'", /* 69 */ 127 "%soperand of '%s' is unsigned in ANSI C", /* 70 */ 128 "too many characters in character constant", /* 71 */ 129 "typedef declares no type name", /* 72 */ 130 "empty character constant", /* 73 */ 131 "no hex digits follow \\x", /* 74 */ 132 "overflow in hex escape", /* 75 */ 133 "character escape does not fit in character", /* 76 */ 134 "bad octal digit %c", /* 77 */ 135 "nonportable character escape", /* 78 */ 136 "dubious escape \\%c", /* 79 */ 137 "dubious escape \\%o", /* 80 */ 138 "\\a undefined in traditional C", /* 81 */ 139 "\\x undefined in traditional C", /* 82 */ 140 "storage class after type is obsolescent", /* 83 */ 141 "ANSI C requires formal parameter before '...'", /* 84 */ 142 "dubious tag declaration: %s %s", /* 85 */ 143 "automatic hides external declaration: %s", /* 86 */ 144 "static hides external declaration: %s", /* 87 */ 145 "typedef hides external declaration: %s", /* 88 */ 146 "typedef redeclared: %s", /* 89 */ 147 "inconsistent redeclaration of extern: %s", /* 90 */ 148 "declaration hides parameter: %s", /* 91 */ 149 "inconsistent redeclaration of static: %s", /* 92 */ 150 "dubious static function at block level: %s", /* 93 */ 151 "function has illegal storage class: %s", /* 94 */ 152 "declaration hides earlier one: %s", /* 95 */ 153 "cannot dereference non-pointer type", /* 96 */ 154 "suffix U is illegal in traditional C", /* 97 */ 155 "suffixes F and L are illegal in traditional C", /* 98 */ 156 "'%s' undefined", /* 99 */ 157 "unary + is illegal in traditional C", /* 100 */ 158 "type '%s' does not have member '%s'", /* 101 */ 159 "illegal member use: %s", /* 102 */ 160 "left operand of '.' must be struct/union object", /* 103 */ 161 "left operand of '->' must be pointer to struct/union not %s",/* 104 */ 162 "non-unique member requires struct/union %s", /* 105 */ 163 "left operand of '->' must be pointer", /* 106 */ 164 "operands of '%s' have incompatible types (%s != %s)", /* 107 */ 165 "operand of '%s' has invalid type (%s)", /* 108 */ 166 "void type illegal in expression", /* 109 */ 167 "pointer to function is not allowed here", /* 110 */ 168 "unacceptable operand of '%s'", /* 111 */ 169 "cannot take address of bit-field", /* 112 */ 170 "cannot take address of register %s", /* 113 */ 171 "%soperand of '%s' must be lvalue", /* 114 */ 172 "%soperand of '%s' must be modifiable lvalue", /* 115 */ 173 "illegal pointer subtraction", /* 116 */ 174 "bitwise '%s' on signed value possibly nonportable", /* 117 */ 175 "semantics of '%s' change in ANSI C; use explicit cast", /* 118 */ 176 "conversion of '%s' to '%s' is out of range", /* 119 */ 177 "bitwise '%s' on signed value nonportable", /* 120 */ 178 "negative shift", /* 121 */ 179 "shift amount %llu is greater than bit-size %llu of '%s'", /* 122 */ 180 "illegal combination of %s (%s) and %s (%s), op %s", /* 123 */ 181 "illegal pointer combination (%s) and (%s), op %s", /* 124 */ 182 "ANSI C forbids ordered comparisons of pointers to functions",/* 125 */ 183 "incompatible types '%s' and '%s' in conditional", /* 126 */ 184 "'&' before array or function: ignored", /* 127 */ 185 "operands have incompatible pointer types, op %s (%s != %s)", /* 128 */ 186 "expression has null effect", /* 129 */ 187 "enum type mismatch: '%s' '%s' '%s'", /* 130 */ 188 "conversion to '%s' may sign-extend incorrectly", /* 131 */ 189 "conversion from '%s' to '%s' may lose accuracy", /* 132 */ 190 "conversion of pointer to '%s' loses bits", /* 133 */ 191 "conversion of pointer to '%s' may lose bits", /* 134 */ 192 "converting '%s' to '%s' may cause alignment problem", /* 135 */ 193 "cannot do pointer arithmetic on operand of unknown size", /* 136 */ 194 "use of incomplete enum type, op %s", /* 137 */ 195 "unknown operand size, op %s", /* 138 */ 196 "division by 0", /* 139 */ 197 "modulus by 0", /* 140 */ 198 "integer overflow detected, op %s", /* 141 */ 199 "floating point overflow detected, op %s", /* 142 */ 200 "cannot take size/alignment of incomplete type", /* 143 */ 201 "cannot take size/alignment of function", /* 144 */ 202 "cannot take size/alignment of bit-field", /* 145 */ 203 "cannot take size/alignment of void", /* 146 */ 204 "invalid cast expression", /* 147 */ 205 "improper cast of void expression", /* 148 */ 206 "illegal function (type %s)", /* 149 */ 207 "argument mismatch: %d arg%s passed, %d expected", /* 150 */ 208 "void expressions may not be arguments, arg #%d", /* 151 */ 209 "argument cannot have unknown size, arg #%d", /* 152 */ 210 "converting '%s' to incompatible '%s' for argument %d", /* 153 */ 211 "illegal combination of %s (%s) and %s (%s), arg #%d", /* 154 */ 212 "argument is incompatible with prototype, arg #%d", /* 155 */ 213 "enum type mismatch, arg #%d (%s != %s)", /* 156 */ 214 "ANSI C treats constant as unsigned", /* 157 */ 215 "%s may be used before set", /* 158 */ 216 "assignment in conditional context", /* 159 */ 217 "operator '==' found where '=' was expected", /* 160 */ 218 "constant in conditional context", /* 161 */ 219 "comparison of %s with %s, op %s", /* 162 */ 220 "a cast does not yield an lvalue", /* 163 */ 221 "assignment of negative constant to unsigned type", /* 164 */ 222 "constant truncated by assignment", /* 165 */ 223 "precision lost in bit-field assignment", /* 166 */ 224 "array subscript cannot be negative: %ld", /* 167 */ 225 "array subscript cannot be > %d: %ld", /* 168 */ 226 "precedence confusion possible: parenthesize!", /* 169 */ 227 "first operand must have scalar type, op ? :", /* 170 */ 228 "cannot assign to '%s' from '%s'", /* 171 */ 229 "too many struct/union initializers", /* 172 */ 230 "too many array initializers, expected %d", /* 173 */ 231 "too many initializers", /* 174 */ 232 "initialization of incomplete type '%s'", /* 175 */ 233 "", /* no longer used */ /* 176 */ 234 "non-constant initializer", /* 177 */ 235 "initializer does not fit", /* 178 */ 236 "cannot initialize struct/union with no named member", /* 179 */ 237 "bit-field initializer does not fit", /* 180 */ 238 "{}-enclosed initializer required", /* 181 */ 239 "incompatible pointer types (%s != %s)", /* 182 */ 240 "illegal combination of %s (%s) and %s (%s)", /* 183 */ 241 "illegal pointer combination", /* 184 */ 242 "cannot initialize '%s' from '%s'", /* 185 */ 243 "bit-field initialization is illegal in traditional C", /* 186 */ 244 "non-null byte ignored in string initializer", /* 187 */ 245 "no automatic aggregate initialization in traditional C", /* 188 */ 246 "", /* no longer used */ /* 189 */ 247 "empty array declaration: %s", /* 190 */ 248 "'%s' set but not used in function '%s'", /* 191 */ 249 "'%s' unused in function '%s'", /* 192 */ 250 "statement not reached", /* 193 */ 251 "label %s redefined", /* 194 */ 252 "case not in switch", /* 195 */ 253 "case label affected by conversion", /* 196 */ 254 "non-constant case expression", /* 197 */ 255 "non-integral case expression", /* 198 */ 256 "duplicate case in switch: %ld", /* 199 */ 257 "duplicate case in switch: %lu", /* 200 */ 258 "default outside switch", /* 201 */ 259 "duplicate default in switch", /* 202 */ 260 "case label must be of type `int' in traditional C", /* 203 */ 261 "controlling expressions must have scalar type", /* 204 */ 262 "switch expression must have integral type", /* 205 */ 263 "enumeration value(s) not handled in switch", /* 206 */ 264 "loop not entered at top", /* 207 */ 265 "break outside loop or switch", /* 208 */ 266 "continue outside loop", /* 209 */ 267 "enum type mismatch between '%s' and '%s' in initialization", /* 210 */ 268 "return value type mismatch (%s) and (%s)", /* 211 */ 269 "cannot return incomplete type", /* 212 */ 270 "void function %s cannot return value", /* 213 */ 271 "function %s expects to return value", /* 214 */ 272 "function implicitly declared to return int", /* 215 */ 273 "function %s has return (e); and return;", /* 216 */ 274 "function %s falls off bottom without returning value", /* 217 */ 275 "ANSI C treats constant as unsigned, op %s", /* 218 */ 276 "concatenated strings are illegal in traditional C", /* 219 */ 277 "fallthrough on case statement", /* 220 */ 278 "initialization of unsigned with negative constant", /* 221 */ 279 "conversion of negative constant to unsigned type", /* 222 */ 280 "end-of-loop code not reached", /* 223 */ 281 "cannot recover from previous errors", /* 224 */ 282 "static function called but not defined: %s()", /* 225 */ 283 "static variable %s unused", /* 226 */ 284 "const object %s should have initializer", /* 227 */ 285 "function cannot return const or volatile object", /* 228 */ 286 "converting '%s' to '%s' is questionable", /* 229 */ 287 "nonportable character comparison, op %s", /* 230 */ 288 "argument '%s' unused in function '%s'", /* 231 */ 289 "label %s unused in function %s", /* 232 */ 290 "struct %s never defined", /* 233 */ 291 "union %s never defined", /* 234 */ 292 "enum %s never defined", /* 235 */ 293 "static function %s unused", /* 236 */ 294 "redeclaration of formal parameter %s", /* 237 */ 295 "initialization of union is illegal in traditional C", /* 238 */ 296 "constant argument to '!'", /* 239 */ 297 "assignment of different structures (%s != %s)", /* 240 */ 298 "dubious operation on enum, op %s", /* 241 */ 299 "combination of '%s' and '%s', op %s", /* 242 */ 300 "dubious comparison of enums, op %s", /* 243 */ 301 "illegal structure pointer combination", /* 244 */ 302 "incompatible structure pointers: '%s' '%s' '%s'", /* 245 */ 303 "dubious conversion of enum to '%s'", /* 246 */ 304 "pointer cast from '%s' to '%s' may be troublesome", /* 247 */ 305 "floating-point constant out of range", /* 248 */ 306 "syntax error '%s'", /* 249 */ 307 "unknown character \\%o", /* 250 */ 308 "malformed integer constant", /* 251 */ 309 "integer constant out of range", /* 252 */ 310 "unterminated character constant", /* 253 */ 311 "newline in string or char constant", /* 254 */ 312 "undefined or invalid # directive", /* 255 */ 313 "unterminated comment", /* 256 */ 314 "extra characters in lint comment", /* 257 */ 315 "unterminated string constant", /* 258 */ 316 "argument #%d is converted from '%s' to '%s' due to prototype", /* 259 */ 317 "previous declaration of %s", /* 260 */ 318 "previous definition of %s", /* 261 */ 319 "\\\" inside character constants undefined in traditional C", /* 262 */ 320 "\\? undefined in traditional C", /* 263 */ 321 "\\v undefined in traditional C", /* 264 */ 322 "%s C does not support 'long long'", /* 265 */ 323 "'long double' is illegal in traditional C", /* 266 */ 324 "shift equal to size of object", /* 267 */ 325 "variable declared inline: %s", /* 268 */ 326 "argument declared inline: %s", /* 269 */ 327 "function prototypes are illegal in traditional C", /* 270 */ 328 "switch expression must be of type `int' in traditional C", /* 271 */ 329 "empty translation unit", /* 272 */ 330 "bit-field type '%s' invalid in ANSI C", /* 273 */ 331 "ANSI C forbids comparison of %s with %s", /* 274 */ 332 "cast discards 'const' from type '%s'", /* 275 */ 333 "__%s__ is illegal for type %s", /* 276 */ 334 "initialization of '%s' with '%s'", /* 277 */ 335 "combination of '%s' and '%s', arg #%d", /* 278 */ 336 "combination of '%s' and '%s' in return", /* 279 */ 337 "must be outside function: /* %s */", /* 280 */ 338 "duplicate use of /* %s */", /* 281 */ 339 "must precede function definition: /* %s */", /* 282 */ 340 "argument number mismatch with directive: /* %s */", /* 283 */ 341 "fallthrough on default statement", /* 284 */ 342 "prototype declaration", /* 285 */ 343 "function definition is not a prototype", /* 286 */ 344 "function declaration is not a prototype", /* 287 */ 345 "dubious use of /* VARARGS */ with /* %s */", /* 288 */ 346 "can't be used together: /* PRINTFLIKE */ /* SCANFLIKE */", /* 289 */ 347 "static function %s declared but not defined", /* 290 */ 348 "invalid multibyte character", /* 291 */ 349 "cannot concatenate wide and regular string literals", /* 292 */ 350 "argument %d must be 'char *' for PRINTFLIKE/SCANFLIKE", /* 293 */ 351 "multi-character character constant", /* 294 */ 352 "conversion of '%s' to '%s' is out of range, arg #%d", /* 295 */ 353 "conversion of negative constant to unsigned type, arg #%d", /* 296 */ 354 "conversion to '%s' may sign-extend incorrectly, arg #%d", /* 297 */ 355 "conversion from '%s' to '%s' may lose accuracy, arg #%d", /* 298 */ 356 "prototype does not match old style definition, arg #%d", /* 299 */ 357 "old style definition", /* 300 */ 358 "array of incomplete type", /* 301 */ 359 "%s returns pointer to automatic object", /* 302 */ 360 "ANSI C forbids conversion of %s to %s", /* 303 */ 361 "ANSI C forbids conversion of %s to %s, arg #%d", /* 304 */ 362 "ANSI C forbids conversion of %s to %s, op %s", /* 305 */ 363 "constant truncated by conversion, op %s", /* 306 */ 364 "static variable %s set but not used", /* 307 */ 365 "invalid type for _Complex", /* 308 */ 366 "extra bits set to 0 in conversion of '%s' to '%s', op '%s'", /* 309 */ 367 "symbol renaming can't be used on function arguments", /* 310 */ 368 "symbol renaming can't be used on automatic variables", /* 311 */ 369 "%s C does not support // comments", /* 312 */ 370 "struct or union member name in initializer is a C9X feature",/* 313 */ 371 "%s is not a structure or a union", /* 314 */ 372 "GCC style struct or union member name in initializer", /* 315 */ 373 "__FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension", /* 316 */ 374 "__func__ is a C9X feature", /* 317 */ 375 "variable array dimension is a C99/GCC extension", /* 318 */ 376 "compound literals are a C9X/GCC extension", /* 319 */ 377 "({ }) is a GCC extension", /* 320 */ 378 "array initializer with designators is a C9X feature", /* 321 */ 379 "zero sized array is a C99 extension", /* 322 */ 380 "continue in 'do ... while (0)' loop", /* 323 */ 381 "suggest cast from '%s' to '%s' on op %s to avoid overflow", /* 324 */ 382 "variable declaration in for loop", /* 325 */ 383 "%s attribute ignored for %s", /* 326 */ 384 "declarations after statements is a C99 feature", /* 327 */ 385 "union cast is a C9X feature", /* 328 */ 386 "type '%s' is not a member of '%s'", /* 329 */ 387 "operand of '%s' must be bool, not '%s'", /* 330 */ 388 "left operand of '%s' must be bool, not '%s'", /* 331 */ 389 "right operand of '%s' must be bool, not '%s'", /* 332 */ 390 "controlling expression must be bool, not '%s'", /* 333 */ 391 "argument #%d expects '%s', gets passed '%s'", /* 334 */ 392 "operand of '%s' must not be bool", /* 335 */ 393 "left operand of '%s' must not be bool", /* 336 */ 394 "right operand of '%s' must not be bool", /* 337 */ 395 "option '%c' should be handled in the switch", /* 338 */ 396 "option '%c' should be listed in the options string", /* 339 */ 397 "initialization with '[a...b]' is a GNU extension", /* 340 */ 398 "argument to '%s' must be 'unsigned char' or EOF, not '%s'", /* 341 */ 399 "argument to '%s' must be cast to 'unsigned char', not to '%s'", /* 342 */ 400 "static array size is a C11 extension", /* 343 */ 401 "bit-field of type plain 'int' has implementation-defined signedness", /* 344 */ 402 }; 403 404 static struct include_level { 405 const char *filename; 406 int lineno; 407 struct include_level *by; 408 } *includes; 409 410 411 void 412 update_location(const char *filename, int lineno, bool is_begin, bool is_end) 413 { 414 struct include_level *top; 415 416 top = includes; 417 if (is_begin && top != NULL) 418 top->lineno = curr_pos.p_line; 419 420 if (top == NULL || is_begin) { 421 top = xmalloc(sizeof(*top)); 422 top->filename = filename; 423 top->lineno = lineno; 424 top->by = includes; 425 includes = top; 426 } else { 427 if (is_end) { 428 includes = top->by; 429 free(top); 430 top = includes; 431 } 432 top->filename = filename; 433 top->lineno = lineno; 434 } 435 } 436 437 static void 438 print_stack_trace(void) 439 { 440 const struct include_level *top; 441 442 if ((top = includes) == NULL) 443 return; 444 /* 445 * Skip the innermost include level since it is already listed in the 446 * diagnostic itself. Furthermore, its lineno is the line number of 447 * the last '#' line, not the current line. 448 */ 449 for (top = top->by; top != NULL; top = top->by) 450 printf("\tincluded from %s(%d)\n", top->filename, top->lineno); 451 } 452 453 /* 454 * print a list of the messages with their ids 455 */ 456 void 457 msglist(void) 458 { 459 size_t i; 460 461 for (i = 0; i < sizeof(msgs) / sizeof(msgs[0]); i++) 462 printf("%zu\t%s\n", i, msgs[i]); 463 } 464 465 /* 466 * If Fflag is not set, lbasename() returns a pointer to the last 467 * component of the path, otherwise it returns the argument. 468 */ 469 static const char * 470 lbasename(const char *path) 471 { 472 const char *p, *base, *dir; 473 474 if (Fflag) 475 return path; 476 477 p = base = dir = path; 478 while (*p != '\0') { 479 if (*p++ == '/') { 480 dir = base; 481 base = p; 482 } 483 } 484 return *base != '\0' ? base : dir; 485 } 486 487 static void 488 verror_at(int msgid, const pos_t *pos, va_list ap) 489 { 490 const char *fn; 491 492 if (ERR_ISSET(msgid, &msgset)) 493 return; 494 495 fn = lbasename(pos->p_file); 496 (void)printf("%s(%d): error: ", fn, pos->p_line); 497 (void)vprintf(msgs[msgid], ap); 498 (void)printf(" [%d]\n", msgid); 499 nerr++; 500 print_stack_trace(); 501 } 502 503 static void 504 vwarning_at(int msgid, const pos_t *pos, va_list ap) 505 { 506 const char *fn; 507 508 if (ERR_ISSET(msgid, &msgset)) 509 return; 510 511 #ifdef DEBUG 512 printf("%s: lwarn=%d msgid=%d\n", __func__, lwarn, msgid); 513 #endif 514 if (lwarn == LWARN_NONE || lwarn == msgid) 515 /* this warning is suppressed by a LINTED comment */ 516 return; 517 518 fn = lbasename(pos->p_file); 519 (void)printf("%s(%d): warning: ", fn, pos->p_line); 520 (void)vprintf(msgs[msgid], ap); 521 (void)printf(" [%d]\n", msgid); 522 if (wflag) 523 nerr++; 524 print_stack_trace(); 525 } 526 527 static void 528 vmessage_at(int msgid, const pos_t *pos, va_list ap) 529 { 530 const char *fn; 531 532 if (ERR_ISSET(msgid, &msgset)) 533 return; 534 535 fn = lbasename(pos->p_file); 536 (void)printf("%s(%d): ", fn, pos->p_line); 537 (void)vprintf(msgs[msgid], ap); 538 (void)printf(" [%d]\n", msgid); 539 print_stack_trace(); 540 } 541 542 void 543 (error_at)(int msgid, const pos_t *pos, ...) 544 { 545 va_list ap; 546 547 va_start(ap, pos); 548 verror_at(msgid, pos, ap); 549 va_end(ap); 550 } 551 552 void 553 (error)(int msgid, ...) 554 { 555 va_list ap; 556 557 va_start(ap, msgid); 558 verror_at(msgid, &curr_pos, ap); 559 va_end(ap); 560 } 561 562 void 563 internal_error(const char *file, int line, const char *msg, ...) 564 { 565 va_list ap; 566 const char *fn; 567 568 fn = lbasename(curr_pos.p_file); 569 (void)fprintf(stderr, "lint: internal error in %s:%d near %s:%d: ", 570 file, line, fn, curr_pos.p_line); 571 va_start(ap, msg); 572 (void)vfprintf(stderr, msg, ap); 573 va_end(ap); 574 (void)fprintf(stderr, "\n"); 575 print_stack_trace(); 576 abort(); 577 } 578 579 void 580 assert_failed(const char *file, int line, const char *func, const char *cond) 581 { 582 const char *fn; 583 584 fn = lbasename(curr_pos.p_file); 585 (void)fprintf(stderr, 586 "lint: assertion \"%s\" failed in %s at %s:%d near %s:%d\n", 587 cond, func, file, line, fn, curr_pos.p_line); 588 print_stack_trace(); 589 abort(); 590 } 591 592 void 593 (warning_at)(int msgid, const pos_t *pos, ...) 594 { 595 va_list ap; 596 597 va_start(ap, pos); 598 vwarning_at(msgid, pos, ap); 599 va_end(ap); 600 } 601 602 void 603 (warning)(int msgid, ...) 604 { 605 va_list ap; 606 607 va_start(ap, msgid); 608 vwarning_at(msgid, &curr_pos, ap); 609 va_end(ap); 610 } 611 612 void 613 (message_at)(int msgid, const pos_t *pos, ...) 614 { 615 va_list ap; 616 617 va_start(ap, pos); 618 vmessage_at(msgid, pos, ap); 619 va_end(ap); 620 } 621 622 void 623 (message)(int msgid, ...) 624 { 625 va_list ap; 626 627 va_start(ap, msgid); 628 vmessage_at(msgid, &curr_pos, ap); 629 va_end(ap); 630 } 631 632 /* 633 * XXX I think the logic is possibly somewhat screwed up here. The 634 * question is, how do we want to interpret the -s and -S flags going 635 * forward? We need to answer that and then we can fix this to be 636 * "right"... [perry, 2 Nov 2002] 637 */ 638 void 639 (c99ism)(int msgid, ...) 640 { 641 va_list ap; 642 bool extensions_ok = Sflag || gflag; 643 644 va_start(ap, msgid); 645 if (sflag && !extensions_ok) { 646 verror_at(msgid, &curr_pos, ap); 647 } else if (sflag || !extensions_ok) { 648 vwarning_at(msgid, &curr_pos, ap); 649 } 650 va_end(ap); 651 } 652 653 void 654 (c11ism)(int msgid, ...) 655 { 656 va_list ap; 657 658 if (c11flag || gflag) 659 return; 660 va_start(ap, msgid); 661 verror_at(msgid, &curr_pos, ap); 662 va_end(ap); 663 } 664 665 void 666 (gnuism)(int msgid, ...) 667 { 668 va_list ap; 669 670 va_start(ap, msgid); 671 if (sflag && !gflag) { 672 verror_at(msgid, &curr_pos, ap); 673 } else if (sflag || !gflag) { 674 vwarning_at(msgid, &curr_pos, ap); 675 } 676 va_end(ap); 677 } 678