diff options
Diffstat (limited to 'scripts/genksyms/genksyms.c')
-rw-r--r-- | scripts/genksyms/genksyms.c | 77 |
1 files changed, 51 insertions, 26 deletions
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 5b0344e20d61..b0381823e404 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c | |||
@@ -42,7 +42,7 @@ static FILE *debugfile; | |||
42 | int cur_line = 1; | 42 | int cur_line = 1; |
43 | char *cur_filename; | 43 | char *cur_filename; |
44 | 44 | ||
45 | static int flag_debug, flag_dump_defs, flag_warnings; | 45 | static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings; |
46 | static const char *arch = ""; | 46 | static const char *arch = ""; |
47 | static const char *mod_prefix = ""; | 47 | static const char *mod_prefix = ""; |
48 | 48 | ||
@@ -50,6 +50,7 @@ static int errors; | |||
50 | static int nsyms; | 50 | static int nsyms; |
51 | 51 | ||
52 | static struct symbol *expansion_trail; | 52 | static struct symbol *expansion_trail; |
53 | static struct symbol *visited_symbols; | ||
53 | 54 | ||
54 | static const char *const symbol_type_name[] = { | 55 | static const char *const symbol_type_name[] = { |
55 | "normal", "typedef", "enum", "struct", "union" | 56 | "normal", "typedef", "enum", "struct", "union" |
@@ -176,6 +177,7 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, | |||
176 | sym->type = type; | 177 | sym->type = type; |
177 | sym->defn = defn; | 178 | sym->defn = defn; |
178 | sym->expansion_trail = NULL; | 179 | sym->expansion_trail = NULL; |
180 | sym->visited = NULL; | ||
179 | sym->is_extern = is_extern; | 181 | sym->is_extern = is_extern; |
180 | 182 | ||
181 | sym->hash_next = symtab[h]; | 183 | sym->hash_next = symtab[h]; |
@@ -236,26 +238,11 @@ static int equal_list(struct string_list *a, struct string_list *b) | |||
236 | 238 | ||
237 | static void print_node(FILE * f, struct string_list *list) | 239 | static void print_node(FILE * f, struct string_list *list) |
238 | { | 240 | { |
239 | switch (list->tag) { | 241 | if (list->tag != SYM_NORMAL) { |
240 | case SYM_STRUCT: | 242 | putc(symbol_type_name[list->tag][0], f); |
241 | putc('s', f); | ||
242 | goto printit; | ||
243 | case SYM_UNION: | ||
244 | putc('u', f); | ||
245 | goto printit; | ||
246 | case SYM_ENUM: | ||
247 | putc('e', f); | ||
248 | goto printit; | ||
249 | case SYM_TYPEDEF: | ||
250 | putc('t', f); | ||
251 | goto printit; | ||
252 | |||
253 | printit: | ||
254 | putc('#', f); | 243 | putc('#', f); |
255 | case SYM_NORMAL: | ||
256 | fputs(list->string, f); | ||
257 | break; | ||
258 | } | 244 | } |
245 | fputs(list->string, f); | ||
259 | } | 246 | } |
260 | 247 | ||
261 | static void print_list(FILE * f, struct string_list *list) | 248 | static void print_list(FILE * f, struct string_list *list) |
@@ -287,9 +274,9 @@ static void print_list(FILE * f, struct string_list *list) | |||
287 | } | 274 | } |
288 | } | 275 | } |
289 | 276 | ||
290 | static unsigned long expand_and_crc_list(struct string_list *list, | 277 | static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) |
291 | unsigned long crc) | ||
292 | { | 278 | { |
279 | struct string_list *list = sym->defn; | ||
293 | struct string_list **e, **b; | 280 | struct string_list **e, **b; |
294 | struct string_list *tmp, **tmp2; | 281 | struct string_list *tmp, **tmp2; |
295 | int elem = 1; | 282 | int elem = 1; |
@@ -332,7 +319,7 @@ static unsigned long expand_and_crc_list(struct string_list *list, | |||
332 | } else { | 319 | } else { |
333 | subsym->expansion_trail = expansion_trail; | 320 | subsym->expansion_trail = expansion_trail; |
334 | expansion_trail = subsym; | 321 | expansion_trail = subsym; |
335 | crc = expand_and_crc_list(subsym->defn, crc); | 322 | crc = expand_and_crc_sym(subsym, crc); |
336 | } | 323 | } |
337 | break; | 324 | break; |
338 | 325 | ||
@@ -382,12 +369,22 @@ static unsigned long expand_and_crc_list(struct string_list *list, | |||
382 | } else { | 369 | } else { |
383 | subsym->expansion_trail = expansion_trail; | 370 | subsym->expansion_trail = expansion_trail; |
384 | expansion_trail = subsym; | 371 | expansion_trail = subsym; |
385 | crc = expand_and_crc_list(subsym->defn, crc); | 372 | crc = expand_and_crc_sym(subsym, crc); |
386 | } | 373 | } |
387 | break; | 374 | break; |
388 | } | 375 | } |
389 | } | 376 | } |
390 | 377 | ||
378 | { | ||
379 | static struct symbol **end = &visited_symbols; | ||
380 | |||
381 | if (!sym->visited) { | ||
382 | *end = sym; | ||
383 | end = &sym->visited; | ||
384 | sym->visited = (struct symbol *)-1L; | ||
385 | } | ||
386 | } | ||
387 | |||
391 | return crc; | 388 | return crc; |
392 | } | 389 | } |
393 | 390 | ||
@@ -406,7 +403,7 @@ void export_symbol(const char *name) | |||
406 | 403 | ||
407 | expansion_trail = (struct symbol *)-1L; | 404 | expansion_trail = (struct symbol *)-1L; |
408 | 405 | ||
409 | crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; | 406 | crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; |
410 | 407 | ||
411 | sym = expansion_trail; | 408 | sym = expansion_trail; |
412 | while (sym != (struct symbol *)-1L) { | 409 | while (sym != (struct symbol *)-1L) { |
@@ -464,6 +461,7 @@ static void genksyms_usage(void) | |||
464 | 461 | ||
465 | int main(int argc, char **argv) | 462 | int main(int argc, char **argv) |
466 | { | 463 | { |
464 | FILE *dumpfile = NULL; | ||
467 | int o; | 465 | int o; |
468 | 466 | ||
469 | #ifdef __GNU_LIBRARY__ | 467 | #ifdef __GNU_LIBRARY__ |
@@ -473,15 +471,16 @@ int main(int argc, char **argv) | |||
473 | {"warnings", 0, 0, 'w'}, | 471 | {"warnings", 0, 0, 'w'}, |
474 | {"quiet", 0, 0, 'q'}, | 472 | {"quiet", 0, 0, 'q'}, |
475 | {"dump", 0, 0, 'D'}, | 473 | {"dump", 0, 0, 'D'}, |
474 | {"dump-types", 1, 0, 'T'}, | ||
476 | {"version", 0, 0, 'V'}, | 475 | {"version", 0, 0, 'V'}, |
477 | {"help", 0, 0, 'h'}, | 476 | {"help", 0, 0, 'h'}, |
478 | {0, 0, 0, 0} | 477 | {0, 0, 0, 0} |
479 | }; | 478 | }; |
480 | 479 | ||
481 | while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", | 480 | while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:", |
482 | &long_opts[0], NULL)) != EOF) | 481 | &long_opts[0], NULL)) != EOF) |
483 | #else /* __GNU_LIBRARY__ */ | 482 | #else /* __GNU_LIBRARY__ */ |
484 | while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) | 483 | while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF) |
485 | #endif /* __GNU_LIBRARY__ */ | 484 | #endif /* __GNU_LIBRARY__ */ |
486 | switch (o) { | 485 | switch (o) { |
487 | case 'a': | 486 | case 'a': |
@@ -502,6 +501,14 @@ int main(int argc, char **argv) | |||
502 | case 'D': | 501 | case 'D': |
503 | flag_dump_defs = 1; | 502 | flag_dump_defs = 1; |
504 | break; | 503 | break; |
504 | case 'T': | ||
505 | flag_dump_types = 1; | ||
506 | dumpfile = fopen(optarg, "w"); | ||
507 | if (!dumpfile) { | ||
508 | perror(optarg); | ||
509 | return 1; | ||
510 | } | ||
511 | break; | ||
505 | case 'h': | 512 | case 'h': |
506 | genksyms_usage(); | 513 | genksyms_usage(); |
507 | return 0; | 514 | return 0; |
@@ -524,6 +531,24 @@ int main(int argc, char **argv) | |||
524 | 531 | ||
525 | yyparse(); | 532 | yyparse(); |
526 | 533 | ||
534 | if (flag_dump_types && visited_symbols) { | ||
535 | while (visited_symbols != (struct symbol *)-1L) { | ||
536 | struct symbol *sym = visited_symbols; | ||
537 | |||
538 | if (sym->type != SYM_NORMAL) { | ||
539 | putc(symbol_type_name[sym->type][0], dumpfile); | ||
540 | putc('#', dumpfile); | ||
541 | } | ||
542 | fputs(sym->name, dumpfile); | ||
543 | putc(' ', dumpfile); | ||
544 | print_list(dumpfile, sym->defn); | ||
545 | putc('\n', dumpfile); | ||
546 | |||
547 | visited_symbols = sym->visited; | ||
548 | sym->visited = NULL; | ||
549 | } | ||
550 | } | ||
551 | |||
527 | if (flag_debug) { | 552 | if (flag_debug) { |
528 | fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", | 553 | fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", |
529 | nsyms, HASH_BUCKETS, | 554 | nsyms, HASH_BUCKETS, |