]> gcc.gnu.org Git - gcc.git/blame - gcc/fix-header.c
(ASM_FINISH_DECLARE_OBJECT): Undef, then define.
[gcc.git] / gcc / fix-header.c
CommitLineData
7936052f
PB
1/* patch-header.c - Make C header file suitable for C++.
2 Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
17
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++:
20
21 * extern "C" { ... } braces are added (inside #ifndef __cplusplus),
05227b51 22 if they seem to be needed. These prevent C++ compilers from name
7936052f
PB
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 reqquired 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 patch-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).
71
72 Written by Per Bothner <bothner@cygnus.com>, July 1993. */
73
74#include <stdio.h>
75#include <ctype.h>
05227b51 76#include <sys/types.h>
49d3ca5c 77#include <sys/stat.h>
05227b51
PB
78#ifndef O_RDONLY
79#define O_RDONLY 0
80#endif
7936052f
PB
81#include "obstack.h"
82#include "scan.h"
83
7936052f
PB
84sstring buf;
85int verbose = 0;
86int partial_count = 0;
87int missing_extern_C_count = 0;
b156894e 88int missing_errno = 0;
7936052f
PB
89
90#include "xsys-protos.h"
91
05227b51
PB
92char *inf_buffer;
93char *inf_limit;
94char *inf_ptr;
05227b51 95
7936052f
PB
96/* Certain standard files get extra treatment */
97
98enum special_file
99{
100 no_special,
101 errno_special,
102 sys_stat_special
103};
104
105enum special_file special_file_handling = no_special;
106
107/* The following are only used when handling sys/stat.h */
108/* They are set if the corresponding macro has been seen. */
109int seen_S_IFBLK = 0, seen_S_ISBLK = 0;
110int seen_S_IFCHR = 0, seen_S_ISCHR = 0;
111int seen_S_IFDIR = 0, seen_S_ISDIR = 0;
112int seen_S_IFIFO = 0, seen_S_ISFIFO = 0;
113int seen_S_IFLNK = 0, seen_S_ISLNK = 0;
114int seen_S_IFREG = 0, seen_S_ISREG = 0;
115
7936052f
PB
116/* Wrapper around free, to avoid prototype clashes. */
117
118void xfree (ptr)
119 char *ptr;
120{
c2b6b9a1 121 free (ptr);
7936052f
PB
122}
123
124#define obstack_chunk_alloc xmalloc
125#define obstack_chunk_free xfree
126struct obstack scan_file_obstack;
127
128/* NOTE: If you edit this, also edit gen-protos.c !! */
129struct fn_decl *
130lookup_std_proto (name)
131 char *name;
132{
c2b6b9a1 133 int i = hash (name) % HASH_SIZE;
7936052f
PB
134 int i0 = i;
135 for (;;)
136 {
137 struct fn_decl *fn;
138 if (hash_tab[i] == 0)
139 return NULL;
140 fn = &std_protos[hash_tab[i]];
141 if (strcmp (fn->fname, name) == 0)
142 return fn;
143 i = (i+1) % HASH_SIZE;
144 if (i == i0)
c2b6b9a1 145 abort ();
7936052f
PB
146 }
147}
148
149char *inc_filename;
150int inc_filename_length;
151char *progname = "patch-header";
152FILE *outf;
153sstring buf;
154sstring line;
155
156int lbrac_line, rbrac_line;
157
158char **required_functions;
159int required_unseen_count;
160
161int
162write_lbrac ()
163{
b156894e
RS
164
165 if (missing_extern_C_count + required_unseen_count > 0)
166 fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
7936052f
PB
167
168 if (partial_count)
169 {
170 fprintf (outf, "#ifndef _PARAMS\n");
171 fprintf (outf, "#if defined(__STDC__) || defined(__cplusplus)\n");
172 fprintf (outf, "#define _PARAMS(ARGS) ARGS\n");
173 fprintf (outf, "#else\n");
174 fprintf (outf, "#define _PARAMS(ARGS) ()\n");
175 fprintf (outf, "#endif\n#endif /* _PARAMS */\n");
176 }
177}
178
179struct partial_proto
180{
181 struct partial_proto *next;
182 char *fname; /* name of function */
183 char *rtype; /* return type */
184 struct fn_decl *fn;
185 int line_seen;
186};
187
188struct partial_proto *partial_proto_list = NULL;
189
190struct partial_proto required_dummy_proto;
191#define REQUIRED(FN) ((FN)->partial == &required_dummy_proto)
192#define SET_REQUIRED(FN) ((FN)->partial = &required_dummy_proto)
193#define CLEAR_REQUIRED(FN) ((FN)->partial = 0)
194
195void
05227b51
PB
196recognized_macro (fname)
197 char *fname;
7936052f 198{
05227b51
PB
199 /* The original include file defines fname as a macro. */
200 struct fn_decl *fn = lookup_std_proto (fname);
7936052f 201
05227b51
PB
202 /* Since fname is a macro, don't require a prototype for it. */
203 if (fn && REQUIRED (fn))
7936052f 204 {
c2b6b9a1 205 CLEAR_REQUIRED (fn);
05227b51
PB
206 required_unseen_count--;
207 }
7936052f 208
05227b51
PB
209 switch (special_file_handling)
210 {
211 case errno_special:
b156894e 212 if (strcmp (fname, "errno") == 0) missing_errno = 0;
05227b51
PB
213 break;
214 case sys_stat_special:
215 if (fname[0] == 'S' && fname[1] == '_')
7936052f 216 {
05227b51
PB
217 if (strcmp (fname, "S_IFBLK") == 0) seen_S_IFBLK++;
218 else if (strcmp (fname, "S_ISBLK") == 0) seen_S_ISBLK++;
219 else if (strcmp (fname, "S_IFCHR") == 0) seen_S_IFCHR++;
220 else if (strcmp (fname, "S_ISCHR") == 0) seen_S_ISCHR++;
221 else if (strcmp (fname, "S_IFDIR") == 0) seen_S_IFDIR++;
222 else if (strcmp (fname, "S_ISDIR") == 0) seen_S_ISDIR++;
223 else if (strcmp (fname, "S_IFIFO") == 0) seen_S_IFIFO++;
224 else if (strcmp (fname, "S_ISFIFO") == 0) seen_S_ISFIFO++;
225 else if (strcmp (fname, "S_IFLNK") == 0) seen_S_IFLNK++;
226 else if (strcmp (fname, "S_ISLNK") == 0) seen_S_ISLNK++;
227 else if (strcmp (fname, "S_IFREG") == 0) seen_S_IFREG++;
228 else if (strcmp (fname, "S_ISREG") == 0) seen_S_ISREG++;
7936052f 229 }
05227b51
PB
230 }
231}
7936052f 232
05227b51
PB
233void
234recognized_extern (name, type)
235 char *name;
236 char *type;
237{
238 switch (special_file_handling)
239 {
240 case errno_special:
b156894e 241 if (strcmp (name, "errno") == 0) missing_errno = 0;
05227b51
PB
242 break;
243 }
244}
7936052f 245
05227b51
PB
246/* Called by scan_decls if it saw a function definition for a function
247 named FNAME, with return type RTYPE, and argument list ARGS,
248 in source file FILE_SEEN on line LINE_SEEN.
249 KIND is 'I' for an inline function;
250 'F' if a normal function declaration preceded by 'extern "C"'
251 (or nested inside 'extern "C"' braces); or
252 'f' for other function declarations. */
7936052f 253
05227b51
PB
254void
255recognized_function (fname, kind, rtype, args, file_seen, line_seen)
256 char *fname;
257 int kind; /* One of 'f' 'F' or 'I' */
258 char *rtype;
259 char *args;
260 char *file_seen;
261 int line_seen;
262{
263 struct partial_proto *partial;
264 int i;
265 struct fn_decl *fn;
266 if (kind == 'f')
267 missing_extern_C_count++;
7936052f 268
05227b51 269 fn = lookup_std_proto (fname);
7936052f 270
05227b51
PB
271 /* Remove the function from the list of required function. */
272 if (fn && REQUIRED (fn))
273 {
c2b6b9a1 274 CLEAR_REQUIRED (fn);
05227b51
PB
275 required_unseen_count--;
276 }
e9cd0b25 277
05227b51
PB
278 /* If we have a full prototype, we're done. */
279 if (args[0] != '\0')
280 return;
281
282 if (kind == 'I') /* don't edit inline function */
283 return;
284
285 /* If the partial prototype was included from some other file,
286 we don't need to patch it up (in this run). */
287 i = strlen (file_seen);
288 if (i < inc_filename_length
289 || strcmp (inc_filename, file_seen + (i - inc_filename_length)) != 0)
290 return;
291
292 if (fn == NULL)
293 return;
c2b6b9a1 294 if (fn->params[0] == '\0' || strcmp (fn->params, "void") == 0)
05227b51
PB
295 return;
296
297 /* We only have a partial function declaration,
298 so remember that we have to add a complete prototype. */
299 partial_count++;
300 partial = (struct partial_proto*)
c2b6b9a1
RS
301 obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
302 partial->fname = obstack_alloc (&scan_file_obstack, strlen (fname) + 1);
05227b51 303 strcpy (partial->fname, fname);
c2b6b9a1 304 partial->rtype = obstack_alloc (&scan_file_obstack, strlen (rtype) + 1);
05227b51
PB
305 strcpy (partial->rtype, rtype);
306 partial->line_seen = line_seen;
307 partial->fn = fn;
308 fn->partial = partial;
309 partial->next = partial_proto_list;
310 partial_proto_list = partial;
311 if (verbose)
312 {
313 fprintf (stderr, "(%s: %s non-prototype function declaration.)\n",
314 inc_filename, fname);
315 }
316}
7936052f 317
05227b51
PB
318void
319read_scan_file (scan_file)
320 FILE *scan_file;
321{
322 char **rptr;
c2b6b9a1 323 obstack_init (&scan_file_obstack);
7936052f 324
05227b51 325 scan_decls (scan_file);
7936052f
PB
326
327 if (missing_extern_C_count + required_unseen_count + partial_count
b156894e 328 + missing_errno == 0)
7936052f
PB
329 {
330 if (verbose)
331 fprintf (stderr, "%s: OK, nothing needs to be done.\n", inc_filename);
332 exit (0);
333 }
e9cd0b25
PB
334 if (!verbose)
335 fprintf (stderr, "%s: fixing %s\n", progname, inc_filename);
336 else
337 {
338 if (required_unseen_count)
339 fprintf (stderr, "%s: %d missing function declarations.\n",
340 inc_filename, required_unseen_count);
341 if (partial_count)
342 fprintf (stderr, "%s: %d non-prototype function declarations.\n",
343 inc_filename, partial_count);
344 if (missing_extern_C_count)
345 fprintf (stderr,
346 "%s: %d declarations not protected by extern \"C\".\n",
347 inc_filename, missing_extern_C_count);
348 }
7936052f
PB
349}
350
351write_rbrac ()
352{
353 struct fn_decl *fn;
354 char **rptr;
355 register struct partial_proto *partial;
356
357 if (required_unseen_count)
358 fprintf (outf, "#if defined(__STDC__) || defined(__cplusplus)\n");
359
360 /* Now we print out prototypes for those functions that we haven't seen. */
361 for (rptr = required_functions; *rptr; rptr++)
362 {
363 fn = lookup_std_proto (*rptr);
364 if (fn == NULL || !REQUIRED (fn))
365 continue;
366 fprintf (outf, "extern %s %s (%s);\n",
367 fn->rtype, fn->fname, fn->params);
368 }
369 if (required_unseen_count)
370 fprintf (outf,
371 "#endif /* defined(__STDC__) || defined(__cplusplus) */\n");
372
373 switch (special_file_handling)
374 {
375 case errno_special:
b156894e 376 if (missing_errno)
7936052f
PB
377 fprintf (outf, "extern int errno;\n");
378 break;
379 case sys_stat_special:
380 if (!seen_S_ISBLK && seen_S_IFBLK)
381 fprintf (outf,
382 "#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n");
383 if (!seen_S_ISCHR && seen_S_IFCHR)
384 fprintf (outf,
385 "#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)\n");
386 if (!seen_S_ISDIR && seen_S_IFDIR)
387 fprintf (outf,
388 "#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)\n");
389 if (!seen_S_ISFIFO && seen_S_IFIFO)
390 fprintf (outf,
391 "#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)\n");
392 if (!seen_S_ISLNK && seen_S_IFLNK)
393 fprintf (outf,
394 "#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)\n");
395 if (!seen_S_ISREG && seen_S_IFREG)
396 fprintf (outf,
397 "#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)\n");
398 break;
399 }
400
401
b156894e
RS
402 if (missing_extern_C_count + required_unseen_count > 0)
403 fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");
7936052f
PB
404}
405
406char *
407strdup (str)
408 char *str;
409{
c2b6b9a1
RS
410 char *copy = (char *) xmalloc (strlen (str) + 1);
411 strcpy (copy, str);
412 return copy;
7936052f
PB
413}
414
415/* Returns 1 iff the file is properly protected from multiple inclusion:
416 #ifndef PROTECT_NAME
417 #define PROTECT_NAME
418 #endif
419
420 */
421
05227b51 422#define INF_GET() (inf_ptr < inf_limit ? *(unsigned char*)inf_ptr++ : EOF)
c2b6b9a1 423#define INF_UNGET(c) ((c)!=EOF && inf_ptr--)
05227b51
PB
424
425int
426inf_skip_spaces (c)
427 int c;
428{
429 for (;;)
430 {
431 if (c == ' ' || c == '\t')
c2b6b9a1 432 c = INF_GET ();
05227b51
PB
433 else if (c == '/')
434 {
c2b6b9a1 435 c = INF_GET ();
05227b51
PB
436 if (c != '*')
437 {
c2b6b9a1 438 INF_UNGET (c);
05227b51
PB
439 return '/';
440 }
c2b6b9a1 441 c = INF_GET ();
05227b51
PB
442 for (;;)
443 {
444 if (c == EOF)
445 return EOF;
446 else if (c != '*')
447 {
448 if (c == '\n')
449 source_lineno++, lineno++;
450 c = INF_GET ();
451 }
c2b6b9a1
RS
452 else if ((c = INF_GET ()) == '/')
453 return INF_GET ();
05227b51
PB
454 }
455 }
456 else
457 break;
458 }
459 return c;
460}
461
462/* Read into STR from inf_buffer upto DELIM. */
463
464int
465inf_read_upto (str, delim)
466 sstring *str;
467 int delim;
468{
469 int ch;
470 for (;;)
471 {
472 ch = INF_GET ();
473 if (ch == EOF || ch == delim)
474 break;
c2b6b9a1 475 SSTRING_PUT (str, ch);
05227b51 476 }
c2b6b9a1 477 MAKE_SSTRING_SPACE (str, 1);
05227b51
PB
478 *str->ptr = 0;
479 return ch;
480}
481
7936052f 482int
05227b51
PB
483inf_scan_ident (s, c)
484 register sstring *s;
485 int c;
486{
487 s->ptr = s->base;
c2b6b9a1 488 if (isalpha (c) || c == '_')
05227b51
PB
489 {
490 for (;;)
491 {
c2b6b9a1 492 SSTRING_PUT (s, c);
05227b51 493 c = INF_GET ();
c2b6b9a1 494 if (c == EOF || !(isalnum (c) || c == '_'))
05227b51
PB
495 break;
496 }
497 }
c2b6b9a1 498 MAKE_SSTRING_SPACE (s, 1);
05227b51
PB
499 *s->ptr = 0;
500 return c;
501}
502
503/* Returns 1 if the file is correctly protected against multiple
504 inclusion, setting *ifndef_line to the line number of the initial #ifndef
505 and setting *endif_line to the final #endif.
506 Otherwise return 0. */
507
508int
509check_protection (ifndef_line, endif_line)
7936052f
PB
510 int *ifndef_line, *endif_line;
511{
512 int c;
513 int if_nesting = 1; /* Level of nesting of #if's */
514 char *protect_name = NULL; /* Identifier following initial #ifndef */
515 int define_seen = 0;
516
517 /* Skip initial white space (including comments). */
518 for (;; lineno++)
519 {
05227b51 520 c = inf_skip_spaces (' ');
7936052f
PB
521 if (c == EOF)
522 return 0;
523 if (c != '\n')
524 break;
525 }
526 if (c != '#')
527 return 0;
05227b51 528 c = inf_scan_ident (&buf, inf_skip_spaces (' '));
c2b6b9a1 529 if (SSTRING_LENGTH (&buf) == 0 || strcmp (buf.base, "ifndef") != 0)
7936052f
PB
530 return 0;
531
532 /* So far so good: We've seen an initial #ifndef. */
533 *ifndef_line = lineno;
05227b51 534 c = inf_scan_ident (&buf, inf_skip_spaces (c));
c2b6b9a1 535 if (SSTRING_LENGTH (&buf) == 0 || c == EOF)
7936052f
PB
536 return 0;
537 protect_name = strdup (buf.base);
538
c2b6b9a1 539 INF_UNGET (c);
05227b51 540 c = inf_read_upto (&buf, '\n');
7936052f
PB
541 if (c == EOF)
542 return 0;
543 lineno++;
544
545 for (;;)
546 {
c2b6b9a1 547 c = inf_skip_spaces (' ');
7936052f
PB
548 if (c == EOF)
549 return 0;
550 if (c == '\n')
551 {
552 lineno++;
553 continue;
554 }
555 if (c != '#')
556 goto skip_to_eol;
05227b51 557 c = inf_scan_ident (&buf, inf_skip_spaces (' '));
c2b6b9a1 558 if (SSTRING_LENGTH (&buf) == 0)
7936052f
PB
559 ;
560 else if (!strcmp (buf.base, "ifndef")
561 || !strcmp (buf.base, "ifdef") || !strcmp (buf.base, "if"))
562 {
563 if_nesting++;
564 }
565 else if (!strcmp (buf.base, "endif"))
566 {
567 if_nesting--;
568 if (if_nesting == 0)
569 break;
570 }
571 else if (!strcmp (buf.base, "else"))
572 {
573 if (if_nesting == 1)
574 return 0;
575 }
576 else if (!strcmp (buf.base, "define"))
577 {
578 if (if_nesting != 1)
579 goto skip_to_eol;
05227b51
PB
580 c = inf_skip_spaces (c);
581 c = inf_scan_ident (&buf, c);
c2b6b9a1 582 if (buf.base[0] > 0 && strcmp (buf.base, protect_name) == 0)
7936052f
PB
583 define_seen = 1;
584 }
585 skip_to_eol:
586 for (;;)
587 {
588 if (c == '\n' || c == EOF)
589 break;
c2b6b9a1 590 c = INF_GET ();
7936052f
PB
591 }
592 if (c == EOF)
593 return 0;
594 lineno++;
595 }
596
597 if (!define_seen)
598 return 0;
599 *endif_line = lineno;
600 /* Skip final white space (including comments). */
601 for (;;)
602 {
05227b51 603 c = inf_skip_spaces (' ');
7936052f
PB
604 if (c == EOF)
605 break;
606 if (c != '\n')
607 return 0;
608 }
609
610 return 1;
611}
612
613int
c2b6b9a1 614main (argc, argv)
7936052f
PB
615 int argc;
616 char **argv;
617{
05227b51
PB
618 int inf_fd;
619 struct stat sbuf;
7936052f
PB
620 int c;
621 int i, done;
622 char *cptr, *cptr0, **pptr;
623 int ifndef_line;
05227b51
PB
624 int endif_line;
625 long to_read;
c2b6b9a1 626 long int inf_size;
7936052f
PB
627
628 if (argv[0] && argv[0][0])
9bbd1091
RS
629 {
630 register char *p;
631
632 progname = 0;
633 for (p = argv[0]; *p; p++)
634 if (*p == '/')
635 progname = p;
636 progname = progname ? progname+1 : argv[0];
637 }
7936052f
PB
638
639 if (argc < 4)
640 {
641 fprintf (stderr, "%s: Usage: foo.h infile.h outfile.h req_funcs <scan-file-name\n",
642 progname);
643 exit (-1);
644 }
645
646 inc_filename = argv[1];
647 inc_filename_length = strlen (inc_filename);
648 if (strcmp (inc_filename, "sys/stat.h") == 0)
649 special_file_handling = sys_stat_special;
650 else if (strcmp (inc_filename, "errno.h") == 0)
b156894e 651 special_file_handling = errno_special, missing_errno = 1;
7936052f
PB
652
653 /* Calculate an upper bound of the number of function names in argv[4] */
654 for (i = 1, cptr = argv[4]; *cptr; cptr++)
655 if (*cptr == ' ') i++;
656 /* Find the list of prototypes required for this include file. */
c2b6b9a1 657 required_functions = (char**)xmalloc ((i+1) * sizeof (char*));
7936052f
PB
658 for (cptr = argv[4], cptr0 = cptr, pptr = required_functions, done = 0;
659 !done; cptr++)
660 {
661 done = *cptr == '\0';
662 if (*cptr == ' ' || done)
663 {
664 *cptr = '\0';
665 if (cptr > cptr0)
666 {
c2b6b9a1 667 struct fn_decl *fn = lookup_std_proto (cptr0);
7936052f
PB
668 *pptr++ = cptr0;
669 if (fn == NULL)
670 fprintf (stderr, "Internal error: No prototype for %s\n",
671 cptr0);
672 else
c2b6b9a1 673 SET_REQUIRED (fn);
7936052f
PB
674 }
675 cptr0 = cptr + 1;
676 }
677 }
678 required_unseen_count = pptr - required_functions;
679 *pptr = 0;
680
681 read_scan_file (stdin);
682
05227b51
PB
683 inf_fd = open (argv[2], O_RDONLY, 0666);
684 if (inf_fd < 0)
7936052f
PB
685 {
686 fprintf (stderr, "%s: Cannot open '%s' for reading -",
687 progname, argv[2]);
688 perror (NULL);
689 exit (-1);
690 }
05227b51
PB
691 if (fstat (inf_fd, &sbuf) < 0)
692 {
693 fprintf (stderr, "%s: Cannot get size of '%s' -", progname, argv[2]);
694 perror (NULL);
695 exit (-1);
696 }
697 inf_size = sbuf.st_size;
698 inf_buffer = (char*) xmalloc (inf_size + 2);
699 inf_buffer[inf_size] = '\n';
700 inf_buffer[inf_size + 1] = '\0';
701 inf_limit = inf_buffer + inf_size;
702 inf_ptr = inf_buffer;
703
704 to_read = inf_size;
705 while (to_read > 0)
706 {
707 long i = read (inf_fd, inf_buffer + inf_size - to_read, to_read);
708 if (i < 0)
709 {
710 fprintf (stderr, "%s: Failed to read '%s' -", progname, argv[2]);
711 perror (NULL);
712 exit (-1);
713 }
714 if (i == 0)
715 {
716 inf_size -= to_read;
717 break;
718 }
719 to_read -= i;
720 }
721
722 close (inf_fd);
7936052f 723
c2b6b9a1
RS
724 /* If file doesn't end with '\n', add one. */
725 if (inf_limit > inf_buffer && inf_limit[-1] != '\n')
726 inf_limit++;
727
9bbd1091 728 unlink (argv[3]);
7936052f
PB
729 outf = fopen (argv[3], "w");
730 if (outf == NULL)
731 {
732 fprintf (stderr, "%s: Cannot open '%s' for writing -",
733 progname, argv[3]);
734 perror (NULL);
735 exit (-1);
736 }
737
05227b51
PB
738 lineno = 1;
739
740 if (check_protection (&ifndef_line, &endif_line))
7936052f
PB
741 {
742#if 0
c2b6b9a1
RS
743 fprintf (stderr, "#ifndef %s on line %d; #endif on line %d\n",
744 protect_name, ifndef_line, endif_line);
7936052f
PB
745#endif
746 lbrac_line = ifndef_line+1;
747 rbrac_line = endif_line;
748 }
749 else
750 {
751 lbrac_line = 1;
752 rbrac_line = -1;
753 }
754
05227b51
PB
755 /* Reset input file. */
756 inf_ptr = inf_buffer;
7936052f
PB
757 lineno = 1;
758
759 for (;;)
760 {
761 if (lineno == lbrac_line)
762 write_lbrac ();
763 if (lineno == rbrac_line)
764 write_rbrac ();
765 for (;;)
766 {
767 struct fn_decl *fn;
c2b6b9a1 768 c = INF_GET ();
7936052f
PB
769 if (c == EOF)
770 break;
771 if (isalpha (c) || c == '_')
772 {
773 struct partial_proto *partial;
05227b51 774 c = inf_scan_ident (&buf, c);
c2b6b9a1 775 INF_UNGET (c);
7936052f
PB
776 fputs (buf.base, outf);
777 fn = lookup_std_proto (buf.base);
778 /* We only want to edit the declaration matching the one
779 seen by scan-decls, as there can be multiple
780 declarations, selected by #ifdef __STDC__ or whatever. */
781 if (fn && fn->partial && fn->partial->line_seen == lineno)
782 {
05227b51 783 c = inf_skip_spaces (' ');
7936052f
PB
784 if (c == EOF)
785 break;
786 if (c == '(')
787 {
05227b51 788 c = inf_skip_spaces (' ');
7936052f
PB
789 if (c == ')')
790 {
791 fprintf (outf, " _PARAMS((%s))", fn->params);
792 }
793 else
794 {
795 putc ('(', outf);
c2b6b9a1 796 INF_UNGET (c);
7936052f
PB
797 }
798 }
799 else
e9cd0b25 800 fprintf (outf, " %c", c);
7936052f
PB
801 }
802 }
803 else
05227b51
PB
804 {
805 putc (c, outf);
806 if (c == '\n')
807 break;
808 }
7936052f
PB
809 }
810 if (c == EOF)
811 break;
812 lineno++;
813 }
814 if (rbrac_line < 0)
815 write_rbrac ();
816
7936052f
PB
817 fclose (outf);
818
819 return 0;
820}
This page took 0.135977 seconds and 5 git commands to generate.