diff options
Diffstat (limited to 'release/src/router/busybox/scripts/config/symbol.c')
-rw-r--r-- | release/src/router/busybox/scripts/config/symbol.c | 629 |
1 files changed, 0 insertions, 629 deletions
diff --git a/release/src/router/busybox/scripts/config/symbol.c b/release/src/router/busybox/scripts/config/symbol.c deleted file mode 100644 index f2d0015d..00000000 --- a/release/src/router/busybox/scripts/config/symbol.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> - * Released under the terms of the GNU GPL v2.0. - */ - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <sys/utsname.h> - -#define LKC_DIRECT_LINK -#include "lkc.h" - -struct symbol symbol_yes = { - name: "y", - curr: { "y", yes }, - flags: SYMBOL_YES|SYMBOL_VALID, -}, symbol_mod = { - name: "m", - curr: { "m", mod }, - flags: SYMBOL_MOD|SYMBOL_VALID, -}, symbol_no = { - name: "n", - curr: { "n", no }, - flags: SYMBOL_NO|SYMBOL_VALID, -}, symbol_empty = { - name: "", - curr: { "", no }, - flags: SYMBOL_VALID, -}; - -int sym_change_count; -struct symbol *modules_sym; - -void sym_add_default(struct symbol *sym, const char *def) -{ - struct property *prop = create_prop(P_DEFAULT); - struct property **propp; - - prop->sym = sym; - prop->def = sym_lookup(def, 1); - - /* append property to the prop list of symbol */ - if (prop->sym) { - for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next) - ; - *propp = prop; - } -} - -void sym_init(void) -{ - struct symbol *sym; - struct utsname uts; - char *p; - static bool inited = false; - - if (inited) - 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; - p = getenv("VERSION"); - 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) -{ - int 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) - type = S_BOOLEAN; - } - } - return type; -} - -const char *sym_type_name(int type) -{ - switch (type) { - case S_BOOLEAN: - return "boolean"; - case S_TRISTATE: - return "tristate"; - case S_INT: - return "integer"; - case S_HEX: - return "hex"; - case S_STRING: - return "string"; - case S_UNKNOWN: - return "unknown"; - } - return "???"; -} - -struct property *sym_get_choice_prop(struct symbol *sym) -{ - struct property *prop; - - for_all_choices(sym, prop) - return prop; - return NULL; -} - -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) - return prop; - } - return NULL; -} - -void sym_calc_visibility(struct symbol *sym) -{ - struct property *prop; - tristate visible, oldvisible; - - /* 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; - } -} - -void sym_calc_value(struct symbol *sym) -{ - struct symbol_value newval, oldval; - struct property *prop, *def_prop; - struct symbol *def_sym; - struct expr *e; - - if (sym->flags & SYMBOL_VALID) - return; - - oldval = sym->curr; - - switch (sym->type) { - case S_INT: - case S_HEX: - case S_STRING: - newval = symbol_empty.curr; - break; - case S_BOOLEAN: - case S_TRISTATE: - 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->flags |= SYMBOL_VALID; - if (!sym_is_choice_value(sym)) - sym->flags &= ~SYMBOL_WRITE; - - sym_calc_visibility(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; - if (sym_is_choice_value(sym) && sym->visible == yes) { - prop = sym_get_choice_prop(sym); - S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; - } - } else { - prop = sym_get_default_prop(sym); - if (prop) { - sym->flags |= SYMBOL_WRITE; - sym_calc_value(prop->def); - newval = prop->def->curr; - } - } - - switch (sym_get_type(sym)) { - case S_TRISTATE: - if (S_TRI(newval) != mod) - break; - sym_calc_value(modules_sym); - if (S_TRI(modules_sym->curr) == no) - S_TRI(newval) = yes; - break; - case S_BOOLEAN: - if (S_TRI(newval) == mod) - S_TRI(newval) = yes; - } - -out: - sym->curr = newval; - - if (sym_is_choice(sym) && S_TRI(newval) == yes) { - def_sym = S_VAL(sym->def); - if (def_sym) { - sym_calc_visibility(def_sym); - if (def_sym->visible == no) - def_sym = NULL; - } - if (!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 (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) - e->right.sym->flags |= flags; - } -} - -void sym_clear_all_valid(void) -{ - struct symbol *sym; - int i; - - for_all_symbols(i, sym) - sym->flags &= ~SYMBOL_VALID; - sym_change_count++; -} - -void sym_set_all_changed(void) -{ - struct symbol *sym; - int i; - - for_all_symbols(i, sym) - sym->flags |= SYMBOL_CHANGED; -} - -bool sym_tristate_within_range(struct symbol *sym, tristate val) -{ - int type = sym_get_type(sym); - - if (sym->visible == no) - return false; - - 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; -} - -bool sym_set_tristate_value(struct symbol *sym, tristate val) -{ - tristate oldval = sym_get_tristate_value(sym); - - if (oldval != val && !sym_tristate_within_range(sym, val)) - return false; - - if (sym->flags & SYMBOL_NEW) { - sym->flags &= ~SYMBOL_NEW; - sym->flags |= SYMBOL_CHANGED; - } - if (sym_is_choice_value(sym) && val == yes) { - struct property *prop = sym_get_choice_prop(sym); - - S_VAL(prop->def->def) = sym; - prop->def->flags &= ~SYMBOL_NEW; - } - - S_TRI(sym->def) = val; - if (oldval != val) { - sym_clear_all_valid(); - if (sym == modules_sym) - sym_set_all_changed(); - } - - return true; -} - -tristate sym_toggle_tristate_value(struct symbol *sym) -{ - tristate oldval, newval; - - oldval = newval = sym_get_tristate_value(sym); - do { - switch (newval) { - case no: - newval = mod; - break; - case mod: - newval = yes; - break; - case yes: - newval = no; - break; - } - if (sym_set_tristate_value(sym, newval)) - break; - } while (oldval != newval); - return newval; -} - -bool sym_string_valid(struct symbol *sym, const char *str) -{ - char ch; - - switch (sym->type) { - case S_STRING: - return true; - case S_INT: - ch = *str++; - if (ch == '-') - ch = *str++; - if (!isdigit((int)ch)) - return false; - if (ch == '0' && *str != 0) - return false; - while ((ch = *str++)) { - if (!isdigit((int)ch)) - return false; - } - return true; - case S_HEX: - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) - str += 2; - ch = *str++; - do { - if (!isxdigit((int)ch)) - return false; - } while ((ch = *str++)); - return true; - case S_BOOLEAN: - case S_TRISTATE: - switch (str[0]) { - case 'y': - case 'Y': - return sym_tristate_within_range(sym, yes); - case 'm': - case 'M': - return sym_tristate_within_range(sym, mod); - case 'n': - case 'N': - return sym_tristate_within_range(sym, no); - } - return false; - default: - return false; - } -} - -bool sym_set_string_value(struct symbol *sym, const char *newval) -{ - const char *oldval; - char *val; - int size; - - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - switch (newval[0]) { - case 'y': - case 'Y': - return sym_set_tristate_value(sym, yes); - case 'm': - case 'M': - return sym_set_tristate_value(sym, mod); - case 'n': - case 'N': - return sym_set_tristate_value(sym, no); - } - return false; - default: - ; - } - - if (!sym_string_valid(sym, newval)) - return false; - - if (sym->flags & SYMBOL_NEW) { - sym->flags &= ~SYMBOL_NEW; - sym->flags |= SYMBOL_CHANGED; - } - - oldval = S_VAL(sym->def); - 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); - *val++ = '0'; - *val++ = 'x'; - } else if (!oldval || strcmp(oldval, newval)) - S_VAL(sym->def) = val = malloc(size); - else - return true; - - strcpy(val, newval); - free((void *)oldval); - sym_clear_all_valid(); - - return true; -} - -const char *sym_get_string_value(struct symbol *sym) -{ - tristate val; - - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - val = sym_get_tristate_value(sym); - switch (val) { - case no: - return "n"; - case mod: - return "m"; - case yes: - return "y"; - } - break; - default: - ; - } - return (const char *)S_VAL(sym->curr); -} - -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; -} - -struct symbol *sym_lookup(const char *name, int isconst) -{ - struct symbol *symbol; - const char *ptr; - char *new_name; - int hash = 0; - - //printf("lookup: %s -> ", name); - if (name) { - if (name[0] && !name[1]) { - switch (name[0]) { - case 'y': return &symbol_yes; - case 'm': return &symbol_mod; - case 'n': return &symbol_no; - } - } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; - - 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); - return symbol; - } - } - } - new_name = strdup(name); - } else { - new_name = NULL; - hash = 256; - } - - symbol = malloc(sizeof(*symbol)); - memset(symbol, 0, sizeof(*symbol)); - symbol->name = new_name; - symbol->type = S_UNKNOWN; - symbol->flags = SYMBOL_NEW; - if (isconst) - symbol->flags |= SYMBOL_CONST; - - symbol->next = symbol_hash[hash]; - symbol_hash[hash] = symbol; - - //printf("n:%p\n", symbol); - return symbol; -} - -struct symbol *sym_find(const char *name) -{ - struct symbol *symbol = NULL; - const char *ptr; - int hash = 0; - - if (!name) - return NULL; - - if (name[0] && !name[1]) { - switch (name[0]) { - case 'y': return &symbol_yes; - case 'm': return &symbol_mod; - case 'n': return &symbol_no; - } - } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; - - for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && - !(symbol->flags & SYMBOL_CONST)) - break; - } - - return symbol; -} - -const char *prop_get_type_name(enum prop_type type) -{ - switch (type) { - case P_PROMPT: - return "prompt"; - case P_COMMENT: - 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"; - } -} |