Merge/rework config system per the latest from linux-2.6.0-test2.
Fix the config bugs revealed by the updated config system. -Erik
This commit is contained in:
parent
461c279ac1
commit
72d8e444f0
@ -35,50 +35,12 @@ static struct menu *rootEntry;
|
||||
|
||||
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 @@ static void strip(char *str)
|
||||
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 @@ static void conf_askvalue(struct symbol *sym, const char *def)
|
||||
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 @@ static void conf_askvalue(struct symbol *sym, const char *def)
|
||||
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 @@ help:
|
||||
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 @@ static int conf_choice(struct menu *menu)
|
||||
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);
|
||||
|
||||
conf_childs:
|
||||
for (child = menu->list; child; child = child->next) {
|
||||
if (!child->sym || !menu_is_visible(child))
|
||||
continue;
|
||||
if (!--cnt)
|
||||
break;
|
||||
}
|
||||
if (!child)
|
||||
continue;
|
||||
if (line[strlen(line) - 1] == '?') {
|
||||
printf("\n%s\n", child->sym->help ?
|
||||
child->sym->help : nohelp_text);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
sym_set_choice_value(sym, child->sym);
|
||||
if (child->list) {
|
||||
indent += 2;
|
||||
conf(child->list);
|
||||
indent -= 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +432,7 @@ static void conf(struct menu *menu)
|
||||
|
||||
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 @@ static void check_conf(struct menu *menu)
|
||||
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 @@ int main(int ac, char **av)
|
||||
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);
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Roman Zippel <zippel@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@ucw.cz>
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -38,7 +36,7 @@ static char *conf_expand_value(const char *in)
|
||||
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 @@ static char *conf_expand_value(const char *in)
|
||||
|
||||
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 conf_read(const char *name)
|
||||
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 @@ int conf_read(const char *name)
|
||||
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 @@ int conf_read(const char *name)
|
||||
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 @@ int conf_read(const char *name)
|
||||
}
|
||||
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 @@ int conf_write(const char *name)
|
||||
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 @@ int conf_write(const char *name)
|
||||
"#\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 @@ int conf_write(const char *name)
|
||||
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 @@ int conf_write(const char *name)
|
||||
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 @@ int conf_write(const char *name)
|
||||
// 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 @@ int conf_write(const char *name)
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
@ -55,6 +55,13 @@ struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
|
||||
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 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
|
||||
|
||||
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 @@ int expr_eq(struct expr *e1, struct expr *e2)
|
||||
trans_count = old_count;
|
||||
return res;
|
||||
case E_CHOICE:
|
||||
case E_RANGE:
|
||||
case E_NONE:
|
||||
/* panic */;
|
||||
}
|
||||
@ -897,6 +918,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
|
||||
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 @@ tristate expr_calc_value(struct expr *e)
|
||||
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 @@ void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, in
|
||||
expr_print(e->right.expr, fn, data, E_AND);
|
||||
break;
|
||||
case E_CHOICE:
|
||||
if (e->left.expr) {
|
||||
expr_print(e->left.expr, fn, data, E_CHOICE);
|
||||
fn(data, " ^ ");
|
||||
}
|
||||
fn(data, e->right.sym->name);
|
||||
if (e->left.expr) {
|
||||
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:
|
||||
{
|
||||
|
@ -18,10 +18,6 @@ extern "C" {
|
||||
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 @@ typedef enum tristate {
|
||||
} 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 @@ union expr_data {
|
||||
};
|
||||
|
||||
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 @@ struct expr_value {
|
||||
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 {
|
||||
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 @@ struct symbol {
|
||||
#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 menu {
|
||||
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 @@ struct file *lookup_file(const char *name);
|
||||
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 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
|
||||
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);
|
||||
@ -233,7 +186,6 @@ static inline int expr_is_no(struct expr *e)
|
||||
return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,12 +21,14 @@ extern "C" {
|
||||
#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_add_menu(void);
|
||||
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 @@ extern struct menu *current_menu;
|
||||
/* 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_is_optional(struct symbol *sym)
|
||||
|
||||
static inline bool sym_has_value(struct symbol *sym)
|
||||
{
|
||||
//return S_VAL(sym->def) != NULL;
|
||||
return sym->flags & SYMBOL_NEW ? false : true;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ P(conf_read,int,(const char *name));
|
||||
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 @@ P(menu_get_parent_menu,struct menu *,(struct menu *menu));
|
||||
|
||||
/* 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));
|
||||
|
@ -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 @@ load_config_help[] =
|
||||
"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 show_readme(void);
|
||||
static void init_wsize(void)
|
||||
{
|
||||
struct winsize ws;
|
||||
char *env;
|
||||
|
||||
if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
|
||||
rows = 24;
|
||||
@ -127,6 +129,20 @@ static void init_wsize(void)
|
||||
} 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 @@ static void build_conf(struct menu *menu)
|
||||
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 @@ static void build_conf(struct menu *menu)
|
||||
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 @@ static void build_conf(struct menu *menu)
|
||||
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 @@ static void build_conf(struct menu *menu)
|
||||
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 @@ static void conf(struct menu *menu)
|
||||
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 @@ static void conf_cleanup(void)
|
||||
{
|
||||
tcsetattr(1, TCSAFLUSH, &ios_org);
|
||||
unlink(".help.tmp");
|
||||
unlink("lxdialog.scrltmp");
|
||||
}
|
||||
|
||||
static void winch_handler(int sig)
|
||||
@ -638,10 +665,9 @@ int main(int ac, char **av)
|
||||
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");
|
||||
|
@ -54,9 +54,34 @@ void menu_end_menu(void)
|
||||
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 @@ void menu_set_type(int type)
|
||||
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 *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
|
||||
{
|
||||
struct property *prop;
|
||||
struct property *prop = prop_alloc(type, current_entry->sym);
|
||||
|
||||
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 *prop = create_prop(token);
|
||||
struct property **propp;
|
||||
|
||||
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 @@ void menu_finalize(struct menu *parent)
|
||||
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 @@ void menu_finalize(struct menu *parent)
|
||||
}
|
||||
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 @@ void menu_finalize(struct menu *parent)
|
||||
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 @@ void menu_finalize(struct menu *parent)
|
||||
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 @@ void menu_finalize(struct menu *parent)
|
||||
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 @@ struct menu *menu_get_parent_menu(struct menu *menu)
|
||||
{
|
||||
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;
|
||||
|
@ -34,24 +34,14 @@ struct symbol *modules_sym;
|
||||
|
||||
void sym_add_default(struct symbol *sym, const char *def)
|
||||
{
|
||||
struct property *prop = create_prop(P_DEFAULT);
|
||||
struct property **propp;
|
||||
struct property *prop = prop_alloc(P_DEFAULT, sym);
|
||||
|
||||
prop->sym = sym;
|
||||
prop->def = sym_lookup(def, 1);
|
||||
|
||||
/* 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 @@ void sym_init(void)
|
||||
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 @@ void sym_init(void)
|
||||
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 @@ const char *sym_type_name(int type)
|
||||
return "string";
|
||||
case S_UNKNOWN:
|
||||
return "unknown";
|
||||
case S_OTHER:
|
||||
break;
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
@ -138,41 +114,104 @@ struct property *sym_get_choice_prop(struct symbol *sym)
|
||||
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 @@ void sym_calc_value(struct symbol *sym)
|
||||
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 @@ void sym_calc_value(struct symbol *sym)
|
||||
/* 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;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prop = sym_get_default_prop(sym);
|
||||
if (prop) {
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
sym_calc_value(prop->def);
|
||||
newval = prop->def->curr;
|
||||
struct symbol *ds = prop_get_symbol(prop);
|
||||
if (ds) {
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
sym_calc_value(ds);
|
||||
newval.val = ds->curr.val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
out:
|
||||
sym->curr = newval;
|
||||
if (sym_is_choice(sym) && newval.tri == yes)
|
||||
sym->curr.val = sym_calc_choice(sym);
|
||||
|
||||
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 (!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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S_VAL(newval) = def_sym;
|
||||
}
|
||||
|
||||
if (memcmp(&oldval, &newval, sizeof(newval)))
|
||||
sym->flags |= SYMBOL_CHANGED;
|
||||
sym->curr = newval;
|
||||
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 @@ void sym_clear_all_valid(void)
|
||||
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 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
|
||||
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 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
|
||||
|
||||
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 @@ bool sym_string_valid(struct symbol *sym, const char *str)
|
||||
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 @@ bool sym_string_valid(struct symbol *sym, const char *str)
|
||||
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 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
|
||||
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 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
|
||||
;
|
||||
}
|
||||
|
||||
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 @@ const char *sym_get_string_value(struct symbol *sym)
|
||||
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 @@ struct symbol *sym_lookup(const char *name, int isconst)
|
||||
char *new_name;
|
||||
int hash = 0;
|
||||
|
||||
//printf("lookup: %s -> ", name);
|
||||
if (name) {
|
||||
if (name[0] && !name[1]) {
|
||||
switch (name[0]) {
|
||||
@ -552,10 +596,8 @@ struct symbol *sym_lookup(const char *name, int isconst)
|
||||
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 @@ struct symbol *sym_lookup(const char *name, int isconst)
|
||||
symbol->next = symbol_hash[hash];
|
||||
symbol_hash[hash] = symbol;
|
||||
|
||||
//printf("n:%p\n", symbol);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
@ -608,6 +649,104 @@ struct symbol *sym_find(const char *name)
|
||||
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 @@ const char *prop_get_type_name(enum prop_type type)
|
||||
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";
|
||||
}
|
||||
|
@ -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 @@ n [A-Za-z0-9_]
|
||||
"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 @@ n [A-Za-z0-9_]
|
||||
"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 @@ n [A-Za-z0-9_]
|
||||
zconflval.string = text;
|
||||
return T_WORD;
|
||||
}
|
||||
#.* /* comment */
|
||||
\\\n current_file->lineno++;
|
||||
.
|
||||
<<EOF>> {
|
||||
BEGIN(INITIAL);
|
||||
@ -151,29 +160,30 @@ n [A-Za-z0-9_]
|
||||
[^'"\\\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 @@ n [A-Za-z0-9_]
|
||||
}
|
||||
append_string(" ", ts);
|
||||
}
|
||||
|
||||
}
|
||||
\n/[^ \t\n] {
|
||||
[ \t]*\n/[^ \t\n] {
|
||||
current_file->lineno++;
|
||||
zconf_endhelp();
|
||||
return T_HELPTEXT;
|
||||
@ -246,12 +255,37 @@ void zconf_starthelp(void)
|
||||
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 @@ void zconf_nextfile(const char *name)
|
||||
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 @@ static struct buffer *zconf_endfile(void)
|
||||
int zconf_lineno(void)
|
||||
{
|
||||
if (current_buf)
|
||||
return current_file->lineno;
|
||||
return current_file->lineno - 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,7 @@ struct symbol *symbol_hash[257];
|
||||
|
||||
#define YYERROR_VERBOSE
|
||||
%}
|
||||
%expect 36
|
||||
%expect 40
|
||||
|
||||
%union
|
||||
{
|
||||
@ -46,6 +46,7 @@ struct symbol *symbol_hash[257];
|
||||
%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 @@ struct symbol *symbol_hash[257];
|
||||
%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 @@ common_block:
|
||||
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 @@ config_entry_start: T_CONFIG T_WORD
|
||||
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_end: end
|
||||
};
|
||||
|
||||
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_stmt:
|
||||
|
||||
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 @@ choice_block:
|
||||
|
||||
/* 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_end: end
|
||||
};
|
||||
|
||||
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 @@ if_block:
|
||||
|
||||
/* 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_end: end
|
||||
};
|
||||
|
||||
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:
|
||||
| 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 @@ help: help_start T_HELPTEXT
|
||||
/* 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 @@ depends: T_DEPENDS T_ON expr
|
||||
|
||||
prompt_stmt_opt:
|
||||
/* empty */
|
||||
| prompt
|
||||
| prompt if_expr
|
||||
{
|
||||
menu_add_prop(P_PROMPT, $1, NULL, NULL);
|
||||
}
|
||||
| prompt T_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 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
|
||||
;
|
||||
|
||||
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 @@ const char *zconf_tokenname(int token)
|
||||
case T_ENDIF: return "endif";
|
||||
}
|
||||
return "<token>";
|
||||
}
|
||||
}
|
||||
|
||||
static bool zconf_endtoken(int token, int starttoken, int endtoken)
|
||||
{
|
||||
@ -470,7 +535,7 @@ static void zconfprint(const char *err, ...)
|
||||
{
|
||||
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 zconfprint(const char *err, ...)
|
||||
|
||||
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 @@ void print_symbol(FILE *out, struct menu *menu)
|
||||
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 @@ void print_symbol(FILE *out, struct menu *menu)
|
||||
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 @@ void print_symbol(FILE *out, struct menu *menu)
|
||||
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 print_symbol(FILE *out, struct menu *menu)
|
||||
|
||||
void zconfdump(FILE *out)
|
||||
{
|
||||
//struct file *file;
|
||||
struct property *prop;
|
||||
struct symbol *sym;
|
||||
struct menu *menu;
|
||||
@ -596,11 +644,6 @@ void zconfdump(FILE *out)
|
||||
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 @@ void zconfdump(FILE *out)
|
||||
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);
|
||||
|
@ -7,7 +7,7 @@ menu "Another Bourne-like Shell"
|
||||
|
||||
choice
|
||||
prompt "Choose your default shell"
|
||||
default "none"
|
||||
default CONFIG_FEATURE_SH_IS_NONE
|
||||
help
|
||||
Choose a shell. The ash shell is the most bash compatible
|
||||
and full featured.
|
||||
|
@ -13,7 +13,7 @@ menu "General Configuration"
|
||||
|
||||
choice
|
||||
prompt "Buffer allocation policy"
|
||||
default "Allocate with Malloc"
|
||||
default CONFIG_FEATURE_BUFFERS_USE_MALLOC
|
||||
help
|
||||
There are 3 ways BusyBox can handle buffer allocations:
|
||||
- Use malloc. This costs code size for the call to xmalloc.
|
||||
|
Loading…
Reference in New Issue
Block a user