Initial revision
[official-gcc.git] / gcc / fix-header.c
blobc21acf054763a86ab020812b792903f92e2db736
1 /* fix-header.c - Make C header file suitable for C++.
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* This program massages a system include file (such as stdio.h),
19 into a form more conformant with ANSI/POSIX, and more suitable for C++:
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.
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.
31 * The program can be given a list of (names of) required standard
32 functions (such as fclose for stdio.h). If a reqquired function
33 is not seen in the input, then a prototype for it will be
34 written to the output.
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>.
44 * If the input file is OK (nothing needs to be done);
45 the output file is not written (nor removed if it exists).
47 There are also some special actions that are done for certain
48 well-known standard include files:
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.
55 * If argv[1] is "errno.h", errno is declared if it was missing.
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.
61 Usage:
62 fix-header FOO.H INFILE.H OUTFILE.H REQUIRED_FUNCS <SCAN-FILE
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 * SCAN-FILE is the output of the scan-decls program.
70 * REQUIRED_FUNCS is a list of required function (e.g. fclose for stdio.h).
72 Written by Per Bothner <bothner@cygnus.com>, July 1993. */
74 #include <stdio.h>
75 #include <ctype.h>
76 #include <sys/types.h>
77 #include <sys/stat.h>
78 #ifndef O_RDONLY
79 #define O_RDONLY 0
80 #endif
81 #include "hconfig.h"
82 #include "obstack.h"
83 #include "scan.h"
85 extern sstring buf;
87 int verbose = 0;
88 int partial_count = 0;
89 #if 0
90 /* All uses of this are ifdefed out. This is no longer needed, because
91 cccp.c implicitly forces the standard include files to be treated as C.
92 Adding an explicit extern "C" is undesireable as it breaks the SunOS 4.x
93 sun4c/romvec.h file. */
94 int missing_extern_C_count = 0;
95 #endif
96 int missing_errno = 0;
98 #include "xsys-protos.h"
100 char *inf_buffer;
101 char *inf_limit;
102 char *inf_ptr;
104 /* Certain standard files get extra treatment */
106 enum special_file
108 no_special,
109 errno_special,
110 sys_stat_special
113 enum special_file special_file_handling = no_special;
115 /* The following are only used when handling sys/stat.h */
116 /* They are set if the corresponding macro has been seen. */
117 int seen_S_IFBLK = 0, seen_S_ISBLK = 0;
118 int seen_S_IFCHR = 0, seen_S_ISCHR = 0;
119 int seen_S_IFDIR = 0, seen_S_ISDIR = 0;
120 int seen_S_IFIFO = 0, seen_S_ISFIFO = 0;
121 int seen_S_IFLNK = 0, seen_S_ISLNK = 0;
122 int seen_S_IFREG = 0, seen_S_ISREG = 0;
124 /* Wrapper around free, to avoid prototype clashes. */
126 void
127 xfree (ptr)
128 char *ptr;
130 free (ptr);
133 /* Avoid error if config defines abort as fancy_abort.
134 It's not worth "really" implementing this because ordinary
135 compiler users never run fix-header. */
137 void
138 fancy_abort ()
140 abort ();
143 #define obstack_chunk_alloc xmalloc
144 #define obstack_chunk_free xfree
145 struct obstack scan_file_obstack;
147 /* NOTE: If you edit this, also edit gen-protos.c !! */
148 struct fn_decl *
149 lookup_std_proto (name)
150 char *name;
152 int i = hash (name) % HASH_SIZE;
153 int i0 = i;
154 for (;;)
156 struct fn_decl *fn;
157 if (hash_tab[i] == 0)
158 return NULL;
159 fn = &std_protos[hash_tab[i]];
160 if (strcmp (fn->fname, name) == 0)
161 return fn;
162 i = (i+1) % HASH_SIZE;
163 if (i == i0)
164 abort ();
168 char *inc_filename;
169 int inc_filename_length;
170 char *progname = "fix-header";
171 FILE *outf;
172 sstring line;
174 int lbrac_line, rbrac_line;
176 char **required_functions;
177 int required_unseen_count;
179 void
180 write_lbrac ()
183 #if 0
184 if (missing_extern_C_count + required_unseen_count > 0)
185 fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
186 #endif
188 if (partial_count)
190 fprintf (outf, "#ifndef _PARAMS\n");
191 fprintf (outf, "#if defined(__STDC__) || defined(__cplusplus)\n");
192 fprintf (outf, "#define _PARAMS(ARGS) ARGS\n");
193 fprintf (outf, "#else\n");
194 fprintf (outf, "#define _PARAMS(ARGS) ()\n");
195 fprintf (outf, "#endif\n#endif /* _PARAMS */\n");
199 struct partial_proto
201 struct partial_proto *next;
202 char *fname; /* name of function */
203 char *rtype; /* return type */
204 struct fn_decl *fn;
205 int line_seen;
208 struct partial_proto *partial_proto_list = NULL;
210 struct partial_proto required_dummy_proto;
211 #define REQUIRED(FN) ((FN)->partial == &required_dummy_proto)
212 #define SET_REQUIRED(FN) ((FN)->partial = &required_dummy_proto)
213 #define CLEAR_REQUIRED(FN) ((FN)->partial = 0)
215 void
216 recognized_macro (fname)
217 char *fname;
219 /* The original include file defines fname as a macro. */
220 struct fn_decl *fn = lookup_std_proto (fname);
222 /* Since fname is a macro, don't require a prototype for it. */
223 if (fn && REQUIRED (fn))
225 CLEAR_REQUIRED (fn);
226 required_unseen_count--;
229 switch (special_file_handling)
231 case errno_special:
232 if (strcmp (fname, "errno") == 0) missing_errno = 0;
233 break;
234 case sys_stat_special:
235 if (fname[0] == 'S' && fname[1] == '_')
237 if (strcmp (fname, "S_IFBLK") == 0) seen_S_IFBLK++;
238 else if (strcmp (fname, "S_ISBLK") == 0) seen_S_ISBLK++;
239 else if (strcmp (fname, "S_IFCHR") == 0) seen_S_IFCHR++;
240 else if (strcmp (fname, "S_ISCHR") == 0) seen_S_ISCHR++;
241 else if (strcmp (fname, "S_IFDIR") == 0) seen_S_IFDIR++;
242 else if (strcmp (fname, "S_ISDIR") == 0) seen_S_ISDIR++;
243 else if (strcmp (fname, "S_IFIFO") == 0) seen_S_IFIFO++;
244 else if (strcmp (fname, "S_ISFIFO") == 0) seen_S_ISFIFO++;
245 else if (strcmp (fname, "S_IFLNK") == 0) seen_S_IFLNK++;
246 else if (strcmp (fname, "S_ISLNK") == 0) seen_S_ISLNK++;
247 else if (strcmp (fname, "S_IFREG") == 0) seen_S_IFREG++;
248 else if (strcmp (fname, "S_ISREG") == 0) seen_S_ISREG++;
253 void
254 recognized_extern (name, type)
255 char *name;
256 char *type;
258 switch (special_file_handling)
260 case errno_special:
261 if (strcmp (name, "errno") == 0) missing_errno = 0;
262 break;
266 /* Called by scan_decls if it saw a function definition for a function
267 named FNAME, with return type RTYPE, and argument list ARGS,
268 in source file FILE_SEEN on line LINE_SEEN.
269 KIND is 'I' for an inline function;
270 'F' if a normal function declaration preceded by 'extern "C"'
271 (or nested inside 'extern "C"' braces); or
272 'f' for other function declarations. */
274 void
275 recognized_function (fname, kind, rtype, args, file_seen, line_seen)
276 char *fname;
277 int kind; /* One of 'f' 'F' or 'I' */
278 char *rtype;
279 char *args;
280 char *file_seen;
281 int line_seen;
283 struct partial_proto *partial;
284 int i;
285 struct fn_decl *fn;
286 #if 0
287 if (kind == 'f')
288 missing_extern_C_count++;
289 #endif
291 fn = lookup_std_proto (fname);
293 /* Remove the function from the list of required function. */
294 if (fn && REQUIRED (fn))
296 CLEAR_REQUIRED (fn);
297 required_unseen_count--;
300 /* If we have a full prototype, we're done. */
301 if (args[0] != '\0')
302 return;
304 if (kind == 'I') /* don't edit inline function */
305 return;
307 /* If the partial prototype was included from some other file,
308 we don't need to patch it up (in this run). */
309 i = strlen (file_seen);
310 if (i < inc_filename_length
311 || strcmp (inc_filename, file_seen + (i - inc_filename_length)) != 0)
312 return;
314 if (fn == NULL)
315 return;
316 if (fn->params[0] == '\0' || strcmp (fn->params, "void") == 0)
317 return;
319 /* We only have a partial function declaration,
320 so remember that we have to add a complete prototype. */
321 partial_count++;
322 partial = (struct partial_proto*)
323 obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
324 partial->fname = obstack_alloc (&scan_file_obstack, strlen (fname) + 1);
325 strcpy (partial->fname, fname);
326 partial->rtype = obstack_alloc (&scan_file_obstack, strlen (rtype) + 1);
327 strcpy (partial->rtype, rtype);
328 partial->line_seen = line_seen;
329 partial->fn = fn;
330 fn->partial = partial;
331 partial->next = partial_proto_list;
332 partial_proto_list = partial;
333 if (verbose)
335 fprintf (stderr, "(%s: %s non-prototype function declaration.)\n",
336 inc_filename, fname);
340 void
341 read_scan_file (scan_file)
342 FILE *scan_file;
344 obstack_init (&scan_file_obstack);
346 scan_decls (scan_file);
348 if (required_unseen_count + partial_count + missing_errno
349 #if 0
350 + missing_extern_C_count
351 #endif
352 == 0)
354 if (verbose)
355 fprintf (stderr, "%s: OK, nothing needs to be done.\n", inc_filename);
356 exit (0);
358 if (!verbose)
359 fprintf (stderr, "%s: fixing %s\n", progname, inc_filename);
360 else
362 if (required_unseen_count)
363 fprintf (stderr, "%s: %d missing function declarations.\n",
364 inc_filename, required_unseen_count);
365 if (partial_count)
366 fprintf (stderr, "%s: %d non-prototype function declarations.\n",
367 inc_filename, partial_count);
368 #if 0
369 if (missing_extern_C_count)
370 fprintf (stderr,
371 "%s: %d declarations not protected by extern \"C\".\n",
372 inc_filename, missing_extern_C_count);
373 #endif
377 void
378 write_rbrac ()
380 struct fn_decl *fn;
381 char **rptr;
383 if (required_unseen_count)
385 fprintf (outf,
386 "#if defined(__cplusplus) || defined(__USE_FIXED_PROTOTYPES__)\n");
387 #ifdef NO_IMPLICIT_EXTERN_C
388 fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
389 #endif
392 /* Now we print out prototypes for those functions that we haven't seen. */
393 for (rptr = required_functions; *rptr; rptr++)
395 int macro_protect = 0;
397 fn = lookup_std_proto (*rptr);
398 if (fn == NULL || !REQUIRED (fn))
399 continue;
401 /* In the case of memmove, protect in case the application
402 defines it as a macro before including the header. */
403 if (!strcmp (fn->fname, "memmove")
404 || !strcmp (fn->fname, "vprintf")
405 || !strcmp (fn->fname, "vfprintf")
406 || !strcmp (fn->fname, "vsprintf")
407 || !strcmp (fn->fname, "rewinddir"))
408 macro_protect = 1;
410 if (macro_protect)
411 fprintf (outf, "#ifndef %s\n", fn->fname);
412 fprintf (outf, "extern %s %s (%s);\n",
413 fn->rtype, fn->fname, fn->params);
414 if (macro_protect)
415 fprintf (outf, "#endif\n");
417 if (required_unseen_count)
419 #ifdef NO_IMPLICIT_EXTERN_C
420 fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");
421 #endif
422 fprintf (outf,
423 "#endif /* defined(__cplusplus) || defined(__USE_FIXED_PROTOTYPES__*/\n");
426 switch (special_file_handling)
428 case errno_special:
429 if (missing_errno)
430 fprintf (outf, "extern int errno;\n");
431 break;
432 case sys_stat_special:
433 if (!seen_S_ISBLK && seen_S_IFBLK)
434 fprintf (outf,
435 "#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n");
436 if (!seen_S_ISCHR && seen_S_IFCHR)
437 fprintf (outf,
438 "#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)\n");
439 if (!seen_S_ISDIR && seen_S_IFDIR)
440 fprintf (outf,
441 "#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)\n");
442 if (!seen_S_ISFIFO && seen_S_IFIFO)
443 fprintf (outf,
444 "#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)\n");
445 if (!seen_S_ISLNK && seen_S_IFLNK)
446 fprintf (outf,
447 "#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)\n");
448 if (!seen_S_ISREG && seen_S_IFREG)
449 fprintf (outf,
450 "#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)\n");
451 break;
455 #if 0
456 if (missing_extern_C_count + required_unseen_count > 0)
457 fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");
458 #endif
461 char *
462 xstrdup (str)
463 char *str;
465 char *copy = (char *) xmalloc (strlen (str) + 1);
466 strcpy (copy, str);
467 return copy;
470 /* Returns 1 iff the file is properly protected from multiple inclusion:
471 #ifndef PROTECT_NAME
472 #define PROTECT_NAME
473 #endif
477 #define INF_GET() (inf_ptr < inf_limit ? *(unsigned char*)inf_ptr++ : EOF)
478 #define INF_UNGET(c) ((c)!=EOF && inf_ptr--)
481 inf_skip_spaces (c)
482 int c;
484 for (;;)
486 if (c == ' ' || c == '\t')
487 c = INF_GET ();
488 else if (c == '/')
490 c = INF_GET ();
491 if (c != '*')
493 INF_UNGET (c);
494 return '/';
496 c = INF_GET ();
497 for (;;)
499 if (c == EOF)
500 return EOF;
501 else if (c != '*')
503 if (c == '\n')
504 source_lineno++, lineno++;
505 c = INF_GET ();
507 else if ((c = INF_GET ()) == '/')
508 return INF_GET ();
511 else
512 break;
514 return c;
517 /* Read into STR from inf_buffer upto DELIM. */
520 inf_read_upto (str, delim)
521 sstring *str;
522 int delim;
524 int ch;
525 for (;;)
527 ch = INF_GET ();
528 if (ch == EOF || ch == delim)
529 break;
530 SSTRING_PUT (str, ch);
532 MAKE_SSTRING_SPACE (str, 1);
533 *str->ptr = 0;
534 return ch;
538 inf_scan_ident (s, c)
539 register sstring *s;
540 int c;
542 s->ptr = s->base;
543 if (isalpha (c) || c == '_')
545 for (;;)
547 SSTRING_PUT (s, c);
548 c = INF_GET ();
549 if (c == EOF || !(isalnum (c) || c == '_'))
550 break;
553 MAKE_SSTRING_SPACE (s, 1);
554 *s->ptr = 0;
555 return c;
558 /* Returns 1 if the file is correctly protected against multiple
559 inclusion, setting *ifndef_line to the line number of the initial #ifndef
560 and setting *endif_line to the final #endif.
561 Otherwise return 0. */
564 check_protection (ifndef_line, endif_line)
565 int *ifndef_line, *endif_line;
567 int c;
568 int if_nesting = 1; /* Level of nesting of #if's */
569 char *protect_name = NULL; /* Identifier following initial #ifndef */
570 int define_seen = 0;
572 /* Skip initial white space (including comments). */
573 for (;; lineno++)
575 c = inf_skip_spaces (' ');
576 if (c == EOF)
577 return 0;
578 if (c != '\n')
579 break;
581 if (c != '#')
582 return 0;
583 c = inf_scan_ident (&buf, inf_skip_spaces (' '));
584 if (SSTRING_LENGTH (&buf) == 0 || strcmp (buf.base, "ifndef") != 0)
585 return 0;
587 /* So far so good: We've seen an initial #ifndef. */
588 *ifndef_line = lineno;
589 c = inf_scan_ident (&buf, inf_skip_spaces (c));
590 if (SSTRING_LENGTH (&buf) == 0 || c == EOF)
591 return 0;
592 protect_name = xstrdup (buf.base);
594 INF_UNGET (c);
595 c = inf_read_upto (&buf, '\n');
596 if (c == EOF)
597 return 0;
598 lineno++;
600 for (;;)
602 c = inf_skip_spaces (' ');
603 if (c == EOF)
604 return 0;
605 if (c == '\n')
607 lineno++;
608 continue;
610 if (c != '#')
611 goto skip_to_eol;
612 c = inf_scan_ident (&buf, inf_skip_spaces (' '));
613 if (SSTRING_LENGTH (&buf) == 0)
615 else if (!strcmp (buf.base, "ifndef")
616 || !strcmp (buf.base, "ifdef") || !strcmp (buf.base, "if"))
618 if_nesting++;
620 else if (!strcmp (buf.base, "endif"))
622 if_nesting--;
623 if (if_nesting == 0)
624 break;
626 else if (!strcmp (buf.base, "else"))
628 if (if_nesting == 1)
629 return 0;
631 else if (!strcmp (buf.base, "define"))
633 if (if_nesting != 1)
634 goto skip_to_eol;
635 c = inf_skip_spaces (c);
636 c = inf_scan_ident (&buf, c);
637 if (buf.base[0] > 0 && strcmp (buf.base, protect_name) == 0)
638 define_seen = 1;
640 skip_to_eol:
641 for (;;)
643 if (c == '\n' || c == EOF)
644 break;
645 c = INF_GET ();
647 if (c == EOF)
648 return 0;
649 lineno++;
652 if (!define_seen)
653 return 0;
654 *endif_line = lineno;
655 /* Skip final white space (including comments). */
656 for (;;)
658 c = inf_skip_spaces (' ');
659 if (c == EOF)
660 break;
661 if (c != '\n')
662 return 0;
665 return 1;
669 main (argc, argv)
670 int argc;
671 char **argv;
673 int inf_fd;
674 struct stat sbuf;
675 int c;
676 int i, done;
677 char *cptr, *cptr0, **pptr;
678 int ifndef_line;
679 int endif_line;
680 long to_read;
681 long int inf_size;
683 if (argv[0] && argv[0][0])
685 register char *p;
687 progname = 0;
688 for (p = argv[0]; *p; p++)
689 if (*p == '/')
690 progname = p;
691 progname = progname ? progname+1 : argv[0];
694 if (argc < 4)
696 fprintf (stderr, "%s: Usage: foo.h infile.h outfile.h req_funcs <scan-file-name\n",
697 progname);
698 exit (-1);
701 inc_filename = argv[1];
702 inc_filename_length = strlen (inc_filename);
703 if (strcmp (inc_filename, "sys/stat.h") == 0)
704 special_file_handling = sys_stat_special;
705 else if (strcmp (inc_filename, "errno.h") == 0)
706 special_file_handling = errno_special, missing_errno = 1;
708 /* Calculate an upper bound of the number of function names in argv[4] */
709 for (i = 1, cptr = argv[4]; *cptr; cptr++)
710 if (*cptr == ' ') i++;
711 /* Find the list of prototypes required for this include file. */
712 required_functions = (char**)xmalloc ((i+1) * sizeof (char*));
713 for (cptr = argv[4], cptr0 = cptr, pptr = required_functions, done = 0;
714 !done; cptr++)
716 done = *cptr == '\0';
717 if (*cptr == ' ' || done)
719 *cptr = '\0';
720 if (cptr > cptr0)
722 struct fn_decl *fn = lookup_std_proto (cptr0);
723 *pptr++ = cptr0;
724 if (fn == NULL)
725 fprintf (stderr, "Internal error: No prototype for %s\n",
726 cptr0);
727 else
728 SET_REQUIRED (fn);
730 cptr0 = cptr + 1;
733 required_unseen_count = pptr - required_functions;
734 *pptr = 0;
736 read_scan_file (stdin);
738 inf_fd = open (argv[2], O_RDONLY, 0666);
739 if (inf_fd < 0)
741 fprintf (stderr, "%s: Cannot open '%s' for reading -",
742 progname, argv[2]);
743 perror (NULL);
744 exit (-1);
746 if (fstat (inf_fd, &sbuf) < 0)
748 fprintf (stderr, "%s: Cannot get size of '%s' -", progname, argv[2]);
749 perror (NULL);
750 exit (-1);
752 inf_size = sbuf.st_size;
753 inf_buffer = (char*) xmalloc (inf_size + 2);
754 inf_buffer[inf_size] = '\n';
755 inf_buffer[inf_size + 1] = '\0';
756 inf_limit = inf_buffer + inf_size;
757 inf_ptr = inf_buffer;
759 to_read = inf_size;
760 while (to_read > 0)
762 long i = read (inf_fd, inf_buffer + inf_size - to_read, to_read);
763 if (i < 0)
765 fprintf (stderr, "%s: Failed to read '%s' -", progname, argv[2]);
766 perror (NULL);
767 exit (-1);
769 if (i == 0)
771 inf_size -= to_read;
772 break;
774 to_read -= i;
777 close (inf_fd);
779 /* If file doesn't end with '\n', add one. */
780 if (inf_limit > inf_buffer && inf_limit[-1] != '\n')
781 inf_limit++;
783 unlink (argv[3]);
784 outf = fopen (argv[3], "w");
785 if (outf == NULL)
787 fprintf (stderr, "%s: Cannot open '%s' for writing -",
788 progname, argv[3]);
789 perror (NULL);
790 exit (-1);
793 lineno = 1;
795 if (check_protection (&ifndef_line, &endif_line))
797 #if 0
798 fprintf (stderr, "#ifndef %s on line %d; #endif on line %d\n",
799 protect_name, ifndef_line, endif_line);
800 #endif
801 lbrac_line = ifndef_line+1;
802 rbrac_line = endif_line;
804 else
806 lbrac_line = 1;
807 rbrac_line = -1;
810 /* Reset input file. */
811 inf_ptr = inf_buffer;
812 lineno = 1;
814 for (;;)
816 if (lineno == lbrac_line)
817 write_lbrac ();
818 if (lineno == rbrac_line)
819 write_rbrac ();
820 for (;;)
822 struct fn_decl *fn;
823 c = INF_GET ();
824 if (c == EOF)
825 break;
826 if (isalpha (c) || c == '_')
828 c = inf_scan_ident (&buf, c);
829 INF_UNGET (c);
830 fputs (buf.base, outf);
831 fn = lookup_std_proto (buf.base);
832 /* We only want to edit the declaration matching the one
833 seen by scan-decls, as there can be multiple
834 declarations, selected by #ifdef __STDC__ or whatever. */
835 if (fn && fn->partial && fn->partial->line_seen == lineno)
837 c = inf_skip_spaces (' ');
838 if (c == EOF)
839 break;
840 if (c == '(')
842 c = inf_skip_spaces (' ');
843 if (c == ')')
845 fprintf (outf, " _PARAMS((%s))", fn->params);
847 else
849 putc ('(', outf);
850 INF_UNGET (c);
853 else
854 fprintf (outf, " %c", c);
857 else
859 putc (c, outf);
860 if (c == '\n')
861 break;
864 if (c == EOF)
865 break;
866 lineno++;
868 if (rbrac_line < 0)
869 write_rbrac ();
871 fclose (outf);
873 return 0;