source: trunk/third/gcc/gen-protos.c @ 11288

Revision 11288, 4.8 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11287, which included commits to RCS files with non-trunk default branches.
Line 
1/* gen-protos.c - massages a list of prototypes, for use by fixproto.
2   Copyright (C) 1993, 1994, 1995, 1996 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18#include <stdio.h>
19#include <ctype.h>
20#include "hconfig.h"
21#include "scan.h"
22#include "cpplib.h"
23#include "cpphash.h"
24
25int verbose = 0;
26char *progname;
27
28#define HASH_SIZE 2503 /* a prime */
29int hash_tab[HASH_SIZE];
30int next_index;
31
32static int
33hashf (name, len, hashsize)
34     register U_CHAR *name;
35     register int len;
36     int hashsize;
37{
38  register int r = 0;
39
40  while (len--)
41    r = HASHSTEP (r, *name++);
42
43  return MAKE_POS (r) % hashsize;
44}
45
46static void
47add_hash (fname)
48     char *fname;
49{
50  int i, i0;
51
52  /* NOTE:  If you edit this, also edit lookup_std_proto in fix-header.c !! */
53  i = hashf (fname, strlen (fname), HASH_SIZE);
54  i0 = i;
55  if (hash_tab[i] != 0)
56    {
57      for (;;)
58        {
59          i = (i+1) % HASH_SIZE;
60          if (i == i0)
61            abort ();
62          if (hash_tab[i] == 0)
63            break;
64        }
65    }
66  hash_tab[i] = next_index;
67
68  next_index++;
69}
70
71/* Given a function prototype, fill in the fields of FN.
72   The result is a boolean indicating if a function prototype was found.
73
74   The input string is modified (trailing NULs are inserted).
75   The fields of FN point to the input string.  */
76
77static int
78parse_fn_proto (start, end, fn)
79     char *start, *end;
80     struct fn_decl *fn;
81{
82  register char *ptr;
83  int param_nesting = 1;
84  char *param_start, *param_end, *decl_start, *name_start, *name_end;
85
86  ptr = end - 1;
87  while (*ptr == ' ' || *ptr == '\t') ptr--;
88  if (*ptr-- != ';')
89    {
90      fprintf (stderr, "Funny input line: %s\n", start);
91      return 0;
92    }
93  while (*ptr == ' ' || *ptr == '\t') ptr--;
94  if (*ptr != ')')
95    {
96      fprintf (stderr, "Funny input line: %s\n", start);
97      return 0;
98    }
99  param_end = ptr;
100  for (;;)
101    {
102      int c = *--ptr;
103      if (c == '(' && --param_nesting == 0)
104        break;
105      else if (c == ')')
106        param_nesting++;
107    }
108  param_start = ptr+1;
109
110  ptr--;
111  while (*ptr == ' ' || *ptr == '\t') ptr--;
112
113  if (!isalnum (*ptr))
114    {
115      if (verbose)
116        fprintf (stderr, "%s: Can't handle this complex prototype: %s\n",
117                 progname, start);
118      return 0;
119    }
120  name_end = ptr+1;
121
122  while (isalnum (*ptr) || *ptr == '_') --ptr;
123  name_start = ptr+1;
124  while (*ptr == ' ' || *ptr == '\t') ptr--;
125  ptr[1] = 0;
126  *param_end = 0;
127  *name_end = 0;
128
129  decl_start = start;
130  if (strncmp (decl_start, "typedef ", 8) == 0)
131    return 0;
132  if (strncmp (decl_start, "extern ", 7) == 0)
133    decl_start += 7;
134
135  fn->fname = name_start;
136  fn->rtype = decl_start;
137  fn->params = param_start;
138  return 1;
139}
140
141int
142main (argc, argv)
143     int argc;
144     char **argv;
145{
146  FILE *inf = stdin;
147  FILE *outf = stdout;
148  int i;
149  sstring linebuf;
150  char **optr;
151  struct fn_decl fn_decl;
152
153  i = strlen (argv[0]);
154  while (i > 0 && argv[0][i-1] != '/') --i;
155  progname = &argv[0][i];
156
157  INIT_SSTRING (&linebuf);
158
159  fprintf (outf, "struct fn_decl std_protos[] = {\n");
160
161  /* A hash table entry of 0 means "unused" so reserve it.  */
162  fprintf (outf, "  {\"\", \"\", \"\"},\n");
163  next_index = 1;
164 
165  for (;;)
166    {
167      int c = skip_spaces (inf, ' ');
168
169      if (c == EOF)
170        break;
171      linebuf.ptr = linebuf.base;
172      ungetc (c, inf);
173      c = read_upto (inf, &linebuf, '\n');
174      if (linebuf.base[0] == '#') /* skip cpp command */
175        continue;
176      if (linebuf.base[0] == '\0') /* skip empty line */
177        continue;
178
179      if (! parse_fn_proto (linebuf.base, linebuf.ptr, &fn_decl))
180        continue;
181
182      add_hash (fn_decl.fname);
183
184      fprintf (outf, "  {\"%s\", \"%s\", \"%s\"},\n",
185               fn_decl.fname, fn_decl.rtype, fn_decl.params);
186
187      if (c == EOF)
188        break;
189    }
190  fprintf (outf, "  {0, 0, 0}\n};\n");
191
192
193  fprintf (outf, "#define HASH_SIZE %d\n", HASH_SIZE);
194  fprintf (outf, "short hash_tab[HASH_SIZE] = {\n");
195  for (i = 0; i < HASH_SIZE; i++)
196    fprintf (outf, "  %d,\n", hash_tab[i]);
197  fprintf (outf, "};\n");
198
199  return 0;
200}
201
202/* Avoid error if config defines abort as fancy_abort.
203   It's not worth "really" implementing this because ordinary
204   compiler users never run fix-header.  */
205
206void
207fancy_abort ()
208{
209  abort ();
210}
211
212void
213fatal (s)
214     char *s;
215{
216  fprintf (stderr, "%s: %s\n", "gen-protos", s);
217  exit (FATAL_EXIT_CODE);
218}
Note: See TracBrowser for help on using the repository browser.