Initial revision
[official-gcc.git] / gcc / gen-protos.c
blob08b7ea85ddc5ecef4de8244234c0bd1a1492a262
1 /* gen-protos.c - massages a list of prototypes, for use by fixproto.
2 Copyright (C) 1993, 94-96, 1998 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 #include "hconfig.h"
19 #include "system.h"
20 #include "scan.h"
21 #include "cpplib.h"
22 #include "cpphash.h"
24 int verbose = 0;
25 char *progname;
27 #define HASH_SIZE 2503 /* a prime */
28 int hash_tab[HASH_SIZE];
29 int next_index;
31 static void
32 add_hash (fname)
33 char *fname;
35 int i, i0;
37 /* NOTE: If you edit this, also edit lookup_std_proto in fix-header.c !! */
38 i = hashf (fname, strlen (fname), HASH_SIZE);
39 i0 = i;
40 if (hash_tab[i] != 0)
42 for (;;)
44 i = (i+1) % HASH_SIZE;
45 if (i == i0)
46 abort ();
47 if (hash_tab[i] == 0)
48 break;
51 hash_tab[i] = next_index;
53 next_index++;
56 /* Given a function prototype, fill in the fields of FN.
57 The result is a boolean indicating if a function prototype was found.
59 The input string is modified (trailing NULs are inserted).
60 The fields of FN point to the input string. */
62 static int
63 parse_fn_proto (start, end, fn)
64 char *start, *end;
65 struct fn_decl *fn;
67 register char *ptr;
68 int param_nesting = 1;
69 char *param_start, *param_end, *decl_start, *name_start, *name_end;
71 ptr = end - 1;
72 while (*ptr == ' ' || *ptr == '\t') ptr--;
73 if (*ptr-- != ';')
75 fprintf (stderr, "Funny input line: %s\n", start);
76 return 0;
78 while (*ptr == ' ' || *ptr == '\t') ptr--;
79 if (*ptr != ')')
81 fprintf (stderr, "Funny input line: %s\n", start);
82 return 0;
84 param_end = ptr;
85 for (;;)
87 int c = *--ptr;
88 if (c == '(' && --param_nesting == 0)
89 break;
90 else if (c == ')')
91 param_nesting++;
93 param_start = ptr+1;
95 ptr--;
96 while (*ptr == ' ' || *ptr == '\t') ptr--;
98 if (!ISALNUM ((unsigned char)*ptr))
100 if (verbose)
101 fprintf (stderr, "%s: Can't handle this complex prototype: %s\n",
102 progname, start);
103 return 0;
105 name_end = ptr+1;
107 while (ISALNUM ((unsigned char)*ptr) || *ptr == '_') --ptr;
108 name_start = ptr+1;
109 while (*ptr == ' ' || *ptr == '\t') ptr--;
110 ptr[1] = 0;
111 *param_end = 0;
112 *name_end = 0;
114 decl_start = start;
115 if (strncmp (decl_start, "typedef ", 8) == 0)
116 return 0;
117 if (strncmp (decl_start, "extern ", 7) == 0)
118 decl_start += 7;
120 fn->fname = name_start;
121 fn->rtype = decl_start;
122 fn->params = param_start;
123 return 1;
127 main (argc, argv)
128 int argc ATTRIBUTE_UNUSED;
129 char **argv;
131 FILE *inf = stdin;
132 FILE *outf = stdout;
133 int i;
134 sstring linebuf;
135 struct fn_decl fn_decl;
137 i = strlen (argv[0]);
138 while (i > 0 && argv[0][i-1] != '/') --i;
139 progname = &argv[0][i];
141 INIT_SSTRING (&linebuf);
143 fprintf (outf, "struct fn_decl std_protos[] = {\n");
145 /* A hash table entry of 0 means "unused" so reserve it. */
146 fprintf (outf, " {\"\", \"\", \"\", 0},\n");
147 next_index = 1;
149 for (;;)
151 int c = skip_spaces (inf, ' ');
153 if (c == EOF)
154 break;
155 linebuf.ptr = linebuf.base;
156 ungetc (c, inf);
157 c = read_upto (inf, &linebuf, '\n');
158 if (linebuf.base[0] == '#') /* skip cpp command */
159 continue;
160 if (linebuf.base[0] == '\0') /* skip empty line */
161 continue;
163 if (! parse_fn_proto (linebuf.base, linebuf.ptr, &fn_decl))
164 continue;
166 add_hash (fn_decl.fname);
168 fprintf (outf, " {\"%s\", \"%s\", \"%s\", 0},\n",
169 fn_decl.fname, fn_decl.rtype, fn_decl.params);
171 if (c == EOF)
172 break;
174 fprintf (outf, " {0, 0, 0, 0}\n};\n");
177 fprintf (outf, "#define HASH_SIZE %d\n", HASH_SIZE);
178 fprintf (outf, "short hash_tab[HASH_SIZE] = {\n");
179 for (i = 0; i < HASH_SIZE; i++)
180 fprintf (outf, " %d,\n", hash_tab[i]);
181 fprintf (outf, "};\n");
183 return 0;
186 /* Avoid error if config defines abort as fancy_abort.
187 It's not worth "really" implementing this because ordinary
188 compiler users never run fix-header. */
190 void
191 fancy_abort ()
193 abort ();
196 void
197 fatal (s)
198 char *s;
200 fprintf (stderr, "%s: %s\n", "gen-protos", s);
201 exit (FATAL_EXIT_CODE);