Mercurial > hg > CbC > CbC_gcc
comparison gcc/gen-protos.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* gen-protos.c - massages a list of prototypes, for use by fixproto. | |
2 Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2003, 2004, 2005, 2007 | |
3 Free Software Foundation, Inc. | |
4 | |
5 This program is free software; you can redistribute it and/or modify it | |
6 under the terms of the GNU General Public License as published by the | |
7 Free Software Foundation; either version 3, or (at your option) any | |
8 later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program; see the file COPYING3. If not see | |
17 <http://www.gnu.org/licenses/>. */ | |
18 | |
19 #include "bconfig.h" | |
20 #include "system.h" | |
21 #include "coretypes.h" | |
22 #include "tm.h" | |
23 #include "scan.h" | |
24 #include "errors.h" | |
25 | |
26 int verbose = 0; | |
27 | |
28 static void add_hash (const char *); | |
29 static int parse_fn_proto (char *, char *, struct fn_decl *); | |
30 | |
31 #define HASH_SIZE 2503 /* a prime */ | |
32 int hash_tab[HASH_SIZE]; | |
33 int next_index; | |
34 int collisions; | |
35 | |
36 static void | |
37 add_hash (const char *fname) | |
38 { | |
39 int i, i0; | |
40 | |
41 /* NOTE: If you edit this, also edit lookup_std_proto in fix-header.c !! */ | |
42 i = hashstr (fname, strlen (fname)) % HASH_SIZE; | |
43 i0 = i; | |
44 if (hash_tab[i] != 0) | |
45 { | |
46 collisions++; | |
47 for (;;) | |
48 { | |
49 i = (i+1) % HASH_SIZE; | |
50 gcc_assert (i != i0); | |
51 if (hash_tab[i] == 0) | |
52 break; | |
53 } | |
54 } | |
55 hash_tab[i] = next_index; | |
56 | |
57 next_index++; | |
58 } | |
59 | |
60 /* Given a function prototype, fill in the fields of FN. | |
61 The result is a boolean indicating if a function prototype was found. | |
62 | |
63 The input string is modified (trailing NULs are inserted). | |
64 The fields of FN point to the input string. */ | |
65 | |
66 static int | |
67 parse_fn_proto (char *start, char *end, struct fn_decl *fn) | |
68 { | |
69 char *ptr; | |
70 int param_nesting = 1; | |
71 char *param_start, *param_end, *decl_start, *name_start, *name_end; | |
72 | |
73 ptr = end - 1; | |
74 while (*ptr == ' ' || *ptr == '\t') ptr--; | |
75 if (*ptr-- != ';') | |
76 { | |
77 fprintf (stderr, "Funny input line: %s\n", start); | |
78 return 0; | |
79 } | |
80 while (*ptr == ' ' || *ptr == '\t') ptr--; | |
81 if (*ptr != ')') | |
82 { | |
83 fprintf (stderr, "Funny input line: %s\n", start); | |
84 return 0; | |
85 } | |
86 param_end = ptr; | |
87 for (;;) | |
88 { | |
89 int c = *--ptr; | |
90 if (c == '(' && --param_nesting == 0) | |
91 break; | |
92 else if (c == ')') | |
93 param_nesting++; | |
94 } | |
95 param_start = ptr+1; | |
96 | |
97 ptr--; | |
98 while (*ptr == ' ' || *ptr == '\t') ptr--; | |
99 | |
100 if (!ISALNUM ((unsigned char)*ptr)) | |
101 { | |
102 if (verbose) | |
103 fprintf (stderr, "%s: Can't handle this complex prototype: %s\n", | |
104 progname, start); | |
105 return 0; | |
106 } | |
107 name_end = ptr+1; | |
108 | |
109 while (ISIDNUM (*ptr)) | |
110 --ptr; | |
111 name_start = ptr+1; | |
112 while (*ptr == ' ' || *ptr == '\t') ptr--; | |
113 ptr[1] = 0; | |
114 *param_end = 0; | |
115 *name_end = 0; | |
116 | |
117 decl_start = start; | |
118 if (strncmp (decl_start, "typedef ", 8) == 0) | |
119 return 0; | |
120 if (strncmp (decl_start, "extern ", 7) == 0) | |
121 decl_start += 7; | |
122 | |
123 fn->fname = name_start; | |
124 fn->rtype = decl_start; | |
125 fn->params = param_start; | |
126 return 1; | |
127 } | |
128 | |
129 int | |
130 main (int argc ATTRIBUTE_UNUSED, char **argv) | |
131 { | |
132 FILE *inf = stdin; | |
133 FILE *outf = stdout; | |
134 int i; | |
135 sstring linebuf; | |
136 struct fn_decl fn_decl; | |
137 | |
138 i = strlen (argv[0]); | |
139 while (i > 0 && argv[0][i-1] != '/') --i; | |
140 progname = &argv[0][i]; | |
141 | |
142 /* Unlock the stdio streams. */ | |
143 unlock_std_streams (); | |
144 | |
145 INIT_SSTRING (&linebuf); | |
146 | |
147 fprintf (outf, "struct fn_decl std_protos[] = {\n"); | |
148 | |
149 /* A hash table entry of 0 means "unused" so reserve it. */ | |
150 fprintf (outf, " {\"\", \"\", \"\", 0},\n"); | |
151 next_index = 1; | |
152 | |
153 for (;;) | |
154 { | |
155 int c = skip_spaces (inf, ' '); | |
156 | |
157 if (c == EOF) | |
158 break; | |
159 linebuf.ptr = linebuf.base; | |
160 ungetc (c, inf); | |
161 c = read_upto (inf, &linebuf, '\n'); | |
162 if (linebuf.base[0] == '#') /* skip cpp command */ | |
163 continue; | |
164 if (linebuf.base[0] == '\0') /* skip empty line */ | |
165 continue; | |
166 | |
167 if (! parse_fn_proto (linebuf.base, linebuf.ptr, &fn_decl)) | |
168 continue; | |
169 | |
170 add_hash (fn_decl.fname); | |
171 | |
172 fprintf (outf, " {\"%s\", \"%s\", \"%s\", 0},\n", | |
173 fn_decl.fname, fn_decl.rtype, fn_decl.params); | |
174 | |
175 if (c == EOF) | |
176 break; | |
177 } | |
178 fprintf (outf, " {0, 0, 0, 0}\n};\n"); | |
179 | |
180 | |
181 fprintf (outf, "#define HASH_SIZE %d\n", HASH_SIZE); | |
182 fprintf (outf, "short hash_tab[HASH_SIZE] = {\n"); | |
183 for (i = 0; i < HASH_SIZE; i++) | |
184 fprintf (outf, " %d,\n", hash_tab[i]); | |
185 fprintf (outf, "};\n"); | |
186 | |
187 fprintf (stderr, "gen-protos: %d entries %d collisions\n", | |
188 next_index, collisions); | |
189 | |
190 return 0; | |
191 } |