OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [fix-header.c] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.