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 ...@@ -86,7 +86,7 @@ $(simple-targets): $(obj)/conf
PHONY += oldnoconfig savedefconfig defconfig PHONY += oldnoconfig savedefconfig defconfig
# oldnoconfig is an alias of olddefconfig, because people already are dependent # 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. # counter-intuitive name.
oldnoconfig: olddefconfig oldnoconfig: olddefconfig
...@@ -126,10 +126,11 @@ tinyconfig: ...@@ -126,10 +126,11 @@ tinyconfig:
# Help text used by make help # Help text used by make help
help: help:
@echo ' config - Update current config utilising a line-oriented program' @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 ' menuconfig - Update current config utilising a menu based program'
@echo ' xconfig - Update current config utilising a QT 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 ' gconfig - Update current config utilising a GTK+ based front-end'
@echo ' oldconfig - Update current config utilising a provided .config as base' @echo ' oldconfig - Update current config utilising a provided .config as base'
@echo ' localmodconfig - Update current config disabling modules not loaded' @echo ' localmodconfig - Update current config disabling modules not loaded'
@echo ' localyesconfig - Update current config converting local mods to core' @echo ' localyesconfig - Update current config converting local mods to core'
...@@ -142,7 +143,8 @@ help: ...@@ -142,7 +143,8 @@ help:
@echo ' alldefconfig - New config with all symbols set to default' @echo ' alldefconfig - New config with all symbols set to default'
@echo ' randconfig - New config with random answer to all options' @echo ' randconfig - New config with random answer to all options'
@echo ' listnewconfig - List new 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 ' kvmconfig - Enable additional options for kvm guest kernel support'
@echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support' @echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support'
@echo ' tinyconfig - Configure the tiniest possible kernel' @echo ' tinyconfig - Configure the tiniest possible kernel'
...@@ -163,9 +165,9 @@ HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ ...@@ -163,9 +165,9 @@ HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
# mconf: Used for the menuconfig target # mconf: Used for the menuconfig target
# Utilizes the lxdialog package # Utilizes the lxdialog package
# qconf: Used for the xconfig target # 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 # 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 # object files used by all kconfig flavours
lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
...@@ -222,11 +224,11 @@ ifeq ($(MAKECMDGOALS),xconfig) ...@@ -222,11 +224,11 @@ ifeq ($(MAKECMDGOALS),xconfig)
$(obj)/.tmp_qtcheck: $(src)/Makefile $(obj)/.tmp_qtcheck: $(src)/Makefile
-include $(obj)/.tmp_qtcheck -include $(obj)/.tmp_qtcheck
# QT needs some extra effort... # Qt needs some extra effort...
$(obj)/.tmp_qtcheck: $(obj)/.tmp_qtcheck:
@set -e; $(kecho) " CHECK qt"; dir=""; pkg=""; \ @set -e; $(kecho) " CHECK qt"; dir=""; pkg=""; \
if ! pkg-config --exists QtCore 2> /dev/null; then \ 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 2> /dev/null && pkg=qt; \
pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
if [ -n "$$pkg" ]; then \ if [ -n "$$pkg" ]; then \
...@@ -240,8 +242,8 @@ $(obj)/.tmp_qtcheck: ...@@ -240,8 +242,8 @@ $(obj)/.tmp_qtcheck:
done; \ done; \
if [ -z "$$dir" ]; then \ if [ -z "$$dir" ]; then \
echo >&2 "*"; \ echo >&2 "*"; \
echo >&2 "* Unable to find any QT installation. Please make sure that"; \ 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 "* 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 "* either qmake can be found or install pkg-config or set"; \
echo >&2 "* the QTDIR environment variable to the correct location."; \ echo >&2 "* the QTDIR environment variable to the correct location."; \
echo >&2 "*"; \ echo >&2 "*"; \
...@@ -278,7 +280,7 @@ $(obj)/gconf.o: $(obj)/.tmp_gtkcheck ...@@ -278,7 +280,7 @@ $(obj)/gconf.o: $(obj)/.tmp_gtkcheck
ifeq ($(MAKECMDGOALS),gconfig) ifeq ($(MAKECMDGOALS),gconfig)
-include $(obj)/.tmp_gtkcheck -include $(obj)/.tmp_gtkcheck
# GTK needs some extra effort, too... # GTK+ needs some extra effort, too...
$(obj)/.tmp_gtkcheck: $(obj)/.tmp_gtkcheck:
@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ @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 \ if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \
...@@ -309,7 +311,7 @@ quiet_cmd_moc = MOC $@ ...@@ -309,7 +311,7 @@ quiet_cmd_moc = MOC $@
$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck $(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck
$(call cmd,moc) $(call cmd,moc)
# Extract gconf menu items for I18N support # Extract gconf menu items for i18n support
$(obj)/gconf.glade.h: $(obj)/gconf.glade $(obj)/gconf.glade.h: $(obj)/gconf.glade
$(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \
$(obj)/gconf.glade $(obj)/gconf.glade
...@@ -13,9 +13,6 @@ ...@@ -13,9 +13,6 @@
static int expr_eq(struct expr *e1, struct expr *e2); static int expr_eq(struct expr *e1, struct expr *e2);
static struct expr *expr_eliminate_yn(struct expr *e); 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) struct expr *expr_alloc_symbol(struct symbol *sym)
{ {
...@@ -82,6 +79,10 @@ struct expr *expr_copy(const struct expr *org) ...@@ -82,6 +79,10 @@ struct expr *expr_copy(const struct expr *org)
e->left.expr = expr_copy(org->left.expr); e->left.expr = expr_copy(org->left.expr);
break; break;
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
e->left.sym = org->left.sym; e->left.sym = org->left.sym;
e->right.sym = org->right.sym; e->right.sym = org->right.sym;
...@@ -114,6 +115,10 @@ void expr_free(struct expr *e) ...@@ -114,6 +115,10 @@ void expr_free(struct expr *e)
expr_free(e->left.expr); expr_free(e->left.expr);
return; return;
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
break; break;
case E_OR: case E_OR:
...@@ -200,6 +205,10 @@ static int expr_eq(struct expr *e1, struct expr *e2) ...@@ -200,6 +205,10 @@ static int expr_eq(struct expr *e1, struct expr *e2)
return 0; return 0;
switch (e1->type) { switch (e1->type) {
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
case E_SYMBOL: case E_SYMBOL:
...@@ -559,62 +568,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct ...@@ -559,62 +568,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
#undef e2 #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) struct expr *expr_eliminate_dups(struct expr *e)
{ {
int oldcount; int oldcount;
...@@ -627,7 +580,6 @@ struct expr *expr_eliminate_dups(struct expr *e) ...@@ -627,7 +580,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
switch (e->type) { switch (e->type) {
case E_OR: case E_AND: case E_OR: case E_AND:
expr_eliminate_dups1(e->type, &e, &e); expr_eliminate_dups1(e->type, &e, &e);
expr_eliminate_dups2(e->type, &e, &e);
default: default:
; ;
} }
...@@ -647,6 +599,10 @@ struct expr *expr_transform(struct expr *e) ...@@ -647,6 +599,10 @@ struct expr *expr_transform(struct expr *e)
return NULL; return NULL;
switch (e->type) { switch (e->type) {
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
case E_SYMBOL: case E_SYMBOL:
case E_LIST: case E_LIST:
...@@ -719,6 +675,22 @@ struct expr *expr_transform(struct expr *e) ...@@ -719,6 +675,22 @@ struct expr *expr_transform(struct expr *e)
e = tmp; e = tmp;
e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
break; 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: case E_OR:
// !(a || b) -> !a && !b // !(a || b) -> !a && !b
tmp = e->left.expr; tmp = e->left.expr;
...@@ -789,6 +761,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym) ...@@ -789,6 +761,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym)
case E_SYMBOL: case E_SYMBOL:
return dep->left.sym == sym; return dep->left.sym == sym;
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
return dep->left.sym == sym || return dep->left.sym == sym ||
dep->right.sym == sym; dep->right.sym == sym;
...@@ -829,57 +805,6 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym) ...@@ -829,57 +805,6 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
return false; 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 *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
{ {
struct expr *e1, *e2; struct expr *e1, *e2;
...@@ -914,6 +839,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb ...@@ -914,6 +839,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
case E_NOT: case E_NOT:
return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
case E_UNEQUAL: case E_UNEQUAL:
case E_LTH:
case E_LEQ:
case E_GTH:
case E_GEQ:
case E_EQUAL: case E_EQUAL:
if (type == E_EQUAL) { if (type == E_EQUAL) {
if (sym == &symbol_yes) if (sym == &symbol_yes)
...@@ -941,10 +870,57 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb ...@@ -941,10 +870,57 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
return NULL; 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 expr_calc_value(struct expr *e)
{ {
tristate val1, val2; tristate val1, val2;
const char *str1, *str2; const char *str1, *str2;
enum string_value_kind k1 = k_string, k2 = k_string;
union string_value lval = {}, rval = {};
int res;
if (!e) if (!e)
return yes; return yes;
...@@ -965,21 +941,57 @@ tristate expr_calc_value(struct expr *e) ...@@ -965,21 +941,57 @@ tristate expr_calc_value(struct expr *e)
val1 = expr_calc_value(e->left.expr); val1 = expr_calc_value(e->left.expr);
return EXPR_NOT(val1); return EXPR_NOT(val1);
case E_EQUAL: case E_EQUAL:
sym_calc_value(e->left.sym); case E_GEQ:
sym_calc_value(e->right.sym); case E_GTH:
str1 = sym_get_string_value(e->left.sym); case E_LEQ:
str2 = sym_get_string_value(e->right.sym); case E_LTH:
return !strcmp(str1, str2) ? yes : no;
case E_UNEQUAL: case E_UNEQUAL:
sym_calc_value(e->left.sym); break;
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;
default: default:
printf("expr_calc_value: %d?\n", e->type); printf("expr_calc_value: %d?\n", e->type);
return no; 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) 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) ...@@ -987,6 +999,12 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
if (t1 == t2) if (t1 == t2)
return 0; return 0;
switch (t1) { 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_EQUAL:
case E_UNEQUAL: case E_UNEQUAL:
if (t2 == E_NOT) if (t2 == E_NOT)
...@@ -1080,6 +1098,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * ...@@ -1080,6 +1098,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
fn(data, NULL, "="); fn(data, NULL, "=");
fn(data, e->right.sym, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
break; 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: case E_UNEQUAL:
if (e->left.sym->name) if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
......
...@@ -29,7 +29,9 @@ typedef enum tristate { ...@@ -29,7 +29,9 @@ typedef enum tristate {
} tristate; } tristate;
enum expr_type { 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 { union expr_data {
......
...@@ -1166,6 +1166,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e) ...@@ -1166,6 +1166,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
case E_NOT: case E_NOT:
return sym_check_expr_deps(e->left.expr); return sym_check_expr_deps(e->left.expr);
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
sym = sym_check_deps(e->left.sym); sym = sym_check_deps(e->left.sym);
if (sym) if (sym)
......
...@@ -122,6 +122,10 @@ n [A-Za-z0-9_] ...@@ -122,6 +122,10 @@ n [A-Za-z0-9_]
"!" return T_NOT; "!" return T_NOT;
"=" return T_EQUAL; "=" return T_EQUAL;
"!=" return T_UNEQUAL; "!=" return T_UNEQUAL;
"<=" return T_LESS_EQUAL;
">=" return T_GREATER_EQUAL;
"<" return T_LESS;
">" return T_GREATER;
\"|\' { \"|\' {
str = yytext[0]; str = yytext[0];
new_string(); new_string();
...@@ -141,7 +145,12 @@ n [A-Za-z0-9_] ...@@ -141,7 +145,12 @@ n [A-Za-z0-9_]
} }
#.* /* comment */ #.* /* comment */
\\\n current_file->lineno++; \\\n current_file->lineno++;
. [[:blank:]]+
. {
fprintf(stderr,
"%s:%d:warning: ignoring unsupported character '%c'\n",
zconf_curname(), zconf_lineno(), *yytext);
}
<<EOF>> { <<EOF>> {
BEGIN(INITIAL); BEGIN(INITIAL);
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -69,6 +69,10 @@ static struct menu *current_menu, *current_entry; ...@@ -69,6 +69,10 @@ static struct menu *current_menu, *current_entry;
%token <string> T_WORD %token <string> T_WORD
%token <string> T_WORD_QUOTE %token <string> T_WORD_QUOTE
%token T_UNEQUAL %token T_UNEQUAL
%token T_LESS
%token T_LESS_EQUAL
%token T_GREATER
%token T_GREATER_EQUAL
%token T_CLOSE_PAREN %token T_CLOSE_PAREN
%token T_OPEN_PAREN %token T_OPEN_PAREN
%token T_EOL %token T_EOL
...@@ -76,6 +80,7 @@ static struct menu *current_menu, *current_entry; ...@@ -76,6 +80,7 @@ static struct menu *current_menu, *current_entry;
%left T_OR %left T_OR
%left T_AND %left T_AND
%left T_EQUAL T_UNEQUAL %left T_EQUAL T_UNEQUAL
%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
%nonassoc T_NOT %nonassoc T_NOT
%type <string> prompt %type <string> prompt
...@@ -467,6 +472,10 @@ if_expr: /* empty */ { $$ = NULL; } ...@@ -467,6 +472,10 @@ if_expr: /* empty */ { $$ = NULL; }
; ;
expr: symbol { $$ = expr_alloc_symbol($1); } 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_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
| symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
| T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } | 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