Commit a95cb3cd authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild

Pull kconfig updates from Michal Marek:

 - kconfig conditions can use usual less/greater than comparisons

 - kconfig warns about stray characters in Kconfig files

 - bogus expression simplification removed

 - some minor fixes

* 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild:
  kconfig: re-generate *.c_shipped files after previous change
  kconfig: allow use of relations other than (in)equality
  kconfig: don't silently ignore unhandled characters
  kconfig: Wrap long "make help" text lines
  scripts/kconfig/Makefile: Cosmetic fixes
  scripts/kconfig/Makefile: Fix spelling of Qt
  Kconfig: Remove bad inference rules expr_eliminate_dups2()
parents 19127af9 4a47f1eb
......@@ -86,7 +86,7 @@ $(simple-targets): $(obj)/conf
PHONY += oldnoconfig savedefconfig defconfig
# oldnoconfig is an alias of olddefconfig, because people already are dependent
# on its behavior(sets new symbols to their default value but not 'n') with the
# on its behavior (sets new symbols to their default value but not 'n') with the
# counter-intuitive name.
oldnoconfig: olddefconfig
......@@ -126,10 +126,11 @@ tinyconfig:
# Help text used by make help
help:
@echo ' config - Update current config utilising a line-oriented program'
@echo ' nconfig - Update current config utilising a ncurses menu based program'
@echo ' nconfig - Update current config utilising a ncurses menu based'
@echo ' program'
@echo ' menuconfig - Update current config utilising a menu based program'
@echo ' xconfig - Update current config utilising a QT based front-end'
@echo ' gconfig - Update current config utilising a GTK based front-end'
@echo ' xconfig - Update current config utilising a Qt based front-end'
@echo ' gconfig - Update current config utilising a GTK+ based front-end'
@echo ' oldconfig - Update current config utilising a provided .config as base'
@echo ' localmodconfig - Update current config disabling modules not loaded'
@echo ' localyesconfig - Update current config converting local mods to core'
......@@ -142,7 +143,8 @@ help:
@echo ' alldefconfig - New config with all symbols set to default'
@echo ' randconfig - New config with random answer to all options'
@echo ' listnewconfig - List new options'
@echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value'
@echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their'
@echo ' default value'
@echo ' kvmconfig - Enable additional options for kvm guest kernel support'
@echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support'
@echo ' tinyconfig - Configure the tiniest possible kernel'
......@@ -163,9 +165,9 @@ HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
# mconf: Used for the menuconfig target
# Utilizes the lxdialog package
# qconf: Used for the xconfig target
# Based on QT which needs to be installed to compile it
# Based on Qt which needs to be installed to compile it
# gconf: Used for the gconfig target
# Based on GTK which needs to be installed to compile it
# Based on GTK+ which needs to be installed to compile it
# object files used by all kconfig flavours
lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
......@@ -222,11 +224,11 @@ ifeq ($(MAKECMDGOALS),xconfig)
$(obj)/.tmp_qtcheck: $(src)/Makefile
-include $(obj)/.tmp_qtcheck
# QT needs some extra effort...
# Qt needs some extra effort...
$(obj)/.tmp_qtcheck:
@set -e; $(kecho) " CHECK qt"; dir=""; pkg=""; \
if ! pkg-config --exists QtCore 2> /dev/null; then \
echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \
echo "* Unable to find the Qt4 tool qmake. Trying to use Qt3"; \
pkg-config --exists qt 2> /dev/null && pkg=qt; \
pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
if [ -n "$$pkg" ]; then \
......@@ -240,8 +242,8 @@ $(obj)/.tmp_qtcheck:
done; \
if [ -z "$$dir" ]; then \
echo >&2 "*"; \
echo >&2 "* Unable to find any QT installation. Please make sure that"; \
echo >&2 "* the QT4 or QT3 development package is correctly installed and"; \
echo >&2 "* Unable to find any Qt installation. Please make sure that"; \
echo >&2 "* the Qt4 or Qt3 development package is correctly installed and"; \
echo >&2 "* either qmake can be found or install pkg-config or set"; \
echo >&2 "* the QTDIR environment variable to the correct location."; \
echo >&2 "*"; \
......@@ -278,7 +280,7 @@ $(obj)/gconf.o: $(obj)/.tmp_gtkcheck
ifeq ($(MAKECMDGOALS),gconfig)
-include $(obj)/.tmp_gtkcheck
# GTK needs some extra effort, too...
# GTK+ needs some extra effort, too...
$(obj)/.tmp_gtkcheck:
@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \
if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \
......@@ -309,7 +311,7 @@ quiet_cmd_moc = MOC $@
$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck
$(call cmd,moc)
# Extract gconf menu items for I18N support
# Extract gconf menu items for i18n support
$(obj)/gconf.glade.h: $(obj)/gconf.glade
$(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \
$(obj)/gconf.glade
......@@ -13,9 +13,6 @@
static int expr_eq(struct expr *e1, struct expr *e2);
static struct expr *expr_eliminate_yn(struct expr *e);
static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
struct expr *expr_alloc_symbol(struct symbol *sym)
{
......@@ -82,6 +79,10 @@ struct expr *expr_copy(const struct expr *org)
e->left.expr = expr_copy(org->left.expr);
break;
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
e->left.sym = org->left.sym;
e->right.sym = org->right.sym;
......@@ -114,6 +115,10 @@ void expr_free(struct expr *e)
expr_free(e->left.expr);
return;
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
break;
case E_OR:
......@@ -200,6 +205,10 @@ static int expr_eq(struct expr *e1, struct expr *e2)
return 0;
switch (e1->type) {
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
case E_SYMBOL:
......@@ -559,62 +568,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
#undef e2
}
static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
struct expr *tmp, *tmp1, *tmp2;
if (e1->type == type) {
expr_eliminate_dups2(type, &e1->left.expr, &e2);
expr_eliminate_dups2(type, &e1->right.expr, &e2);
return;
}
if (e2->type == type) {
expr_eliminate_dups2(type, &e1, &e2->left.expr);
expr_eliminate_dups2(type, &e1, &e2->right.expr);
}
if (e1 == e2)
return;
switch (e1->type) {
case E_OR:
expr_eliminate_dups2(e1->type, &e1, &e1);
// (FOO || BAR) && (!FOO && !BAR) -> n
tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
tmp2 = expr_copy(e2);
tmp = expr_extract_eq_and(&tmp1, &tmp2);
if (expr_is_yes(tmp1)) {
expr_free(e1);
e1 = expr_alloc_symbol(&symbol_no);
trans_count++;
}
expr_free(tmp2);
expr_free(tmp1);
expr_free(tmp);
break;
case E_AND:
expr_eliminate_dups2(e1->type, &e1, &e1);
// (FOO && BAR) || (!FOO || !BAR) -> y
tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
tmp2 = expr_copy(e2);
tmp = expr_extract_eq_or(&tmp1, &tmp2);
if (expr_is_no(tmp1)) {
expr_free(e1);
e1 = expr_alloc_symbol(&symbol_yes);
trans_count++;
}
expr_free(tmp2);
expr_free(tmp1);
expr_free(tmp);
break;
default:
;
}
#undef e1
#undef e2
}
struct expr *expr_eliminate_dups(struct expr *e)
{
int oldcount;
......@@ -627,7 +580,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
switch (e->type) {
case E_OR: case E_AND:
expr_eliminate_dups1(e->type, &e, &e);
expr_eliminate_dups2(e->type, &e, &e);
default:
;
}
......@@ -647,6 +599,10 @@ struct expr *expr_transform(struct expr *e)
return NULL;
switch (e->type) {
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
case E_SYMBOL:
case E_LIST:
......@@ -719,6 +675,22 @@ struct expr *expr_transform(struct expr *e)
e = tmp;
e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
break;
case E_LEQ:
case E_GEQ:
// !a<='x' -> a>'x'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = e->type == E_LEQ ? E_GTH : E_LTH;
break;
case E_LTH:
case E_GTH:
// !a<'x' -> a>='x'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
break;
case E_OR:
// !(a || b) -> !a && !b
tmp = e->left.expr;
......@@ -789,6 +761,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym)
case E_SYMBOL:
return dep->left.sym == sym;
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
return dep->left.sym == sym ||
dep->right.sym == sym;
......@@ -829,57 +805,6 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
return false;
}
static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
{
struct expr *tmp = NULL;
expr_extract_eq(E_AND, &tmp, ep1, ep2);
if (tmp) {
*ep1 = expr_eliminate_yn(*ep1);
*ep2 = expr_eliminate_yn(*ep2);
}
return tmp;
}
static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
{
struct expr *tmp = NULL;
expr_extract_eq(E_OR, &tmp, ep1, ep2);
if (tmp) {
*ep1 = expr_eliminate_yn(*ep1);
*ep2 = expr_eliminate_yn(*ep2);
}
return tmp;
}
static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
if (e1->type == type) {
expr_extract_eq(type, ep, &e1->left.expr, &e2);
expr_extract_eq(type, ep, &e1->right.expr, &e2);
return;
}
if (e2->type == type) {
expr_extract_eq(type, ep, ep1, &e2->left.expr);
expr_extract_eq(type, ep, ep1, &e2->right.expr);
return;
}
if (expr_eq(e1, e2)) {
*ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
expr_free(e2);
if (type == E_AND) {
e1 = expr_alloc_symbol(&symbol_yes);
e2 = expr_alloc_symbol(&symbol_yes);
} else if (type == E_OR) {
e1 = expr_alloc_symbol(&symbol_no);
e2 = expr_alloc_symbol(&symbol_no);
}
}
#undef e1
#undef e2
}
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
{
struct expr *e1, *e2;
......@@ -914,6 +839,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
case E_NOT:
return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
case E_UNEQUAL:
case E_LTH:
case E_LEQ:
case E_GTH:
case E_GEQ:
case E_EQUAL:
if (type == E_EQUAL) {
if (sym == &symbol_yes)
......@@ -941,10 +870,57 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
return NULL;
}
enum string_value_kind {
k_string,
k_signed,
k_unsigned,
k_invalid
};
union string_value {
unsigned long long u;
signed long long s;
};
static enum string_value_kind expr_parse_string(const char *str,
enum symbol_type type,
union string_value *val)
{
char *tail;
enum string_value_kind kind;
errno = 0;
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
return k_string;
case S_INT:
val->s = strtoll(str, &tail, 10);
kind = k_signed;
break;
case S_HEX:
val->u = strtoull(str, &tail, 16);
kind = k_unsigned;
break;
case S_STRING:
case S_UNKNOWN:
val->s = strtoll(str, &tail, 0);
kind = k_signed;
break;
default:
return k_invalid;
}
return !errno && !*tail && tail > str && isxdigit(tail[-1])
? kind : k_string;
}
tristate expr_calc_value(struct expr *e)
{
tristate val1, val2;
const char *str1, *str2;
enum string_value_kind k1 = k_string, k2 = k_string;
union string_value lval = {}, rval = {};
int res;
if (!e)
return yes;
......@@ -965,21 +941,57 @@ tristate expr_calc_value(struct expr *e)
val1 = expr_calc_value(e->left.expr);
return EXPR_NOT(val1);
case E_EQUAL:
sym_calc_value(e->left.sym);
sym_calc_value(e->right.sym);
str1 = sym_get_string_value(e->left.sym);
str2 = sym_get_string_value(e->right.sym);
return !strcmp(str1, str2) ? yes : no;
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
sym_calc_value(e->left.sym);
sym_calc_value(e->right.sym);
str1 = sym_get_string_value(e->left.sym);
str2 = sym_get_string_value(e->right.sym);
return !strcmp(str1, str2) ? no : yes;
break;
default:
printf("expr_calc_value: %d?\n", e->type);
return no;
}
sym_calc_value(e->left.sym);
sym_calc_value(e->right.sym);
str1 = sym_get_string_value(e->left.sym);
str2 = sym_get_string_value(e->right.sym);
if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
k1 = expr_parse_string(str1, e->left.sym->type, &lval);
k2 = expr_parse_string(str2, e->right.sym->type, &rval);
}
if (k1 == k_string || k2 == k_string)
res = strcmp(str1, str2);
else if (k1 == k_invalid || k2 == k_invalid) {
if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
return no;
}
res = strcmp(str1, str2);
} else if (k1 == k_unsigned || k2 == k_unsigned)
res = (lval.u > rval.u) - (lval.u < rval.u);
else /* if (k1 == k_signed && k2 == k_signed) */
res = (lval.s > rval.s) - (lval.s < rval.s);
switch(e->type) {
case E_EQUAL:
return res ? no : yes;
case E_GEQ:
return res >= 0 ? yes : no;
case E_GTH:
return res > 0 ? yes : no;
case E_LEQ:
return res <= 0 ? yes : no;
case E_LTH:
return res < 0 ? yes : no;
case E_UNEQUAL:
return res ? yes : no;
default:
printf("expr_calc_value: relation %d?\n", e->type);
return no;
}
}
static int expr_compare_type(enum expr_type t1, enum expr_type t2)
......@@ -987,6 +999,12 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
if (t1 == t2)
return 0;
switch (t1) {
case E_LEQ:
case E_LTH:
case E_GEQ:
case E_GTH:
if (t2 == E_EQUAL || t2 == E_UNEQUAL)
return 1;
case E_EQUAL:
case E_UNEQUAL:
if (t2 == E_NOT)
......@@ -1080,6 +1098,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
fn(data, NULL, "=");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_LEQ:
case E_LTH:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);
else
fn(data, NULL, "<choice>");
fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_GEQ:
case E_GTH:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);
else
fn(data, NULL, "<choice>");
fn(data, NULL, e->type == E_LEQ ? ">=" : ">");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_UNEQUAL:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);
......
......@@ -29,7 +29,9 @@ typedef enum tristate {
} tristate;
enum expr_type {
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
E_NONE, E_OR, E_AND, E_NOT,
E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ,
E_LIST, E_SYMBOL, E_RANGE
};
union expr_data {
......
......@@ -1166,6 +1166,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
case E_NOT:
return sym_check_expr_deps(e->left.expr);
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
sym = sym_check_deps(e->left.sym);
if (sym)
......
......@@ -122,6 +122,10 @@ n [A-Za-z0-9_]
"!" return T_NOT;
"=" return T_EQUAL;
"!=" return T_UNEQUAL;
"<=" return T_LESS_EQUAL;
">=" return T_GREATER_EQUAL;
"<" return T_LESS;
">" return T_GREATER;
\"|\' {
str = yytext[0];
new_string();
......@@ -141,7 +145,12 @@ n [A-Za-z0-9_]
}
#.* /* comment */
\\\n current_file->lineno++;
.
[[:blank:]]+
. {
fprintf(stderr,
"%s:%d:warning: ignoring unsupported character '%c'\n",
zconf_curname(), zconf_lineno(), *yytext);
}
<<EOF>> {
BEGIN(INITIAL);
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -69,6 +69,10 @@ static struct menu *current_menu, *current_entry;
%token <string> T_WORD
%token <string> T_WORD_QUOTE
%token T_UNEQUAL
%token T_LESS
%token T_LESS_EQUAL
%token T_GREATER
%token T_GREATER_EQUAL
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
%token T_EOL
......@@ -76,6 +80,7 @@ static struct menu *current_menu, *current_entry;
%left T_OR
%left T_AND
%left T_EQUAL T_UNEQUAL
%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
%nonassoc T_NOT
%type <string> prompt
......@@ -467,6 +472,10 @@ if_expr: /* empty */ { $$ = NULL; }
;
expr: symbol { $$ = expr_alloc_symbol($1); }
| symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); }
| symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); }
| symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); }
| symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); }
| symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
| symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
| T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment