aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2015-06-15 08:00:21 -0400
committerMichal Marek <mmarek@suse.cz>2015-06-15 08:05:58 -0400
commit31847b67bec0e989961118520406a63fdeac7246 (patch)
tree1c38fb180047884dd1428b1d84beccf78c37ccc7 /scripts
parent2e0d737fc76f8d31e2265b3f0392749f75efd735 (diff)
kconfig: allow use of relations other than (in)equality
Over the years I found it desirable to be able to use all sorts of relations, not just (in)equality. And apparently I'm not the only one, as there's at least one example in the tree where the programmer assumed this would work (see DEBUG_UART_8250_WORD in arch/arm/Kconfig.debug). Another possible use would e.g. be to fold the two SMP/NR_CPUS prompts into one: SMP could be promptless, simply depending on NR_CPUS > 1. A (desirable) side effect of this change - resulting from numeric values now necessarily being compared as numbers rather than as strings - is that comparing hex values now works as expected: Other than int ones (which aren't allowed to have leading zeroes), zeroes following the 0x prefix made them compare unequal even if their values were equal. Signed-off-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Michal Marek <mmarek@suse.cz>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/kconfig/expr.c167
-rw-r--r--scripts/kconfig/expr.h4
-rw-r--r--scripts/kconfig/symbol.c4
-rw-r--r--scripts/kconfig/zconf.l4
-rw-r--r--scripts/kconfig/zconf.y9
5 files changed, 177 insertions, 11 deletions
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 0d7364ce9132..667d1aa23711 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -79,6 +79,10 @@ struct expr *expr_copy(const struct expr *org)
79 e->left.expr = expr_copy(org->left.expr); 79 e->left.expr = expr_copy(org->left.expr);
80 break; 80 break;
81 case E_EQUAL: 81 case E_EQUAL:
82 case E_GEQ:
83 case E_GTH:
84 case E_LEQ:
85 case E_LTH:
82 case E_UNEQUAL: 86 case E_UNEQUAL:
83 e->left.sym = org->left.sym; 87 e->left.sym = org->left.sym;
84 e->right.sym = org->right.sym; 88 e->right.sym = org->right.sym;
@@ -111,6 +115,10 @@ void expr_free(struct expr *e)
111 expr_free(e->left.expr); 115 expr_free(e->left.expr);
112 return; 116 return;
113 case E_EQUAL: 117 case E_EQUAL:
118 case E_GEQ:
119 case E_GTH:
120 case E_LEQ:
121 case E_LTH:
114 case E_UNEQUAL: 122 case E_UNEQUAL:
115 break; 123 break;
116 case E_OR: 124 case E_OR:
@@ -197,6 +205,10 @@ static int expr_eq(struct expr *e1, struct expr *e2)
197 return 0; 205 return 0;
198 switch (e1->type) { 206 switch (e1->type) {
199 case E_EQUAL: 207 case E_EQUAL:
208 case E_GEQ:
209 case E_GTH:
210 case E_LEQ:
211 case E_LTH:
200 case E_UNEQUAL: 212 case E_UNEQUAL:
201 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;
202 case E_SYMBOL: 214 case E_SYMBOL:
@@ -587,6 +599,10 @@ struct expr *expr_transform(struct expr *e)
587 return NULL; 599 return NULL;
588 switch (e->type) { 600 switch (e->type) {
589 case E_EQUAL: 601 case E_EQUAL:
602 case E_GEQ:
603 case E_GTH:
604 case E_LEQ:
605 case E_LTH:
590 case E_UNEQUAL: 606 case E_UNEQUAL:
591 case E_SYMBOL: 607 case E_SYMBOL:
592 case E_LIST: 608 case E_LIST:
@@ -659,6 +675,22 @@ struct expr *expr_transform(struct expr *e)
659 e = tmp; 675 e = tmp;
660 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; 676 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
661 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;
662 case E_OR: 694 case E_OR:
663 // !(a || b) -> !a && !b 695 // !(a || b) -> !a && !b
664 tmp = e->left.expr; 696 tmp = e->left.expr;
@@ -729,6 +761,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym)
729 case E_SYMBOL: 761 case E_SYMBOL:
730 return dep->left.sym == sym; 762 return dep->left.sym == sym;
731 case E_EQUAL: 763 case E_EQUAL:
764 case E_GEQ:
765 case E_GTH:
766 case E_LEQ:
767 case E_LTH:
732 case E_UNEQUAL: 768 case E_UNEQUAL:
733 return dep->left.sym == sym || 769 return dep->left.sym == sym ||
734 dep->right.sym == sym; 770 dep->right.sym == sym;
@@ -803,6 +839,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
803 case E_NOT: 839 case E_NOT:
804 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);
805 case E_UNEQUAL: 841 case E_UNEQUAL:
842 case E_LTH:
843 case E_LEQ:
844 case E_GTH:
845 case E_GEQ:
806 case E_EQUAL: 846 case E_EQUAL:
807 if (type == E_EQUAL) { 847 if (type == E_EQUAL) {
808 if (sym == &symbol_yes) 848 if (sym == &symbol_yes)
@@ -830,10 +870,57 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
830 return NULL; 870 return NULL;
831} 871}
832 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
833tristate expr_calc_value(struct expr *e) 917tristate expr_calc_value(struct expr *e)
834{ 918{
835 tristate val1, val2; 919 tristate val1, val2;
836 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;
837 924
838 if (!e) 925 if (!e)
839 return yes; 926 return yes;
@@ -854,21 +941,57 @@ tristate expr_calc_value(struct expr *e)
854 val1 = expr_calc_value(e->left.expr); 941 val1 = expr_calc_value(e->left.expr);
855 return EXPR_NOT(val1); 942 return EXPR_NOT(val1);
856 case E_EQUAL: 943 case E_EQUAL:
857 sym_calc_value(e->left.sym); 944 case E_GEQ:
858 sym_calc_value(e->right.sym); 945 case E_GTH:
859 str1 = sym_get_string_value(e->left.sym); 946 case E_LEQ:
860 str2 = sym_get_string_value(e->right.sym); 947 case E_LTH:
861 return !strcmp(str1, str2) ? yes : no;
862 case E_UNEQUAL: 948 case E_UNEQUAL:
863 sym_calc_value(e->left.sym); 949 break;
864 sym_calc_value(e->right.sym);
865 str1 = sym_get_string_value(e->left.sym);
866 str2 = sym_get_string_value(e->right.sym);
867 return !strcmp(str1, str2) ? no : yes;
868 default: 950 default:
869 printf("expr_calc_value: %d?\n", e->type); 951 printf("expr_calc_value: %d?\n", e->type);
870 return no; 952 return no;
871 } 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 }
872} 995}
873 996
874static int expr_compare_type(enum expr_type t1, enum expr_type t2) 997static int expr_compare_type(enum expr_type t1, enum expr_type t2)
@@ -876,6 +999,12 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
876 if (t1 == t2) 999 if (t1 == t2)
877 return 0; 1000 return 0;
878 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;
879 case E_EQUAL: 1008 case E_EQUAL:
880 case E_UNEQUAL: 1009 case E_UNEQUAL:
881 if (t2 == E_NOT) 1010 if (t2 == E_NOT)
@@ -969,6 +1098,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
969 fn(data, NULL, "="); 1098 fn(data, NULL, "=");
970 fn(data, e->right.sym, e->right.sym->name); 1099 fn(data, e->right.sym, e->right.sym->name);
971 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;
972 case E_UNEQUAL: 1119 case E_UNEQUAL:
973 if (e->left.sym->name) 1120 if (e->left.sym->name)
974 fn(data, e->left.sym, e->left.sym->name); 1121 fn(data, e->left.sym, e->left.sym->name);
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index a2fc96a2bd2c..973b6f733368 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -29,7 +29,9 @@ typedef enum tristate {
29} tristate; 29} tristate;
30 30
31enum expr_type { 31enum expr_type {
32 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE 32 E_NONE, E_OR, E_AND, E_NOT,
33 E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ,
34 E_LIST, E_SYMBOL, E_RANGE
33}; 35};
34 36
35union expr_data { 37union expr_data {
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 6731377f9bb2..70c5ee189dce 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -1166,6 +1166,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
1166 case E_NOT: 1166 case E_NOT:
1167 return sym_check_expr_deps(e->left.expr); 1167 return sym_check_expr_deps(e->left.expr);
1168 case E_EQUAL: 1168 case E_EQUAL:
1169 case E_GEQ:
1170 case E_GTH:
1171 case E_LEQ:
1172 case E_LTH:
1169 case E_UNEQUAL: 1173 case E_UNEQUAL:
1170 sym = sym_check_deps(e->left.sym); 1174 sym = sym_check_deps(e->left.sym);
1171 if (sym) 1175 if (sym)
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 16741396d264..200a3fe30091 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -122,6 +122,10 @@ n [A-Za-z0-9_]
122 "!" return T_NOT; 122 "!" return T_NOT;
123 "=" return T_EQUAL; 123 "=" return T_EQUAL;
124 "!=" return T_UNEQUAL; 124 "!=" return T_UNEQUAL;
125 "<=" return T_LESS_EQUAL;
126 ">=" return T_GREATER_EQUAL;
127 "<" return T_LESS;
128 ">" return T_GREATER;
125 \"|\' { 129 \"|\' {
126 str = yytext[0]; 130 str = yytext[0];
127 new_string(); 131 new_string();
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 0f683cfa53e9..71bf8bff696a 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -69,6 +69,10 @@ static struct menu *current_menu, *current_entry;
69%token <string> T_WORD 69%token <string> T_WORD
70%token <string> T_WORD_QUOTE 70%token <string> T_WORD_QUOTE
71%token T_UNEQUAL 71%token T_UNEQUAL
72%token T_LESS
73%token T_LESS_EQUAL
74%token T_GREATER
75%token T_GREATER_EQUAL
72%token T_CLOSE_PAREN 76%token T_CLOSE_PAREN
73%token T_OPEN_PAREN 77%token T_OPEN_PAREN
74%token T_EOL 78%token T_EOL
@@ -76,6 +80,7 @@ static struct menu *current_menu, *current_entry;
76%left T_OR 80%left T_OR
77%left T_AND 81%left T_AND
78%left T_EQUAL T_UNEQUAL 82%left T_EQUAL T_UNEQUAL
83%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
79%nonassoc T_NOT 84%nonassoc T_NOT
80 85
81%type <string> prompt 86%type <string> prompt
@@ -467,6 +472,10 @@ if_expr: /* empty */ { $$ = NULL; }
467; 472;
468 473
469expr: symbol { $$ = expr_alloc_symbol($1); } 474expr: symbol { $$ = expr_alloc_symbol($1); }
475 | symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); }
476 | symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); }
477 | symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); }
478 | symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); }
470 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } 479 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
471 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } 480 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
472 | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } 481 | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }