source: trunk/third/gcc/fix-header.c @ 11288

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