diff options
Diffstat (limited to 'scripts/asn1_compiler.c')
| -rw-r--r-- | scripts/asn1_compiler.c | 229 |
1 files changed, 142 insertions, 87 deletions
diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c index 1c75e22b6385..e000f44e37b8 100644 --- a/scripts/asn1_compiler.c +++ b/scripts/asn1_compiler.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <stdio.h> | 13 | #include <stdio.h> |
| 14 | #include <stdlib.h> | 14 | #include <stdlib.h> |
| 15 | #include <stdint.h> | 15 | #include <stdint.h> |
| 16 | #include <stdbool.h> | ||
| 16 | #include <string.h> | 17 | #include <string.h> |
| 17 | #include <ctype.h> | 18 | #include <ctype.h> |
| 18 | #include <unistd.h> | 19 | #include <unistd.h> |
| @@ -293,8 +294,8 @@ static const char *const directives[NR__DIRECTIVES] = { | |||
| 293 | 294 | ||
| 294 | struct action { | 295 | struct action { |
| 295 | struct action *next; | 296 | struct action *next; |
| 297 | char *name; | ||
| 296 | unsigned char index; | 298 | unsigned char index; |
| 297 | char name[]; | ||
| 298 | }; | 299 | }; |
| 299 | 300 | ||
| 300 | static struct action *action_list; | 301 | static struct action *action_list; |
| @@ -305,15 +306,17 @@ struct token { | |||
| 305 | enum token_type token_type : 8; | 306 | enum token_type token_type : 8; |
| 306 | unsigned char size; | 307 | unsigned char size; |
| 307 | struct action *action; | 308 | struct action *action; |
| 308 | const char *value; | 309 | char *content; |
| 309 | struct type *type; | 310 | struct type *type; |
| 310 | }; | 311 | }; |
| 311 | 312 | ||
| 312 | static struct token *token_list; | 313 | static struct token *token_list; |
| 313 | static unsigned nr_tokens; | 314 | static unsigned nr_tokens; |
| 314 | static _Bool verbose; | 315 | static bool verbose_opt; |
| 316 | static bool debug_opt; | ||
| 315 | 317 | ||
| 316 | #define debug(fmt, ...) do { if (verbose) printf(fmt, ## __VA_ARGS__); } while (0) | 318 | #define verbose(fmt, ...) do { if (verbose_opt) printf(fmt, ## __VA_ARGS__); } while (0) |
| 319 | #define debug(fmt, ...) do { if (debug_opt) printf(fmt, ## __VA_ARGS__); } while (0) | ||
| 317 | 320 | ||
| 318 | static int directive_compare(const void *_key, const void *_pdir) | 321 | static int directive_compare(const void *_key, const void *_pdir) |
| 319 | { | 322 | { |
| @@ -325,11 +328,9 @@ static int directive_compare(const void *_key, const void *_pdir) | |||
| 325 | dlen = strlen(dir); | 328 | dlen = strlen(dir); |
| 326 | clen = (dlen < token->size) ? dlen : token->size; | 329 | clen = (dlen < token->size) ? dlen : token->size; |
| 327 | 330 | ||
| 328 | //debug("cmp(%*.*s,%s) = ", | 331 | //debug("cmp(%s,%s) = ", token->content, dir); |
| 329 | // (int)token->size, (int)token->size, token->value, | ||
| 330 | // dir); | ||
| 331 | 332 | ||
| 332 | val = memcmp(token->value, dir, clen); | 333 | val = memcmp(token->content, dir, clen); |
| 333 | if (val != 0) { | 334 | if (val != 0) { |
| 334 | //debug("%d [cmp]\n", val); | 335 | //debug("%d [cmp]\n", val); |
| 335 | return val; | 336 | return val; |
| @@ -349,7 +350,7 @@ static int directive_compare(const void *_key, const void *_pdir) | |||
| 349 | static void tokenise(char *buffer, char *end) | 350 | static void tokenise(char *buffer, char *end) |
| 350 | { | 351 | { |
| 351 | struct token *tokens; | 352 | struct token *tokens; |
| 352 | char *line, *nl, *p, *q; | 353 | char *line, *nl, *start, *p, *q; |
| 353 | unsigned tix, lineno; | 354 | unsigned tix, lineno; |
| 354 | 355 | ||
| 355 | /* Assume we're going to have half as many tokens as we have | 356 | /* Assume we're going to have half as many tokens as we have |
| @@ -408,11 +409,11 @@ static void tokenise(char *buffer, char *end) | |||
| 408 | break; | 409 | break; |
| 409 | 410 | ||
| 410 | tokens[tix].line = lineno; | 411 | tokens[tix].line = lineno; |
| 411 | tokens[tix].value = p; | 412 | start = p; |
| 412 | 413 | ||
| 413 | /* Handle string tokens */ | 414 | /* Handle string tokens */ |
| 414 | if (isalpha(*p)) { | 415 | if (isalpha(*p)) { |
| 415 | const char **dir; | 416 | const char **dir, *start = p; |
| 416 | 417 | ||
| 417 | /* Can be a directive, type name or element | 418 | /* Can be a directive, type name or element |
| 418 | * name. Find the end of the name. | 419 | * name. Find the end of the name. |
| @@ -423,10 +424,18 @@ static void tokenise(char *buffer, char *end) | |||
| 423 | tokens[tix].size = q - p; | 424 | tokens[tix].size = q - p; |
| 424 | p = q; | 425 | p = q; |
| 425 | 426 | ||
| 427 | tokens[tix].content = malloc(tokens[tix].size + 1); | ||
| 428 | if (!tokens[tix].content) { | ||
| 429 | perror(NULL); | ||
| 430 | exit(1); | ||
| 431 | } | ||
| 432 | memcpy(tokens[tix].content, start, tokens[tix].size); | ||
| 433 | tokens[tix].content[tokens[tix].size] = 0; | ||
| 434 | |||
| 426 | /* If it begins with a lowercase letter then | 435 | /* If it begins with a lowercase letter then |
| 427 | * it's an element name | 436 | * it's an element name |
| 428 | */ | 437 | */ |
| 429 | if (islower(tokens[tix].value[0])) { | 438 | if (islower(tokens[tix].content[0])) { |
| 430 | tokens[tix++].token_type = TOKEN_ELEMENT_NAME; | 439 | tokens[tix++].token_type = TOKEN_ELEMENT_NAME; |
| 431 | continue; | 440 | continue; |
| 432 | } | 441 | } |
| @@ -455,6 +464,13 @@ static void tokenise(char *buffer, char *end) | |||
| 455 | q++; | 464 | q++; |
| 456 | tokens[tix].size = q - p; | 465 | tokens[tix].size = q - p; |
| 457 | p = q; | 466 | p = q; |
| 467 | tokens[tix].content = malloc(tokens[tix].size + 1); | ||
| 468 | if (!tokens[tix].content) { | ||
| 469 | perror(NULL); | ||
| 470 | exit(1); | ||
| 471 | } | ||
| 472 | memcpy(tokens[tix].content, start, tokens[tix].size); | ||
| 473 | tokens[tix].content[tokens[tix].size] = 0; | ||
| 458 | tokens[tix++].token_type = TOKEN_NUMBER; | 474 | tokens[tix++].token_type = TOKEN_NUMBER; |
| 459 | continue; | 475 | continue; |
| 460 | } | 476 | } |
| @@ -463,6 +479,7 @@ static void tokenise(char *buffer, char *end) | |||
| 463 | if (memcmp(p, "::=", 3) == 0) { | 479 | if (memcmp(p, "::=", 3) == 0) { |
| 464 | p += 3; | 480 | p += 3; |
| 465 | tokens[tix].size = 3; | 481 | tokens[tix].size = 3; |
| 482 | tokens[tix].content = "::="; | ||
| 466 | tokens[tix++].token_type = TOKEN_ASSIGNMENT; | 483 | tokens[tix++].token_type = TOKEN_ASSIGNMENT; |
| 467 | continue; | 484 | continue; |
| 468 | } | 485 | } |
| @@ -472,12 +489,14 @@ static void tokenise(char *buffer, char *end) | |||
| 472 | if (memcmp(p, "({", 2) == 0) { | 489 | if (memcmp(p, "({", 2) == 0) { |
| 473 | p += 2; | 490 | p += 2; |
| 474 | tokens[tix].size = 2; | 491 | tokens[tix].size = 2; |
| 492 | tokens[tix].content = "({"; | ||
| 475 | tokens[tix++].token_type = TOKEN_OPEN_ACTION; | 493 | tokens[tix++].token_type = TOKEN_OPEN_ACTION; |
| 476 | continue; | 494 | continue; |
| 477 | } | 495 | } |
| 478 | if (memcmp(p, "})", 2) == 0) { | 496 | if (memcmp(p, "})", 2) == 0) { |
| 479 | p += 2; | 497 | p += 2; |
| 480 | tokens[tix].size = 2; | 498 | tokens[tix].size = 2; |
| 499 | tokens[tix].content = "})"; | ||
| 481 | tokens[tix++].token_type = TOKEN_CLOSE_ACTION; | 500 | tokens[tix++].token_type = TOKEN_CLOSE_ACTION; |
| 482 | continue; | 501 | continue; |
| 483 | } | 502 | } |
| @@ -488,22 +507,27 @@ static void tokenise(char *buffer, char *end) | |||
| 488 | switch (*p) { | 507 | switch (*p) { |
| 489 | case '{': | 508 | case '{': |
| 490 | p += 1; | 509 | p += 1; |
| 510 | tokens[tix].content = "{"; | ||
| 491 | tokens[tix++].token_type = TOKEN_OPEN_CURLY; | 511 | tokens[tix++].token_type = TOKEN_OPEN_CURLY; |
| 492 | continue; | 512 | continue; |
| 493 | case '}': | 513 | case '}': |
| 494 | p += 1; | 514 | p += 1; |
| 515 | tokens[tix].content = "}"; | ||
| 495 | tokens[tix++].token_type = TOKEN_CLOSE_CURLY; | 516 | tokens[tix++].token_type = TOKEN_CLOSE_CURLY; |
| 496 | continue; | 517 | continue; |
| 497 | case '[': | 518 | case '[': |
| 498 | p += 1; | 519 | p += 1; |
| 520 | tokens[tix].content = "["; | ||
| 499 | tokens[tix++].token_type = TOKEN_OPEN_SQUARE; | 521 | tokens[tix++].token_type = TOKEN_OPEN_SQUARE; |
| 500 | continue; | 522 | continue; |
| 501 | case ']': | 523 | case ']': |
| 502 | p += 1; | 524 | p += 1; |
| 525 | tokens[tix].content = "]"; | ||
| 503 | tokens[tix++].token_type = TOKEN_CLOSE_SQUARE; | 526 | tokens[tix++].token_type = TOKEN_CLOSE_SQUARE; |
| 504 | continue; | 527 | continue; |
| 505 | case ',': | 528 | case ',': |
| 506 | p += 1; | 529 | p += 1; |
| 530 | tokens[tix].content = ","; | ||
| 507 | tokens[tix++].token_type = TOKEN_COMMA; | 531 | tokens[tix++].token_type = TOKEN_COMMA; |
| 508 | continue; | 532 | continue; |
| 509 | default: | 533 | default: |
| @@ -518,22 +542,20 @@ static void tokenise(char *buffer, char *end) | |||
| 518 | } | 542 | } |
| 519 | 543 | ||
| 520 | nr_tokens = tix; | 544 | nr_tokens = tix; |
| 521 | debug("Extracted %u tokens\n", nr_tokens); | 545 | verbose("Extracted %u tokens\n", nr_tokens); |
| 522 | 546 | ||
| 523 | #if 0 | 547 | #if 0 |
| 524 | { | 548 | { |
| 525 | int n; | 549 | int n; |
| 526 | for (n = 0; n < nr_tokens; n++) | 550 | for (n = 0; n < nr_tokens; n++) |
| 527 | debug("Token %3u: '%*.*s'\n", | 551 | debug("Token %3u: '%s'\n", n, token_list[n].content); |
| 528 | n, | ||
| 529 | (int)token_list[n].size, (int)token_list[n].size, | ||
| 530 | token_list[n].value); | ||
| 531 | } | 552 | } |
| 532 | #endif | 553 | #endif |
| 533 | } | 554 | } |
| 534 | 555 | ||
| 535 | static void build_type_list(void); | 556 | static void build_type_list(void); |
| 536 | static void parse(void); | 557 | static void parse(void); |
| 558 | static void dump_elements(void); | ||
| 537 | static void render(FILE *out, FILE *hdr); | 559 | static void render(FILE *out, FILE *hdr); |
| 538 | 560 | ||
| 539 | /* | 561 | /* |
| @@ -548,16 +570,27 @@ int main(int argc, char **argv) | |||
| 548 | char *kbuild_verbose; | 570 | char *kbuild_verbose; |
| 549 | int fd; | 571 | int fd; |
| 550 | 572 | ||
| 573 | kbuild_verbose = getenv("KBUILD_VERBOSE"); | ||
| 574 | if (kbuild_verbose) | ||
| 575 | verbose_opt = atoi(kbuild_verbose); | ||
| 576 | |||
| 577 | while (argc > 4) { | ||
| 578 | if (strcmp(argv[1], "-v") == 0) | ||
| 579 | verbose_opt = true; | ||
| 580 | else if (strcmp(argv[1], "-d") == 0) | ||
| 581 | debug_opt = true; | ||
| 582 | else | ||
| 583 | break; | ||
| 584 | memmove(&argv[1], &argv[2], (argc - 2) * sizeof(char *)); | ||
| 585 | argc--; | ||
| 586 | } | ||
| 587 | |||
| 551 | if (argc != 4) { | 588 | if (argc != 4) { |
| 552 | fprintf(stderr, "Format: %s <grammar-file> <c-file> <hdr-file>\n", | 589 | fprintf(stderr, "Format: %s [-v] [-d] <grammar-file> <c-file> <hdr-file>\n", |
| 553 | argv[0]); | 590 | argv[0]); |
| 554 | exit(2); | 591 | exit(2); |
| 555 | } | 592 | } |
| 556 | 593 | ||
| 557 | kbuild_verbose = getenv("KBUILD_VERBOSE"); | ||
| 558 | if (kbuild_verbose) | ||
| 559 | verbose = atoi(kbuild_verbose); | ||
| 560 | |||
| 561 | filename = argv[1]; | 594 | filename = argv[1]; |
| 562 | outputname = argv[2]; | 595 | outputname = argv[2]; |
| 563 | headername = argv[3]; | 596 | headername = argv[3]; |
| @@ -608,6 +641,7 @@ int main(int argc, char **argv) | |||
| 608 | tokenise(buffer, buffer + readlen); | 641 | tokenise(buffer, buffer + readlen); |
| 609 | build_type_list(); | 642 | build_type_list(); |
| 610 | parse(); | 643 | parse(); |
| 644 | dump_elements(); | ||
| 611 | 645 | ||
| 612 | out = fopen(outputname, "w"); | 646 | out = fopen(outputname, "w"); |
| 613 | if (!out) { | 647 | if (!out) { |
| @@ -693,7 +727,7 @@ static int type_index_compare(const void *_a, const void *_b) | |||
| 693 | if ((*a)->name->size != (*b)->name->size) | 727 | if ((*a)->name->size != (*b)->name->size) |
| 694 | return (*a)->name->size - (*b)->name->size; | 728 | return (*a)->name->size - (*b)->name->size; |
| 695 | else | 729 | else |
| 696 | return memcmp((*a)->name->value, (*b)->name->value, | 730 | return memcmp((*a)->name->content, (*b)->name->content, |
| 697 | (*a)->name->size); | 731 | (*a)->name->size); |
| 698 | } | 732 | } |
| 699 | 733 | ||
| @@ -706,7 +740,7 @@ static int type_finder(const void *_key, const void *_ti) | |||
| 706 | if (token->size != type->name->size) | 740 | if (token->size != type->name->size) |
| 707 | return token->size - type->name->size; | 741 | return token->size - type->name->size; |
| 708 | else | 742 | else |
| 709 | return memcmp(token->value, type->name->value, | 743 | return memcmp(token->content, type->name->content, |
| 710 | token->size); | 744 | token->size); |
| 711 | } | 745 | } |
| 712 | 746 | ||
| @@ -756,14 +790,11 @@ static void build_type_list(void) | |||
| 756 | 790 | ||
| 757 | qsort(type_index, nr, sizeof(type_index[0]), type_index_compare); | 791 | qsort(type_index, nr, sizeof(type_index[0]), type_index_compare); |
| 758 | 792 | ||
| 759 | debug("Extracted %u types\n", nr_types); | 793 | verbose("Extracted %u types\n", nr_types); |
| 760 | #if 0 | 794 | #if 0 |
| 761 | for (n = 0; n < nr_types; n++) { | 795 | for (n = 0; n < nr_types; n++) { |
| 762 | struct type *type = type_index[n]; | 796 | struct type *type = type_index[n]; |
| 763 | debug("- %*.*s\n", | 797 | debug("- %*.*s\n", type->name->content); |
| 764 | (int)type->name->size, | ||
| 765 | (int)type->name->size, | ||
| 766 | type->name->value); | ||
| 767 | } | 798 | } |
| 768 | #endif | 799 | #endif |
| 769 | } | 800 | } |
| @@ -793,15 +824,14 @@ static void parse(void) | |||
| 793 | type->element->type_def = type; | 824 | type->element->type_def = type; |
| 794 | 825 | ||
| 795 | if (cursor != type[1].name) { | 826 | if (cursor != type[1].name) { |
| 796 | fprintf(stderr, "%s:%d: Parse error at token '%*.*s'\n", | 827 | fprintf(stderr, "%s:%d: Parse error at token '%s'\n", |
| 797 | filename, cursor->line, | 828 | filename, cursor->line, cursor->content); |
| 798 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 799 | exit(1); | 829 | exit(1); |
| 800 | } | 830 | } |
| 801 | 831 | ||
| 802 | } while (type++, !(type->flags & TYPE_STOP_MARKER)); | 832 | } while (type++, !(type->flags & TYPE_STOP_MARKER)); |
| 803 | 833 | ||
| 804 | debug("Extracted %u actions\n", nr_actions); | 834 | verbose("Extracted %u actions\n", nr_actions); |
| 805 | } | 835 | } |
| 806 | 836 | ||
| 807 | static struct element *element_list; | 837 | static struct element *element_list; |
| @@ -862,34 +892,31 @@ static struct element *parse_type(struct token **_cursor, struct token *end, | |||
| 862 | cursor++; | 892 | cursor++; |
| 863 | break; | 893 | break; |
| 864 | default: | 894 | default: |
| 865 | fprintf(stderr, "%s:%d: Unrecognised tag class token '%*.*s'\n", | 895 | fprintf(stderr, "%s:%d: Unrecognised tag class token '%s'\n", |
| 866 | filename, cursor->line, | 896 | filename, cursor->line, cursor->content); |
| 867 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 868 | exit(1); | 897 | exit(1); |
| 869 | } | 898 | } |
| 870 | 899 | ||
| 871 | if (cursor >= end) | 900 | if (cursor >= end) |
| 872 | goto overrun_error; | 901 | goto overrun_error; |
| 873 | if (cursor->token_type != TOKEN_NUMBER) { | 902 | if (cursor->token_type != TOKEN_NUMBER) { |
| 874 | fprintf(stderr, "%s:%d: Missing tag number '%*.*s'\n", | 903 | fprintf(stderr, "%s:%d: Missing tag number '%s'\n", |
| 875 | filename, cursor->line, | 904 | filename, cursor->line, cursor->content); |
| 876 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 877 | exit(1); | 905 | exit(1); |
| 878 | } | 906 | } |
| 879 | 907 | ||
| 880 | element->tag &= ~0x1f; | 908 | element->tag &= ~0x1f; |
| 881 | element->tag |= strtoul(cursor->value, &p, 10); | 909 | element->tag |= strtoul(cursor->content, &p, 10); |
| 882 | element->flags |= ELEMENT_TAG_SPECIFIED; | 910 | element->flags |= ELEMENT_TAG_SPECIFIED; |
| 883 | if (p - cursor->value != cursor->size) | 911 | if (p - cursor->content != cursor->size) |
| 884 | abort(); | 912 | abort(); |
| 885 | cursor++; | 913 | cursor++; |
| 886 | 914 | ||
| 887 | if (cursor >= end) | 915 | if (cursor >= end) |
| 888 | goto overrun_error; | 916 | goto overrun_error; |
| 889 | if (cursor->token_type != TOKEN_CLOSE_SQUARE) { | 917 | if (cursor->token_type != TOKEN_CLOSE_SQUARE) { |
| 890 | fprintf(stderr, "%s:%d: Missing closing square bracket '%*.*s'\n", | 918 | fprintf(stderr, "%s:%d: Missing closing square bracket '%s'\n", |
| 891 | filename, cursor->line, | 919 | filename, cursor->line, cursor->content); |
| 892 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 893 | exit(1); | 920 | exit(1); |
| 894 | } | 921 | } |
| 895 | cursor++; | 922 | cursor++; |
| @@ -989,9 +1016,8 @@ static struct element *parse_type(struct token **_cursor, struct token *end, | |||
| 989 | ref = bsearch(cursor, type_index, nr_types, sizeof(type_index[0]), | 1016 | ref = bsearch(cursor, type_index, nr_types, sizeof(type_index[0]), |
| 990 | type_finder); | 1017 | type_finder); |
| 991 | if (!ref) { | 1018 | if (!ref) { |
| 992 | fprintf(stderr, "%s:%d: Type '%*.*s' undefined\n", | 1019 | fprintf(stderr, "%s:%d: Type '%s' undefined\n", |
| 993 | filename, cursor->line, | 1020 | filename, cursor->line, cursor->content); |
| 994 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 995 | exit(1); | 1021 | exit(1); |
| 996 | } | 1022 | } |
| 997 | cursor->type = *ref; | 1023 | cursor->type = *ref; |
| @@ -1040,9 +1066,8 @@ static struct element *parse_type(struct token **_cursor, struct token *end, | |||
| 1040 | break; | 1066 | break; |
| 1041 | 1067 | ||
| 1042 | default: | 1068 | default: |
| 1043 | fprintf(stderr, "%s:%d: Token '%*.*s' does not introduce a type\n", | 1069 | fprintf(stderr, "%s:%d: Token '%s' does not introduce a type\n", |
| 1044 | filename, cursor->line, | 1070 | filename, cursor->line, cursor->content); |
| 1045 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 1046 | exit(1); | 1071 | exit(1); |
| 1047 | } | 1072 | } |
| 1048 | 1073 | ||
| @@ -1059,20 +1084,18 @@ static struct element *parse_type(struct token **_cursor, struct token *end, | |||
| 1059 | if (cursor >= end) | 1084 | if (cursor >= end) |
| 1060 | goto overrun_error; | 1085 | goto overrun_error; |
| 1061 | if (cursor->token_type != TOKEN_ELEMENT_NAME) { | 1086 | if (cursor->token_type != TOKEN_ELEMENT_NAME) { |
| 1062 | fprintf(stderr, "%s:%d: Token '%*.*s' is not an action function name\n", | 1087 | fprintf(stderr, "%s:%d: Token '%s' is not an action function name\n", |
| 1063 | filename, cursor->line, | 1088 | filename, cursor->line, cursor->content); |
| 1064 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 1065 | exit(1); | 1089 | exit(1); |
| 1066 | } | 1090 | } |
| 1067 | 1091 | ||
| 1068 | action = malloc(sizeof(struct action) + cursor->size + 1); | 1092 | action = malloc(sizeof(struct action)); |
| 1069 | if (!action) { | 1093 | if (!action) { |
| 1070 | perror(NULL); | 1094 | perror(NULL); |
| 1071 | exit(1); | 1095 | exit(1); |
| 1072 | } | 1096 | } |
| 1073 | action->index = 0; | 1097 | action->index = 0; |
| 1074 | memcpy(action->name, cursor->value, cursor->size); | 1098 | action->name = cursor->content; |
| 1075 | action->name[cursor->size] = 0; | ||
| 1076 | 1099 | ||
| 1077 | for (ppaction = &action_list; | 1100 | for (ppaction = &action_list; |
| 1078 | *ppaction; | 1101 | *ppaction; |
| @@ -1102,9 +1125,8 @@ static struct element *parse_type(struct token **_cursor, struct token *end, | |||
| 1102 | if (cursor >= end) | 1125 | if (cursor >= end) |
| 1103 | goto overrun_error; | 1126 | goto overrun_error; |
| 1104 | if (cursor->token_type != TOKEN_CLOSE_ACTION) { | 1127 | if (cursor->token_type != TOKEN_CLOSE_ACTION) { |
| 1105 | fprintf(stderr, "%s:%d: Missing close action, got '%*.*s'\n", | 1128 | fprintf(stderr, "%s:%d: Missing close action, got '%s'\n", |
| 1106 | filename, cursor->line, | 1129 | filename, cursor->line, cursor->content); |
| 1107 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 1108 | exit(1); | 1130 | exit(1); |
| 1109 | } | 1131 | } |
| 1110 | cursor++; | 1132 | cursor++; |
| @@ -1114,9 +1136,8 @@ static struct element *parse_type(struct token **_cursor, struct token *end, | |||
| 1114 | return top; | 1136 | return top; |
| 1115 | 1137 | ||
| 1116 | parse_error: | 1138 | parse_error: |
| 1117 | fprintf(stderr, "%s:%d: Unexpected token '%*.*s'\n", | 1139 | fprintf(stderr, "%s:%d: Unexpected token '%s'\n", |
| 1118 | filename, cursor->line, | 1140 | filename, cursor->line, cursor->content); |
| 1119 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 1120 | exit(1); | 1141 | exit(1); |
| 1121 | 1142 | ||
| 1122 | overrun_error: | 1143 | overrun_error: |
| @@ -1134,9 +1155,8 @@ static struct element *parse_compound(struct token **_cursor, struct token *end, | |||
| 1134 | struct token *cursor = *_cursor, *name; | 1155 | struct token *cursor = *_cursor, *name; |
| 1135 | 1156 | ||
| 1136 | if (cursor->token_type != TOKEN_OPEN_CURLY) { | 1157 | if (cursor->token_type != TOKEN_OPEN_CURLY) { |
| 1137 | fprintf(stderr, "%s:%d: Expected compound to start with brace not '%*.*s'\n", | 1158 | fprintf(stderr, "%s:%d: Expected compound to start with brace not '%s'\n", |
| 1138 | filename, cursor->line, | 1159 | filename, cursor->line, cursor->content); |
| 1139 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 1140 | exit(1); | 1160 | exit(1); |
| 1141 | } | 1161 | } |
| 1142 | cursor++; | 1162 | cursor++; |
| @@ -1177,9 +1197,8 @@ static struct element *parse_compound(struct token **_cursor, struct token *end, | |||
| 1177 | children->flags &= ~ELEMENT_CONDITIONAL; | 1197 | children->flags &= ~ELEMENT_CONDITIONAL; |
| 1178 | 1198 | ||
| 1179 | if (cursor->token_type != TOKEN_CLOSE_CURLY) { | 1199 | if (cursor->token_type != TOKEN_CLOSE_CURLY) { |
| 1180 | fprintf(stderr, "%s:%d: Expected compound closure, got '%*.*s'\n", | 1200 | fprintf(stderr, "%s:%d: Expected compound closure, got '%s'\n", |
| 1181 | filename, cursor->line, | 1201 | filename, cursor->line, cursor->content); |
| 1182 | (int)cursor->size, (int)cursor->size, cursor->value); | ||
| 1183 | exit(1); | 1202 | exit(1); |
| 1184 | } | 1203 | } |
| 1185 | cursor++; | 1204 | cursor++; |
| @@ -1192,6 +1211,52 @@ overrun_error: | |||
| 1192 | exit(1); | 1211 | exit(1); |
| 1193 | } | 1212 | } |
| 1194 | 1213 | ||
| 1214 | static void dump_element(const struct element *e, int level) | ||
| 1215 | { | ||
| 1216 | const struct element *c; | ||
| 1217 | const struct type *t = e->type_def; | ||
| 1218 | const char *name = e->name ? e->name->content : "."; | ||
| 1219 | const char *tname = t && t->name ? t->name->content : "."; | ||
| 1220 | char tag[32]; | ||
| 1221 | |||
| 1222 | if (e->class == 0 && e->method == 0 && e->tag == 0) | ||
| 1223 | strcpy(tag, "<...>"); | ||
| 1224 | else if (e->class == ASN1_UNIV) | ||
| 1225 | sprintf(tag, "%s %s %s", | ||
| 1226 | asn1_classes[e->class], | ||
| 1227 | asn1_methods[e->method], | ||
| 1228 | asn1_universal_tags[e->tag]); | ||
| 1229 | else | ||
| 1230 | sprintf(tag, "%s %s %u", | ||
| 1231 | asn1_classes[e->class], | ||
| 1232 | asn1_methods[e->method], | ||
| 1233 | e->tag); | ||
| 1234 | |||
| 1235 | printf("%c%c%c%c%c %c %*s[*] \e[33m%s\e[m %s %s \e[35m%s\e[m\n", | ||
| 1236 | e->flags & ELEMENT_IMPLICIT ? 'I' : '-', | ||
| 1237 | e->flags & ELEMENT_EXPLICIT ? 'E' : '-', | ||
| 1238 | e->flags & ELEMENT_TAG_SPECIFIED ? 'T' : '-', | ||
| 1239 | e->flags & ELEMENT_SKIPPABLE ? 'S' : '-', | ||
| 1240 | e->flags & ELEMENT_CONDITIONAL ? 'C' : '-', | ||
| 1241 | "-tTqQcaro"[e->compound], | ||
| 1242 | level, "", | ||
| 1243 | tag, | ||
| 1244 | tname, | ||
| 1245 | name, | ||
| 1246 | e->action ? e->action->name : ""); | ||
| 1247 | if (e->compound == TYPE_REF) | ||
| 1248 | dump_element(e->type->type->element, level + 3); | ||
| 1249 | else | ||
| 1250 | for (c = e->children; c; c = c->next) | ||
| 1251 | dump_element(c, level + 3); | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | static void dump_elements(void) | ||
| 1255 | { | ||
| 1256 | if (debug_opt) | ||
| 1257 | dump_element(type_list[0].element, 0); | ||
| 1258 | } | ||
| 1259 | |||
| 1195 | static void render_element(FILE *out, struct element *e, struct element *tag); | 1260 | static void render_element(FILE *out, struct element *e, struct element *tag); |
| 1196 | static void render_out_of_line_list(FILE *out); | 1261 | static void render_out_of_line_list(FILE *out); |
| 1197 | 1262 | ||
| @@ -1293,7 +1358,7 @@ static void render(FILE *out, FILE *hdr) | |||
| 1293 | } | 1358 | } |
| 1294 | 1359 | ||
| 1295 | /* We do two passes - the first one calculates all the offsets */ | 1360 | /* We do two passes - the first one calculates all the offsets */ |
| 1296 | debug("Pass 1\n"); | 1361 | verbose("Pass 1\n"); |
| 1297 | nr_entries = 0; | 1362 | nr_entries = 0; |
| 1298 | root = &type_list[0]; | 1363 | root = &type_list[0]; |
| 1299 | render_element(NULL, root->element, NULL); | 1364 | render_element(NULL, root->element, NULL); |
| @@ -1304,7 +1369,7 @@ static void render(FILE *out, FILE *hdr) | |||
| 1304 | e->flags &= ~ELEMENT_RENDERED; | 1369 | e->flags &= ~ELEMENT_RENDERED; |
| 1305 | 1370 | ||
| 1306 | /* And then we actually render */ | 1371 | /* And then we actually render */ |
| 1307 | debug("Pass 2\n"); | 1372 | verbose("Pass 2\n"); |
| 1308 | fprintf(out, "\n"); | 1373 | fprintf(out, "\n"); |
| 1309 | fprintf(out, "static const unsigned char %s_machine[] = {\n", | 1374 | fprintf(out, "static const unsigned char %s_machine[] = {\n", |
| 1310 | grammar_name); | 1375 | grammar_name); |
| @@ -1390,9 +1455,7 @@ static void render_element(FILE *out, struct element *e, struct element *tag) | |||
| 1390 | outofline = 1; | 1455 | outofline = 1; |
| 1391 | 1456 | ||
| 1392 | if (e->type_def && out) { | 1457 | if (e->type_def && out) { |
| 1393 | render_more(out, "\t// %*.*s\n", | 1458 | render_more(out, "\t// %s\n", e->type_def->name->content); |
| 1394 | (int)e->type_def->name->size, (int)e->type_def->name->size, | ||
| 1395 | e->type_def->name->value); | ||
| 1396 | } | 1459 | } |
| 1397 | 1460 | ||
| 1398 | /* Render the operation */ | 1461 | /* Render the operation */ |
| @@ -1404,9 +1467,7 @@ static void render_element(FILE *out, struct element *e, struct element *tag) | |||
| 1404 | render_opcode(out, "ASN1_OP_%sMATCH_ANY%s%s,", | 1467 | render_opcode(out, "ASN1_OP_%sMATCH_ANY%s%s,", |
| 1405 | cond, act, skippable ? "_OR_SKIP" : ""); | 1468 | cond, act, skippable ? "_OR_SKIP" : ""); |
| 1406 | if (e->name) | 1469 | if (e->name) |
| 1407 | render_more(out, "\t\t// %*.*s", | 1470 | render_more(out, "\t\t// %s", e->name->content); |
| 1408 | (int)e->name->size, (int)e->name->size, | ||
| 1409 | e->name->value); | ||
| 1410 | render_more(out, "\n"); | 1471 | render_more(out, "\n"); |
| 1411 | goto dont_render_tag; | 1472 | goto dont_render_tag; |
| 1412 | 1473 | ||
| @@ -1439,9 +1500,7 @@ static void render_element(FILE *out, struct element *e, struct element *tag) | |||
| 1439 | 1500 | ||
| 1440 | x = tag ?: e; | 1501 | x = tag ?: e; |
| 1441 | if (x->name) | 1502 | if (x->name) |
| 1442 | render_more(out, "\t\t// %*.*s", | 1503 | render_more(out, "\t\t// %s", x->name->content); |
| 1443 | (int)x->name->size, (int)x->name->size, | ||
| 1444 | x->name->value); | ||
| 1445 | render_more(out, "\n"); | 1504 | render_more(out, "\n"); |
| 1446 | 1505 | ||
| 1447 | /* Render the tag */ | 1506 | /* Render the tag */ |
| @@ -1479,10 +1538,8 @@ dont_render_tag: | |||
| 1479 | * skipability */ | 1538 | * skipability */ |
| 1480 | render_opcode(out, "_jump_target(%u),", e->entry_index); | 1539 | render_opcode(out, "_jump_target(%u),", e->entry_index); |
| 1481 | if (e->type_def && e->type_def->name) | 1540 | if (e->type_def && e->type_def->name) |
| 1482 | render_more(out, "\t\t// --> %*.*s", | 1541 | render_more(out, "\t\t// --> %s", |
| 1483 | (int)e->type_def->name->size, | 1542 | e->type_def->name->content); |
| 1484 | (int)e->type_def->name->size, | ||
| 1485 | e->type_def->name->value); | ||
| 1486 | render_more(out, "\n"); | 1543 | render_more(out, "\n"); |
| 1487 | if (!(e->flags & ELEMENT_RENDERED)) { | 1544 | if (!(e->flags & ELEMENT_RENDERED)) { |
| 1488 | e->flags |= ELEMENT_RENDERED; | 1545 | e->flags |= ELEMENT_RENDERED; |
| @@ -1507,10 +1564,8 @@ dont_render_tag: | |||
| 1507 | * skipability */ | 1564 | * skipability */ |
| 1508 | render_opcode(out, "_jump_target(%u),", e->entry_index); | 1565 | render_opcode(out, "_jump_target(%u),", e->entry_index); |
| 1509 | if (e->type_def && e->type_def->name) | 1566 | if (e->type_def && e->type_def->name) |
| 1510 | render_more(out, "\t\t// --> %*.*s", | 1567 | render_more(out, "\t\t// --> %s", |
| 1511 | (int)e->type_def->name->size, | 1568 | e->type_def->name->content); |
| 1512 | (int)e->type_def->name->size, | ||
| 1513 | e->type_def->name->value); | ||
| 1514 | render_more(out, "\n"); | 1569 | render_more(out, "\n"); |
| 1515 | if (!(e->flags & ELEMENT_RENDERED)) { | 1570 | if (!(e->flags & ELEMENT_RENDERED)) { |
| 1516 | e->flags |= ELEMENT_RENDERED; | 1571 | e->flags |= ELEMENT_RENDERED; |
