#define HASH_BUCKETS 4096
static struct symbol *symtab[HASH_BUCKETS];
-FILE *debugfile;
+static FILE *debugfile;
int cur_line = 1;
-char *cur_filename, *output_directory;
+char *cur_filename;
-int flag_debug, flag_dump_defs, flag_warnings;
-const char *arch = "";
-const char *mod_prefix = "";
+static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings;
+static const char *arch = "";
+static const char *mod_prefix = "";
static int errors;
static int nsyms;
static struct symbol *expansion_trail;
+static struct symbol *visited_symbols;
static const char *const symbol_type_name[] = {
"normal", "typedef", "enum", "struct", "union"
};
+static int equal_list(struct string_list *a, struct string_list *b);
+static void print_list(FILE * f, struct string_list *list);
+
/*----------------------------------------------------------------------*/
static const unsigned int crctab32[] = {
0x2d02ef8dU
};
-static inline unsigned long
-partial_crc32_one(unsigned char c, unsigned long crc)
+static unsigned long partial_crc32_one(unsigned char c, unsigned long crc)
{
return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
}
-static inline unsigned long partial_crc32(const char *s, unsigned long crc)
+static unsigned long partial_crc32(const char *s, unsigned long crc)
{
while (*s)
crc = partial_crc32_one(*s++, crc);
return crc;
}
-static inline unsigned long crc32(const char *s)
+static unsigned long crc32(const char *s)
{
return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
}
/*----------------------------------------------------------------------*/
-static inline enum symbol_type map_to_ns(enum symbol_type t)
+static enum symbol_type map_to_ns(enum symbol_type t)
{
if (t == SYM_TYPEDEF)
t = SYM_NORMAL;
struct symbol *sym;
for (sym = symtab[h]; sym; sym = sym->hash_next)
- if (map_to_ns(sym->type) == map_to_ns(ns)
- && strcmp(name, sym->name) == 0)
+ if (map_to_ns(sym->type) == map_to_ns(ns) &&
+ strcmp(name, sym->name) == 0)
break;
return sym;
unsigned long h = crc32(name) % HASH_BUCKETS;
struct symbol *sym;
- for (sym = symtab[h]; sym; sym = sym->hash_next)
+ for (sym = symtab[h]; sym; sym = sym->hash_next) {
if (map_to_ns(sym->type) == map_to_ns(type)
&& strcmp(name, sym->name) == 0) {
if (!equal_list(sym->defn, defn))
error_with_pos("redefinition of %s", name);
return sym;
}
+ }
sym = xmalloc(sizeof(*sym));
sym->name = name;
sym->type = type;
sym->defn = defn;
sym->expansion_trail = NULL;
+ sym->visited = NULL;
sym->is_extern = is_extern;
sym->hash_next = symtab[h];
/*----------------------------------------------------------------------*/
-inline void free_node(struct string_list *node)
+void free_node(struct string_list *node)
{
free(node->string);
free(node);
}
}
-inline struct string_list *copy_node(struct string_list *node)
+struct string_list *copy_node(struct string_list *node)
{
struct string_list *newnode;
return newnode;
}
-struct string_list *copy_list(struct string_list *s, struct string_list *e)
-{
- struct string_list *h, *p;
-
- if (s == e)
- return NULL;
-
- p = h = copy_node(s);
- while ((s = s->next) != e)
- p = p->next = copy_node(s);
- p->next = NULL;
-
- return h;
-}
-
-int equal_list(struct string_list *a, struct string_list *b)
+static int equal_list(struct string_list *a, struct string_list *b)
{
while (a && b) {
if (a->tag != b->tag || strcmp(a->string, b->string))
return !a && !b;
}
-static inline void print_node(FILE * f, struct string_list *list)
+static void print_node(FILE * f, struct string_list *list)
{
- switch (list->tag) {
- case SYM_STRUCT:
- putc('s', f);
- goto printit;
- case SYM_UNION:
- putc('u', f);
- goto printit;
- case SYM_ENUM:
- putc('e', f);
- goto printit;
- case SYM_TYPEDEF:
- putc('t', f);
- goto printit;
-
- printit:
+ if (list->tag != SYM_NORMAL) {
+ putc(symbol_type_name[list->tag][0], f);
putc('#', f);
- case SYM_NORMAL:
- fputs(list->string, f);
- break;
}
+ fputs(list->string, f);
}
-void print_list(FILE * f, struct string_list *list)
+static void print_list(FILE * f, struct string_list *list)
{
struct string_list **e, **b;
struct string_list *tmp, **tmp2;
}
}
-static unsigned long
-expand_and_crc_list(struct string_list *list, unsigned long crc)
+static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
{
+ struct string_list *list = sym->defn;
struct string_list **e, **b;
struct string_list *tmp, **tmp2;
int elem = 1;
} else {
subsym->expansion_trail = expansion_trail;
expansion_trail = subsym;
- crc = expand_and_crc_list(subsym->defn, crc);
+ crc = expand_and_crc_sym(subsym, crc);
}
break;
cur->string);
}
- crc =
- partial_crc32(symbol_type_name[cur->tag],
- crc);
+ crc = partial_crc32(symbol_type_name[cur->tag],
+ crc);
crc = partial_crc32_one(' ', crc);
crc = partial_crc32(cur->string, crc);
crc = partial_crc32_one(' ', crc);
} else {
subsym->expansion_trail = expansion_trail;
expansion_trail = subsym;
- crc = expand_and_crc_list(subsym->defn, crc);
+ crc = expand_and_crc_sym(subsym, crc);
}
break;
}
}
+ {
+ static struct symbol **end = &visited_symbols;
+
+ if (!sym->visited) {
+ *end = sym;
+ end = &sym->visited;
+ sym->visited = (struct symbol *)-1L;
+ }
+ }
+
return crc;
}
expansion_trail = (struct symbol *)-1L;
- crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff;
+ crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
sym = expansion_trail;
while (sym != (struct symbol *)-1L) {
}
/*----------------------------------------------------------------------*/
-
-void error(const char *fmt, ...)
-{
- va_list args;
-
- if (flag_warnings) {
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- putc('\n', stderr);
-
- errors++;
- }
-}
-
void error_with_pos(const char *fmt, ...)
{
va_list args;
}
}
-void genksyms_usage(void)
+static void genksyms_usage(void)
{
fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n"
#ifdef __GNU_LIBRARY__
int main(int argc, char **argv)
{
+ FILE *dumpfile = NULL;
int o;
#ifdef __GNU_LIBRARY__
{"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'},
{"dump", 0, 0, 'D'},
+ {"dump-types", 1, 0, 'T'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
- while ((o = getopt_long(argc, argv, "a:dwqVDk:p:",
+ while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:",
&long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */
- while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF)
+ while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF)
#endif /* __GNU_LIBRARY__ */
switch (o) {
case 'a':
case 'D':
flag_dump_defs = 1;
break;
+ case 'T':
+ flag_dump_types = 1;
+ dumpfile = fopen(optarg, "w");
+ if (!dumpfile) {
+ perror(optarg);
+ return 1;
+ }
+ break;
case 'h':
genksyms_usage();
return 0;
yyparse();
+ if (flag_dump_types && visited_symbols) {
+ while (visited_symbols != (struct symbol *)-1L) {
+ struct symbol *sym = visited_symbols;
+
+ if (sym->type != SYM_NORMAL) {
+ putc(symbol_type_name[sym->type][0], dumpfile);
+ putc('#', dumpfile);
+ }
+ fputs(sym->name, dumpfile);
+ putc(' ', dumpfile);
+ print_list(dumpfile, sym->defn);
+ putc('\n', dumpfile);
+
+ visited_symbols = sym->visited;
+ sym->visited = NULL;
+ }
+ }
+
if (flag_debug) {
fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
nsyms, HASH_BUCKETS,