aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig/expr.c')
-rw-r--r--scripts/kconfig/expr.c288
1 files changed, 163 insertions, 125 deletions
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index d6626521f9b9..667d1aa23711 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -11,6 +11,9 @@
11 11
12#define DEBUG_EXPR 0 12#define DEBUG_EXPR 0
13 13
14static int expr_eq(struct expr *e1, struct expr *e2);
15static struct expr *expr_eliminate_yn(struct expr *e);
16
14struct expr *expr_alloc_symbol(struct symbol *sym) 17struct expr *expr_alloc_symbol(struct symbol *sym)
15{ 18{
16 struct expr *e = xcalloc(1, sizeof(*e)); 19 struct expr *e = xcalloc(1, sizeof(*e));
@@ -76,6 +79,10 @@ struct expr *expr_copy(const struct expr *org)
76 e->left.expr = expr_copy(org->left.expr); 79 e->left.expr = expr_copy(org->left.expr);
77 break; 80 break;
78 case E_EQUAL: 81 case E_EQUAL:
82 case E_GEQ:
83 case E_GTH:
84 case E_LEQ:
85 case E_LTH:
79 case E_UNEQUAL: 86 case E_UNEQUAL:
80 e->left.sym = org->left.sym; 87 e->left.sym = org->left.sym;
81 e->right.sym = org->right.sym; 88 e->right.sym = org->right.sym;
@@ -108,6 +115,10 @@ void expr_free(struct expr *e)
108 expr_free(e->left.expr); 115 expr_free(e->left.expr);
109 return; 116 return;
110 case E_EQUAL: 117 case E_EQUAL:
118 case E_GEQ:
119 case E_GTH:
120 case E_LEQ:
121 case E_LTH:
111 case E_UNEQUAL: 122 case E_UNEQUAL:
112 break; 123 break;
113 case E_OR: 124 case E_OR:
@@ -186,7 +197,7 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
186#undef e1 197#undef e1
187#undef e2 198#undef e2
188 199
189int expr_eq(struct expr *e1, struct expr *e2) 200static int expr_eq(struct expr *e1, struct expr *e2)
190{ 201{
191 int res, old_count; 202 int res, old_count;
192 203
@@ -194,6 +205,10 @@ int expr_eq(struct expr *e1, struct expr *e2)
194 return 0; 205 return 0;
195 switch (e1->type) { 206 switch (e1->type) {
196 case E_EQUAL: 207 case E_EQUAL:
208 case E_GEQ:
209 case E_GTH:
210 case E_LEQ:
211 case E_LTH:
197 case E_UNEQUAL: 212 case E_UNEQUAL:
198 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; 213 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
199 case E_SYMBOL: 214 case E_SYMBOL:
@@ -228,7 +243,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
228 return 0; 243 return 0;
229} 244}
230 245
231struct expr *expr_eliminate_yn(struct expr *e) 246static struct expr *expr_eliminate_yn(struct expr *e)
232{ 247{
233 struct expr *tmp; 248 struct expr *tmp;
234 249
@@ -553,62 +568,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
553#undef e2 568#undef e2
554} 569}
555 570
556static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
557{
558#define e1 (*ep1)
559#define e2 (*ep2)
560 struct expr *tmp, *tmp1, *tmp2;
561
562 if (e1->type == type) {
563 expr_eliminate_dups2(type, &e1->left.expr, &e2);
564 expr_eliminate_dups2(type, &e1->right.expr, &e2);
565 return;
566 }
567 if (e2->type == type) {
568 expr_eliminate_dups2(type, &e1, &e2->left.expr);
569 expr_eliminate_dups2(type, &e1, &e2->right.expr);
570 }
571 if (e1 == e2)
572 return;
573
574 switch (e1->type) {
575 case E_OR:
576 expr_eliminate_dups2(e1->type, &e1, &e1);
577 // (FOO || BAR) && (!FOO && !BAR) -> n
578 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
579 tmp2 = expr_copy(e2);
580 tmp = expr_extract_eq_and(&tmp1, &tmp2);
581 if (expr_is_yes(tmp1)) {
582 expr_free(e1);
583 e1 = expr_alloc_symbol(&symbol_no);
584 trans_count++;
585 }
586 expr_free(tmp2);
587 expr_free(tmp1);
588 expr_free(tmp);
589 break;
590 case E_AND:
591 expr_eliminate_dups2(e1->type, &e1, &e1);
592 // (FOO && BAR) || (!FOO || !BAR) -> y
593 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
594 tmp2 = expr_copy(e2);
595 tmp = expr_extract_eq_or(&tmp1, &tmp2);
596 if (expr_is_no(tmp1)) {
597 expr_free(e1);
598 e1 = expr_alloc_symbol(&symbol_yes);
599 trans_count++;
600 }
601 expr_free(tmp2);
602 expr_free(tmp1);
603 expr_free(tmp);
604 break;
605 default:
606 ;
607 }
608#undef e1
609#undef e2
610}
611
612struct expr *expr_eliminate_dups(struct expr *e) 571struct expr *expr_eliminate_dups(struct expr *e)
613{ 572{
614 int oldcount; 573 int oldcount;
@@ -621,7 +580,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
621 switch (e->type) { 580 switch (e->type) {
622 case E_OR: case E_AND: 581 case E_OR: case E_AND:
623 expr_eliminate_dups1(e->type, &e, &e); 582 expr_eliminate_dups1(e->type, &e, &e);
624 expr_eliminate_dups2(e->type, &e, &e);
625 default: 583 default:
626 ; 584 ;
627 } 585 }
@@ -641,6 +599,10 @@ struct expr *expr_transform(struct expr *e)
641 return NULL; 599 return NULL;
642 switch (e->type) { 600 switch (e->type) {
643 case E_EQUAL: 601 case E_EQUAL:
602 case E_GEQ:
603 case E_GTH:
604 case E_LEQ:
605 case E_LTH:
644 case E_UNEQUAL: 606 case E_UNEQUAL:
645 case E_SYMBOL: 607 case E_SYMBOL:
646 case E_LIST: 608 case E_LIST:
@@ -713,6 +675,22 @@ struct expr *expr_transform(struct expr *e)
713 e = tmp; 675 e = tmp;
714 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; 676 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
715 break; 677 break;
678 case E_LEQ:
679 case E_GEQ:
680 // !a<='x' -> a>'x'
681 tmp = e->left.expr;
682 free(e);
683 e = tmp;
684 e->type = e->type == E_LEQ ? E_GTH : E_LTH;
685 break;
686 case E_LTH:
687 case E_GTH:
688 // !a<'x' -> a>='x'
689 tmp = e->left.expr;
690 free(e);
691 e = tmp;
692 e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
693 break;
716 case E_OR: 694 case E_OR:
717 // !(a || b) -> !a && !b 695 // !(a || b) -> !a && !b
718 tmp = e->left.expr; 696 tmp = e->left.expr;
@@ -783,6 +761,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym)
783 case E_SYMBOL: 761 case E_SYMBOL:
784 return dep->left.sym == sym; 762 return dep->left.sym == sym;
785 case E_EQUAL: 763 case E_EQUAL:
764 case E_GEQ:
765 case E_GTH:
766 case E_LEQ:
767 case E_LTH:
786 case E_UNEQUAL: 768 case E_UNEQUAL:
787 return dep->left.sym == sym || 769 return dep->left.sym == sym ||
788 dep->right.sym == sym; 770 dep->right.sym == sym;
@@ -823,57 +805,6 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
823 return false; 805 return false;
824} 806}
825 807
826struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
827{
828 struct expr *tmp = NULL;
829 expr_extract_eq(E_AND, &tmp, ep1, ep2);
830 if (tmp) {
831 *ep1 = expr_eliminate_yn(*ep1);
832 *ep2 = expr_eliminate_yn(*ep2);
833 }
834 return tmp;
835}
836
837struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
838{
839 struct expr *tmp = NULL;
840 expr_extract_eq(E_OR, &tmp, ep1, ep2);
841 if (tmp) {
842 *ep1 = expr_eliminate_yn(*ep1);
843 *ep2 = expr_eliminate_yn(*ep2);
844 }
845 return tmp;
846}
847
848void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
849{
850#define e1 (*ep1)
851#define e2 (*ep2)
852 if (e1->type == type) {
853 expr_extract_eq(type, ep, &e1->left.expr, &e2);
854 expr_extract_eq(type, ep, &e1->right.expr, &e2);
855 return;
856 }
857 if (e2->type == type) {
858 expr_extract_eq(type, ep, ep1, &e2->left.expr);
859 expr_extract_eq(type, ep, ep1, &e2->right.expr);
860 return;
861 }
862 if (expr_eq(e1, e2)) {
863 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
864 expr_free(e2);
865 if (type == E_AND) {
866 e1 = expr_alloc_symbol(&symbol_yes);
867 e2 = expr_alloc_symbol(&symbol_yes);
868 } else if (type == E_OR) {
869 e1 = expr_alloc_symbol(&symbol_no);
870 e2 = expr_alloc_symbol(&symbol_no);
871 }
872 }
873#undef e1
874#undef e2
875}
876
877struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) 808struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
878{ 809{
879 struct expr *e1, *e2; 810 struct expr *e1, *e2;
@@ -908,6 +839,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
908 case E_NOT: 839 case E_NOT:
909 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); 840 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
910 case E_UNEQUAL: 841 case E_UNEQUAL:
842 case E_LTH:
843 case E_LEQ:
844 case E_GTH:
845 case E_GEQ:
911 case E_EQUAL: 846 case E_EQUAL:
912 if (type == E_EQUAL) { 847 if (type == E_EQUAL) {
913 if (sym == &symbol_yes) 848 if (sym == &symbol_yes)
@@ -935,10 +870,57 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
935 return NULL; 870 return NULL;
936} 871}
937 872
873enum string_value_kind {
874 k_string,
875 k_signed,
876 k_unsigned,
877 k_invalid
878};
879
880union string_value {
881 unsigned long long u;
882 signed long long s;
883};
884
885static enum string_value_kind expr_parse_string(const char *str,
886 enum symbol_type type,
887 union string_value *val)
888{
889 char *tail;
890 enum string_value_kind kind;
891
892 errno = 0;
893 switch (type) {
894 case S_BOOLEAN:
895 case S_TRISTATE:
896 return k_string;
897 case S_INT:
898 val->s = strtoll(str, &tail, 10);
899 kind = k_signed;
900 break;
901 case S_HEX:
902 val->u = strtoull(str, &tail, 16);
903 kind = k_unsigned;
904 break;
905 case S_STRING:
906 case S_UNKNOWN:
907 val->s = strtoll(str, &tail, 0);
908 kind = k_signed;
909 break;
910 default:
911 return k_invalid;
912 }
913 return !errno && !*tail && tail > str && isxdigit(tail[-1])
914 ? kind : k_string;
915}
916
938tristate expr_calc_value(struct expr *e) 917tristate expr_calc_value(struct expr *e)
939{ 918{
940 tristate val1, val2; 919 tristate val1, val2;
941 const char *str1, *str2; 920 const char *str1, *str2;
921 enum string_value_kind k1 = k_string, k2 = k_string;
922 union string_value lval = {}, rval = {};
923 int res;
942 924
943 if (!e) 925 if (!e)
944 return yes; 926 return yes;
@@ -959,31 +941,70 @@ tristate expr_calc_value(struct expr *e)
959 val1 = expr_calc_value(e->left.expr); 941 val1 = expr_calc_value(e->left.expr);
960 return EXPR_NOT(val1); 942 return EXPR_NOT(val1);
961 case E_EQUAL: 943 case E_EQUAL:
962 sym_calc_value(e->left.sym); 944 case E_GEQ:
963 sym_calc_value(e->right.sym); 945 case E_GTH:
964 str1 = sym_get_string_value(e->left.sym); 946 case E_LEQ:
965 str2 = sym_get_string_value(e->right.sym); 947 case E_LTH:
966 return !strcmp(str1, str2) ? yes : no;
967 case E_UNEQUAL: 948 case E_UNEQUAL:
968 sym_calc_value(e->left.sym); 949 break;
969 sym_calc_value(e->right.sym);
970 str1 = sym_get_string_value(e->left.sym);
971 str2 = sym_get_string_value(e->right.sym);
972 return !strcmp(str1, str2) ? no : yes;
973 default: 950 default:
974 printf("expr_calc_value: %d?\n", e->type); 951 printf("expr_calc_value: %d?\n", e->type);
975 return no; 952 return no;
976 } 953 }
954
955 sym_calc_value(e->left.sym);
956 sym_calc_value(e->right.sym);
957 str1 = sym_get_string_value(e->left.sym);
958 str2 = sym_get_string_value(e->right.sym);
959
960 if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
961 k1 = expr_parse_string(str1, e->left.sym->type, &lval);
962 k2 = expr_parse_string(str2, e->right.sym->type, &rval);
963 }
964
965 if (k1 == k_string || k2 == k_string)
966 res = strcmp(str1, str2);
967 else if (k1 == k_invalid || k2 == k_invalid) {
968 if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
969 printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
970 return no;
971 }
972 res = strcmp(str1, str2);
973 } else if (k1 == k_unsigned || k2 == k_unsigned)
974 res = (lval.u > rval.u) - (lval.u < rval.u);
975 else /* if (k1 == k_signed && k2 == k_signed) */
976 res = (lval.s > rval.s) - (lval.s < rval.s);
977
978 switch(e->type) {
979 case E_EQUAL:
980 return res ? no : yes;
981 case E_GEQ:
982 return res >= 0 ? yes : no;
983 case E_GTH:
984 return res > 0 ? yes : no;
985 case E_LEQ:
986 return res <= 0 ? yes : no;
987 case E_LTH:
988 return res < 0 ? yes : no;
989 case E_UNEQUAL:
990 return res ? yes : no;
991 default:
992 printf("expr_calc_value: relation %d?\n", e->type);
993 return no;
994 }
977} 995}
978 996
979int expr_compare_type(enum expr_type t1, enum expr_type t2) 997static int expr_compare_type(enum expr_type t1, enum expr_type t2)
980{ 998{
981#if 0
982 return 1;
983#else
984 if (t1 == t2) 999 if (t1 == t2)
985 return 0; 1000 return 0;
986 switch (t1) { 1001 switch (t1) {
1002 case E_LEQ:
1003 case E_LTH:
1004 case E_GEQ:
1005 case E_GTH:
1006 if (t2 == E_EQUAL || t2 == E_UNEQUAL)
1007 return 1;
987 case E_EQUAL: 1008 case E_EQUAL:
988 case E_UNEQUAL: 1009 case E_UNEQUAL:
989 if (t2 == E_NOT) 1010 if (t2 == E_NOT)
@@ -1005,7 +1026,6 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
1005 } 1026 }
1006 printf("[%dgt%d?]", t1, t2); 1027 printf("[%dgt%d?]", t1, t2);
1007 return 0; 1028 return 0;
1008#endif
1009} 1029}
1010 1030
1011static inline struct expr * 1031static inline struct expr *
@@ -1078,6 +1098,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
1078 fn(data, NULL, "="); 1098 fn(data, NULL, "=");
1079 fn(data, e->right.sym, e->right.sym->name); 1099 fn(data, e->right.sym, e->right.sym->name);
1080 break; 1100 break;
1101 case E_LEQ:
1102 case E_LTH:
1103 if (e->left.sym->name)
1104 fn(data, e->left.sym, e->left.sym->name);
1105 else
1106 fn(data, NULL, "<choice>");
1107 fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
1108 fn(data, e->right.sym, e->right.sym->name);
1109 break;
1110 case E_GEQ:
1111 case E_GTH:
1112 if (e->left.sym->name)
1113 fn(data, e->left.sym, e->left.sym->name);
1114 else
1115 fn(data, NULL, "<choice>");
1116 fn(data, NULL, e->type == E_LEQ ? ">=" : ">");
1117 fn(data, e->right.sym, e->right.sym->name);
1118 break;
1081 case E_UNEQUAL: 1119 case E_UNEQUAL:
1082 if (e->left.sym->name) 1120 if (e->left.sym->name)
1083 fn(data, e->left.sym, e->left.sym->name); 1121 fn(data, e->left.sym, e->left.sym->name);