00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "hconfig.h"
00020 #include "system.h"
00021 #include "scan.h"
00022 #undef abort
00023
00024 int verbose = 0;
00025 const char *progname;
00026
00027 static void add_hash PARAMS ((const char *));
00028 static int parse_fn_proto PARAMS ((char *, char *, struct fn_decl *));
00029
00030 #define HASH_SIZE 2503
00031 int hash_tab[HASH_SIZE];
00032 int next_index;
00033 int collisions;
00034
00035 static void
00036 add_hash (fname)
00037 const char *fname;
00038 {
00039 int i, i0;
00040
00041
00042 i = hashstr (fname, strlen (fname)) % HASH_SIZE;
00043 i0 = i;
00044 if (hash_tab[i] != 0)
00045 {
00046 collisions++;
00047 for (;;)
00048 {
00049 i = (i+1) % HASH_SIZE;
00050 if (i == i0)
00051 abort ();
00052 if (hash_tab[i] == 0)
00053 break;
00054 }
00055 }
00056 hash_tab[i] = next_index;
00057
00058 next_index++;
00059 }
00060
00061
00062
00063
00064
00065
00066
00067 static int
00068 parse_fn_proto (start, end, fn)
00069 char *start, *end;
00070 struct fn_decl *fn;
00071 {
00072 char *ptr;
00073 int param_nesting = 1;
00074 char *param_start, *param_end, *decl_start, *name_start, *name_end;
00075
00076 ptr = end - 1;
00077 while (*ptr == ' ' || *ptr == '\t') ptr--;
00078 if (*ptr-- != ';')
00079 {
00080 fprintf (stderr, "Funny input line: %s\n", start);
00081 return 0;
00082 }
00083 while (*ptr == ' ' || *ptr == '\t') ptr--;
00084 if (*ptr != ')')
00085 {
00086 fprintf (stderr, "Funny input line: %s\n", start);
00087 return 0;
00088 }
00089 param_end = ptr;
00090 for (;;)
00091 {
00092 int c = *--ptr;
00093 if (c == '(' && --param_nesting == 0)
00094 break;
00095 else if (c == ')')
00096 param_nesting++;
00097 }
00098 param_start = ptr+1;
00099
00100 ptr--;
00101 while (*ptr == ' ' || *ptr == '\t') ptr--;
00102
00103 if (!ISALNUM ((unsigned char)*ptr))
00104 {
00105 if (verbose)
00106 fprintf (stderr, "%s: Can't handle this complex prototype: %s\n",
00107 progname, start);
00108 return 0;
00109 }
00110 name_end = ptr+1;
00111
00112 while (ISIDNUM (*ptr))
00113 --ptr;
00114 name_start = ptr+1;
00115 while (*ptr == ' ' || *ptr == '\t') ptr--;
00116 ptr[1] = 0;
00117 *param_end = 0;
00118 *name_end = 0;
00119
00120 decl_start = start;
00121 if (strncmp (decl_start, "typedef ", 8) == 0)
00122 return 0;
00123 if (strncmp (decl_start, "extern ", 7) == 0)
00124 decl_start += 7;
00125
00126 fn->fname = name_start;
00127 fn->rtype = decl_start;
00128 fn->params = param_start;
00129 return 1;
00130 }
00131
00132 extern int main PARAMS ((int, char **));
00133
00134 int
00135 main (argc, argv)
00136 int argc ATTRIBUTE_UNUSED;
00137 char **argv;
00138 {
00139 FILE *inf = stdin;
00140 FILE *outf = stdout;
00141 int i;
00142 sstring linebuf;
00143 struct fn_decl fn_decl;
00144
00145 i = strlen (argv[0]);
00146 while (i > 0 && argv[0][i-1] != '/') --i;
00147 progname = &argv[0][i];
00148
00149 INIT_SSTRING (&linebuf);
00150
00151 fprintf (outf, "struct fn_decl std_protos[] = {\n");
00152
00153
00154 fprintf (outf, " {\"\", \"\", \"\", 0},\n");
00155 next_index = 1;
00156
00157 for (;;)
00158 {
00159 int c = skip_spaces (inf, ' ');
00160
00161 if (c == EOF)
00162 break;
00163 linebuf.ptr = linebuf.base;
00164 ungetc (c, inf);
00165 c = read_upto (inf, &linebuf, '\n');
00166 if (linebuf.base[0] == '#')
00167 continue;
00168 if (linebuf.base[0] == '\0')
00169 continue;
00170
00171 if (! parse_fn_proto (linebuf.base, linebuf.ptr, &fn_decl))
00172 continue;
00173
00174 add_hash (fn_decl.fname);
00175
00176 fprintf (outf, " {\"%s\", \"%s\", \"%s\", 0},\n",
00177 fn_decl.fname, fn_decl.rtype, fn_decl.params);
00178
00179 if (c == EOF)
00180 break;
00181 }
00182 fprintf (outf, " {0, 0, 0, 0}\n};\n");
00183
00184
00185 fprintf (outf, "#define HASH_SIZE %d\n", HASH_SIZE);
00186 fprintf (outf, "short hash_tab[HASH_SIZE] = {\n");
00187 for (i = 0; i < HASH_SIZE; i++)
00188 fprintf (outf, " %d,\n", hash_tab[i]);
00189 fprintf (outf, "};\n");
00190
00191 fprintf (stderr, "gen-protos: %d entries %d collisions\n",
00192 next_index, collisions);
00193
00194 return 0;
00195 }