fix-header.c revision 50397
1/* fix-header.c - Make C header file suitable for C++. 2 Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc. 3 4This program is free software; you can redistribute it and/or modify it 5under the terms of the GNU General Public License as published by the 6Free Software Foundation; either version 2, or (at your option) any 7later version. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12GNU General Public License for more details. 13 14You should have received a copy of the GNU General Public License 15along with this program; if not, write to the Free Software 16Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18/* This program massages a system include file (such as stdio.h), 19 into a form that is compatible with GNU C and GNU C++. 20 21 * extern "C" { ... } braces are added (inside #ifndef __cplusplus), 22 if they seem to be needed. These prevent C++ compilers from name 23 mangling the functions inside the braces. 24 25 * If an old-style incomplete function declaration is seen (without 26 an argument list), and it is a "standard" function listed in 27 the file sys-protos.h (and with a non-empty argument list), then 28 the declaration is converted to a complete prototype by replacing 29 the empty parameter list with the argument list from sys-protos.h. 30 31 * The program can be given a list of (names of) required standard 32 functions (such as fclose for stdio.h). If a required function 33 is not seen in the input, then a prototype for it will be 34 written to the output. 35 36 * If all of the non-comment code of the original file is protected 37 against multiple inclusion: 38 #ifndef FOO 39 #define FOO 40 <body of include file> 41 #endif 42 then extra matter added to the include file is placed inside the <body>. 43 44 * If the input file is OK (nothing needs to be done); 45 the output file is not written (nor removed if it exists). 46 47 There are also some special actions that are done for certain 48 well-known standard include files: 49 50 * If argv[1] is "sys/stat.h", the Posix.1 macros 51 S_ISBLK, S_ISCHR, S_ISDIR, S_ISFIFO, S_ISLNK, S_ISREG are added if 52 they were missing, and the corresponding "traditional" S_IFxxx 53 macros were defined. 54 55 * If argv[1] is "errno.h", errno is declared if it was missing. 56 57 * TODO: The input file should be read complete into memory, because: 58 a) it needs to be scanned twice anyway, and 59 b) it would be nice to allow update in place. 60 61 Usage: 62 fix-header FOO.H INFILE.H OUTFILE.H [OPTIONS] 63 where: 64 * FOO.H is the relative file name of the include file, 65 as it would be #include'd by a C file. (E.g. stdio.h) 66 * INFILE.H is a full pathname for the input file (e.g. /usr/include/stdio.h) 67 * OUTFILE.H is the full pathname for where to write the output file, 68 if anything needs to be done. (e.g. ./include/stdio.h) 69 * OPTIONS are such as you would pass to cpp. 70 71 Written by Per Bothner <bothner@cygnus.com>, July 1993. */ 72 73#include "hconfig.h" 74#ifdef __STDC__ 75#include <stdarg.h> 76#else 77#include <varargs.h> 78#endif 79#include "system.h" 80#include "gansidecl.h" 81#include "obstack.h" 82#include "scan.h" 83#include "cpplib.h" 84#include "cpphash.h" 85 86void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1; 87 88sstring buf; 89 90int verbose = 0; 91int partial_count = 0; 92int warnings = 0; 93 94/* We no longer need to add extern "C", because cpp implicitly 95 forces the standard include files to be treated as C. */ 96/*#define ADD_MISSING_EXTERN_C 1 */ 97 98#if ADD_MISSING_EXTERN_C 99int missing_extern_C_count = 0; 100#endif 101 102#include "xsys-protos.h" 103 104#ifdef FIXPROTO_IGNORE_LIST 105/* This is a currently unused feature. */ 106 107/* List of files and directories to ignore. 108 A directory name (ending in '/') means ignore anything in that 109 directory. (It might be more efficient to do directory pruning 110 earlier in fixproto, but this is simpler and easier to customize.) */ 111 112static char *files_to_ignore[] = { 113 "X11/", 114 FIXPROTO_IGNORE_LIST 115 0 116}; 117#endif 118 119char *inf_buffer; 120char *inf_limit; 121char *inf_ptr; 122 123/* Certain standard files get extra treatment */ 124 125enum special_file 126{ 127 no_special, 128#ifdef errno_h 129#undef errno_h 130#endif 131 errno_h, 132#ifdef stdio_h 133#undef stdio_h 134#endif 135 stdio_h, 136#ifdef stdlib_h 137#undef stdlib_h 138#endif 139 stdlib_h, 140#ifdef sys_stat_h 141#undef sys_stat_h 142#endif 143 sys_stat_h 144}; 145 146/* A NAMELIST is a sequence of names, separated by '\0', and terminated 147 by an empty name (i.e. by "\0\0"). */ 148 149typedef const char *namelist; 150 151/* The following macros provide the bits for symbol_flags. */ 152typedef int symbol_flags; 153 154/* Used to mark names defined in the ANSI/ISO C standard. */ 155#define ANSI_SYMBOL 1 156 157/* We no longer massage include files for POSIX or XOPEN symbols, 158 as there are now several versions of the POSIX and XOPEN standards, 159 and it would be a maintenance nightmare for us to track them all. 160 Better to be compatible with the system include files. */ 161/*#define ADD_MISSING_POSIX 1 */ 162/*#define ADD_MISSING_XOPEN 1 */ 163 164#if ADD_MISSING_POSIX 165/* Used to mark names defined in the Posix.1 or Posix.2 standard. */ 166#define POSIX1_SYMBOL 2 167#define POSIX2_SYMBOL 4 168#else 169#define POSIX1_SYMBOL 0 170#define POSIX2_SYMBOL 0 171#endif 172 173#if ADD_MISSING_XOPEN 174/* Used to mark names defined in X/Open Portability Guide. */ 175#define XOPEN_SYMBOL 8 176/* Used to mark names defined in X/Open UNIX Extensions. */ 177#define XOPEN_EXTENDED_SYMBOL 16 178#else 179#define XOPEN_SYMBOL 0 180#define XOPEN_EXTENDED_SYMBOL 0 181#endif 182 183/* Used to indicate names that are not functions */ 184#define MACRO_SYMBOL 512 185 186struct symbol_list { 187 symbol_flags flags; 188 namelist names; 189}; 190 191#define SYMBOL_TABLE_SIZE 10 192struct symbol_list symbol_table[SYMBOL_TABLE_SIZE]; 193int cur_symbol_table_size; 194 195void 196add_symbols (flags, names) 197 symbol_flags flags; 198 namelist names; 199{ 200 symbol_table[cur_symbol_table_size].flags = flags; 201 symbol_table[cur_symbol_table_size].names = names; 202 cur_symbol_table_size++; 203 if (cur_symbol_table_size >= SYMBOL_TABLE_SIZE) 204 fatal ("too many calls to add_symbols"); 205 symbol_table[cur_symbol_table_size].names = NULL; /* Termination. */ 206} 207 208struct std_include_entry { 209 const char *name; 210 symbol_flags flags; 211 namelist names; 212}; 213 214const char NONE[] = ""; /* The empty namelist. */ 215 216/* Special name to indicate a continuation line in std_include_table. */ 217const char CONTINUED[] = ""; 218 219struct std_include_entry *include_entry; 220 221struct std_include_entry std_include_table [] = { 222 { "ctype.h", ANSI_SYMBOL, 223 "isalnum\0isalpha\0iscntrl\0isdigit\0isgraph\0islower\0\ 224isprint\0ispunct\0isspace\0isupper\0isxdigit\0tolower\0toupper\0" }, 225 226 { "dirent.h", POSIX1_SYMBOL, "closedir\0opendir\0readdir\0rewinddir\0"}, 227 228 { "errno.h", ANSI_SYMBOL|MACRO_SYMBOL, "errno\0" }, 229 230 /* ANSI_SYMBOL is wrong, but ... */ 231 { "curses.h", ANSI_SYMBOL, "box\0delwin\0endwin\0getcurx\0getcury\0initscr\0\ 232mvcur\0mvwprintw\0mvwscanw\0newwin\0overlay\0overwrite\0\ 233scroll\0subwin\0touchwin\0waddstr\0wclear\0wclrtobot\0wclrtoeol\0\ 234waddch\0wdelch\0wdeleteln\0werase\0wgetch\0wgetstr\0winsch\0winsertln\0\ 235wmove\0wprintw\0wrefresh\0wscanw\0wstandend\0wstandout\0" }, 236 237 { "fcntl.h", POSIX1_SYMBOL, "creat\0fcntl\0open\0" }, 238 239 /* Maybe also "getgrent fgetgrent setgrent endgrent" */ 240 { "grp.h", POSIX1_SYMBOL, "getgrgid\0getgrnam\0" }, 241 242/*{ "limit.h", ... provided by gcc }, */ 243 244 { "locale.h", ANSI_SYMBOL, "localeconv\0setlocale\0" }, 245 246 { "math.h", ANSI_SYMBOL, 247 "acos\0asin\0atan\0atan2\0ceil\0cos\0cosh\0exp\0\ 248fabs\0floor\0fmod\0frexp\0ldexp\0log10\0log\0modf\0pow\0sin\0sinh\0sqrt\0\ 249tan\0tanh\0" }, 250 251 { CONTINUED, ANSI_SYMBOL|MACRO_SYMBOL, "HUGE_VAL\0" }, 252 253 { "pwd.h", POSIX1_SYMBOL, "getpwnam\0getpwuid\0" }, 254 255 /* Left out siglongjmp sigsetjmp - these depend on sigjmp_buf. */ 256 { "setjmp.h", ANSI_SYMBOL, "longjmp\0setjmp\0" }, 257 258 /* Left out signal() - its prototype is too complex for us! 259 Also left out "sigaction sigaddset sigdelset sigemptyset 260 sigfillset sigismember sigpending sigprocmask sigsuspend" 261 because these need sigset_t or struct sigaction. 262 Most systems that provide them will also declare them. */ 263 { "signal.h", ANSI_SYMBOL, "kill\0raise\0" }, 264 265 { "stdio.h", ANSI_SYMBOL, 266 "clearerr\0fclose\0feof\0ferror\0fflush\0fgetc\0fgetpos\0\ 267fgets\0fopen\0fprintf\0fputc\0fputs\0fread\0freopen\0fscanf\0fseek\0\ 268fsetpos\0ftell\0fwrite\0getc\0getchar\0gets\0perror\0\ 269printf\0putc\0putchar\0puts\0remove\0rename\0rewind\0scanf\0setbuf\0\ 270setvbuf\0sprintf\0sscanf\0vprintf\0vsprintf\0vfprintf\0tmpfile\0\ 271tmpnam\0ungetc\0" }, 272 { CONTINUED, POSIX1_SYMBOL, "fdopen\0fileno\0" }, 273 { CONTINUED, POSIX2_SYMBOL, "pclose\0popen\0" }, /* I think ... */ 274/* Should perhaps also handle NULL, EOF, ... ? */ 275 276 /* "div ldiv", - ignored because these depend on div_t, ldiv_t 277 ignore these: "mblen mbstowcs mbstowc wcstombs wctomb" 278 Left out getgroups, because SunOS4 has incompatible BSD and SVR4 versions. 279 Should perhaps also add NULL */ 280 { "stdlib.h", ANSI_SYMBOL, 281 "abort\0abs\0atexit\0atof\0atoi\0atol\0bsearch\0calloc\0\ 282exit\0free\0getenv\0labs\0malloc\0putenv\0qsort\0rand\0realloc\0\ 283srand\0strtod\0strtol\0strtoul\0system\0" }, 284 { CONTINUED, ANSI_SYMBOL|MACRO_SYMBOL, "EXIT_FAILURE\0EXIT_SUCCESS\0" }, 285 286 { "string.h", ANSI_SYMBOL, "memchr\0memcmp\0memcpy\0memmove\0memset\0\ 287strcat\0strchr\0strcmp\0strcoll\0strcpy\0strcspn\0strerror\0\ 288strlen\0strncat\0strncmp\0strncpy\0strpbrk\0strrchr\0strspn\0strstr\0\ 289strtok\0strxfrm\0" }, 290/* Should perhaps also add NULL and size_t */ 291 292 { "strings.h", XOPEN_EXTENDED_SYMBOL, 293 "bcmp\0bcopy\0bzero\0ffs\0index\0rindex\0strcasecmp\0strncasecmp\0" }, 294 295 { "strops.h", XOPEN_EXTENDED_SYMBOL, "ioctl\0" }, 296 297 /* Actually, XPG4 does not seem to have <sys/ioctl.h>, but defines 298 ioctl in <strops.h>. However, many systems have it is sys/ioctl.h, 299 and many systems do have <sys/ioctl.h> but not <strops.h>. */ 300 { "sys/ioctl.h", XOPEN_EXTENDED_SYMBOL, "ioctl\0" }, 301 302 { "sys/socket.h", XOPEN_EXTENDED_SYMBOL, "socket\0" }, 303 304 { "sys/stat.h", POSIX1_SYMBOL, 305 "chmod\0fstat\0mkdir\0mkfifo\0stat\0lstat\0umask\0" }, 306 { CONTINUED, POSIX1_SYMBOL|MACRO_SYMBOL, 307 "S_ISDIR\0S_ISBLK\0S_ISCHR\0S_ISFIFO\0S_ISREG\0S_ISLNK\0S_IFDIR\0\ 308S_IFBLK\0S_IFCHR\0S_IFIFO\0S_IFREG\0S_IFLNK\0" }, 309 { CONTINUED, XOPEN_EXTENDED_SYMBOL, "fchmod\0" }, 310 311#if 0 312/* How do we handle fd_set? */ 313 { "sys/time.h", XOPEN_EXTENDED_SYMBOL, "select\0" }, 314 { "sys/select.h", XOPEN_EXTENDED_SYMBOL /* fake */, "select\0" }, 315#endif 316 317 { "sys/times.h", POSIX1_SYMBOL, "times\0" }, 318 /* "sys/types.h" add types (not in old g++-include) */ 319 320 { "sys/utsname.h", POSIX1_SYMBOL, "uname\0" }, 321 322 { "sys/wait.h", POSIX1_SYMBOL, "wait\0waitpid\0" }, 323 { CONTINUED, POSIX1_SYMBOL|MACRO_SYMBOL, 324 "WEXITSTATUS\0WIFEXITED\0WIFSIGNALED\0WIFSTOPPED\0WSTOPSIG\0\ 325WTERMSIG\0WNOHANG\0WNOTRACED\0" }, 326 327 { "tar.h", POSIX1_SYMBOL, NONE }, 328 329 { "termios.h", POSIX1_SYMBOL, 330 "cfgetispeed\0cfgetospeed\0cfsetispeed\0cfsetospeed\0tcdrain\0tcflow\0tcflush\0tcgetattr\0tcsendbreak\0tcsetattr\0" }, 331 332 { "time.h", ANSI_SYMBOL, 333 "asctime\0clock\0ctime\0difftime\0gmtime\0localtime\0mktime\0strftime\0time\0tzset\0" }, 334 335 { "unistd.h", POSIX1_SYMBOL, 336 "_exit\0access\0alarm\0chdir\0chown\0close\0ctermid\0cuserid\0\ 337dup\0dup2\0execl\0execle\0execlp\0execv\0execve\0execvp\0fork\0fpathconf\0\ 338getcwd\0getegid\0geteuid\0getgid\0getlogin\0getpgrp\0getpid\0\ 339getppid\0getuid\0isatty\0link\0lseek\0pathconf\0pause\0pipe\0read\0rmdir\0\ 340setgid\0setpgid\0setsid\0setuid\0sleep\0sysconf\0tcgetpgrp\0tcsetpgrp\0\ 341ttyname\0unlink\0write\0" }, 342 { CONTINUED, POSIX2_SYMBOL, "getopt\0" }, 343 { CONTINUED, XOPEN_EXTENDED_SYMBOL, 344 "lockf\0gethostid\0gethostname\0readlink\0" }, 345 346 { "utime.h", POSIX1_SYMBOL, "utime\0" }, 347 348 { NULL, 0, NONE } 349}; 350 351enum special_file special_file_handling = no_special; 352 353/* They are set if the corresponding macro has been seen. */ 354/* The following are only used when handling sys/stat.h */ 355int seen_S_IFBLK = 0, seen_S_ISBLK = 0; 356int seen_S_IFCHR = 0, seen_S_ISCHR = 0; 357int seen_S_IFDIR = 0, seen_S_ISDIR = 0; 358int seen_S_IFIFO = 0, seen_S_ISFIFO = 0; 359int seen_S_IFLNK = 0, seen_S_ISLNK = 0; 360int seen_S_IFREG = 0, seen_S_ISREG = 0; 361/* The following are only used when handling errno.h */ 362int seen_errno = 0; 363/* The following are only used when handling stdlib.h */ 364int seen_EXIT_FAILURE = 0, seen_EXIT_SUCCESS = 0; 365 366/* Wrapper around free, to avoid prototype clashes. */ 367 368void 369xfree (ptr) 370 char *ptr; 371{ 372 free (ptr); 373} 374 375/* Avoid error if config defines abort as fancy_abort. 376 It's not worth "really" implementing this because ordinary 377 compiler users never run fix-header. */ 378 379void 380fancy_abort () 381{ 382 abort (); 383} 384 385#define obstack_chunk_alloc xmalloc 386#define obstack_chunk_free xfree 387struct obstack scan_file_obstack; 388 389/* NOTE: If you edit this, also edit gen-protos.c !! */ 390 391struct fn_decl * 392lookup_std_proto (name, name_length) 393 const char *name; 394 int name_length; 395{ 396 int i = hashf (name, name_length, HASH_SIZE); 397 int i0 = i; 398 for (;;) 399 { 400 struct fn_decl *fn; 401 if (hash_tab[i] == 0) 402 return NULL; 403 fn = &std_protos[hash_tab[i]]; 404 if (strlen (fn->fname) == name_length 405 && strncmp (fn->fname, name, name_length) == 0) 406 return fn; 407 i = (i+1) % HASH_SIZE; 408 if (i == i0) 409 abort (); 410 } 411} 412 413char *inc_filename; 414int inc_filename_length; 415char *progname = "fix-header"; 416FILE *outf; 417sstring line; 418 419int lbrac_line, rbrac_line; 420 421int required_unseen_count = 0; 422int required_other = 0; 423 424void 425write_lbrac () 426{ 427 428#if ADD_MISSING_EXTERN_C 429 if (missing_extern_C_count + required_unseen_count > 0) 430 fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); 431#endif 432 433 if (partial_count) 434 { 435 fprintf (outf, "#ifndef _PARAMS\n"); 436 fprintf (outf, "#if defined(__STDC__) || defined(__cplusplus)\n"); 437 fprintf (outf, "#define _PARAMS(ARGS) ARGS\n"); 438 fprintf (outf, "#else\n"); 439 fprintf (outf, "#define _PARAMS(ARGS) ()\n"); 440 fprintf (outf, "#endif\n#endif /* _PARAMS */\n"); 441 } 442} 443 444struct partial_proto 445{ 446 struct partial_proto *next; 447 char *fname; /* name of function */ 448 char *rtype; /* return type */ 449 struct fn_decl *fn; 450 int line_seen; 451}; 452 453struct partial_proto *partial_proto_list = NULL; 454 455struct partial_proto required_dummy_proto, seen_dummy_proto; 456#define REQUIRED(FN) ((FN)->partial == &required_dummy_proto) 457#define SET_REQUIRED(FN) ((FN)->partial = &required_dummy_proto) 458#define SET_SEEN(FN) ((FN)->partial = &seen_dummy_proto) 459#define SEEN(FN) ((FN)->partial == &seen_dummy_proto) 460 461void 462recognized_macro (fname) 463 char *fname; 464{ 465 /* The original include file defines fname as a macro. */ 466 struct fn_decl *fn = lookup_std_proto (fname, strlen (fname)); 467 468 /* Since fname is a macro, don't require a prototype for it. */ 469 if (fn) 470 { 471 if (REQUIRED (fn)) 472 required_unseen_count--; 473 SET_SEEN (fn); 474 } 475 476 switch (special_file_handling) 477 { 478 case errno_h: 479 if (strcmp (fname, "errno") == 0 && !seen_errno) 480 seen_errno = 1, required_other--; 481 break; 482 case stdlib_h: 483 if (strcmp (fname, "EXIT_FAILURE") == 0 && !seen_EXIT_FAILURE) 484 seen_EXIT_FAILURE = 1, required_other--; 485 if (strcmp (fname, "EXIT_SUCCESS") == 0 && !seen_EXIT_SUCCESS) 486 seen_EXIT_SUCCESS = 1, required_other--; 487 break; 488 case sys_stat_h: 489 if (fname[0] == 'S' && fname[1] == '_') 490 { 491 if (strcmp (fname, "S_IFBLK") == 0) seen_S_IFBLK++; 492 else if (strcmp (fname, "S_ISBLK") == 0) seen_S_ISBLK++; 493 else if (strcmp (fname, "S_IFCHR") == 0) seen_S_IFCHR++; 494 else if (strcmp (fname, "S_ISCHR") == 0) seen_S_ISCHR++; 495 else if (strcmp (fname, "S_IFDIR") == 0) seen_S_IFDIR++; 496 else if (strcmp (fname, "S_ISDIR") == 0) seen_S_ISDIR++; 497 else if (strcmp (fname, "S_IFIFO") == 0) seen_S_IFIFO++; 498 else if (strcmp (fname, "S_ISFIFO") == 0) seen_S_ISFIFO++; 499 else if (strcmp (fname, "S_IFLNK") == 0) seen_S_IFLNK++; 500 else if (strcmp (fname, "S_ISLNK") == 0) seen_S_ISLNK++; 501 else if (strcmp (fname, "S_IFREG") == 0) seen_S_IFREG++; 502 else if (strcmp (fname, "S_ISREG") == 0) seen_S_ISREG++; 503 } 504 break; 505 506 default: 507 break; 508 } 509} 510 511void 512recognized_extern (name, name_length, type, type_length) 513 char *name; 514 char *type; 515 int name_length, type_length; 516{ 517 switch (special_file_handling) 518 { 519 case errno_h: 520 if (name_length == 5 && strncmp (name, "errno", 5) == 0 && !seen_errno) 521 seen_errno = 1, required_other--; 522 break; 523 524 default: 525 break; 526 } 527} 528 529/* Called by scan_decls if it saw a function definition for a function 530 named FNAME, with return type RTYPE, and argument list ARGS, 531 in source file FILE_SEEN on line LINE_SEEN. 532 KIND is 'I' for an inline function; 533 'F' if a normal function declaration preceded by 'extern "C"' 534 (or nested inside 'extern "C"' braces); or 535 'f' for other function declarations. */ 536 537void 538recognized_function (fname, fname_length, 539 kind, rtype, rtype_length, 540 have_arg_list, file_seen, line_seen) 541 char *fname; 542 int fname_length; 543 int kind; /* One of 'f' 'F' or 'I' */ 544 char *rtype; 545 int rtype_length; 546 int have_arg_list; 547 char *file_seen; 548 int line_seen; 549{ 550 struct partial_proto *partial; 551 int i; 552 struct fn_decl *fn; 553#if ADD_MISSING_EXTERN_C 554 if (kind == 'f') 555 missing_extern_C_count++; 556#endif 557 558 fn = lookup_std_proto (fname, fname_length); 559 560 /* Remove the function from the list of required function. */ 561 if (fn) 562 { 563 if (REQUIRED (fn)) 564 required_unseen_count--; 565 SET_SEEN (fn); 566 } 567 568 /* If we have a full prototype, we're done. */ 569 if (have_arg_list) 570 return; 571 572 if (kind == 'I') /* don't edit inline function */ 573 return; 574 575 /* If the partial prototype was included from some other file, 576 we don't need to patch it up (in this run). */ 577 i = strlen (file_seen); 578 if (i < inc_filename_length 579 || strcmp (inc_filename, file_seen + (i - inc_filename_length)) != 0) 580 return; 581 582 if (fn == NULL) 583 return; 584 if (fn->params[0] == '\0' || strcmp (fn->params, "void") == 0) 585 return; 586 587 /* We only have a partial function declaration, 588 so remember that we have to add a complete prototype. */ 589 partial_count++; 590 partial = (struct partial_proto *) 591 obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto)); 592 partial->fname = obstack_alloc (&scan_file_obstack, fname_length + 1); 593 bcopy (fname, partial->fname, fname_length); 594 partial->fname[fname_length] = 0; 595 partial->rtype = obstack_alloc (&scan_file_obstack, rtype_length + 1); 596 sprintf (partial->rtype, "%.*s", rtype_length, rtype); 597 partial->line_seen = line_seen; 598 partial->fn = fn; 599 fn->partial = partial; 600 partial->next = partial_proto_list; 601 partial_proto_list = partial; 602 if (verbose) 603 { 604 fprintf (stderr, "(%s: %s non-prototype function declaration.)\n", 605 inc_filename, partial->fname); 606 } 607} 608 609/* For any name in NAMES that is defined as a macro, 610 call recognized_macro on it. */ 611 612void 613check_macro_names (pfile, names) 614 cpp_reader *pfile; 615 namelist names; 616{ 617 while (*names) 618 { 619 if (cpp_lookup (pfile, names, -1, -1)) 620 recognized_macro (names); 621 names += strlen (names) + 1; 622 } 623} 624 625void 626read_scan_file (in_fname, argc, argv) 627 char *in_fname; 628 int argc; 629 char **argv; 630{ 631 cpp_reader scan_in; 632 cpp_options scan_options; 633 struct fn_decl *fn; 634 int i; 635 register struct symbol_list *cur_symbols; 636 637 obstack_init (&scan_file_obstack); 638 639 cpp_reader_init (&scan_in); 640 scan_in.data = &scan_options; 641 cpp_options_init (&scan_options); 642 i = cpp_handle_options (&scan_in, argc, argv); 643 if (i < argc && ! CPP_FATAL_ERRORS (&scan_in)) 644 cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]); 645 if (CPP_FATAL_ERRORS (&scan_in)) 646 exit (FATAL_EXIT_CODE); 647 648 if (! cpp_start_read (&scan_in, in_fname)) 649 exit (FATAL_EXIT_CODE); 650 CPP_OPTIONS (&scan_in)->no_line_commands = 1; 651 652 scan_decls (&scan_in, argc, argv); 653 for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++) 654 check_macro_names (&scan_in, cur_symbols->names); 655 656 if (verbose && (scan_in.errors + warnings) > 0) 657 fprintf (stderr, "(%s: %d errors and %d warnings from cpp)\n", 658 inc_filename, scan_in.errors, warnings); 659 if (scan_in.errors) 660 exit (SUCCESS_EXIT_CODE); 661 662 /* Traditionally, getc and putc are defined in terms of _filbuf and _flsbuf. 663 If so, those functions are also required. */ 664 if (special_file_handling == stdio_h 665 && (fn = lookup_std_proto ("_filbuf", 7)) != NULL) 666 { 667 static char getchar_call[] = "getchar();"; 668 cpp_buffer *buf 669 = cpp_push_buffer (&scan_in, getchar_call, sizeof(getchar_call) - 1); 670 int old_written = CPP_WRITTEN (&scan_in); 671 int seen_filbuf = 0; 672 673 /* Scan the macro expansion of "getchar();". */ 674 for (;;) 675 { 676 enum cpp_token token = cpp_get_token (&scan_in); 677 int length = CPP_WRITTEN (&scan_in) - old_written; 678 CPP_SET_WRITTEN (&scan_in, old_written); 679 if (token == CPP_EOF) /* Should not happen ... */ 680 break; 681 if (token == CPP_POP && CPP_BUFFER (&scan_in) == buf) 682 { 683 cpp_pop_buffer (&scan_in); 684 break; 685 } 686 if (token == CPP_NAME && length == 7 687 && strcmp ("_filbuf", scan_in.token_buffer + old_written) == 0) 688 seen_filbuf++; 689 } 690 if (seen_filbuf) 691 { 692 int need_filbuf = !SEEN (fn) && !REQUIRED (fn); 693 struct fn_decl *flsbuf_fn = lookup_std_proto ("_flsbuf", 7); 694 int need_flsbuf 695 = flsbuf_fn && !SEEN (flsbuf_fn) && !REQUIRED (flsbuf_fn); 696 697 /* Append "_filbuf" and/or "_flsbuf" to the required functions. */ 698 if (need_filbuf + need_flsbuf) 699 { 700 char *new_list; 701 if (need_filbuf) 702 SET_REQUIRED (fn); 703 if (need_flsbuf) 704 SET_REQUIRED (flsbuf_fn); 705 if (need_flsbuf + need_filbuf == 2) 706 new_list = "_filbuf\0_flsbuf\0"; 707 else if (need_flsbuf) 708 new_list = "_flsbuf\0"; 709 else /* if (need_flsbuf) */ 710 new_list = "_filbuf\0"; 711 add_symbols (ANSI_SYMBOL, new_list); 712 required_unseen_count += need_filbuf + need_flsbuf; 713 } 714 } 715 } 716 717 if (required_unseen_count + partial_count + required_other 718#if ADD_MISSING_EXTERN_C 719 + missing_extern_C_count 720#endif 721 == 0) 722 { 723 if (verbose) 724 fprintf (stderr, "%s: OK, nothing needs to be done.\n", inc_filename); 725 exit (SUCCESS_EXIT_CODE); 726 } 727 if (!verbose) 728 fprintf (stderr, "%s: fixing %s\n", progname, inc_filename); 729 else 730 { 731 if (required_unseen_count) 732 fprintf (stderr, "%s: %d missing function declarations.\n", 733 inc_filename, required_unseen_count); 734 if (partial_count) 735 fprintf (stderr, "%s: %d non-prototype function declarations.\n", 736 inc_filename, partial_count); 737#if ADD_MISSING_EXTERN_C 738 if (missing_extern_C_count) 739 fprintf (stderr, 740 "%s: %d declarations not protected by extern \"C\".\n", 741 inc_filename, missing_extern_C_count); 742#endif 743 } 744} 745 746void 747write_rbrac () 748{ 749 struct fn_decl *fn; 750 const char *cptr; 751 register struct symbol_list *cur_symbols; 752 753 if (required_unseen_count) 754 { 755#ifdef NO_IMPLICIT_EXTERN_C 756 fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); 757#endif 758 } 759 760 /* Now we print out prototypes for those functions that we haven't seen. */ 761 for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++) 762 { 763 int if_was_emitted = 0; 764 int name_len; 765 cptr = cur_symbols->names; 766 for ( ; (name_len = strlen (cptr)) != 0; cptr+= name_len + 1) 767 { 768 int macro_protect = 0; 769 770 if (cur_symbols->flags & MACRO_SYMBOL) 771 continue; 772 773 fn = lookup_std_proto (cptr, name_len); 774 if (fn == NULL || !REQUIRED (fn)) 775 continue; 776 777 if (!if_was_emitted) 778 { 779/* what about curses. ??? or _flsbuf/_filbuf ??? */ 780 if (cur_symbols->flags & ANSI_SYMBOL) 781 fprintf (outf, 782 "#if defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus) || defined (__STRICT_ANSI__)\n"); 783 else if (cur_symbols->flags & (POSIX1_SYMBOL|POSIX2_SYMBOL)) 784 fprintf (outf, 785 "#if defined(__USE_FIXED_PROTOTYPES__) || (defined(__cplusplus) \\\n\ 786 ? (!defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE)) \\\n\ 787 : (defined(__STRICT_ANSI__) && defined(_POSIX_SOURCE)))\n"); 788 else if (cur_symbols->flags & XOPEN_SYMBOL) 789 { 790 fprintf (outf, 791 "#if defined(__USE_FIXED_PROTOTYPES__) \\\n\ 792 || (defined(__STRICT_ANSI__) && defined(_XOPEN_SOURCE))\n"); 793 } 794 else if (cur_symbols->flags & XOPEN_EXTENDED_SYMBOL) 795 { 796 fprintf (outf, 797 "#if defined(__USE_FIXED_PROTOTYPES__) \\\n\ 798 || (defined(__STRICT_ANSI__) && defined(_XOPEN_EXTENDED_SOURCE))\n"); 799 } 800 else 801 { 802 fatal ("internal error for function %s", fn->fname); 803 } 804 if_was_emitted = 1; 805 } 806 807 /* In the case of memmove, protect in case the application 808 defines it as a macro before including the header. */ 809 if (!strcmp (fn->fname, "memmove") 810 || !strcmp (fn->fname, "vprintf") 811 || !strcmp (fn->fname, "vfprintf") 812 || !strcmp (fn->fname, "vsprintf") 813 || !strcmp (fn->fname, "rewinddir") 814 || !strcmp (fn->fname, "abort")) 815 macro_protect = 1; 816 817 if (macro_protect) 818 fprintf (outf, "#ifndef %s\n", fn->fname); 819 fprintf (outf, "extern %s %s (%s);\n", 820 fn->rtype, fn->fname, fn->params); 821 if (macro_protect) 822 fprintf (outf, "#endif\n"); 823 } 824 if (if_was_emitted) 825 fprintf (outf, 826 "#endif /* defined(__USE_FIXED_PROTOTYPES__) || ... */\n"); 827 } 828 if (required_unseen_count) 829 { 830#ifdef NO_IMPLICIT_EXTERN_C 831 fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n"); 832#endif 833 } 834 835 switch (special_file_handling) 836 { 837 case errno_h: 838 if (!seen_errno) 839 fprintf (outf, "extern int errno;\n"); 840 break; 841 case stdlib_h: 842 if (!seen_EXIT_FAILURE) 843 fprintf (outf, "#define EXIT_FAILURE 1\n"); 844 if (!seen_EXIT_SUCCESS) 845 fprintf (outf, "#define EXIT_SUCCESS 0\n"); 846 break; 847 case sys_stat_h: 848 if (!seen_S_ISBLK && seen_S_IFBLK) 849 fprintf (outf, 850 "#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n"); 851 if (!seen_S_ISCHR && seen_S_IFCHR) 852 fprintf (outf, 853 "#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)\n"); 854 if (!seen_S_ISDIR && seen_S_IFDIR) 855 fprintf (outf, 856 "#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)\n"); 857 if (!seen_S_ISFIFO && seen_S_IFIFO) 858 fprintf (outf, 859 "#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)\n"); 860 if (!seen_S_ISLNK && seen_S_IFLNK) 861 fprintf (outf, 862 "#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)\n"); 863 if (!seen_S_ISREG && seen_S_IFREG) 864 fprintf (outf, 865 "#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)\n"); 866 break; 867 868 default: 869 break; 870 } 871 872 873#if ADD_MISSING_EXTERN_C 874 if (missing_extern_C_count + required_unseen_count > 0) 875 fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n"); 876#endif 877} 878 879char * 880xstrdup (str) 881 char *str; 882{ 883 char *copy = (char *) xmalloc (strlen (str) + 1); 884 strcpy (copy, str); 885 return copy; 886} 887 888/* Returns 1 iff the file is properly protected from multiple inclusion: 889 #ifndef PROTECT_NAME 890 #define PROTECT_NAME 891 #endif 892 893 */ 894 895#define INF_GET() (inf_ptr < inf_limit ? *(unsigned char *) inf_ptr++ : EOF) 896#define INF_UNGET(c) ((c)!=EOF && inf_ptr--) 897 898int 899inf_skip_spaces (c) 900 int c; 901{ 902 for (;;) 903 { 904 if (c == ' ' || c == '\t') 905 c = INF_GET (); 906 else if (c == '/') 907 { 908 c = INF_GET (); 909 if (c != '*') 910 { 911 (void) INF_UNGET (c); 912 return '/'; 913 } 914 c = INF_GET (); 915 for (;;) 916 { 917 if (c == EOF) 918 return EOF; 919 else if (c != '*') 920 { 921 if (c == '\n') 922 source_lineno++, lineno++; 923 c = INF_GET (); 924 } 925 else if ((c = INF_GET ()) == '/') 926 return INF_GET (); 927 } 928 } 929 else 930 break; 931 } 932 return c; 933} 934 935/* Read into STR from inf_buffer upto DELIM. */ 936 937int 938inf_read_upto (str, delim) 939 sstring *str; 940 int delim; 941{ 942 int ch; 943 for (;;) 944 { 945 ch = INF_GET (); 946 if (ch == EOF || ch == delim) 947 break; 948 SSTRING_PUT (str, ch); 949 } 950 MAKE_SSTRING_SPACE (str, 1); 951 *str->ptr = 0; 952 return ch; 953} 954 955int 956inf_scan_ident (s, c) 957 register sstring *s; 958 int c; 959{ 960 s->ptr = s->base; 961 if (ISALPHA (c) || c == '_') 962 { 963 for (;;) 964 { 965 SSTRING_PUT (s, c); 966 c = INF_GET (); 967 if (c == EOF || !(ISALNUM (c) || c == '_')) 968 break; 969 } 970 } 971 MAKE_SSTRING_SPACE (s, 1); 972 *s->ptr = 0; 973 return c; 974} 975 976/* Returns 1 if the file is correctly protected against multiple 977 inclusion, setting *ifndef_line to the line number of the initial #ifndef 978 and setting *endif_line to the final #endif. 979 Otherwise return 0. */ 980 981int 982check_protection (ifndef_line, endif_line) 983 int *ifndef_line, *endif_line; 984{ 985 int c; 986 int if_nesting = 1; /* Level of nesting of #if's */ 987 char *protect_name = NULL; /* Identifier following initial #ifndef */ 988 int define_seen = 0; 989 990 /* Skip initial white space (including comments). */ 991 for (;; lineno++) 992 { 993 c = inf_skip_spaces (' '); 994 if (c == EOF) 995 return 0; 996 if (c != '\n') 997 break; 998 } 999 if (c != '#') 1000 return 0; 1001 c = inf_scan_ident (&buf, inf_skip_spaces (' ')); 1002 if (SSTRING_LENGTH (&buf) == 0 || strcmp (buf.base, "ifndef") != 0) 1003 return 0; 1004 1005 /* So far so good: We've seen an initial #ifndef. */ 1006 *ifndef_line = lineno; 1007 c = inf_scan_ident (&buf, inf_skip_spaces (c)); 1008 if (SSTRING_LENGTH (&buf) == 0 || c == EOF) 1009 return 0; 1010 protect_name = xstrdup (buf.base); 1011 1012 (void) INF_UNGET (c); 1013 c = inf_read_upto (&buf, '\n'); 1014 if (c == EOF) 1015 return 0; 1016 lineno++; 1017 1018 for (;;) 1019 { 1020 c = inf_skip_spaces (' '); 1021 if (c == EOF) 1022 return 0; 1023 if (c == '\n') 1024 { 1025 lineno++; 1026 continue; 1027 } 1028 if (c != '#') 1029 goto skip_to_eol; 1030 c = inf_scan_ident (&buf, inf_skip_spaces (' ')); 1031 if (SSTRING_LENGTH (&buf) == 0) 1032 ; 1033 else if (!strcmp (buf.base, "ifndef") 1034 || !strcmp (buf.base, "ifdef") || !strcmp (buf.base, "if")) 1035 { 1036 if_nesting++; 1037 } 1038 else if (!strcmp (buf.base, "endif")) 1039 { 1040 if_nesting--; 1041 if (if_nesting == 0) 1042 break; 1043 } 1044 else if (!strcmp (buf.base, "else")) 1045 { 1046 if (if_nesting == 1) 1047 return 0; 1048 } 1049 else if (!strcmp (buf.base, "define")) 1050 { 1051 if (if_nesting != 1) 1052 goto skip_to_eol; 1053 c = inf_skip_spaces (c); 1054 c = inf_scan_ident (&buf, c); 1055 if (buf.base[0] > 0 && strcmp (buf.base, protect_name) == 0) 1056 define_seen = 1; 1057 } 1058 skip_to_eol: 1059 for (;;) 1060 { 1061 if (c == '\n' || c == EOF) 1062 break; 1063 c = INF_GET (); 1064 } 1065 if (c == EOF) 1066 return 0; 1067 lineno++; 1068 } 1069 1070 if (!define_seen) 1071 return 0; 1072 *endif_line = lineno; 1073 /* Skip final white space (including comments). */ 1074 for (;;) 1075 { 1076 c = inf_skip_spaces (' '); 1077 if (c == EOF) 1078 break; 1079 if (c != '\n') 1080 return 0; 1081 } 1082 1083 return 1; 1084} 1085 1086int 1087main (argc, argv) 1088 int argc; 1089 char **argv; 1090{ 1091 int inf_fd; 1092 struct stat sbuf; 1093 int c; 1094#ifdef FIXPROTO_IGNORE_LIST 1095 int i; 1096#endif 1097 const char *cptr; 1098 int ifndef_line; 1099 int endif_line; 1100 long to_read; 1101 long int inf_size; 1102 register struct symbol_list *cur_symbols; 1103 1104 if (argv[0] && argv[0][0]) 1105 { 1106 register char *p; 1107 1108 progname = 0; 1109 for (p = argv[0]; *p; p++) 1110 if (*p == '/') 1111 progname = p; 1112 progname = progname ? progname+1 : argv[0]; 1113 } 1114 1115 if (argc < 4) 1116 { 1117 fprintf (stderr, "%s: Usage: foo.h infile.h outfile.h options\n", 1118 progname); 1119 exit (FATAL_EXIT_CODE); 1120 } 1121 1122 inc_filename = argv[1]; 1123 inc_filename_length = strlen (inc_filename); 1124 1125#ifdef FIXPROTO_IGNORE_LIST 1126 for (i = 0; files_to_ignore[i] != NULL; i++) 1127 { 1128 char *ignore_name = files_to_ignore[i]; 1129 int ignore_len = strlen (ignore_name); 1130 if (strncmp (inc_filename, ignore_name, ignore_len) == 0) 1131 { 1132 if (ignore_name[ignore_len-1] == '/' 1133 || inc_filename[ignore_len] == '\0') 1134 { 1135 if (verbose) 1136 fprintf (stderr, "%s: ignoring %s\n", progname, inc_filename); 1137 exit (SUCCESS_EXIT_CODE); 1138 } 1139 } 1140 1141 } 1142#endif 1143 1144 if (strcmp (inc_filename, "sys/stat.h") == 0) 1145 special_file_handling = sys_stat_h; 1146 else if (strcmp (inc_filename, "errno.h") == 0) 1147 special_file_handling = errno_h, required_other++; 1148 else if (strcmp (inc_filename, "stdlib.h") == 0) 1149 special_file_handling = stdlib_h, required_other+=2; 1150 else if (strcmp (inc_filename, "stdio.h") == 0) 1151 special_file_handling = stdio_h; 1152 include_entry = std_include_table; 1153 while (include_entry->name != NULL 1154 && (include_entry->name == CONTINUED 1155 || strcmp (inc_filename, include_entry->name) != 0)) 1156 include_entry++; 1157 1158 if (include_entry->name != NULL) 1159 { 1160 struct std_include_entry *entry; 1161 cur_symbol_table_size = 0; 1162 for (entry = include_entry; ;) 1163 { 1164 if (entry->flags) 1165 add_symbols (entry->flags, entry->names); 1166 entry++; 1167 if (entry->name != CONTINUED) 1168 break; 1169 } 1170 } 1171 else 1172 symbol_table[0].names = NULL; 1173 1174 /* Count and mark the prototypes required for this include file. */ 1175 for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++) 1176 { 1177 int name_len; 1178 if (cur_symbols->flags & MACRO_SYMBOL) 1179 continue; 1180 cptr = cur_symbols->names; 1181 for ( ; (name_len = strlen (cptr)) != 0; cptr+= name_len + 1) 1182 { 1183 struct fn_decl *fn = lookup_std_proto (cptr, name_len); 1184 required_unseen_count++; 1185 if (fn == NULL) 1186 fprintf (stderr, "Internal error: No prototype for %s\n", cptr); 1187 else 1188 SET_REQUIRED (fn); 1189 } 1190 } 1191 1192 read_scan_file (argv[2], argc - 4, argv + 4); 1193 1194 inf_fd = open (argv[2], O_RDONLY, 0666); 1195 if (inf_fd < 0) 1196 { 1197 fprintf (stderr, "%s: Cannot open '%s' for reading -", 1198 progname, argv[2]); 1199 perror (NULL); 1200 exit (FATAL_EXIT_CODE); 1201 } 1202 if (fstat (inf_fd, &sbuf) < 0) 1203 { 1204 fprintf (stderr, "%s: Cannot get size of '%s' -", progname, argv[2]); 1205 perror (NULL); 1206 exit (FATAL_EXIT_CODE); 1207 } 1208 inf_size = sbuf.st_size; 1209 inf_buffer = (char *) xmalloc (inf_size + 2); 1210 inf_buffer[inf_size] = '\n'; 1211 inf_buffer[inf_size + 1] = '\0'; 1212 inf_limit = inf_buffer + inf_size; 1213 inf_ptr = inf_buffer; 1214 1215 to_read = inf_size; 1216 while (to_read > 0) 1217 { 1218 long i = read (inf_fd, inf_buffer + inf_size - to_read, to_read); 1219 if (i < 0) 1220 { 1221 fprintf (stderr, "%s: Failed to read '%s' -", progname, argv[2]); 1222 perror (NULL); 1223 exit (FATAL_EXIT_CODE); 1224 } 1225 if (i == 0) 1226 { 1227 inf_size -= to_read; 1228 break; 1229 } 1230 to_read -= i; 1231 } 1232 1233 close (inf_fd); 1234 1235 /* If file doesn't end with '\n', add one. */ 1236 if (inf_limit > inf_buffer && inf_limit[-1] != '\n') 1237 inf_limit++; 1238 1239 unlink (argv[3]); 1240 outf = fopen (argv[3], "w"); 1241 if (outf == NULL) 1242 { 1243 fprintf (stderr, "%s: Cannot open '%s' for writing -", 1244 progname, argv[3]); 1245 perror (NULL); 1246 exit (FATAL_EXIT_CODE); 1247 } 1248 1249 lineno = 1; 1250 1251 if (check_protection (&ifndef_line, &endif_line)) 1252 { 1253 lbrac_line = ifndef_line+1; 1254 rbrac_line = endif_line; 1255 } 1256 else 1257 { 1258 lbrac_line = 1; 1259 rbrac_line = -1; 1260 } 1261 1262 /* Reset input file. */ 1263 inf_ptr = inf_buffer; 1264 lineno = 1; 1265 1266 for (;;) 1267 { 1268 if (lineno == lbrac_line) 1269 write_lbrac (); 1270 if (lineno == rbrac_line) 1271 write_rbrac (); 1272 for (;;) 1273 { 1274 struct fn_decl *fn; 1275 c = INF_GET (); 1276 if (c == EOF) 1277 break; 1278 if (ISALPHA (c) || c == '_') 1279 { 1280 c = inf_scan_ident (&buf, c); 1281 (void) INF_UNGET (c); 1282 fputs (buf.base, outf); 1283 fn = lookup_std_proto (buf.base, strlen (buf.base)); 1284 /* We only want to edit the declaration matching the one 1285 seen by scan-decls, as there can be multiple 1286 declarations, selected by #ifdef __STDC__ or whatever. */ 1287 if (fn && fn->partial && fn->partial->line_seen == lineno) 1288 { 1289 c = inf_skip_spaces (' '); 1290 if (c == EOF) 1291 break; 1292 if (c == '(') 1293 { 1294 c = inf_skip_spaces (' '); 1295 if (c == ')') 1296 { 1297 fprintf (outf, " _PARAMS((%s))", fn->params); 1298 } 1299 else 1300 { 1301 putc ('(', outf); 1302 (void) INF_UNGET (c); 1303 } 1304 } 1305 else 1306 fprintf (outf, " %c", c); 1307 } 1308 } 1309 else 1310 { 1311 putc (c, outf); 1312 if (c == '\n') 1313 break; 1314 } 1315 } 1316 if (c == EOF) 1317 break; 1318 lineno++; 1319 } 1320 if (rbrac_line < 0) 1321 write_rbrac (); 1322 1323 fclose (outf); 1324 1325 return 0; 1326} 1327 1328/* Stub error functions. These replace cpperror.c, 1329 because we want to suppress error messages. */ 1330 1331void 1332cpp_file_line_for_message (pfile, filename, line, column) 1333 cpp_reader * pfile; 1334 char *filename; 1335 int line, column; 1336{ 1337 if (!verbose) 1338 return; 1339 if (column > 0) 1340 fprintf (stderr, "%s:%d:%d: ", filename, line, column); 1341 else 1342 fprintf (stderr, "%s:%d: ", filename, line); 1343} 1344 1345void 1346cpp_print_containing_files (pfile) 1347 cpp_reader *pfile ATTRIBUTE_UNUSED; 1348{ 1349} 1350 1351/* IS_ERROR is 2 for fatal error, 1 for error, 0 for warning */ 1352 1353void 1354v_cpp_message (pfile, is_error, msg, ap) 1355 cpp_reader *pfile; 1356 int is_error; 1357 const char *msg; 1358 va_list ap; 1359{ 1360 if (is_error == 1) 1361 pfile->errors++; 1362 else if (is_error > 1) 1363 pfile->errors = CPP_FATAL_LIMIT; 1364 if (!verbose) 1365 return; 1366 if (!is_error) 1367 fprintf (stderr, "warning: "); 1368 vfprintf (stderr, msg, ap); 1369 fprintf (stderr, "\n"); 1370} 1371 1372void 1373cpp_message VPROTO ((cpp_reader *pfile, int is_error, const char *msg, ...)) 1374{ 1375#ifndef __STDC__ 1376 cpp_reader *pfile; 1377 int is_error; 1378 const char *msg; 1379#endif 1380 va_list ap; 1381 1382 VA_START (ap, msg); 1383 1384#ifndef __STDC__ 1385 pfile = va_arg (ap, cpp_reader *); 1386 is_error = va_arg (ap, const int); 1387 msg = va_arg (ap, const char *); 1388#endif 1389 1390 v_cpp_message(pfile, is_error, msg, ap); 1391 va_end(ap); 1392} 1393 1394static void 1395v_fatal (str, ap) 1396 const char * str; 1397 va_list ap; 1398{ 1399 fprintf (stderr, "%s: %s: ", progname, inc_filename); 1400 vfprintf (stderr, str, ap); 1401 fprintf (stderr, "\n"); 1402 1403 exit (FATAL_EXIT_CODE); 1404} 1405 1406void 1407fatal VPROTO ((const char *str, ...)) 1408{ 1409#ifndef __STDC__ 1410 const char *str; 1411#endif 1412 va_list ap; 1413 1414 VA_START(ap, str); 1415 1416#ifndef __STDC__ 1417 str = va_arg (ap, const char *); 1418#endif 1419 1420 v_fatal(str, ap); 1421 va_end(ap); 1422} 1423 1424void 1425cpp_fatal VPROTO ((cpp_reader * pfile, const char *str, ...)) 1426{ 1427#ifndef __STDC__ 1428 cpp_reader * pfile; 1429 const char *str; 1430#endif 1431 va_list ap; 1432 1433 VA_START(ap, str); 1434 1435#ifndef __STDC__ 1436 pfile = va_arg (ap, cpp_reader *); 1437 str = va_arg (ap, const char *); 1438#endif 1439 1440 v_fatal(str, ap); 1441 va_end(ap); 1442} 1443 1444void 1445cpp_pfatal_with_name (pfile, name) 1446 cpp_reader *pfile; 1447 const char *name; 1448{ 1449 cpp_perror_with_name (pfile, name); 1450 exit (FATAL_EXIT_CODE); 1451} 1452