1 /* messages.c - error reporter - 2 Copyright (C) 1987, 91, 92, 93, 94, 95, 96, 97, 1998 3 Free Software Foundation, Inc. 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. */ 20 21 #include "as.h" 22 23 #include <stdio.h> 24 #ifdef HAVE_ERRNO_H 25 #include <errno.h> 26 #endif 27 28 #ifdef USE_STDARG 29 #include <stdarg.h> 30 #endif 31 32 #ifdef USE_VARARGS 33 #include <varargs.h> 34 #endif 35 36 #if !defined (USE_STDARG) && !defined (USE_VARARGS) 37 /* Roll our own. */ 38 #define va_alist REST 39 #define va_dcl 40 typedef int * va_list; 41 #define va_start(ARGS) ARGS = &REST 42 #define va_end(ARGS) 43 #endif 44 45 static void identify PARAMS ((char *)); 46 static void as_show_where PARAMS ((void)); 47 static void as_warn_internal PARAMS ((char *, unsigned int, char *)); 48 static void as_bad_internal PARAMS ((char *, unsigned int, char *)); 49 50 /* 51 * Despite the rest of the comments in this file, (FIXME-SOON), 52 * here is the current scheme for error messages etc: 53 * 54 * as_fatal() is used when gas is quite confused and 55 * continuing the assembly is pointless. In this case we 56 * exit immediately with error status. 57 * 58 * as_bad() is used to mark errors that result in what we 59 * presume to be a useless object file. Say, we ignored 60 * something that might have been vital. If we see any of 61 * these, assembly will continue to the end of the source, 62 * no object file will be produced, and we will terminate 63 * with error status. The new option, -Z, tells us to 64 * produce an object file anyway but we still exit with 65 * error status. The assumption here is that you don't want 66 * this object file but we could be wrong. 67 * 68 * as_warn() is used when we have an error from which we 69 * have a plausible error recovery. eg, masking the top 70 * bits of a constant that is longer than will fit in the 71 * destination. In this case we will continue to assemble 72 * the source, although we may have made a bad assumption, 73 * and we will produce an object file and return normal exit 74 * status (ie, no error). The new option -X tells us to 75 * treat all as_warn() errors as as_bad() errors. That is, 76 * no object file will be produced and we will exit with 77 * error status. The idea here is that we don't kill an 78 * entire make because of an error that we knew how to 79 * correct. On the other hand, sometimes you might want to 80 * stop the make at these points. 81 * 82 * as_tsktsk() is used when we see a minor error for which 83 * our error recovery action is almost certainly correct. 84 * In this case, we print a message and then assembly 85 * continues as though no error occurred. 86 */ 87 88 static void 89 identify (file) 90 char *file; 91 { 92 static int identified; 93 if (identified) 94 return; 95 identified++; 96 97 if (!file) 98 { 99 unsigned int x; 100 as_where (&file, &x); 101 } 102 103 if (file) 104 fprintf (stderr, "%s: ", file); 105 fprintf (stderr, _("Assembler messages:\n")); 106 } 107 108 static int warning_count; /* Count of number of warnings issued */ 109 110 int 111 had_warnings () 112 { 113 return (warning_count); 114 } 115 116 /* Nonzero if we've hit a 'bad error', and should not write an obj file, 117 and exit with a nonzero error code */ 118 119 static int error_count; 120 121 int 122 had_errors () 123 { 124 return (error_count); 125 } 126 127 128 /* Print the current location to stderr. */ 129 130 static void 131 as_show_where () 132 { 133 char *file; 134 unsigned int line; 135 136 as_where (&file, &line); 137 identify (file); 138 if (file) 139 fprintf (stderr, "%s:%u: ", file, line); 140 } 141 142 /* 143 * a s _ p e r r o r 144 * 145 * Like perror(3), but with more info. 146 */ 147 148 void 149 as_perror (gripe, filename) 150 const char *gripe; /* Unpunctuated error theme. */ 151 const char *filename; 152 { 153 const char *errtxt; 154 155 as_show_where (); 156 fprintf (stderr, gripe, filename); 157 #ifdef BFD_ASSEMBLER 158 errtxt = bfd_errmsg (bfd_get_error ()); 159 #else 160 errtxt = xstrerror (errno); 161 #endif 162 fprintf (stderr, ": %s\n", errtxt); 163 errno = 0; 164 #ifdef BFD_ASSEMBLER 165 bfd_set_error (bfd_error_no_error); 166 #endif 167 } 168 169 /* 170 * a s _ t s k t s k () 171 * 172 * Send to stderr a string as a warning, and locate warning 173 * in input file(s). 174 * Please only use this for when we have some recovery action. 175 * Please explain in string (which may have '\n's) what recovery was done. 176 */ 177 178 #ifdef USE_STDARG 179 void 180 as_tsktsk (const char *format,...) 181 { 182 va_list args; 183 184 as_show_where (); 185 va_start (args, format); 186 vfprintf (stderr, format, args); 187 va_end (args); 188 (void) putc ('\n', stderr); 189 } /* as_tsktsk() */ 190 #else 191 void 192 as_tsktsk (format, va_alist) 193 const char *format; 194 va_dcl 195 { 196 va_list args; 197 198 as_show_where (); 199 va_start (args); 200 vfprintf (stderr, format, args); 201 va_end (args); 202 (void) putc ('\n', stderr); 203 } /* as_tsktsk() */ 204 #endif /* not NO_STDARG */ 205 206 /* The common portion of as_warn and as_warn_where. */ 207 208 static void 209 as_warn_internal (file, line, buffer) 210 char *file; 211 unsigned int line; 212 char *buffer; 213 { 214 ++warning_count; 215 216 if (file == NULL) 217 as_where (&file, &line); 218 219 identify (file); 220 if (file) 221 fprintf (stderr, "%s:%u: ", file, line); 222 fprintf (stderr, _("Warning: ")); 223 fputs (buffer, stderr); 224 (void) putc ('\n', stderr); 225 #ifndef NO_LISTING 226 listing_warning (buffer); 227 #endif 228 } 229 230 /* 231 * a s _ w a r n () 232 * 233 * Send to stderr a string as a warning, and locate warning 234 * in input file(s). 235 * Please only use this for when we have some recovery action. 236 * Please explain in string (which may have '\n's) what recovery was done. 237 */ 238 239 #ifdef USE_STDARG 240 void 241 as_warn (const char *format,...) 242 { 243 va_list args; 244 char buffer[2000]; 245 246 if (!flag_no_warnings) 247 { 248 va_start (args, format); 249 vsprintf (buffer, format, args); 250 va_end (args); 251 as_warn_internal ((char *) NULL, 0, buffer); 252 } 253 } /* as_warn() */ 254 #else 255 /*VARARGS1 */ 256 void 257 as_warn (format, va_alist) 258 const char *format; 259 va_dcl 260 { 261 va_list args; 262 char buffer[2000]; 263 264 if (!flag_no_warnings) 265 { 266 va_start (args); 267 vsprintf (buffer, format, args); 268 va_end (args); 269 as_warn_internal ((char *) NULL, 0, buffer); 270 } 271 } /* as_warn() */ 272 #endif /* not NO_STDARG */ 273 274 /* as_warn_where, like as_bad but the file name and line number are 275 passed in. Unfortunately, we have to repeat the function in order 276 to handle the varargs correctly and portably. */ 277 278 #ifdef USE_STDARG 279 void 280 as_warn_where (char *file, unsigned int line, const char *format,...) 281 { 282 va_list args; 283 char buffer[2000]; 284 285 if (!flag_no_warnings) 286 { 287 va_start (args, format); 288 vsprintf (buffer, format, args); 289 va_end (args); 290 as_warn_internal (file, line, buffer); 291 } 292 } /* as_warn() */ 293 #else 294 /*VARARGS1 */ 295 void 296 as_warn_where (file, line, format, va_alist) 297 char *file; 298 unsigned int line; 299 const char *format; 300 va_dcl 301 { 302 va_list args; 303 char buffer[2000]; 304 305 if (!flag_no_warnings) 306 { 307 va_start (args); 308 vsprintf (buffer, format, args); 309 va_end (args); 310 as_warn_internal (file, line, buffer); 311 } 312 } /* as_warn() */ 313 #endif /* not NO_STDARG */ 314 315 /* The common portion of as_bad and as_bad_where. */ 316 317 static void 318 as_bad_internal (file, line, buffer) 319 char *file; 320 unsigned int line; 321 char *buffer; 322 { 323 ++error_count; 324 325 if (file == NULL) 326 as_where (&file, &line); 327 328 identify (file); 329 if (file) 330 fprintf (stderr, "%s:%u: ", file, line); 331 fprintf (stderr, _("Error: ")); 332 fputs (buffer, stderr); 333 (void) putc ('\n', stderr); 334 #ifndef NO_LISTING 335 listing_error (buffer); 336 #endif 337 } 338 339 /* 340 * a s _ b a d () 341 * 342 * Send to stderr a string as a warning, and locate warning in input file(s). 343 * Please us when there is no recovery, but we want to continue processing 344 * but not produce an object file. 345 * Please explain in string (which may have '\n's) what recovery was done. 346 */ 347 348 #ifdef USE_STDARG 349 void 350 as_bad (const char *format,...) 351 { 352 va_list args; 353 char buffer[2000]; 354 355 va_start (args, format); 356 vsprintf (buffer, format, args); 357 va_end (args); 358 359 as_bad_internal ((char *) NULL, 0, buffer); 360 } 361 362 #else 363 /*VARARGS1 */ 364 void 365 as_bad (format, va_alist) 366 const char *format; 367 va_dcl 368 { 369 va_list args; 370 char buffer[2000]; 371 372 va_start (args); 373 vsprintf (buffer, format, args); 374 va_end (args); 375 376 as_bad_internal ((char *) NULL, 0, buffer); 377 } 378 #endif /* not NO_STDARG */ 379 380 /* as_bad_where, like as_bad but the file name and line number are 381 passed in. Unfortunately, we have to repeat the function in order 382 to handle the varargs correctly and portably. */ 383 384 #ifdef USE_STDARG 385 void 386 as_bad_where (char *file, unsigned int line, const char *format,...) 387 { 388 va_list args; 389 char buffer[2000]; 390 391 va_start (args, format); 392 vsprintf (buffer, format, args); 393 va_end (args); 394 395 as_bad_internal (file, line, buffer); 396 } 397 398 #else 399 /*VARARGS1 */ 400 void 401 as_bad_where (file, line, format, va_alist) 402 char *file; 403 unsigned int line; 404 const char *format; 405 va_dcl 406 { 407 va_list args; 408 char buffer[2000]; 409 410 va_start (args); 411 vsprintf (buffer, format, args); 412 va_end (args); 413 414 as_bad_internal (file, line, buffer); 415 } 416 #endif /* not NO_STDARG */ 417 418 /* 419 * a s _ f a t a l () 420 * 421 * Send to stderr a string as a fatal message, and print location of error in 422 * input file(s). 423 * Please only use this for when we DON'T have some recovery action. 424 * It xexit()s with a warning status. 425 */ 426 427 #ifdef USE_STDARG 428 void 429 as_fatal (const char *format,...) 430 { 431 va_list args; 432 433 as_show_where (); 434 va_start (args, format); 435 fprintf (stderr, _("Fatal error: ")); 436 vfprintf (stderr, format, args); 437 (void) putc ('\n', stderr); 438 va_end (args); 439 xexit (EXIT_FAILURE); 440 } /* as_fatal() */ 441 #else 442 /*VARARGS1*/ 443 void 444 as_fatal (format, va_alist) 445 char *format; 446 va_dcl 447 { 448 va_list args; 449 450 as_show_where (); 451 va_start (args); 452 fprintf (stderr, _("Fatal error: ")); 453 vfprintf (stderr, format, args); 454 (void) putc ('\n', stderr); 455 va_end (args); 456 xexit (EXIT_FAILURE); 457 } /* as_fatal() */ 458 #endif /* not NO_STDARG */ 459 460 /* 461 * as_assert: Indicate assertion failure. 462 * Arguments: Filename, line number, optional function name. 463 */ 464 465 void 466 as_assert (file, line, fn) 467 const char *file, *fn; 468 int line; 469 { 470 as_show_where (); 471 fprintf (stderr, _("Internal error!\n")); 472 if (fn) 473 fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"), 474 fn, file, line); 475 else 476 fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line); 477 fprintf (stderr, _("Please report this bug.\n")); 478 xexit (EXIT_FAILURE); 479 } 480 481 /* as_abort: Print a friendly message saying how totally hosed we are, 482 and exit without producing a core file. */ 483 void 484 as_abort (file, line, fn) 485 const char *file, *fn; 486 int line; 487 { 488 as_show_where (); 489 if (fn) 490 fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"), 491 file, line, fn); 492 else 493 fprintf (stderr, _("Internal error, aborting at %s line %d\n"), 494 file, line); 495 fprintf (stderr, _("Please report this bug.\n")); 496 xexit (EXIT_FAILURE); 497 } 498 499 /* Support routines. */ 500 501 void 502 fprint_value (file, val) 503 FILE *file; 504 valueT val; 505 { 506 if (sizeof (val) <= sizeof (long)) 507 { 508 fprintf (file, "%ld", (long) val); 509 return; 510 } 511 #ifdef BFD_ASSEMBLER 512 if (sizeof (val) <= sizeof (bfd_vma)) 513 { 514 fprintf_vma (file, val); 515 return; 516 } 517 #endif 518 abort (); 519 } 520 521 void 522 sprint_value (buf, val) 523 char *buf; 524 valueT val; 525 { 526 if (sizeof (val) <= sizeof (long)) 527 { 528 sprintf (buf, "%ld", (long) val); 529 return; 530 } 531 #ifdef BFD_ASSEMBLER 532 if (sizeof (val) <= sizeof (bfd_vma)) 533 { 534 sprintf_vma (buf, val); 535 return; 536 } 537 #endif 538 abort (); 539 } 540 541 /* end of messages.c */ 542