[BusyBox-cvs] busybox/scripts/config conf.c, 1.1, 1.2 confdata.c, 1.2, 1.3 expr.c, 1.1, 1.2 expr.h, 1.1, 1.2 lex.zconf.c_shipped, 1.1, 1.2 lkc.h, 1.1, 1.2 lkc_proto.h, 1.2, 1.3 mconf.c, 1.2, 1.3 menu.c, 1.1, 1.2 symbol.c, 1.1, 1.2 zconf.l, 1.1, 1.2 zconf.tab.c_shipped, 1.1, 1.2 zconf.y, 1.1, 1.2
Erik Andersen
andersen at busybox.net
Tue Aug 5 02:18:29 UTC 2003
Update of /var/cvs/busybox/scripts/config
In directory winder:/tmp/cvs-serv24937/scripts/config
Modified Files:
conf.c confdata.c expr.c expr.h lex.zconf.c_shipped lkc.h
lkc_proto.h mconf.c menu.c symbol.c zconf.l
zconf.tab.c_shipped zconf.y
Log Message:
Merge/rework config system per the latest from linux-2.6.0-test2.
Fix the config bugs revealed by the updated config system.
-Erik
Index: confdata.c
===================================================================
RCS file: /var/cvs/busybox/scripts/config/confdata.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- confdata.c 12 Jun 2003 22:09:08 -0000 1.2
+++ confdata.c 5 Aug 2003 02:18:24 -0000 1.3
@@ -1,11 +1,9 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel at linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
- *
- * Allow 'n' as a symbol value.
- * 2002-11-05 Petr Baudis <pasky at ucw.cz>
*/
+#include <sys/stat.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -38,7 +36,7 @@
strncat(res_value, in, src - in);
src++;
dst = name;
- while (isalnum((int)*src) || *src == '_')
+ while (isalnum(*src) || *src == '_')
*dst++ = *src++;
*dst = 0;
sym = sym_lookup(name, 0);
@@ -53,7 +51,18 @@
char *conf_get_default_confname(void)
{
- return conf_expand_value(conf_defname);
+ struct stat buf;
+ static char fullname[4096+1];
+ char *env, *name;
+
+ name = conf_expand_value(conf_defname);
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ if (!stat(fullname, &buf))
+ return fullname;
+ }
+ return name;
}
int conf_read(const char *name)
@@ -68,12 +77,12 @@
int i;
if (name) {
- in = fopen(name, "r");
+ in = zconf_fopen(name);
} else {
const char **names = conf_confnames;
while ((name = *names++)) {
name = conf_expand_value(name);
- in = fopen(name, "r");
+ in = zconf_fopen(name);
if (in) {
printf("#\n"
"# using defaults found in %s\n"
@@ -93,44 +102,43 @@
case S_INT:
case S_HEX:
case S_STRING:
- if (S_VAL(sym->def))
- free(S_VAL(sym->def));
+ if (sym->user.val)
+ free(sym->user.val);
default:
- S_VAL(sym->def) = NULL;
- S_TRI(sym->def) = no;
- ;
+ sym->user.val = NULL;
+ sym->user.tri = no;
}
}
while (fgets(line, sizeof(line), in)) {
lineno++;
+ sym = NULL;
switch (line[0]) {
- case '\n':
- break;
- case ' ':
- break;
case '#':
- p = strchr(line, ' ');
- if (!p)
+ if (line[1]!=' ')
continue;
- *p++ = 0;
- p = strchr(p, ' ');
+ p = strchr(line + 2, ' ');
if (!p)
continue;
*p++ = 0;
if (strncmp(p, "is not set", 10))
continue;
- sym = sym_lookup(line+2, 0);
+ sym = sym_find(line + 2);
+ if (!sym) {
+ fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 2);
+ break;
+ }
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
- sym->def = symbol_no.curr;
+ sym->user.tri = no;
sym->flags &= ~SYMBOL_NEW;
break;
default:
;
}
break;
+
case 'A' ... 'Z':
p = strchr(line, '=');
if (!p)
@@ -145,24 +153,24 @@
break;
}
switch (sym->type) {
- case S_TRISTATE:
+ case S_TRISTATE:
if (p[0] == 'm') {
- S_TRI(sym->def) = mod;
+ sym->user.tri = mod;
sym->flags &= ~SYMBOL_NEW;
break;
}
case S_BOOLEAN:
if (p[0] == 'y') {
- S_TRI(sym->def) = yes;
+ sym->user.tri = yes;
sym->flags &= ~SYMBOL_NEW;
break;
}
if (p[0] == 'n') {
- S_TRI(sym->def) = no;
+ sym->user.tri = no;
sym->flags &= ~SYMBOL_NEW;
break;
}
- break;
+ break;
case S_STRING:
if (*p++ != '"')
break;
@@ -173,48 +181,71 @@
}
memmove(p2, p2 + 1, strlen(p2));
}
+ if (!p2) {
+ fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
+ exit(1);
+ }
case S_INT:
case S_HEX:
if (sym_string_valid(sym, p)) {
- S_VAL(sym->def) = strdup(p);
+ sym->user.val = strdup(p);
sym->flags &= ~SYMBOL_NEW;
- } else
- fprintf(stderr, "%s:%d:symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
+ } else {
+ fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
+ exit(1);
+ }
break;
default:
;
}
- if (sym_is_choice_value(sym)) {
- prop = sym_get_choice_prop(sym);
- switch (S_TRI(sym->def)) {
- case mod:
- if (S_TRI(prop->def->def) == yes)
- /* warn? */;
- break;
- case yes:
- if (S_TRI(prop->def->def) != no)
- /* warn? */;
- S_VAL(prop->def->def) = sym;
- break;
- case no:
- break;
- }
- S_TRI(prop->def->def) = S_TRI(sym->def);
- }
+ break;
+ case '\n':
break;
default:
continue;
}
+ if (sym && sym_is_choice_value(sym)) {
+ struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+ switch (sym->user.tri) {
+ case no:
+ break;
+ case mod:
+ if (cs->user.tri == yes)
+ /* warn? */;
+ break;
+ case yes:
+ if (cs->user.tri != no)
+ /* warn? */;
+ cs->user.val = sym;
+ break;
+ }
+ cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
+ cs->flags &= ~SYMBOL_NEW;
+ }
}
fclose(in);
for_all_symbols(i, sym) {
+ sym_calc_value(sym);
+ if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
+ if (sym->visible == no)
+ sym->flags |= SYMBOL_NEW;
+ switch (sym->type) {
+ case S_STRING:
+ case S_INT:
+ case S_HEX:
+ if (!sym_string_within_range(sym, sym->user.val))
+ sym->flags |= SYMBOL_NEW;
+ default:
+ break;
+ }
+ }
if (!sym_is_choice(sym))
continue;
prop = sym_get_choice_prop(sym);
- for (e = prop->dep; e; e = e->left.expr)
- sym->flags |= e->right.sym->flags & SYMBOL_NEW;
- sym->flags &= ~SYMBOL_NEW;
+ for (e = prop->expr; e; e = e->left.expr)
+ if (e->right.sym->visible != no)
+ sym->flags |= e->right.sym->flags & SYMBOL_NEW;
}
sym_change_count = 1;
@@ -227,29 +258,50 @@
FILE *out, *out_h;
struct symbol *sym;
struct menu *menu;
- char oldname[128];
+ const char *basename;
+ char dirname[128], tmpname[128], newname[128];
int type, l;
const char *str;
- out = fopen(".tmpconfig", "w");
+ dirname[0] = 0;
+ if (name && name[0]) {
+ char *slash = strrchr(name, '/');
+ if (slash) {
+ int size = slash - name + 1;
+ memcpy(dirname, name, size);
+ dirname[size] = 0;
+ if (slash[1])
+ basename = slash + 1;
+ else
+ basename = conf_def_filename;
+ } else
+ basename = name;
+ } else
+ basename = conf_def_filename;
+
+ sprintf(newname, "%s.tmpconfig.%d", dirname, getpid());
+ out = fopen(newname, "w");
if (!out)
return 1;
- out_h = fopen(".tmpconfig.h", "w");
- if (!out_h)
- return 1;
+ out_h = NULL;
+ if (!name) {
+ out_h = fopen(".tmpconfig.h", "w");
+ if (!out_h)
+ return 1;
+ }
fprintf(out, "#\n"
"# Automatically generated make config: don't edit\n"
"#\n");
- fprintf(out_h, "/*\n"
- " * Automatically generated header file: don't edit\n"
- " */\n\n"
- "#define AUTOCONF_INCLUDED\n\n"
- "/* Version Number */\n"
- "#define BB_VER \"%s\"\n"
- "#define BB_BT \"%s\"\n\n",
- getenv("VERSION"),
- getenv("BUILDTIME")
- );
+ if (out_h)
+ fprintf(out_h, "/*\n"
+ " * Automatically generated header file: don't edit\n"
+ " */\n\n"
+ "#define AUTOCONF_INCLUDED\n\n"
+ "/* Version Number */\n"
+ "#define BB_VER \"%s\"\n"
+ "#define BB_BT \"%s\"\n\n",
+ getenv("VERSION"),
+ getenv("BUILDTIME"));
if (!sym_change_count)
sym_clear_all_valid();
@@ -265,10 +317,11 @@
"#\n"
"# %s\n"
"#\n", str);
- fprintf(out_h, "\n"
- "/*\n"
- " * %s\n"
- " */\n", str);
+ if (out_h)
+ fprintf(out_h, "\n"
+ "/*\n"
+ " * %s\n"
+ " */\n", str);
} else if (!(sym->flags & SYMBOL_CHOICE)) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
@@ -277,7 +330,7 @@
type = sym->type;
if (type == S_TRISTATE) {
sym_calc_value(modules_sym);
- if (S_TRI(modules_sym->curr) == no)
+ if (modules_sym->curr.tri == no)
type = S_BOOLEAN;
}
switch (type) {
@@ -286,17 +339,20 @@
switch (sym_get_tristate_value(sym)) {
case no:
fprintf(out, "# %s is not set\n", sym->name);
- fprintf(out_h, "#undef %s\n", sym->name);
+ if (out_h)
+ fprintf(out_h, "#undef %s\n", sym->name);
break;
- case mod:
#if 0
+ case mod:
fprintf(out, "%s=m\n", sym->name);
- fprintf(out_h, "#define __%s__MODULE 1\n", sym->name);
-#endif
+ if (out_h)
+ fprintf(out_h, "#define %s_MODULE 1\n", sym->name);
break;
+#endif
case yes:
fprintf(out, "%s=y\n", sym->name);
- fprintf(out_h, "#define %s 1\n", sym->name);
+ if (out_h)
+ fprintf(out_h, "#define %s 1\n", sym->name);
break;
}
break;
@@ -304,34 +360,40 @@
// fix me
str = sym_get_string_value(sym);
fprintf(out, "%s=\"", sym->name);
- fprintf(out_h, "#define %s \"", sym->name);
+ if (out_h)
+ fprintf(out_h, "#define %s \"", sym->name);
do {
l = strcspn(str, "\"\\");
if (l) {
fwrite(str, l, 1, out);
- fwrite(str, l, 1, out_h);
+ if (out_h)
+ fwrite(str, l, 1, out_h);
}
str += l;
while (*str == '\\' || *str == '"') {
fprintf(out, "\\%c", *str);
- fprintf(out_h, "\\%c", *str);
+ if (out_h)
+ fprintf(out_h, "\\%c", *str);
str++;
}
} while (*str);
fputs("\"\n", out);
- fputs("\"\n", out_h);
+ if (out_h)
+ fputs("\"\n", out_h);
break;
case S_HEX:
str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
fprintf(out, "%s=%s\n", sym->name, str);
- fprintf(out_h, "#define %s 0x%s\n", sym->name, str);
+ if (out_h)
+ fprintf(out_h, "#define %s 0x%s\n", sym->name, str);
break;
}
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "%s=%s\n", sym->name, str);
- fprintf(out_h, "#define %s %s\n", sym->name, str);
+ if (out_h)
+ fprintf(out_h, "#define %s %s\n", sym->name, str);
break;
}
}
@@ -351,18 +413,19 @@
}
}
fclose(out);
- fclose(out_h);
-
- if (!name) {
+ if (out_h) {
+ fclose(out_h);
rename(".tmpconfig.h", "include/config.h");
- name = conf_def_filename;
file_write_dep(NULL);
- } else
- unlink(".tmpconfig.h");
-
- sprintf(oldname, "%s.old", name);
- rename(name, oldname);
- if (rename(".tmpconfig", name))
+ }
+ if (!name || basename != conf_def_filename) {
+ if (!name)
+ name = conf_def_filename;
+ sprintf(tmpname, "%s.old", name);
+ rename(name, tmpname);
+ }
+ sprintf(tmpname, "%s%s", dirname, basename);
+ if (rename(newname, tmpname))
return 1;
sym_change_count = 0;
Index: mconf.c
===================================================================
RCS file: /var/cvs/busybox/scripts/config/mconf.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mconf.c 30 Jun 2003 18:14:04 -0000 1.2
+++ mconf.c 5 Aug 2003 02:18:25 -0000 1.3
@@ -28,6 +28,7 @@
#define LKC_DIRECT_LINK
#include "lkc.h"
+static char menu_backtitle[128];
static const char menu_instructions[] =
"Arrow keys navigate the menu. "
"<Enter> selects submenus --->. "
@@ -65,7 +66,7 @@
"configurations available on a single machine.\n"
"\n"
"If you have saved a previous configuration in a file other than the\n"
- "BusyBox default, entering the name of the file here will allow you\n"
+ "BusyBox's default, entering the name of the file here will allow you\n"
"to modify that configuration.\n"
"\n"
"If you are uncertain, then you have probably never used alternate\n"
@@ -120,6 +121,7 @@
static void init_wsize(void)
{
struct winsize ws;
+ char *env;
if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
rows = 24;
@@ -127,6 +129,20 @@
} else {
rows = ws.ws_row;
cols = ws.ws_col;
+ if (!rows) {
+ env = getenv("LINES");
+ if (env)
+ rows = atoi(env);
+ if (!rows)
+ rows = 24;
+ }
+ if (!cols) {
+ env = getenv("COLUMNS");
+ if (env)
+ cols = atoi(env);
+ if (!cols)
+ cols = 80;
+ }
}
if (rows < 19 || cols < 80) {
@@ -226,9 +242,7 @@
menu->data ? "-->" : "++>",
indent + 1, ' ', prompt);
} else {
- if (menu->parent != &rootmenu)
- cprint_name(" %*c", indent + 1, ' ');
- cprint_name("%s --->", prompt);
+ cprint_name(" %*c%s --->", indent + 1, ' ', prompt);
}
if (single_menu_mode && menu->data)
@@ -303,7 +317,10 @@
switch (type) {
case S_BOOLEAN:
cprint_tag("t%p", menu);
- cprint_name("[%c]", val == no ? ' ' : '*');
+ if (sym_is_changable(sym))
+ cprint_name("[%c]", val == no ? ' ' : '*');
+ else
+ cprint_name("---");
break;
case S_TRISTATE:
cprint_tag("t%p", menu);
@@ -312,7 +329,10 @@
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
- cprint_name("<%c>", ch);
+ if (sym_is_changable(sym))
+ cprint_name("<%c>", ch);
+ else
+ cprint_name("---");
break;
default:
cprint_tag("s%p", menu);
@@ -321,12 +341,18 @@
if (tmp < 0)
tmp = 0;
cprint_name("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
- sym_has_value(sym) ? "" : " (NEW)");
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
goto conf_childs;
}
}
cprint_name("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
- sym_has_value(sym) ? "" : " (NEW)");
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
+ if (menu->prompt->type == P_MENU) {
+ cprint_name(" --->");
+ return;
+ }
}
conf_childs:
@@ -390,13 +416,15 @@
switch (type) {
case 'm':
if (single_menu_mode)
- submenu->data = (submenu->data)? NULL : (void *)1;
+ submenu->data = (void *) (long) !submenu->data;
else
conf(submenu);
break;
case 't':
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
+ else if (submenu->prompt->type == P_MENU)
+ conf(submenu);
break;
case 's':
conf_string(submenu);
@@ -602,7 +630,6 @@
{
tcsetattr(1, TCSAFLUSH, &ios_org);
unlink(".help.tmp");
- unlink("lxdialog.scrltmp");
}
static void winch_handler(int sig)
@@ -638,10 +665,9 @@
conf_parse(av[1]);
conf_read(NULL);
- backtitle = malloc(128);
sym = sym_lookup("VERSION", 0);
sym_calc_value(sym);
- snprintf(backtitle, 128, "BusyBox v%s Configuration",
+ snprintf(menu_backtitle, 128, "BusyBox v%s Configuration",
sym_get_string_value(sym));
mode = getenv("MENUCONFIG_MODE");
Index: zconf.tab.c_shipped
===================================================================
RCS file: /var/cvs/busybox/scripts/config/zconf.tab.c_shipped,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- zconf.tab.c_shipped 5 Dec 2002 08:41:08 -0000 1.1
+++ zconf.tab.c_shipped 5 Aug 2003 02:18:25 -0000 1.2
@@ -1,7 +1,7 @@
-/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
+/* A Bison parser, made by GNU Bison 1.875a. */
/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,10 +34,13 @@
USER NAME SPACE" below. */
[...2076 lines suppressed...]
- // break;
- //case T_IF:
- // fputs("\nif\n", out);
default:
;
}
- if (!expr_is_yes(E_EXPR(prop->visible))) {
+ if (!expr_is_yes(prop->visible.expr)) {
fputs(" depends ", out);
- expr_fprint(E_EXPR(prop->visible), out);
+ expr_fprint(prop->visible.expr, out);
fputc('\n', out);
}
fputs("\n", out);
@@ -2014,4 +2123,5 @@
#include "expr.c"
#include "symbol.c"
#include "menu.c"
+
Index: lkc.h
===================================================================
RCS file: /var/cvs/busybox/scripts/config/lkc.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- lkc.h 5 Dec 2002 08:41:07 -0000 1.1
+++ lkc.h 5 Aug 2003 02:18:24 -0000 1.2
@@ -21,12 +21,14 @@
#include "lkc_proto.h"
#undef P
-void symbol_end(char *help);
+#define SRCTREE "srctree"
+
int zconfparse(void);
void zconfdump(FILE *out);
extern int zconfdebug;
void zconf_starthelp(void);
+FILE *zconf_fopen(const char *name);
void zconf_initscan(const char *name);
void zconf_nextfile(const char *name);
int zconf_lineno(void);
@@ -47,9 +49,11 @@
void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
void menu_end_entry(void);
-struct property *create_prop(enum prop_type type);
void menu_add_dep(struct expr *dep);
-struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep);
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
+void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
void menu_finalize(struct menu *parent);
void menu_set_type(int type);
struct file *file_lookup(const char *name);
@@ -61,16 +65,20 @@
/* symbol.c */
void sym_init(void);
void sym_clear_all_valid(void);
+void sym_set_changed(struct symbol *sym);
+struct symbol *sym_check_deps(struct symbol *sym);
+struct property *prop_alloc(enum prop_type type, struct symbol *sym);
+struct symbol *prop_get_symbol(struct property *prop);
static inline tristate sym_get_tristate_value(struct symbol *sym)
{
- return S_TRI(sym->curr);
+ return sym->curr.tri;
}
static inline struct symbol *sym_get_choice_value(struct symbol *sym)
{
- return (struct symbol *)S_VAL(sym->curr);
+ return (struct symbol *)sym->curr.val;
}
static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
@@ -95,7 +103,6 @@
static inline bool sym_has_value(struct symbol *sym)
{
- //return S_VAL(sym->def) != NULL;
return sym->flags & SYMBOL_NEW ? false : true;
}
Index: zconf.l
===================================================================
RCS file: /var/cvs/busybox/scripts/config/zconf.l,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- zconf.l 5 Dec 2002 08:41:08 -0000 1.1
+++ zconf.l 5 Aug 2003 02:18:25 -0000 1.2
@@ -7,6 +7,7 @@
* Released under the terms of the GNU GPL v2.0.
*/
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -14,7 +15,6 @@
#define LKC_DIRECT_LINK
#include "lkc.h"
-#include "zconf.tab.h"
#define START_STRSIZE 16
@@ -96,6 +96,7 @@
"endchoice" BEGIN(PARAM); return T_ENDCHOICE;
"comment" BEGIN(PARAM); return T_COMMENT;
"config" BEGIN(PARAM); return T_CONFIG;
+ "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
"help" BEGIN(PARAM); return T_HELP;
"if" BEGIN(PARAM); return T_IF;
"endif" BEGIN(PARAM); return T_ENDIF;
@@ -105,11 +106,17 @@
"default" BEGIN(PARAM); return T_DEFAULT;
"prompt" BEGIN(PARAM); return T_PROMPT;
"tristate" BEGIN(PARAM); return T_TRISTATE;
+ "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
"bool" BEGIN(PARAM); return T_BOOLEAN;
"boolean" BEGIN(PARAM); return T_BOOLEAN;
+ "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
+ "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
"int" BEGIN(PARAM); return T_INT;
"hex" BEGIN(PARAM); return T_HEX;
"string" BEGIN(PARAM); return T_STRING;
+ "select" BEGIN(PARAM); return T_SELECT;
+ "enable" BEGIN(PARAM); return T_SELECT;
+ "range" BEGIN(PARAM); return T_RANGE;
{n}+ {
alloc_string(yytext, yyleng);
zconflval.string = text;
@@ -141,6 +148,8 @@
zconflval.string = text;
return T_WORD;
}
+ #.* /* comment */
+ \\\n current_file->lineno++;
.
<<EOF>> {
BEGIN(INITIAL);
@@ -151,29 +160,30 @@
[^'"\\\n]+/\n {
append_string(yytext, yyleng);
zconflval.string = text;
- return T_STRING;
+ return T_WORD_QUOTE;
}
[^'"\\\n]+ {
append_string(yytext, yyleng);
}
\\.?/\n {
- append_string(yytext+1, yyleng);
+ append_string(yytext + 1, yyleng - 1);
zconflval.string = text;
- return T_STRING;
+ return T_WORD_QUOTE;
}
\\.? {
- append_string(yytext+1, yyleng);
+ append_string(yytext + 1, yyleng - 1);
}
\'|\" {
if (str == yytext[0]) {
BEGIN(PARAM);
zconflval.string = text;
- return T_STRING;
+ return T_WORD_QUOTE;
} else
append_string(yytext, 1);
}
\n {
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
+ current_file->lineno++;
BEGIN(INITIAL);
return T_EOL;
}
@@ -204,9 +214,8 @@
}
append_string(" ", ts);
}
-
}
- \n/[^ \t\n] {
+ [ \t]*\n/[^ \t\n] {
current_file->lineno++;
zconf_endhelp();
return T_HELPTEXT;
@@ -246,12 +255,37 @@
static void zconf_endhelp(void)
{
zconflval.string = text;
- BEGIN(INITIAL);
+ BEGIN(INITIAL);
+}
+
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+ char *env, fullname[PATH_MAX+1];
+ FILE *f;
+
+ f = fopen(name, "r");
+ if (!f && name[0] != '/') {
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ f = fopen(fullname, "r");
+ }
+ }
+ return f;
}
void zconf_initscan(const char *name)
{
- yyin = fopen(name, "r");
+ yyin = zconf_fopen(name);
if (!yyin) {
printf("can't find file %s\n", name);
exit(1);
@@ -272,7 +306,7 @@
memset(buf, 0, sizeof(*buf));
current_buf->state = YY_CURRENT_BUFFER;
- yyin = fopen(name, "r");
+ yyin = zconf_fopen(name);
if (!yyin) {
printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
exit(1);
@@ -318,7 +352,7 @@
int zconf_lineno(void)
{
if (current_buf)
- return current_file->lineno;
+ return current_file->lineno - 1;
else
return 0;
}
Index: conf.c
===================================================================
RCS file: /var/cvs/busybox/scripts/config/conf.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- conf.c 5 Dec 2002 08:41:06 -0000 1.1
+++ conf.c 5 Aug 2003 02:18:24 -0000 1.2
@@ -35,50 +35,12 @@
static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
-#if 0
-static void printc(int ch)
-{
- static int sep = 0;
-
- if (!sep) {
- putchar('[');
- sep = 1;
- } else if (ch)
- putchar('/');
- if (!ch) {
- putchar(']');
- putchar(' ');
- sep = 0;
- } else
- putchar(ch);
-}
-#endif
-
-static void printo(const char *o)
-{
- static int sep = 0;
-
- if (!sep) {
- putchar('(');
- sep = 1;
- } else if (o) {
- putchar(',');
- putchar(' ');
- }
- if (!o) {
- putchar(')');
- putchar(' ');
- sep = 0;
- } else
- printf("%s", o);
-}
-
static void strip(char *str)
{
char *p = str;
int l;
- while ((isspace((int)*p)))
+ while ((isspace(*p)))
p++;
l = strlen(p);
if (p != str)
@@ -86,10 +48,20 @@
if (!l)
return;
p = str + l - 1;
- while ((isspace((int)*p)))
+ while ((isspace(*p)))
*p-- = 0;
}
+static void check_stdin(void)
+{
+ if (!valid_stdin && input_mode == ask_silent) {
+ printf("aborted!\n\n");
+ printf("Console input/output is redirected. ");
+ printf("Run 'make oldconfig' to update configuration.\n\n");
+ exit(1);
+ }
+}
+
static void conf_askvalue(struct symbol *sym, const char *def)
{
enum symbol_type type = sym_get_type(sym);
@@ -101,6 +73,13 @@
line[0] = '\n';
line[1] = 0;
+ if (!sym_is_changable(sym)) {
+ printf("%s\n", def);
+ line[0] = '\n';
+ line[1] = 0;
+ return;
+ }
+
switch (input_mode) {
case ask_new:
case ask_silent:
@@ -108,12 +87,7 @@
printf("%s\n", def);
return;
}
- if (!valid_stdin && input_mode == ask_silent) {
- printf("aborted!\n\n");
- printf("Console input/output is redirected. ");
- printf("Run 'make oldconfig' to update configuration.\n\n");
- exit(1);
- }
+ check_stdin();
case ask_all:
fflush(stdout);
fgets(line, 128, stdin);
@@ -294,9 +268,8 @@
static int conf_choice(struct menu *menu)
{
struct symbol *sym, *def_sym;
- struct menu *cmenu, *def_menu;
- const char *help;
- int type, len;
+ struct menu *child;
+ int type;
bool is_new;
sym = menu->sym;
@@ -314,72 +287,111 @@
break;
}
} else {
- sym->def = sym->curr;
- if (S_TRI(sym->curr) == mod) {
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ return 1;
+ case mod:
printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
return 0;
+ case yes:
+ break;
}
}
while (1) {
- printf("%*s%s ", indent - 1, "", menu_get_prompt(menu));
+ int cnt, def;
+
+ printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
def_sym = sym_get_choice_value(sym);
- def_menu = NULL;
- for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
- if (!menu_is_visible(cmenu))
+ cnt = def = 0;
+ line[0] = '0';
+ line[1] = 0;
+ for (child = menu->list; child; child = child->next) {
+ if (!menu_is_visible(child))
continue;
- printo(menu_get_prompt(cmenu));
- if (cmenu->sym == def_sym)
- def_menu = cmenu;
- }
- printo(NULL);
- if (def_menu)
- printf("[%s] ", menu_get_prompt(def_menu));
- else {
+ if (!child->sym) {
+ printf("%*c %s\n", indent, '*', menu_get_prompt(child));
+ continue;
+ }
+ cnt++;
+ if (child->sym == def_sym) {
+ def = cnt;
+ printf("%*c", indent, '>');
+ } else
+ printf("%*c", indent, ' ');
+ printf(" %d. %s", cnt, menu_get_prompt(child));
+ if (child->sym->name)
+ printf(" (%s)", child->sym->name);
+ if (!sym_has_value(child->sym))
+ printf(" (NEW)");
printf("\n");
- return 1;
}
+ printf("%*schoice", indent - 1, "");
+ if (cnt == 1) {
+ printf("[1]: 1\n");
+ goto conf_childs;
+ }
+ printf("[1-%d", cnt);
+ if (sym->help)
+ printf("?");
+ printf("]: ");
switch (input_mode) {
case ask_new:
case ask_silent:
+ if (!is_new) {
+ cnt = def;
+ printf("%d\n", cnt);
+ break;
+ }
+ check_stdin();
case ask_all:
- conf_askvalue(sym, menu_get_prompt(def_menu));
+ fflush(stdout);
+ fgets(line, 128, stdin);
strip(line);
+ if (line[0] == '?') {
+ printf("\n%s\n", menu->sym->help ?
+ menu->sym->help : nohelp_text);
+ continue;
+ }
+ if (!line[0])
+ cnt = def;
+ else if (isdigit(line[0]))
+ cnt = atoi(line);
+ else
+ continue;
+ break;
+ case set_random:
+ def = (random() % cnt) + 1;
+ case set_default:
+ case set_yes:
+ case set_mod:
+ case set_no:
+ cnt = def;
+ printf("%d\n", cnt);
break;
- default:
- line[0] = 0;
- printf("\n");
- }
- if (line[0] == '?' && !line[1]) {
- help = nohelp_text;
- if (menu->sym->help)
- help = menu->sym->help;
- printf("\n%s\n", help);
- continue;
}
- if (line[0]) {
- len = strlen(line);
- line[len] = 0;
- def_menu = NULL;
- for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
- if (!cmenu->sym || !menu_is_visible(cmenu))
- continue;
- if (!strncasecmp(line, menu_get_prompt(cmenu), len)) {
- def_menu = cmenu;
- break;
- }
- }
+ conf_childs:
+ for (child = menu->list; child; child = child->next) {
+ if (!child->sym || !menu_is_visible(child))
+ continue;
+ if (!--cnt)
+ break;
}
- if (def_menu) {
- sym_set_choice_value(sym, def_menu->sym);
- if (def_menu->list) {
- indent += 2;
- conf(def_menu->list);
- indent -= 2;
- }
- return 1;
+ if (!child)
+ continue;
+ if (line[strlen(line) - 1] == '?') {
+ printf("\n%s\n", child->sym->help ?
+ child->sym->help : nohelp_text);
+ continue;
+ }
+ sym_set_choice_value(sym, child->sym);
+ if (child->list) {
+ indent += 2;
+ conf(child->list);
+ indent -= 2;
}
+ return 1;
}
}
@@ -420,7 +432,7 @@
if (sym_is_choice(sym)) {
conf_choice(menu);
- if (S_TRI(sym->curr) != mod)
+ if (sym->curr.tri != mod)
return;
goto conf_childs;
}
@@ -454,29 +466,17 @@
return;
sym = menu->sym;
- if (!sym)
- goto conf_childs;
-
- if (sym_is_choice(sym)) {
- if (!sym_has_value(sym)) {
+ if (sym) {
+ if (sym_is_changable(sym) && !sym_has_value(sym)) {
if (!conf_cnt++)
printf("*\n* Restart config...\n*\n");
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
- if (sym_get_tristate_value(sym) != mod)
+ if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
return;
- goto conf_childs;
- }
-
- if (!sym_has_value(sym)) {
- if (!conf_cnt++)
- printf("*\n* Restart config...\n*\n");
- rootEntry = menu_get_parent_menu(menu);
- conf(rootEntry);
}
-conf_childs:
for (child = menu->list; child; child = child->next)
check_conf(child);
}
@@ -536,8 +536,8 @@
printf("***\n"
"*** You have not yet configured BusyBox!\n"
"***\n"
- "*** Please run some configurator (e.g. \"make oldconfig\"\n"
- "*** or \"make menuconfig\").\n"
+ "*** Please run some configurator (e.g. \"make config\" or\n"
+ "*** \"make oldconfig\" or \"make menuconfig\").\n"
"***\n");
exit(1);
}
Index: symbol.c
===================================================================
RCS file: /var/cvs/busybox/scripts/config/symbol.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- symbol.c 5 Dec 2002 08:41:08 -0000 1.1
+++ symbol.c 5 Aug 2003 02:18:25 -0000 1.2
@@ -34,24 +34,14 @@
void sym_add_default(struct symbol *sym, const char *def)
{
- struct property *prop = create_prop(P_DEFAULT);
- struct property **propp;
-
- prop->sym = sym;
- prop->def = sym_lookup(def, 1);
+ struct property *prop = prop_alloc(P_DEFAULT, sym);
- /* append property to the prop list of symbol */
- if (prop->sym) {
- for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
- ;
- *propp = prop;
- }
+ prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
}
void sym_init(void)
{
struct symbol *sym;
- struct utsname uts;
char *p;
static bool inited = false;
@@ -59,17 +49,6 @@
return;
inited = true;
- uname(&uts);
-
-#if 0
- sym = sym_lookup("ARCH", 0);
- sym->type = S_STRING;
- sym->flags |= SYMBOL_AUTO;
- p = getenv("ARCH");
- if (p)
- sym_add_default(sym, p);
-#endif
-
sym = sym_lookup("VERSION", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
@@ -77,37 +56,32 @@
if (p)
sym_add_default(sym, p);
-#if 0
- sym = sym_lookup("UNAME_RELEASE", 0);
- sym->type = S_STRING;
- sym->flags |= SYMBOL_AUTO;
- sym_add_default(sym, uts.release);
-#endif
-
sym = sym_lookup("TARGET_ARCH", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("TARGET_ARCH");
if (p)
sym_add_default(sym, p);
+
}
-int sym_get_type(struct symbol *sym)
+enum symbol_type sym_get_type(struct symbol *sym)
{
- int type = sym->type;
+ enum symbol_type type = sym->type;
+
if (type == S_TRISTATE) {
if (sym_is_choice_value(sym) && sym->visible == yes)
type = S_BOOLEAN;
else {
sym_calc_value(modules_sym);
- if (S_TRI(modules_sym->curr) == no)
+ if (modules_sym->curr.tri == no)
type = S_BOOLEAN;
}
}
return type;
}
-const char *sym_type_name(int type)
+const char *sym_type_name(enum symbol_type type)
{
switch (type) {
case S_BOOLEAN:
@@ -122,6 +96,8 @@
return "string";
case S_UNKNOWN:
return "unknown";
+ case S_OTHER:
+ break;
}
return "???";
}
@@ -138,41 +114,104 @@
struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
- tristate visible;
for_all_defaults(sym, prop) {
- visible = E_CALC(prop->visible);
- if (visible != no)
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri != no)
return prop;
}
return NULL;
}
-void sym_calc_visibility(struct symbol *sym)
+struct property *sym_get_range_prop(struct symbol *sym)
{
struct property *prop;
- tristate visible, oldvisible;
+
+ for_all_properties(sym, prop, P_RANGE) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri != no)
+ return prop;
+ }
+ return NULL;
+}
+
+static void sym_calc_visibility(struct symbol *sym)
+{
+ struct property *prop;
+ tristate tri;
/* any prompt visible? */
- oldvisible = sym->visible;
- visible = no;
- for_all_prompts(sym, prop)
- visible = E_OR(visible, E_CALC(prop->visible));
- if (oldvisible != visible) {
- sym->visible = visible;
- sym->flags |= SYMBOL_CHANGED;
+ tri = no;
+ for_all_prompts(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ tri = E_OR(tri, prop->visible.tri);
+ }
+ if (sym->visible != tri) {
+ sym->visible = tri;
+ sym_set_changed(sym);
+ }
+ if (sym_is_choice_value(sym))
+ return;
+ tri = no;
+ if (sym->rev_dep.expr)
+ tri = expr_calc_value(sym->rev_dep.expr);
+ if (sym->rev_dep.tri != tri) {
+ sym->rev_dep.tri = tri;
+ sym_set_changed(sym);
}
}
+static struct symbol *sym_calc_choice(struct symbol *sym)
+{
+ struct symbol *def_sym;
+ struct property *prop;
+ struct expr *e;
+
+ /* is the user choice visible? */
+ def_sym = sym->user.val;
+ if (def_sym) {
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* any of the defaults visible? */
+ for_all_defaults(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri == no)
+ continue;
+ def_sym = prop_get_symbol(prop);
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* just get the first visible value */
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->expr; e; e = e->left.expr) {
+ def_sym = e->right.sym;
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* no choice? reset tristate value */
+ sym->curr.tri = no;
+ return NULL;
+}
+
void sym_calc_value(struct symbol *sym)
{
struct symbol_value newval, oldval;
- struct property *prop, *def_prop;
- struct symbol *def_sym;
+ struct property *prop;
struct expr *e;
+ if (!sym)
+ return;
+
if (sym->flags & SYMBOL_VALID)
return;
+ sym->flags |= SYMBOL_VALID;
oldval = sym->curr;
@@ -187,17 +226,10 @@
newval = symbol_no.curr;
break;
default:
- S_VAL(newval) = sym->name;
- S_TRI(newval) = no;
- if (sym->flags & SYMBOL_CONST) {
- goto out;
- }
- //newval = symbol_empty.curr;
- // generate warning somewhere here later
- //S_TRI(newval) = yes;
- goto out;
+ sym->curr.val = sym->name;
+ sym->curr.tri = no;
+ return;
}
- sym->flags |= SYMBOL_VALID;
if (!sym_is_choice_value(sym))
sym->flags &= ~SYMBOL_WRITE;
@@ -206,95 +238,77 @@
/* set default if recursively called */
sym->curr = newval;
- if (sym->visible != no) {
- sym->flags |= SYMBOL_WRITE;
- if (!sym_has_value(sym)) {
- if (!sym_is_choice(sym)) {
- prop = sym_get_default_prop(sym);
- if (prop) {
- sym_calc_value(prop->def);
- newval = prop->def->curr;
- }
- }
- } else
- newval = sym->def;
-
- S_TRI(newval) = E_AND(S_TRI(newval), sym->visible);
- /* if the symbol is visible and not optionial,
- * possibly ignore old user choice. */
- if (!sym_is_optional(sym) && S_TRI(newval) == no)
- S_TRI(newval) = sym->visible;
+ switch (sym_get_type(sym)) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
if (sym_is_choice_value(sym) && sym->visible == yes) {
prop = sym_get_choice_prop(sym);
- S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no;
- }
- } else {
- prop = sym_get_default_prop(sym);
- if (prop) {
+ newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
+ } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
sym->flags |= SYMBOL_WRITE;
- sym_calc_value(prop->def);
- newval = prop->def->curr;
+ if (sym_has_value(sym))
+ newval.tri = sym->user.tri;
+ else if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop)
+ newval.tri = expr_calc_value(prop->expr);
+ }
+ newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
+ } else if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ sym->flags |= SYMBOL_WRITE;
+ newval.tri = expr_calc_value(prop->expr);
+ }
}
- }
-
- switch (sym_get_type(sym)) {
- case S_TRISTATE:
- if (S_TRI(newval) != mod)
- break;
- sym_calc_value(modules_sym);
- if (S_TRI(modules_sym->curr) == no)
- S_TRI(newval) = yes;
- break;
- case S_BOOLEAN:
- if (S_TRI(newval) == mod)
- S_TRI(newval) = yes;
- }
-
-out:
- sym->curr = newval;
-
- if (sym_is_choice(sym) && S_TRI(newval) == yes) {
- def_sym = S_VAL(sym->def);
- if (def_sym) {
- sym_calc_visibility(def_sym);
- if (def_sym->visible == no)
- def_sym = NULL;
+ if (sym_get_type(sym) == S_BOOLEAN) {
+ if (newval.tri == mod)
+ newval.tri = yes;
+ if (sym->visible == mod)
+ sym->visible = yes;
+ if (sym->rev_dep.tri == mod)
+ sym->rev_dep.tri = yes;
}
- if (!def_sym) {
- for_all_defaults(sym, def_prop) {
- if (E_CALC(def_prop->visible) == no)
- continue;
- sym_calc_visibility(def_prop->def);
- if (def_prop->def->visible != no) {
- def_sym = def_prop->def;
- break;
- }
+ break;
+ case S_STRING:
+ case S_HEX:
+ case S_INT:
+ if (sym->visible != no) {
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym)) {
+ newval.val = sym->user.val;
+ break;
}
}
-
- if (!def_sym) {
- prop = sym_get_choice_prop(sym);
- for (e = prop->dep; e; e = e->left.expr) {
- sym_calc_visibility(e->right.sym);
- if (e->right.sym->visible != no) {
- def_sym = e->right.sym;
- break;
- }
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ struct symbol *ds = prop_get_symbol(prop);
+ if (ds) {
+ sym->flags |= SYMBOL_WRITE;
+ sym_calc_value(ds);
+ newval.val = ds->curr.val;
}
}
-
- S_VAL(newval) = def_sym;
+ break;
+ default:
+ ;
}
- if (memcmp(&oldval, &newval, sizeof(newval)))
- sym->flags |= SYMBOL_CHANGED;
sym->curr = newval;
+ if (sym_is_choice(sym) && newval.tri == yes)
+ sym->curr.val = sym_calc_choice(sym);
+
+ if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
+ sym_set_changed(sym);
if (sym_is_choice(sym)) {
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
prop = sym_get_choice_prop(sym);
- for (e = prop->dep; e; e = e->left.expr)
+ for (e = prop->expr; e; e = e->left.expr) {
e->right.sym->flags |= flags;
+ if (flags & SYMBOL_CHANGED)
+ sym_set_changed(e->right.sym);
+ }
}
}
@@ -308,13 +322,24 @@
sym_change_count++;
}
+void sym_set_changed(struct symbol *sym)
+{
+ struct property *prop;
+
+ sym->flags |= SYMBOL_CHANGED;
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu)
+ prop->menu->flags |= MENU_CHANGED;
+ }
+}
+
void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
- sym->flags |= SYMBOL_CHANGED;
+ sym_set_changed(sym);
}
bool sym_tristate_within_range(struct symbol *sym, tristate val)
@@ -327,19 +352,13 @@
if (type != S_BOOLEAN && type != S_TRISTATE)
return false;
- switch (val) {
- case no:
- if (sym_is_choice_value(sym) && sym->visible == yes)
- return false;
- return sym_is_optional(sym);
- case mod:
- if (sym_is_choice_value(sym) && sym->visible == yes)
- return false;
- return type == S_TRISTATE;
- case yes:
- return type == S_BOOLEAN || sym->visible == yes;
- }
- return false;
+ if (type == S_BOOLEAN && val == mod)
+ return false;
+ if (sym->visible <= sym->rev_dep.tri)
+ return false;
+ if (sym_is_choice_value(sym) && sym->visible == yes)
+ return val == yes;
+ return val >= sym->rev_dep.tri && val <= sym->visible;
}
bool sym_set_tristate_value(struct symbol *sym, tristate val)
@@ -351,16 +370,16 @@
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
- sym->flags |= SYMBOL_CHANGED;
+ sym_set_changed(sym);
}
if (sym_is_choice_value(sym) && val == yes) {
- struct property *prop = sym_get_choice_prop(sym);
+ struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
- S_VAL(prop->def->def) = sym;
- prop->def->flags &= ~SYMBOL_NEW;
+ cs->user.val = sym;
+ cs->flags &= ~SYMBOL_NEW;
}
- S_TRI(sym->def) = val;
+ sym->user.tri = val;
if (oldval != val) {
sym_clear_all_valid();
if (sym == modules_sym)
@@ -404,12 +423,12 @@
ch = *str++;
if (ch == '-')
ch = *str++;
- if (!isdigit((int)ch))
+ if (!isdigit(ch))
return false;
if (ch == '0' && *str != 0)
return false;
while ((ch = *str++)) {
- if (!isdigit((int)ch))
+ if (!isdigit(ch))
return false;
}
return true;
@@ -418,21 +437,58 @@
str += 2;
ch = *str++;
do {
- if (!isxdigit((int)ch))
+ if (!isxdigit(ch))
return false;
} while ((ch = *str++));
return true;
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
- case 'y':
- case 'Y':
+ case 'y': case 'Y':
+ case 'm': case 'M':
+ case 'n': case 'N':
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool sym_string_within_range(struct symbol *sym, const char *str)
+{
+ struct property *prop;
+ int val;
+
+ switch (sym->type) {
+ case S_STRING:
+ return sym_string_valid(sym, str);
+ case S_INT:
+ if (!sym_string_valid(sym, str))
+ return false;
+ prop = sym_get_range_prop(sym);
+ if (!prop)
+ return true;
+ val = strtol(str, NULL, 10);
+ return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
+ val <= strtol(prop->expr->right.sym->name, NULL, 10);
+ case S_HEX:
+ if (!sym_string_valid(sym, str))
+ return false;
+ prop = sym_get_range_prop(sym);
+ if (!prop)
+ return true;
+ val = strtol(str, NULL, 16);
+ return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
+ val <= strtol(prop->expr->right.sym->name, NULL, 16);
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (str[0]) {
+ case 'y': case 'Y':
return sym_tristate_within_range(sym, yes);
- case 'm':
- case 'M':
+ case 'm': case 'M':
return sym_tristate_within_range(sym, mod);
- case 'n':
- case 'N':
+ case 'n': case 'N':
return sym_tristate_within_range(sym, no);
}
return false;
@@ -451,14 +507,11 @@
case S_BOOLEAN:
case S_TRISTATE:
switch (newval[0]) {
- case 'y':
- case 'Y':
+ case 'y': case 'Y':
return sym_set_tristate_value(sym, yes);
- case 'm':
- case 'M':
+ case 'm': case 'M':
return sym_set_tristate_value(sym, mod);
- case 'n':
- case 'N':
+ case 'n': case 'N':
return sym_set_tristate_value(sym, no);
}
return false;
@@ -466,23 +519,23 @@
;
}
- if (!sym_string_valid(sym, newval))
+ if (!sym_string_within_range(sym, newval))
return false;
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
- sym->flags |= SYMBOL_CHANGED;
+ sym_set_changed(sym);
}
- oldval = S_VAL(sym->def);
+ oldval = sym->user.val;
size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2;
- S_VAL(sym->def) = val = malloc(size);
+ sym->user.val = val = malloc(size);
*val++ = '0';
*val++ = 'x';
} else if (!oldval || strcmp(oldval, newval))
- S_VAL(sym->def) = val = malloc(size);
+ sym->user.val = val = malloc(size);
else
return true;
@@ -513,20 +566,12 @@
default:
;
}
- return (const char *)S_VAL(sym->curr);
+ return (const char *)sym->curr.val;
}
bool sym_is_changable(struct symbol *sym)
{
- if (sym->visible == no)
- return false;
- /* at least 'n' and 'y'/'m' is selectable */
- if (sym_is_optional(sym))
- return true;
- /* no 'n', so 'y' and 'm' must be selectable */
- if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes)
- return true;
- return false;
+ return sym->visible > sym->rev_dep.tri;
}
struct symbol *sym_lookup(const char *name, int isconst)
@@ -536,7 +581,6 @@
char *new_name;
int hash = 0;
- //printf("lookup: %s -> ", name);
if (name) {
if (name[0] && !name[1]) {
switch (name[0]) {
@@ -552,10 +596,8 @@
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name)) {
if ((isconst && symbol->flags & SYMBOL_CONST) ||
- (!isconst && !(symbol->flags & SYMBOL_CONST))) {
- //printf("h:%p\n", symbol);
+ (!isconst && !(symbol->flags & SYMBOL_CONST)))
return symbol;
- }
}
}
new_name = strdup(name);
@@ -575,7 +617,6 @@
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;
- //printf("n:%p\n", symbol);
return symbol;
}
@@ -608,6 +649,104 @@
return symbol;
}
+struct symbol *sym_check_deps(struct symbol *sym);
+
+static struct symbol *sym_check_expr_deps(struct expr *e)
+{
+ struct symbol *sym;
+
+ if (!e)
+ return NULL;
+ switch (e->type) {
+ case E_OR:
+ case E_AND:
+ sym = sym_check_expr_deps(e->left.expr);
+ if (sym)
+ return sym;
+ return sym_check_expr_deps(e->right.expr);
+ case E_NOT:
+ return sym_check_expr_deps(e->left.expr);
+ case E_EQUAL:
+ case E_UNEQUAL:
+ sym = sym_check_deps(e->left.sym);
+ if (sym)
+ return sym;
+ return sym_check_deps(e->right.sym);
+ case E_SYMBOL:
+ return sym_check_deps(e->left.sym);
+ default:
+ break;
+ }
+ printf("Oops! How to check %d?\n", e->type);
+ return NULL;
+}
+
+struct symbol *sym_check_deps(struct symbol *sym)
+{
+ struct symbol *sym2;
+ struct property *prop;
+
+ if (sym->flags & SYMBOL_CHECK_DONE)
+ return NULL;
+ if (sym->flags & SYMBOL_CHECK) {
+ printf("Warning! Found recursive dependency: %s", sym->name);
+ return sym;
+ }
+
+ sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+ sym2 = sym_check_expr_deps(sym->rev_dep.expr);
+ if (sym2)
+ goto out;
+
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->type == P_CHOICE)
+ continue;
+ sym2 = sym_check_expr_deps(prop->visible.expr);
+ if (sym2)
+ goto out;
+ if (prop->type != P_DEFAULT || sym_is_choice(sym))
+ continue;
+ sym2 = sym_check_expr_deps(prop->expr);
+ if (sym2)
+ goto out;
+ }
+out:
+ if (sym2)
+ printf(" %s", sym->name);
+ sym->flags &= ~SYMBOL_CHECK;
+ return sym2;
+}
+
+struct property *prop_alloc(enum prop_type type, struct symbol *sym)
+{
+ struct property *prop;
+ struct property **propp;
+
+ prop = malloc(sizeof(*prop));
+ memset(prop, 0, sizeof(*prop));
+ prop->type = type;
+ prop->sym = sym;
+ prop->file = current_file;
+ prop->lineno = zconf_lineno();
+
+ /* append property to the prop list of symbol */
+ if (sym) {
+ for (propp = &sym->prop; *propp; propp = &(*propp)->next)
+ ;
+ *propp = prop;
+ }
+
+ return prop;
+}
+
+struct symbol *prop_get_symbol(struct property *prop)
+{
+ if (prop->expr && (prop->expr->type == E_SYMBOL ||
+ prop->expr->type == E_CHOICE))
+ return prop->expr->left.sym;
+ return NULL;
+}
+
const char *prop_get_type_name(enum prop_type type)
{
switch (type) {
@@ -617,13 +756,16 @@
return "comment";
case P_MENU:
return "menu";
- case P_ROOTMENU:
- return "rootmenu";
case P_DEFAULT:
return "default";
case P_CHOICE:
return "choice";
- default:
- return "unknown";
+ case P_SELECT:
+ return "select";
+ case P_RANGE:
+ return "range";
+ case P_UNKNOWN:
+ break;
}
+ return "unknown";
}
Index: menu.c
===================================================================
RCS file: /var/cvs/busybox/scripts/config/menu.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- menu.c 5 Dec 2002 08:41:07 -0000 1.1
+++ menu.c 5 Aug 2003 02:18:25 -0000 1.2
@@ -54,9 +54,34 @@
current_menu = current_menu->parent;
}
+struct expr *menu_check_dep(struct expr *e)
+{
+ if (!e)
+ return e;
+
+ switch (e->type) {
+ case E_NOT:
+ e->left.expr = menu_check_dep(e->left.expr);
+ break;
+ case E_OR:
+ case E_AND:
+ e->left.expr = menu_check_dep(e->left.expr);
+ e->right.expr = menu_check_dep(e->right.expr);
+ break;
+ case E_SYMBOL:
+ /* change 'm' into 'm' && MODULES */
+ if (e->left.sym == &symbol_mod)
+ return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+ break;
+ default:
+ break;
+ }
+ return e;
+}
+
void menu_add_dep(struct expr *dep)
{
- current_entry->dep = expr_alloc_and(current_entry->dep, dep);
+ current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
}
void menu_set_type(int type)
@@ -69,56 +94,43 @@
sym->type = type;
return;
}
- fprintf(stderr, "%s:%d: type of '%s' redefined from '%s' to '%s'\n",
+ fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n",
current_entry->file->name, current_entry->lineno,
sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type));
}
-struct property *create_prop(enum prop_type type)
-{
- struct property *prop;
-
- prop = malloc(sizeof(*prop));
- memset(prop, 0, sizeof(*prop));
- prop->type = type;
- prop->file = current_file;
- prop->lineno = zconf_lineno();
-
- return prop;
-}
-
-struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep)
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
{
- struct property *prop = create_prop(token);
- struct property **propp;
+ struct property *prop = prop_alloc(type, current_entry->sym);
- prop->sym = current_entry->sym;
prop->menu = current_entry;
prop->text = prompt;
- prop->def = def;
- E_EXPR(prop->visible) = dep;
+ prop->expr = expr;
+ prop->visible.expr = menu_check_dep(dep);
- if (prompt)
+ if (prompt) {
+ if (current_entry->prompt)
+ fprintf(stderr, "%s:%d: prompt redefined\n",
+ current_entry->file->name, current_entry->lineno);
current_entry->prompt = prop;
-
- /* append property to the prop list of symbol */
- if (prop->sym) {
- for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
- ;
- *propp = prop;
}
return prop;
}
-void menu_add_prompt(int token, char *prompt, struct expr *dep)
+void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
{
- current_entry->prompt = menu_add_prop(token, prompt, NULL, dep);
+ menu_add_prop(type, prompt, NULL, dep);
}
-void menu_add_default(int token, struct symbol *def, struct expr *dep)
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
{
- current_entry->prompt = menu_add_prop(token, NULL, def, dep);
+ menu_add_prop(type, NULL, expr, dep);
+}
+
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
+{
+ menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
}
void menu_finalize(struct menu *parent)
@@ -126,7 +138,7 @@
struct menu *menu, *last_menu;
struct symbol *sym;
struct property *prop;
- struct expr *parentdep, *basedep, *dep, *dep2;
+ struct expr *parentdep, *basedep, *dep, *dep2, **ep;
sym = parent->sym;
if (parent->list) {
@@ -143,7 +155,7 @@
}
parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt)
- parentdep = E_EXPR(parent->prompt->visible);
+ parentdep = parent->prompt->visible.expr;
else
parentdep = parent->dep;
@@ -159,23 +171,28 @@
for (; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
- dep = expr_transform(E_EXPR(prop->visible));
+ dep = expr_transform(prop->visible.expr);
dep = expr_alloc_and(expr_copy(basedep), dep);
dep = expr_eliminate_dups(dep);
if (menu->sym && menu->sym->type != S_TRISTATE)
dep = expr_trans_bool(dep);
- E_EXPR(prop->visible) = dep;
+ prop->visible.expr = dep;
+ if (prop->type == P_SELECT) {
+ struct symbol *es = prop_get_symbol(prop);
+ es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
+ expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
+ }
}
}
for (menu = parent->list; menu; menu = menu->next)
menu_finalize(menu);
- } else if (sym && parent->prompt) {
- basedep = E_EXPR(parent->prompt->visible);
+ } else if (sym) {
+ basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
basedep = expr_eliminate_dups(expr_transform(basedep));
last_menu = NULL;
for (menu = parent->next; menu; menu = menu->next) {
- dep = menu->prompt ? E_EXPR(menu->prompt->visible) : menu->dep;
+ dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
if (!expr_contains_symbol(dep, sym))
break;
if (expr_depends_symbol(dep, sym))
@@ -204,14 +221,27 @@
for (menu = parent->list; menu; menu = menu->next) {
if (sym && sym_is_choice(sym) && menu->sym) {
menu->sym->flags |= SYMBOL_CHOICEVAL;
+ if (!menu->prompt)
+ fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n",
+ menu->file->name, menu->lineno);
+ for (prop = menu->sym->prop; prop; prop = prop->next) {
+ if (prop->type == P_PROMPT && prop->menu != menu) {
+ fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n",
+ prop->file->name, prop->lineno);
+
+ }
+ if (prop->type == P_DEFAULT)
+ fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n",
+ prop->file->name, prop->lineno);
+ }
current_entry = menu;
menu_set_type(sym->type);
- menu_add_prop(P_CHOICE, NULL, parent->sym, NULL);
- prop = sym_get_choice_prop(parent->sym);
- //dep = expr_alloc_one(E_CHOICE, dep);
- //dep->right.sym = menu->sym;
- prop->dep = expr_alloc_one(E_CHOICE, prop->dep);
- prop->dep->right.sym = menu->sym;
+ menu_add_symbol(P_CHOICE, sym, NULL);
+ prop = sym_get_choice_prop(sym);
+ for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
+ ;
+ *ep = expr_alloc_one(E_CHOICE, NULL);
+ (*ep)->right.sym = menu->sym;
}
if (menu->list && (!menu->prompt || !menu->prompt->text)) {
for (last_menu = menu->list; ; last_menu = last_menu->next) {
@@ -224,20 +254,79 @@
menu->list = NULL;
}
}
+
+ if (sym && !(sym->flags & SYMBOL_WARNED)) {
+ struct symbol *sym2;
+ if (sym->type == S_UNKNOWN)
+ fprintf(stderr, "%s:%d:warning: config symbol defined without type\n",
+ parent->file->name, parent->lineno);
+
+ if (sym_is_choice(sym) && !parent->prompt)
+ fprintf(stderr, "%s:%d:warning: choice must have a prompt\n",
+ parent->file->name, parent->lineno);
+
+ for (prop = sym->prop; prop; prop = prop->next) {
+ switch (prop->type) {
+ case P_DEFAULT:
+ if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+ prop->expr->type != E_SYMBOL)
+ fprintf(stderr, "%s:%d:warning: default must be a single symbol\n",
+ prop->file->name, prop->lineno);
+ break;
+ case P_SELECT:
+ sym2 = prop_get_symbol(prop);
+ if ((sym->type != S_BOOLEAN && sym->type != S_TRISTATE) ||
+ (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE))
+ fprintf(stderr, "%s:%d:warning: enable is only allowed with boolean and tristate symbols\n",
+ prop->file->name, prop->lineno);
+ break;
+ case P_RANGE:
+ if (sym->type != S_INT && sym->type != S_HEX)
+ fprintf(stderr, "%s:%d:warning: range is only allowed for int or hex symbols\n",
+ prop->file->name, prop->lineno);
+ if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
+ !sym_string_valid(sym, prop->expr->right.sym->name))
+ fprintf(stderr, "%s:%d:warning: range is invalid\n",
+ prop->file->name, prop->lineno);
+ break;
+ default:
+ ;
+ }
+ }
+ sym->flags |= SYMBOL_WARNED;
+ }
+
+ if (sym && !sym_is_optional(sym) && parent->prompt) {
+ sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
+ expr_alloc_and(parent->prompt->visible.expr,
+ expr_alloc_symbol(&symbol_mod)));
+ }
}
bool menu_is_visible(struct menu *menu)
{
+ struct menu *child;
+ struct symbol *sym;
tristate visible;
if (!menu->prompt)
return false;
- if (menu->sym) {
- sym_calc_value(menu->sym);
- visible = E_TRI(menu->prompt->visible);
+ sym = menu->sym;
+ if (sym) {
+ sym_calc_value(sym);
+ visible = menu->prompt->visible.tri;
} else
- visible = E_CALC(menu->prompt->visible);
- return visible != no;
+ visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
+
+ if (visible != no)
+ return true;
+ if (!sym || sym_get_tristate_value(menu->sym) == no)
+ return false;
+
+ for (child = menu->list; child; child = child->next)
+ if (menu_is_visible(child))
+ return true;
+ return false;
}
const char *menu_get_prompt(struct menu *menu)
@@ -258,10 +347,9 @@
{
enum prop_type type;
- while (menu != &rootmenu) {
- menu = menu->parent;
+ for (; menu != &rootmenu; menu = menu->parent) {
type = menu->prompt ? menu->prompt->type : 0;
- if (type == P_MENU || type == P_ROOTMENU)
+ if (type == P_MENU)
break;
}
return menu;
Index: zconf.y
===================================================================
RCS file: /var/cvs/busybox/scripts/config/zconf.y,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- zconf.y 5 Dec 2002 08:41:09 -0000 1.1
+++ zconf.y 5 Aug 2003 02:18:25 -0000 1.2
@@ -27,7 +27,7 @@
#define YYERROR_VERBOSE
%}
-%expect 36
+%expect 40
%union
{
@@ -46,6 +46,7 @@
%token T_ENDCHOICE
%token T_COMMENT
%token T_CONFIG
+%token T_MENUCONFIG
%token T_HELP
%token <string> T_HELPTEXT
%token T_IF
@@ -56,17 +57,22 @@
%token T_PROMPT
%token T_DEFAULT
%token T_TRISTATE
+%token T_DEF_TRISTATE
%token T_BOOLEAN
+%token T_DEF_BOOLEAN
+%token T_STRING
%token T_INT
%token T_HEX
%token <string> T_WORD
-%token <string> T_STRING
+%token <string> T_WORD_QUOTE
%token T_UNEQUAL
%token T_EOF
%token T_EOL
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
%token T_ON
+%token T_SELECT
+%token T_RANGE
%left T_OR
%left T_AND
@@ -103,14 +109,15 @@
if_stmt
| comment_stmt
| config_stmt
+ | menuconfig_stmt
| source_stmt
| nl_or_eof
;
-/* config entry */
+/* config/menuconfig entry */
-config_entry_start: T_CONFIG T_WORD
+config_entry_start: T_CONFIG T_WORD T_EOL
{
struct symbol *sym = sym_lookup($2, 0);
sym->flags |= SYMBOL_OPTIONAL;
@@ -118,74 +125,118 @@
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
};
-config_stmt: config_entry_start T_EOL config_option_list
+config_stmt: config_entry_start config_option_list
+{
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+};
+
+menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
+{
+ struct symbol *sym = sym_lookup($2, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+menuconfig_stmt: menuconfig_entry_start config_option_list
{
+ if (current_entry->prompt)
+ current_entry->prompt->type = P_MENU;
+ else
+ zconfprint("warning: menuconfig statement without prompt");
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
};
config_option_list:
/* empty */
- | config_option_list config_option T_EOL
- | config_option_list depends T_EOL
+ | config_option_list config_option
+ | config_option_list depends
| config_option_list help
| config_option_list T_EOL
-{ };
+;
-config_option: T_TRISTATE prompt_stmt_opt
+config_option: T_TRISTATE prompt_stmt_opt T_EOL
{
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
};
-config_option: T_BOOLEAN prompt_stmt_opt
+config_option: T_DEF_TRISTATE expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_BOOLEAN prompt_stmt_opt T_EOL
{
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
};
-config_option: T_INT prompt_stmt_opt
+config_option: T_DEF_BOOLEAN expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_INT prompt_stmt_opt T_EOL
{
menu_set_type(S_INT);
printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
};
-config_option: T_HEX prompt_stmt_opt
+config_option: T_HEX prompt_stmt_opt T_EOL
{
menu_set_type(S_HEX);
printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
};
-config_option: T_STRING prompt_stmt_opt
+config_option: T_STRING prompt_stmt_opt T_EOL
{
menu_set_type(S_STRING);
printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
};
-config_option: T_PROMPT prompt if_expr
+config_option: T_PROMPT prompt if_expr T_EOL
{
- menu_add_prop(P_PROMPT, $2, NULL, $3);
+ menu_add_prompt(P_PROMPT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
-config_option: T_DEFAULT symbol if_expr
+config_option: T_DEFAULT expr if_expr T_EOL
{
- menu_add_prop(P_DEFAULT, NULL, $2, $3);
+ menu_add_expr(P_DEFAULT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
+config_option: T_SELECT T_WORD if_expr T_EOL
+{
+ menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
+ printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_RANGE symbol symbol if_expr T_EOL
+{
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
+ printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+};
+
/* choice entry */
-choice: T_CHOICE
+choice: T_CHOICE T_EOL
{
struct symbol *sym = sym_lookup(NULL, 0);
sym->flags |= SYMBOL_CHOICE;
menu_add_entry(sym);
- menu_add_prop(P_CHOICE, NULL, NULL, NULL);
+ menu_add_expr(P_CHOICE, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
};
-choice_entry: choice T_EOL choice_option_list
+choice_entry: choice choice_option_list
{
menu_end_entry();
menu_add_menu();
@@ -200,7 +251,7 @@
};
choice_stmt:
- choice_entry choice_block choice_end T_EOL
+ choice_entry choice_block choice_end
| choice_entry choice_block
{
printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
@@ -209,28 +260,39 @@
choice_option_list:
/* empty */
- | choice_option_list choice_option T_EOL
- | choice_option_list depends T_EOL
+ | choice_option_list choice_option
+ | choice_option_list depends
| choice_option_list help
| choice_option_list T_EOL
;
-choice_option: T_PROMPT prompt if_expr
+choice_option: T_PROMPT prompt if_expr T_EOL
{
- menu_add_prop(P_PROMPT, $2, NULL, $3);
+ menu_add_prompt(P_PROMPT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
-choice_option: T_OPTIONAL
+choice_option: T_TRISTATE prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_OPTIONAL T_EOL
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
};
-choice_option: T_DEFAULT symbol
+choice_option: T_DEFAULT T_WORD if_expr T_EOL
{
- menu_add_prop(P_DEFAULT, NULL, $2, NULL);
- //current_choice->prop->def = $2;
+ menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
@@ -241,11 +303,10 @@
/* if entry */
-if: T_IF expr
+if: T_IF expr T_EOL
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
- //current_entry->prompt = menu_add_prop(T_IF, NULL, NULL, $2);
menu_add_dep($2);
menu_end_entry();
menu_add_menu();
@@ -260,8 +321,8 @@
};
if_stmt:
- if T_EOL if_block if_end T_EOL
- | if T_EOL if_block
+ if if_block if_end
+ | if if_block
{
printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
@@ -276,14 +337,14 @@
/* menu entry */
-menu: T_MENU prompt
+menu: T_MENU prompt T_EOL
{
menu_add_entry(NULL);
menu_add_prop(P_MENU, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
};
-menu_entry: menu T_EOL depends_list
+menu_entry: menu depends_list
{
menu_end_entry();
menu_add_menu();
@@ -298,7 +359,7 @@
};
menu_stmt:
- menu_entry menu_block menu_end T_EOL
+ menu_entry menu_block menu_end
| menu_entry menu_block
{
printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
@@ -313,27 +374,27 @@
| menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
;
-source: T_SOURCE prompt
+source: T_SOURCE prompt T_EOL
{
$$ = $2;
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
};
-source_stmt: source T_EOL
+source_stmt: source
{
zconf_nextfile($1);
};
/* comment entry */
-comment: T_COMMENT prompt
+comment: T_COMMENT prompt T_EOL
{
menu_add_entry(NULL);
menu_add_prop(P_COMMENT, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
};
-comment_stmt: comment T_EOL depends_list
+comment_stmt: comment depends_list
{
menu_end_entry();
};
@@ -354,21 +415,21 @@
/* depends option */
depends_list: /* empty */
- | depends_list depends T_EOL
+ | depends_list depends
| depends_list T_EOL
-{ };
+;
-depends: T_DEPENDS T_ON expr
+depends: T_DEPENDS T_ON expr T_EOL
{
menu_add_dep($3);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
}
- | T_DEPENDS expr
+ | T_DEPENDS expr T_EOL
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
}
- | T_REQUIRES expr
+ | T_REQUIRES expr T_EOL
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
@@ -378,22 +439,18 @@
prompt_stmt_opt:
/* empty */
- | prompt
-{
- menu_add_prop(P_PROMPT, $1, NULL, NULL);
-}
- | prompt T_IF expr
+ | prompt if_expr
{
- menu_add_prop(P_PROMPT, $1, NULL, $3);
+ menu_add_prop(P_PROMPT, $1, NULL, $2);
};
prompt: T_WORD
- | T_STRING
+ | T_WORD_QUOTE
;
-end: T_ENDMENU { $$ = T_ENDMENU; }
- | T_ENDCHOICE { $$ = T_ENDCHOICE; }
- | T_ENDIF { $$ = T_ENDIF; }
+end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
+ | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
+ | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
;
nl_or_eof:
@@ -413,26 +470,34 @@
;
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
- | T_STRING { $$ = sym_lookup($1, 1); free($1); }
+ | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
;
%%
void conf_parse(const char *name)
{
+ struct symbol *sym;
+ int i;
+
zconf_initscan(name);
sym_init();
menu_init();
- rootmenu.prompt = menu_add_prop(P_MENU, "BusyBox Configuration", NULL, NULL);
+ modules_sym = sym_lookup("MODULES", 0);
+ rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
//zconfdebug = 1;
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
-
- modules_sym = sym_lookup("MODULES", 0);
+ for_all_symbols(i, sym) {
+ if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
+ printf("\n");
+ else
+ sym->flags |= SYMBOL_CHECK_DONE;
+ }
sym_change_count = 1;
}
@@ -448,7 +513,7 @@
case T_ENDIF: return "endif";
}
return "<token>";
-}
+}
static bool zconf_endtoken(int token, int starttoken, int endtoken)
{
@@ -470,7 +535,7 @@
{
va_list ap;
- fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
@@ -479,7 +544,7 @@
static void zconferror(const char *err)
{
- fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err);
+ fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
}
void print_quoted_string(FILE *out, const char *str)
@@ -504,8 +569,6 @@
struct symbol *sym = menu->sym;
struct property *prop;
- //sym->flags |= SYMBOL_PRINTED;
-
if (sym_is_choice(sym))
fprintf(out, "choice\n");
else
@@ -530,13 +593,6 @@
fputs(" ???\n", out);
break;
}
-#if 0
- if (!expr_is_yes(sym->dep)) {
- fputs(" depends ", out);
- expr_fprint(sym->dep, out);
- fputc('\n', out);
- }
-#endif
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
@@ -544,25 +600,18 @@
case P_PROMPT:
fputs(" prompt ", out);
print_quoted_string(out, prop->text);
- if (prop->def) {
- fputc(' ', out);
- if (prop->def->flags & SYMBOL_CONST)
- print_quoted_string(out, prop->def->name);
- else
- fputs(prop->def->name, out);
- }
- if (!expr_is_yes(E_EXPR(prop->visible))) {
+ if (!expr_is_yes(prop->visible.expr)) {
fputs(" if ", out);
- expr_fprint(E_EXPR(prop->visible), out);
+ expr_fprint(prop->visible.expr, out);
}
fputc('\n', out);
break;
case P_DEFAULT:
fputs( " default ", out);
- print_quoted_string(out, prop->def->name);
- if (!expr_is_yes(E_EXPR(prop->visible))) {
+ expr_fprint(prop->expr, out);
+ if (!expr_is_yes(prop->visible.expr)) {
fputs(" if ", out);
- expr_fprint(E_EXPR(prop->visible), out);
+ expr_fprint(prop->visible.expr, out);
}
fputc('\n', out);
break;
@@ -585,7 +634,6 @@
void zconfdump(FILE *out)
{
- //struct file *file;
struct property *prop;
struct symbol *sym;
struct menu *menu;
@@ -596,11 +644,6 @@
print_symbol(out, menu);
else if ((prop = menu->prompt)) {
switch (prop->type) {
- //case T_MAINMENU:
- // fputs("\nmainmenu ", out);
- // print_quoted_string(out, prop->text);
- // fputs("\n", out);
- // break;
case P_COMMENT:
fputs("\ncomment ", out);
print_quoted_string(out, prop->text);
@@ -611,19 +654,12 @@
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
- //case T_SOURCE:
- // fputs("\nsource ", out);
- // print_quoted_string(out, prop->text);
- // fputs("\n", out);
- // break;
- //case T_IF:
- // fputs("\nif\n", out);
default:
;
}
- if (!expr_is_yes(E_EXPR(prop->visible))) {
+ if (!expr_is_yes(prop->visible.expr)) {
fputs(" depends ", out);
- expr_fprint(E_EXPR(prop->visible), out);
+ expr_fprint(prop->visible.expr, out);
fputc('\n', out);
}
fputs("\n", out);
Index: lex.zconf.c_shipped
===================================================================
RCS file: /var/cvs/busybox/scripts/config/lex.zconf.c_shipped,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- lex.zconf.c_shipped 5 Dec 2002 08:41:07 -0000 1.1
+++ lex.zconf.c_shipped 5 Aug 2003 02:18:24 -0000 1.2
@@ -1,50 +1,84 @@
-#define yy_create_buffer zconf_create_buffer
-#define yy_delete_buffer zconf_delete_buffer
-#define yy_scan_buffer zconf_scan_buffer
-#define yy_scan_string zconf_scan_string
-#define yy_scan_bytes zconf_scan_bytes
-#define yy_flex_debug zconf_flex_debug
-#define yy_init_buffer zconf_init_buffer
-#define yy_flush_buffer zconf_flush_buffer
-#define yy_load_buffer_state zconf_load_buffer_state
-#define yy_switch_to_buffer zconf_switch_to_buffer
-#define yyin zconfin
[...4718 lines suppressed...]
+ fclose(zconfin);
+ zconf_delete_buffer(YY_CURRENT_BUFFER);
+ zconf_switch_to_buffer(parent->state);
}
free(current_buf);
current_buf = parent;
@@ -3266,7 +3673,7 @@
int zconf_lineno(void)
{
if (current_buf)
- return current_file->lineno;
+ return current_file->lineno - 1;
else
return 0;
}
@@ -3278,3 +3685,4 @@
else
return "<none>";
}
+
Index: lkc_proto.h
===================================================================
RCS file: /var/cvs/busybox/scripts/config/lkc_proto.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- lkc_proto.h 31 Mar 2003 16:27:18 -0000 1.2
+++ lkc_proto.h 5 Aug 2003 02:18:25 -0000 1.3
@@ -5,7 +5,7 @@
P(conf_write,int,(const char *name));
/* menu.c */
-extern struct menu rootmenu;
+P(rootmenu,struct menu,);
P(menu_is_visible,bool,(struct menu *menu));
P(menu_get_prompt,const char *,(struct menu *menu));
@@ -14,17 +14,18 @@
/* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
-extern int sym_change_count;
+P(sym_change_count,int,);
P(sym_lookup,struct symbol *,(const char *name, int isconst));
P(sym_find,struct symbol *,(const char *name));
-P(sym_type_name,const char *,(int type));
+P(sym_type_name,const char *,(enum symbol_type type));
P(sym_calc_value,void,(struct symbol *sym));
-P(sym_get_type,int,(struct symbol *sym));
+P(sym_get_type,enum symbol_type,(struct symbol *sym));
P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
+P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
P(sym_is_changable,bool,(struct symbol *sym));
P(sym_get_choice_prop,struct property *,(struct symbol *sym));
Index: expr.c
===================================================================
RCS file: /var/cvs/busybox/scripts/config/expr.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- expr.c 5 Dec 2002 08:41:06 -0000 1.1
+++ expr.c 5 Aug 2003 02:18:24 -0000 1.2
@@ -55,6 +55,13 @@
return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
}
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
+{
+ if (!e1)
+ return e2;
+ return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
+}
+
struct expr *expr_copy(struct expr *org)
{
struct expr *e;
@@ -158,9 +165,22 @@
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
{
- if (!e1 || !e2 || e1->type != e2->type)
+ if (!e1 || !e2)
return;
- __expr_eliminate_eq(e1->type, ep1, ep2);
+ switch (e1->type) {
+ case E_OR:
+ case E_AND:
+ __expr_eliminate_eq(e1->type, ep1, ep2);
+ default:
+ ;
+ }
+ if (e1->type != e2->type) switch (e2->type) {
+ case E_OR:
+ case E_AND:
+ __expr_eliminate_eq(e2->type, ep1, ep2);
+ default:
+ ;
+ }
e1 = expr_eliminate_yn(e1);
e2 = expr_eliminate_yn(e2);
}
@@ -195,6 +215,7 @@
trans_count = old_count;
return res;
case E_CHOICE:
+ case E_RANGE:
case E_NONE:
/* panic */;
}
@@ -897,6 +918,7 @@
case E_SYMBOL:
return expr_alloc_comp(type, e->left.sym, sym);
case E_CHOICE:
+ case E_RANGE:
case E_NONE:
/* panic */;
}
@@ -914,7 +936,7 @@
switch (e->type) {
case E_SYMBOL:
sym_calc_value(e->left.sym);
- return S_TRI(e->left.sym->curr);
+ return e->left.sym->curr.tri;
case E_AND:
val1 = expr_calc_value(e->left.expr);
val2 = expr_calc_value(e->right.expr);
@@ -1017,11 +1039,18 @@
expr_print(e->right.expr, fn, data, E_AND);
break;
case E_CHOICE:
+ fn(data, e->right.sym->name);
if (e->left.expr) {
- expr_print(e->left.expr, fn, data, E_CHOICE);
fn(data, " ^ ");
+ expr_print(e->left.expr, fn, data, E_CHOICE);
}
+ break;
+ case E_RANGE:
+ fn(data, "[");
+ fn(data, e->left.sym->name);
+ fn(data, " ");
fn(data, e->right.sym->name);
+ fn(data, "]");
break;
default:
{
Index: expr.h
===================================================================
RCS file: /var/cvs/busybox/scripts/config/expr.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- expr.h 5 Dec 2002 08:41:06 -0000 1.1
+++ expr.h 5 Aug 2003 02:18:24 -0000 1.2
@@ -18,10 +18,6 @@
struct file {
struct file *next;
struct file *parent;
-#ifdef CML1
- struct statement *stmt;
- struct statement *last_stmt;
-#endif
char *name;
int lineno;
int flags;
@@ -36,7 +32,7 @@
} tristate;
enum expr_type {
- E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL
+ E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
};
union expr_data {
@@ -45,18 +41,10 @@
};
struct expr {
-#ifdef CML1
- int token;
-#else
enum expr_type type;
-#endif
union expr_data left, right;
};
-#define E_TRI(ev) ((ev).tri)
-#define E_EXPR(ev) ((ev).expr)
-#define E_CALC(ev) (E_TRI(ev) = expr_calc_value(E_EXPR(ev)))
-
#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
#define E_NOT(dep) (2-(dep))
@@ -66,12 +54,8 @@
tristate tri;
};
-#define S_VAL(sv) ((sv).value)
-#define S_TRI(sv) ((sv).tri)
-#define S_EQ(sv1, sv2) (S_VAL(sv1) == S_VAL(sv2) || !strcmp(S_VAL(sv1), S_VAL(sv2)))
-
struct symbol_value {
- void *value;
+ void *val;
tristate tri;
};
@@ -83,31 +67,17 @@
struct symbol *next;
char *name;
char *help;
-#ifdef CML1
- int type;
-#else
enum symbol_type type;
-#endif
- struct symbol_value curr, def;
+ struct symbol_value curr, user;
tristate visible;
int flags;
struct property *prop;
struct expr *dep, *dep2;
- struct menu *menu;
+ struct expr_value rev_dep;
};
#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
-#ifdef CML1
-#define SYMBOL_UNKNOWN S_UNKNOWN
-#define SYMBOL_BOOLEAN S_BOOLEAN
-#define SYMBOL_TRISTATE S_TRISTATE
-#define SYMBOL_INT S_INT
-#define SYMBOL_HEX S_HEX
-#define SYMBOL_STRING S_STRING
-#define SYMBOL_OTHER S_OTHER
-#endif
-
#define SYMBOL_YES 0x0001
#define SYMBOL_MOD 0x0002
#define SYMBOL_NO 0x0004
@@ -122,42 +92,38 @@
#define SYMBOL_CHANGED 0x0400
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000
+#define SYMBOL_CHECKED 0x2000
+#define SYMBOL_CHECK_DONE 0x4000
+#define SYMBOL_WARNED 0x8000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257
#define SYMBOL_HASHMASK 0xff
enum prop_type {
- P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE
+ P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
};
struct property {
struct property *next;
struct symbol *sym;
-#ifdef CML1
- int token;
-#else
enum prop_type type;
-#endif
const char *text;
- struct symbol *def;
struct expr_value visible;
- struct expr *dep;
- struct expr *dep2;
+ struct expr *expr;
struct menu *menu;
struct file *file;
int lineno;
-#ifdef CML1
- struct property *next_pos;
-#endif
};
#define for_all_properties(sym, st, tok) \
for (st = sym->prop; st; st = st->next) \
if (st->type == (tok))
-#define for_all_prompts(sym, st) for_all_properties(sym, st, P_PROMPT)
#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
+#define for_all_prompts(sym, st) \
+ for (st = sym->prop; st; st = st->next) \
+ if (st->text)
struct menu {
struct menu *next;
@@ -166,12 +132,16 @@
struct symbol *sym;
struct property *prompt;
struct expr *dep;
+ unsigned int flags;
//char *help;
struct file *file;
int lineno;
void *data;
};
+#define MENU_CHANGED 0x0001
+#define MENU_ROOT 0x0002
+
#ifndef SWIG
extern struct file *file_list;
@@ -181,18 +151,12 @@
extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym;
extern int cdebug;
-extern int print_type;
struct expr *expr_alloc_symbol(struct symbol *sym);
-#ifdef CML1
-struct expr *expr_alloc_one(int token, struct expr *ce);
-struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2);
-struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2);
-#else
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
-#endif
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
struct expr *expr_copy(struct expr *org);
void expr_free(struct expr *e);
int expr_eq(struct expr *e1, struct expr *e2);
@@ -212,17 +176,6 @@
void expr_fprint(struct expr *e, FILE *out);
void print_expr(int mask, struct expr *e, int prevtoken);
-#ifdef CML1
-static inline int expr_is_yes(struct expr *e)
-{
- return !e || (e->token == WORD && e->left.sym == &symbol_yes);
-}
-
-static inline int expr_is_no(struct expr *e)
-{
- return e && (e->token == WORD && e->left.sym == &symbol_no);
-}
-#else
static inline int expr_is_yes(struct expr *e)
{
return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
@@ -232,7 +185,6 @@
{
return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
}
-#endif
#endif
#ifdef __cplusplus
More information about the busybox-cvs
mailing list