Commit 3d348653 by Doug Evans

gen-protos.c (overrides): New static local.

	* gen-protos.c (overrides): New static local.
	(add_hash,parse_fn_proto): New static functions.
	(main): Add prototypes from SYS_PROTO_OVERRIDES to hash table before
	parsing sys-protos.h.  Reserve entry 0 in std_protos.
	* alpha/alpha.h (SYS_PROTO_OVERRIDES): Define.

From-SVN: r12598
parent d50014ae
...@@ -2253,3 +2253,7 @@ do { \ ...@@ -2253,3 +2253,7 @@ do { \
#define HAS_INIT_SECTION #define HAS_INIT_SECTION
#define LD_INIT_SWITCH "-init" #define LD_INIT_SWITCH "-init"
#define LD_FINI_SWITCH "-fini" #define LD_FINI_SWITCH "-fini"
/* Define gethostid in unistd.h as returning an int, not a long. */
#define SYS_PROTO_OVERRIDES \
"extern int gethostid (void);",
/* gen-protos.c - massages a list of prototypes, for use by fixproto. /* gen-protos.c - massages a list of prototypes, for use by fixproto.
Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the under the terms of the GNU General Public License as published by the
...@@ -22,9 +22,23 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ...@@ -22,9 +22,23 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpplib.h" #include "cpplib.h"
#include "cpphash.h" #include "cpphash.h"
int verbose = 0;
char *progname;
/* Table of prototypes that override sys-protos.h. */
static char *overrides[] =
{
#ifdef SYS_PROTO_OVERRIDES
SYS_PROTO_OVERRIDES
#endif
0
};
#define HASH_SIZE 2503 /* a prime */ #define HASH_SIZE 2503 /* a prime */
int hash_tab[HASH_SIZE];
int next_index;
int static int
hashf (name, len, hashsize) hashf (name, len, hashsize)
register U_CHAR *name; register U_CHAR *name;
register int len; register int len;
...@@ -38,67 +52,58 @@ hashf (name, len, hashsize) ...@@ -38,67 +52,58 @@ hashf (name, len, hashsize)
return MAKE_POS (r) % hashsize; return MAKE_POS (r) % hashsize;
} }
int hash_tab[HASH_SIZE]; static void
int verbose = 0; add_hash (fname)
char *progname; char *fname;
sstring linebuf;
/* Avoid error if config defines abort as fancy_abort.
It's not worth "really" implementing this because ordinary
compiler users never run fix-header. */
void
fancy_abort ()
{ {
int i, i0;
/* NOTE: If you edit this, also edit lookup_std_proto in fix-header.c !! */
i = hashf (fname, strlen (fname), HASH_SIZE);
i0 = i;
if (hash_tab[i] != 0)
{
for (;;)
{
i = (i+1) % HASH_SIZE;
if (i == i0)
abort (); abort ();
} if (hash_tab[i] == 0)
break;
}
}
hash_tab[i] = next_index;
int next_index++;
main (argc, argv) }
int argc;
char **argv;
{
FILE *inf = stdin;
FILE *outf = stdout;
int next_index = 0;
int i, i0;
i = strlen (argv[0]); /* Given a function prototype, fill in the fields of FN.
while (i > 0 && argv[0][i-1] != '/') --i; The result is a boolean indicating if a function prototype was found.
progname = &argv[0][i];
fprintf (outf, "struct fn_decl std_protos[] = {\n"); The input string is modified (trailing NULs are inserted).
The fields of FN point to the input string. */
for (;;) static int
{ parse_fn_proto (start, end, fn)
int c = skip_spaces (inf, ' '); char *start, *end;
int param_nesting = 1; struct fn_decl *fn;
char *param_start, *param_end, *decl_start, {
*name_start, *name_end;
register char *ptr; register char *ptr;
if (c == EOF) int param_nesting = 1;
break; char *param_start, *param_end, *decl_start, *name_start, *name_end;
linebuf.ptr = linebuf.base;
ungetc (c, inf);
c = read_upto (inf, &linebuf, '\n');
if (linebuf.base[0] == '#') /* skip cpp command */
continue;
if (linebuf.base[0] == '\0') /* skip empty line */
continue;
ptr = linebuf.ptr - 1; ptr = end - 1;
while (*ptr == ' ' || *ptr == '\t') ptr--; while (*ptr == ' ' || *ptr == '\t') ptr--;
if (*ptr-- != ';') if (*ptr-- != ';')
{ {
fprintf (stderr, "Funny input line: %s\n", linebuf.base); fprintf (stderr, "Funny input line: %s\n", start);
continue; return 0;
} }
while (*ptr == ' ' || *ptr == '\t') ptr--; while (*ptr == ' ' || *ptr == '\t') ptr--;
if (*ptr != ')') if (*ptr != ')')
{ {
fprintf (stderr, "Funny input line: %s\n", linebuf.base); fprintf (stderr, "Funny input line: %s\n", start);
continue; return 0;
} }
param_end = ptr; param_end = ptr;
for (;;) for (;;)
...@@ -118,8 +123,8 @@ main (argc, argv) ...@@ -118,8 +123,8 @@ main (argc, argv)
{ {
if (verbose) if (verbose)
fprintf (stderr, "%s: Can't handle this complex prototype: %s\n", fprintf (stderr, "%s: Can't handle this complex prototype: %s\n",
argv[0], linebuf.base); progname, start);
continue; return 0;
} }
name_end = ptr+1; name_end = ptr+1;
...@@ -127,43 +132,94 @@ main (argc, argv) ...@@ -127,43 +132,94 @@ main (argc, argv)
name_start = ptr+1; name_start = ptr+1;
while (*ptr == ' ' || *ptr == '\t') ptr--; while (*ptr == ' ' || *ptr == '\t') ptr--;
ptr[1] = 0; ptr[1] = 0;
*name_end = 0;
*param_end = 0; *param_end = 0;
*name_end = 0; *name_end = 0;
decl_start = linebuf.base; decl_start = start;
if (strncmp (decl_start, "typedef ", 8) == 0) if (strncmp (decl_start, "typedef ", 8) == 0)
continue; return 0;
if (strncmp (decl_start, "extern ", 7) == 0) if (strncmp (decl_start, "extern ", 7) == 0)
decl_start += 7; decl_start += 7;
fn->fname = name_start;
fn->rtype = decl_start;
fn->params = param_start;
return 1;
}
/* NOTE: If you edit this, int
also edit lookup_std_proto in fix-header.c !! */ main (argc, argv)
i = hashf (name_start, name_end - name_start, HASH_SIZE); int argc;
i0 = i; char **argv;
if (hash_tab[i] != 0) {
FILE *inf = stdin;
FILE *outf = stdout;
int i;
sstring linebuf;
char **optr;
struct fn_decl fn_decl;
i = strlen (argv[0]);
while (i > 0 && argv[0][i-1] != '/') --i;
progname = &argv[0][i];
INIT_SSTRING (&linebuf);
fprintf (outf, "struct fn_decl std_protos[] = {\n");
/* A hash table entry of 0 means "unused" so reserve it. */
fprintf (outf, " {\"\", \"\", \"\"},\n");
next_index = 1;
/* Output the overriding prototypes first so fix-header will use them
in preference to the default ones. */
/* ??? Two copies of the prototype are output. This doesn't cause any
problems, but one might wish to avoid outputting the second one. */
for (optr = overrides; *optr; ++optr)
{ {
/* Using sstring's here may be overkill but parse_fn_proto modifies
the input string. */
linebuf.ptr = linebuf.base;
make_sstring_space (&linebuf, strlen (*optr) + 1);
strcpy (linebuf.base, *optr);
linebuf.ptr = linebuf.base + strlen (*optr);
if (! parse_fn_proto (linebuf.base, linebuf.ptr, &fn_decl))
continue;
add_hash (fn_decl.fname);
fprintf (outf, " {\"%s\", \"%s\", \"%s\"},\n",
fn_decl.fname, fn_decl.rtype, fn_decl.params);
}
for (;;) for (;;)
{ {
i = (i+1) % HASH_SIZE; int c = skip_spaces (inf, ' ');
if (i == i0)
abort (); if (c == EOF)
if (hash_tab[i] == 0)
break; break;
} linebuf.ptr = linebuf.base;
} ungetc (c, inf);
hash_tab[i] = next_index; c = read_upto (inf, &linebuf, '\n');
if (linebuf.base[0] == '#') /* skip cpp command */
continue;
if (linebuf.base[0] == '\0') /* skip empty line */
continue;
if (! parse_fn_proto (linebuf.base, linebuf.ptr, &fn_decl))
continue;
fprintf (outf, " {\"%s\", \"%s\", \"%s\" },\n", add_hash (fn_decl.fname);
name_start, decl_start, param_start);
next_index++; fprintf (outf, " {\"%s\", \"%s\", \"%s\"},\n",
fn_decl.fname, fn_decl.rtype, fn_decl.params);
if (c == EOF) if (c == EOF)
break; break;
} }
fprintf (outf, "{0, 0, 0}\n};\n"); fprintf (outf, " {0, 0, 0}\n};\n");
fprintf (outf, "#define HASH_SIZE %d\n", HASH_SIZE); fprintf (outf, "#define HASH_SIZE %d\n", HASH_SIZE);
...@@ -175,6 +231,16 @@ main (argc, argv) ...@@ -175,6 +231,16 @@ main (argc, argv)
return 0; return 0;
} }
/* Avoid error if config defines abort as fancy_abort.
It's not worth "really" implementing this because ordinary
compiler users never run fix-header. */
void
fancy_abort ()
{
abort ();
}
void void
fatal (s) fatal (s)
char *s; char *s;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment