diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-08-22 01:15:00 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-08-22 01:15:00 +0200 |
commit | a122b52d66464db7310022872e9eed1e55ea980c (patch) | |
tree | 0671177f49adce02f79447f557145b8a5254df14 /utils/imxtools | |
parent | 81f97f67e2638623abe3ba4094bffea563832355 (diff) | |
download | rockbox-a122b52d66464db7310022872e9eed1e55ea980c.tar.gz rockbox-a122b52d66464db7310022872e9eed1e55ea980c.zip |
sbtools: factor code in command parser
Change-Id: I790c373b8a0319cdb00650d3c59919bd4b0b96f6
Diffstat (limited to 'utils/imxtools')
-rw-r--r-- | utils/imxtools/sbtools/dbparser.c | 102 |
1 files changed, 19 insertions, 83 deletions
diff --git a/utils/imxtools/sbtools/dbparser.c b/utils/imxtools/sbtools/dbparser.c index 414b771617..6cba91f34b 100644 --- a/utils/imxtools/sbtools/dbparser.c +++ b/utils/imxtools/sbtools/dbparser.c | |||
@@ -582,15 +582,7 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
582 | 582 | ||
583 | /* add initial constants */ | 583 | /* add initial constants */ |
584 | for(int i = 0; i < NR_INITIAL_CONSTANTS; i++) | 584 | for(int i = 0; i < NR_INITIAL_CONSTANTS; i++) |
585 | { | 585 | db_add_int_opt(&cmd_file->constant_list, init_const_name[i], init_const_value[i]); |
586 | struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); | ||
587 | memset(opt, 0, sizeof(struct cmd_option_t)); | ||
588 | opt->name = strdup(init_const_name[i]); | ||
589 | opt->is_string = false; | ||
590 | opt->val = init_const_value[i]; | ||
591 | opt->next = cmd_file->constant_list; | ||
592 | cmd_file->constant_list = opt; | ||
593 | } | ||
594 | 586 | ||
595 | struct lex_ctx_t lctx; | 587 | struct lex_ctx_t lctx; |
596 | lctx.ctx.file = file; | 588 | lctx.ctx.file = file; |
@@ -611,22 +603,17 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
611 | 603 | ||
612 | while(true) | 604 | while(true) |
613 | { | 605 | { |
614 | struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); | ||
615 | memset(opt, 0, sizeof(struct cmd_option_t)); | ||
616 | next(true); | 606 | next(true); |
617 | if(lexem.type == LEX_RBRACE) | 607 | if(lexem.type == LEX_RBRACE) |
618 | break; | 608 | break; |
619 | if(lexem.type != LEX_IDENTIFIER) | 609 | if(lexem.type != LEX_IDENTIFIER) |
620 | parse_error(lexem, "Identifier expected in constants\n"); | 610 | parse_error(lexem, "Identifier expected in constants\n"); |
621 | opt->name = lexem.str; | 611 | const char *name = lexem.str; |
622 | next(false); /* lexem string is kept as option name */ | 612 | next(false); /* lexem string is kept as option name */ |
623 | if(lexem.type != LEX_EQUAL) | 613 | if(lexem.type != LEX_EQUAL) |
624 | parse_error(lexem, "'=' expected after identifier\n"); | 614 | parse_error(lexem, "'=' expected after identifier\n"); |
625 | next(true); | 615 | next(true); |
626 | opt->is_string = false; | 616 | db_add_int_opt(&cmd_file->constant_list, name, parse_intexpr(&lctx, cmd_file->constant_list)); |
627 | opt->val = parse_intexpr(&lctx, cmd_file->constant_list); | ||
628 | opt->next = cmd_file->constant_list; | ||
629 | cmd_file->constant_list = opt; | ||
630 | if(lexem.type != LEX_SEMICOLON) | 617 | if(lexem.type != LEX_SEMICOLON) |
631 | parse_error(lexem, "';' expected after string\n"); | 618 | parse_error(lexem, "';' expected after string\n"); |
632 | } | 619 | } |
@@ -644,28 +631,20 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
644 | next(true); | 631 | next(true); |
645 | if(lexem.type == LEX_RBRACE) | 632 | if(lexem.type == LEX_RBRACE) |
646 | break; | 633 | break; |
647 | struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); | ||
648 | memset(opt, 0, sizeof(struct cmd_option_t)); | ||
649 | if(lexem.type != LEX_IDENTIFIER) | 634 | if(lexem.type != LEX_IDENTIFIER) |
650 | parse_error(lexem, "Identifier expected in options\n"); | 635 | parse_error(lexem, "Identifier expected in options\n"); |
651 | opt->name = lexem.str; | 636 | const char *name = lexem.str; |
652 | next(false); /* lexem string is kept as option name */ | 637 | next(false); /* lexem string is kept as option name */ |
653 | if(lexem.type != LEX_EQUAL) | 638 | if(lexem.type != LEX_EQUAL) |
654 | parse_error(lexem, "'=' expected after identifier\n"); | 639 | parse_error(lexem, "'=' expected after identifier\n"); |
655 | next(true); | 640 | next(true); |
656 | if(lexem.type == LEX_STRING) | 641 | if(lexem.type == LEX_STRING) |
657 | { | 642 | { |
658 | opt->is_string = true; | 643 | db_add_str_opt(&cmd_file->opt_list, name, lexem.str); |
659 | opt->str = lexem.str; | 644 | next(true); |
660 | next(false); /* lexem string is kept as option name */ | ||
661 | } | 645 | } |
662 | else | 646 | else |
663 | { | 647 | db_add_int_opt(&cmd_file->opt_list, name, parse_intexpr(&lctx, cmd_file->constant_list)); |
664 | opt->is_string = false; | ||
665 | opt->val = parse_intexpr(&lctx, cmd_file->constant_list); | ||
666 | } | ||
667 | opt->next = cmd_file->opt_list; | ||
668 | cmd_file->opt_list = opt; | ||
669 | if(lexem.type != LEX_SEMICOLON) | 648 | if(lexem.type != LEX_SEMICOLON) |
670 | parse_error(lexem, "';' expected after string\n"); | 649 | parse_error(lexem, "';' expected after string\n"); |
671 | } | 650 | } |
@@ -683,30 +662,27 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
683 | next(true); | 662 | next(true); |
684 | if(lexem.type == LEX_RBRACE) | 663 | if(lexem.type == LEX_RBRACE) |
685 | break; | 664 | break; |
686 | struct cmd_source_t *src = xmalloc(sizeof(struct cmd_source_t)); | ||
687 | memset(src, 0, sizeof(struct cmd_source_t)); | ||
688 | if(lexem.type != LEX_IDENTIFIER) | 665 | if(lexem.type != LEX_IDENTIFIER) |
689 | parse_error(lexem, "identifier expected in sources\n"); | 666 | parse_error(lexem, "identifier expected in sources\n"); |
690 | src->identifier = lexem.str; | 667 | const char *srcid = lexem.str; |
668 | if(db_find_source_by_id(cmd_file, srcid) != NULL) | ||
669 | parse_error(lexem, "Duplicate source identifier\n"); | ||
691 | next(false); /* lexem string is kept as source name */ | 670 | next(false); /* lexem string is kept as source name */ |
692 | if(lexem.type != LEX_EQUAL) | 671 | if(lexem.type != LEX_EQUAL) |
693 | parse_error(lexem, "'=' expected after identifier\n"); | 672 | parse_error(lexem, "'=' expected after identifier\n"); |
694 | next(true); | 673 | next(true); |
695 | if(lexem.type == LEX_STRING) | 674 | if(lexem.type == LEX_STRING) |
696 | { | 675 | { |
697 | src->is_extern = false; | 676 | db_add_source(cmd_file, srcid, lexem.str); |
698 | src->filename = lexem.str; | 677 | next(true); |
699 | next(false); /* lexem string is kept as file name */ | ||
700 | } | 678 | } |
701 | else if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "extern")) | 679 | else if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "extern")) |
702 | { | 680 | { |
703 | src->is_extern = true; | ||
704 | src->filename = strdup("<extern>"); /* duplicate because it will be free'd */ | ||
705 | next(true); | 681 | next(true); |
706 | if(lexem.type != LEX_LPAREN) | 682 | if(lexem.type != LEX_LPAREN) |
707 | parse_error(lexem, "'(' expected after 'extern'\n"); | 683 | parse_error(lexem, "'(' expected after 'extern'\n"); |
708 | next(true); | 684 | next(true); |
709 | src->extern_nr = parse_intexpr(&lctx, cmd_file->constant_list); | 685 | db_add_extern_source(cmd_file, srcid, parse_intexpr(&lctx, cmd_file->constant_list)); |
710 | if(lexem.type != LEX_RPAREN) | 686 | if(lexem.type != LEX_RPAREN) |
711 | parse_error(lexem, "')' expected\n"); | 687 | parse_error(lexem, "')' expected\n"); |
712 | next(true); | 688 | next(true); |
@@ -715,24 +691,14 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
715 | parse_error(lexem, "String or 'extern' expected after '='\n"); | 691 | parse_error(lexem, "String or 'extern' expected after '='\n"); |
716 | if(lexem.type != LEX_SEMICOLON) | 692 | if(lexem.type != LEX_SEMICOLON) |
717 | parse_error(lexem, "';' expected\n"); | 693 | parse_error(lexem, "';' expected\n"); |
718 | if(db_find_source_by_id(cmd_file, src->identifier) != NULL) | ||
719 | parse_error(lexem, "Duplicate source identifier\n"); | ||
720 | /* type filled later */ | ||
721 | src->type = CMD_SRC_UNK; | ||
722 | src->next = cmd_file->source_list; | ||
723 | cmd_file->source_list = src; | ||
724 | } | 694 | } |
725 | 695 | ||
726 | /* sections */ | 696 | /* sections */ |
727 | struct cmd_section_t *end_sec = NULL; | ||
728 | while(true) | 697 | while(true) |
729 | { | 698 | { |
730 | next(true); | 699 | next(true); |
731 | if(lexem.type == LEX_EOF) | 700 | if(lexem.type == LEX_EOF) |
732 | break; | 701 | break; |
733 | struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t)); | ||
734 | struct cmd_inst_t *end_list = NULL; | ||
735 | memset(sec, 0, sizeof(struct cmd_section_t)); | ||
736 | if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0) | 702 | if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0) |
737 | parse_error(lexem, "'section' expected\n"); | 703 | parse_error(lexem, "'section' expected\n"); |
738 | next(true); | 704 | next(true); |
@@ -740,35 +706,27 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
740 | parse_error(lexem, "'(' expected after 'section'\n"); | 706 | parse_error(lexem, "'(' expected after 'section'\n"); |
741 | next(true); | 707 | next(true); |
742 | /* can be any number */ | 708 | /* can be any number */ |
743 | sec->identifier = parse_intexpr(&lctx, cmd_file->constant_list); | 709 | struct cmd_section_t *sec = db_add_section(cmd_file, parse_intexpr(&lctx, cmd_file->constant_list), false); |
744 | /* options ? */ | 710 | /* options ? */ |
745 | if(lexem.type == LEX_SEMICOLON) | 711 | if(lexem.type == LEX_SEMICOLON) |
746 | { | 712 | { |
747 | do | 713 | do |
748 | { | 714 | { |
749 | next(true); | 715 | next(true); |
750 | struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); | ||
751 | memset(opt, 0, sizeof(struct cmd_option_t)); | ||
752 | if(lexem.type != LEX_IDENTIFIER) | 716 | if(lexem.type != LEX_IDENTIFIER) |
753 | parse_error(lexem, "Identifier expected for section option\n"); | 717 | parse_error(lexem, "Identifier expected for section option\n"); |
754 | opt->name = lexem.str; | 718 | const char *name = lexem.str; |
755 | next(false); /* lexem string is kept as option name */ | 719 | next(false); /* lexem string is kept as option name */ |
756 | if(lexem.type != LEX_EQUAL) | 720 | if(lexem.type != LEX_EQUAL) |
757 | parse_error(lexem, "'=' expected after option identifier\n"); | 721 | parse_error(lexem, "'=' expected after option identifier\n"); |
758 | next(true); | 722 | next(true); |
759 | if(lexem.type == LEX_STRING) | 723 | if(lexem.type == LEX_STRING) |
760 | { | 724 | { |
761 | opt->is_string = true; | 725 | db_add_str_opt(&sec->opt_list, name, lexem.str); |
762 | opt->str = lexem.str; | 726 | next(true); |
763 | next(false); /* lexem string is kept as option string */ | ||
764 | } | 727 | } |
765 | else | 728 | else |
766 | { | 729 | db_add_int_opt(&sec->opt_list, name, parse_intexpr(&lctx, cmd_file->constant_list)); |
767 | opt->is_string = false; | ||
768 | opt->val = parse_intexpr(&lctx, cmd_file->constant_list); | ||
769 | } | ||
770 | opt->next = sec->opt_list; | ||
771 | sec->opt_list = opt; | ||
772 | }while(lexem.type == LEX_COLON); | 730 | }while(lexem.type == LEX_COLON); |
773 | } | 731 | } |
774 | if(lexem.type != LEX_RPAREN) | 732 | if(lexem.type != LEX_RPAREN) |
@@ -783,8 +741,7 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
783 | next(true); | 741 | next(true); |
784 | if(lexem.type == LEX_RBRACE) | 742 | if(lexem.type == LEX_RBRACE) |
785 | break; | 743 | break; |
786 | struct cmd_inst_t *inst = xmalloc(sizeof(struct cmd_inst_t)); | 744 | struct cmd_inst_t *inst = db_add_inst(&sec->inst_list, CMD_LOAD, 0); |
787 | memset(inst, 0, sizeof(struct cmd_inst_t)); | ||
788 | if(lexem.type != LEX_IDENTIFIER) | 745 | if(lexem.type != LEX_IDENTIFIER) |
789 | parse_error(lexem, "Instruction expected in section\n"); | 746 | parse_error(lexem, "Instruction expected in section\n"); |
790 | if(strcmp(lexem.str, "load") == 0) | 747 | if(strcmp(lexem.str, "load") == 0) |
@@ -851,16 +808,6 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
851 | } | 808 | } |
852 | else | 809 | else |
853 | parse_error(lexem, "Internal error"); | 810 | parse_error(lexem, "Internal error"); |
854 | if(end_list == NULL) | ||
855 | { | ||
856 | sec->inst_list = inst; | ||
857 | end_list = inst; | ||
858 | } | ||
859 | else | ||
860 | { | ||
861 | end_list->next = inst; | ||
862 | end_list = inst; | ||
863 | } | ||
864 | } | 811 | } |
865 | } | 812 | } |
866 | else if(lexem.type == LEX_LE) | 813 | else if(lexem.type == LEX_LE) |
@@ -876,17 +823,6 @@ struct cmd_file_t *db_parse_file(const char *file) | |||
876 | } | 823 | } |
877 | else | 824 | else |
878 | parse_error(lexem, "'{' or '<=' expected after section directive\n"); | 825 | parse_error(lexem, "'{' or '<=' expected after section directive\n"); |
879 | |||
880 | if(end_sec == NULL) | ||
881 | { | ||
882 | cmd_file->section_list = sec; | ||
883 | end_sec = sec; | ||
884 | } | ||
885 | else | ||
886 | { | ||
887 | end_sec->next = sec; | ||
888 | end_sec = sec; | ||
889 | } | ||
890 | } | 826 | } |
891 | #undef lexem | 827 | #undef lexem |
892 | #undef next | 828 | #undef next |