1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 3*1da177e4SLinus Torvalds * Released under the terms of the GNU GPL v2.0. 4*1da177e4SLinus Torvalds */ 5*1da177e4SLinus Torvalds 6*1da177e4SLinus Torvalds #include <ctype.h> 7*1da177e4SLinus Torvalds #include <stdlib.h> 8*1da177e4SLinus Torvalds #include <string.h> 9*1da177e4SLinus Torvalds #include <regex.h> 10*1da177e4SLinus Torvalds #include <sys/utsname.h> 11*1da177e4SLinus Torvalds 12*1da177e4SLinus Torvalds #define LKC_DIRECT_LINK 13*1da177e4SLinus Torvalds #include "lkc.h" 14*1da177e4SLinus Torvalds 15*1da177e4SLinus Torvalds struct symbol symbol_yes = { 16*1da177e4SLinus Torvalds .name = "y", 17*1da177e4SLinus Torvalds .curr = { "y", yes }, 18*1da177e4SLinus Torvalds .flags = SYMBOL_YES|SYMBOL_VALID, 19*1da177e4SLinus Torvalds }, symbol_mod = { 20*1da177e4SLinus Torvalds .name = "m", 21*1da177e4SLinus Torvalds .curr = { "m", mod }, 22*1da177e4SLinus Torvalds .flags = SYMBOL_MOD|SYMBOL_VALID, 23*1da177e4SLinus Torvalds }, symbol_no = { 24*1da177e4SLinus Torvalds .name = "n", 25*1da177e4SLinus Torvalds .curr = { "n", no }, 26*1da177e4SLinus Torvalds .flags = SYMBOL_NO|SYMBOL_VALID, 27*1da177e4SLinus Torvalds }, symbol_empty = { 28*1da177e4SLinus Torvalds .name = "", 29*1da177e4SLinus Torvalds .curr = { "", no }, 30*1da177e4SLinus Torvalds .flags = SYMBOL_VALID, 31*1da177e4SLinus Torvalds }; 32*1da177e4SLinus Torvalds 33*1da177e4SLinus Torvalds int sym_change_count; 34*1da177e4SLinus Torvalds struct symbol *modules_sym; 35*1da177e4SLinus Torvalds tristate modules_val; 36*1da177e4SLinus Torvalds 37*1da177e4SLinus Torvalds void sym_add_default(struct symbol *sym, const char *def) 38*1da177e4SLinus Torvalds { 39*1da177e4SLinus Torvalds struct property *prop = prop_alloc(P_DEFAULT, sym); 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); 42*1da177e4SLinus Torvalds } 43*1da177e4SLinus Torvalds 44*1da177e4SLinus Torvalds void sym_init(void) 45*1da177e4SLinus Torvalds { 46*1da177e4SLinus Torvalds struct symbol *sym; 47*1da177e4SLinus Torvalds struct utsname uts; 48*1da177e4SLinus Torvalds char *p; 49*1da177e4SLinus Torvalds static bool inited = false; 50*1da177e4SLinus Torvalds 51*1da177e4SLinus Torvalds if (inited) 52*1da177e4SLinus Torvalds return; 53*1da177e4SLinus Torvalds inited = true; 54*1da177e4SLinus Torvalds 55*1da177e4SLinus Torvalds uname(&uts); 56*1da177e4SLinus Torvalds 57*1da177e4SLinus Torvalds sym = sym_lookup("ARCH", 0); 58*1da177e4SLinus Torvalds sym->type = S_STRING; 59*1da177e4SLinus Torvalds sym->flags |= SYMBOL_AUTO; 60*1da177e4SLinus Torvalds p = getenv("ARCH"); 61*1da177e4SLinus Torvalds if (p) 62*1da177e4SLinus Torvalds sym_add_default(sym, p); 63*1da177e4SLinus Torvalds 64*1da177e4SLinus Torvalds sym = sym_lookup("KERNELRELEASE", 0); 65*1da177e4SLinus Torvalds sym->type = S_STRING; 66*1da177e4SLinus Torvalds sym->flags |= SYMBOL_AUTO; 67*1da177e4SLinus Torvalds p = getenv("KERNELRELEASE"); 68*1da177e4SLinus Torvalds if (p) 69*1da177e4SLinus Torvalds sym_add_default(sym, p); 70*1da177e4SLinus Torvalds 71*1da177e4SLinus Torvalds sym = sym_lookup("UNAME_RELEASE", 0); 72*1da177e4SLinus Torvalds sym->type = S_STRING; 73*1da177e4SLinus Torvalds sym->flags |= SYMBOL_AUTO; 74*1da177e4SLinus Torvalds sym_add_default(sym, uts.release); 75*1da177e4SLinus Torvalds } 76*1da177e4SLinus Torvalds 77*1da177e4SLinus Torvalds enum symbol_type sym_get_type(struct symbol *sym) 78*1da177e4SLinus Torvalds { 79*1da177e4SLinus Torvalds enum symbol_type type = sym->type; 80*1da177e4SLinus Torvalds 81*1da177e4SLinus Torvalds if (type == S_TRISTATE) { 82*1da177e4SLinus Torvalds if (sym_is_choice_value(sym) && sym->visible == yes) 83*1da177e4SLinus Torvalds type = S_BOOLEAN; 84*1da177e4SLinus Torvalds else if (modules_val == no) 85*1da177e4SLinus Torvalds type = S_BOOLEAN; 86*1da177e4SLinus Torvalds } 87*1da177e4SLinus Torvalds return type; 88*1da177e4SLinus Torvalds } 89*1da177e4SLinus Torvalds 90*1da177e4SLinus Torvalds const char *sym_type_name(enum symbol_type type) 91*1da177e4SLinus Torvalds { 92*1da177e4SLinus Torvalds switch (type) { 93*1da177e4SLinus Torvalds case S_BOOLEAN: 94*1da177e4SLinus Torvalds return "boolean"; 95*1da177e4SLinus Torvalds case S_TRISTATE: 96*1da177e4SLinus Torvalds return "tristate"; 97*1da177e4SLinus Torvalds case S_INT: 98*1da177e4SLinus Torvalds return "integer"; 99*1da177e4SLinus Torvalds case S_HEX: 100*1da177e4SLinus Torvalds return "hex"; 101*1da177e4SLinus Torvalds case S_STRING: 102*1da177e4SLinus Torvalds return "string"; 103*1da177e4SLinus Torvalds case S_UNKNOWN: 104*1da177e4SLinus Torvalds return "unknown"; 105*1da177e4SLinus Torvalds case S_OTHER: 106*1da177e4SLinus Torvalds break; 107*1da177e4SLinus Torvalds } 108*1da177e4SLinus Torvalds return "???"; 109*1da177e4SLinus Torvalds } 110*1da177e4SLinus Torvalds 111*1da177e4SLinus Torvalds struct property *sym_get_choice_prop(struct symbol *sym) 112*1da177e4SLinus Torvalds { 113*1da177e4SLinus Torvalds struct property *prop; 114*1da177e4SLinus Torvalds 115*1da177e4SLinus Torvalds for_all_choices(sym, prop) 116*1da177e4SLinus Torvalds return prop; 117*1da177e4SLinus Torvalds return NULL; 118*1da177e4SLinus Torvalds } 119*1da177e4SLinus Torvalds 120*1da177e4SLinus Torvalds struct property *sym_get_default_prop(struct symbol *sym) 121*1da177e4SLinus Torvalds { 122*1da177e4SLinus Torvalds struct property *prop; 123*1da177e4SLinus Torvalds 124*1da177e4SLinus Torvalds for_all_defaults(sym, prop) { 125*1da177e4SLinus Torvalds prop->visible.tri = expr_calc_value(prop->visible.expr); 126*1da177e4SLinus Torvalds if (prop->visible.tri != no) 127*1da177e4SLinus Torvalds return prop; 128*1da177e4SLinus Torvalds } 129*1da177e4SLinus Torvalds return NULL; 130*1da177e4SLinus Torvalds } 131*1da177e4SLinus Torvalds 132*1da177e4SLinus Torvalds struct property *sym_get_range_prop(struct symbol *sym) 133*1da177e4SLinus Torvalds { 134*1da177e4SLinus Torvalds struct property *prop; 135*1da177e4SLinus Torvalds 136*1da177e4SLinus Torvalds for_all_properties(sym, prop, P_RANGE) { 137*1da177e4SLinus Torvalds prop->visible.tri = expr_calc_value(prop->visible.expr); 138*1da177e4SLinus Torvalds if (prop->visible.tri != no) 139*1da177e4SLinus Torvalds return prop; 140*1da177e4SLinus Torvalds } 141*1da177e4SLinus Torvalds return NULL; 142*1da177e4SLinus Torvalds } 143*1da177e4SLinus Torvalds 144*1da177e4SLinus Torvalds static void sym_calc_visibility(struct symbol *sym) 145*1da177e4SLinus Torvalds { 146*1da177e4SLinus Torvalds struct property *prop; 147*1da177e4SLinus Torvalds tristate tri; 148*1da177e4SLinus Torvalds 149*1da177e4SLinus Torvalds /* any prompt visible? */ 150*1da177e4SLinus Torvalds tri = no; 151*1da177e4SLinus Torvalds for_all_prompts(sym, prop) { 152*1da177e4SLinus Torvalds prop->visible.tri = expr_calc_value(prop->visible.expr); 153*1da177e4SLinus Torvalds tri = E_OR(tri, prop->visible.tri); 154*1da177e4SLinus Torvalds } 155*1da177e4SLinus Torvalds if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) 156*1da177e4SLinus Torvalds tri = yes; 157*1da177e4SLinus Torvalds if (sym->visible != tri) { 158*1da177e4SLinus Torvalds sym->visible = tri; 159*1da177e4SLinus Torvalds sym_set_changed(sym); 160*1da177e4SLinus Torvalds } 161*1da177e4SLinus Torvalds if (sym_is_choice_value(sym)) 162*1da177e4SLinus Torvalds return; 163*1da177e4SLinus Torvalds tri = no; 164*1da177e4SLinus Torvalds if (sym->rev_dep.expr) 165*1da177e4SLinus Torvalds tri = expr_calc_value(sym->rev_dep.expr); 166*1da177e4SLinus Torvalds if (tri == mod && sym_get_type(sym) == S_BOOLEAN) 167*1da177e4SLinus Torvalds tri = yes; 168*1da177e4SLinus Torvalds if (sym->rev_dep.tri != tri) { 169*1da177e4SLinus Torvalds sym->rev_dep.tri = tri; 170*1da177e4SLinus Torvalds sym_set_changed(sym); 171*1da177e4SLinus Torvalds } 172*1da177e4SLinus Torvalds } 173*1da177e4SLinus Torvalds 174*1da177e4SLinus Torvalds static struct symbol *sym_calc_choice(struct symbol *sym) 175*1da177e4SLinus Torvalds { 176*1da177e4SLinus Torvalds struct symbol *def_sym; 177*1da177e4SLinus Torvalds struct property *prop; 178*1da177e4SLinus Torvalds struct expr *e; 179*1da177e4SLinus Torvalds 180*1da177e4SLinus Torvalds /* is the user choice visible? */ 181*1da177e4SLinus Torvalds def_sym = sym->user.val; 182*1da177e4SLinus Torvalds if (def_sym) { 183*1da177e4SLinus Torvalds sym_calc_visibility(def_sym); 184*1da177e4SLinus Torvalds if (def_sym->visible != no) 185*1da177e4SLinus Torvalds return def_sym; 186*1da177e4SLinus Torvalds } 187*1da177e4SLinus Torvalds 188*1da177e4SLinus Torvalds /* any of the defaults visible? */ 189*1da177e4SLinus Torvalds for_all_defaults(sym, prop) { 190*1da177e4SLinus Torvalds prop->visible.tri = expr_calc_value(prop->visible.expr); 191*1da177e4SLinus Torvalds if (prop->visible.tri == no) 192*1da177e4SLinus Torvalds continue; 193*1da177e4SLinus Torvalds def_sym = prop_get_symbol(prop); 194*1da177e4SLinus Torvalds sym_calc_visibility(def_sym); 195*1da177e4SLinus Torvalds if (def_sym->visible != no) 196*1da177e4SLinus Torvalds return def_sym; 197*1da177e4SLinus Torvalds } 198*1da177e4SLinus Torvalds 199*1da177e4SLinus Torvalds /* just get the first visible value */ 200*1da177e4SLinus Torvalds prop = sym_get_choice_prop(sym); 201*1da177e4SLinus Torvalds for (e = prop->expr; e; e = e->left.expr) { 202*1da177e4SLinus Torvalds def_sym = e->right.sym; 203*1da177e4SLinus Torvalds sym_calc_visibility(def_sym); 204*1da177e4SLinus Torvalds if (def_sym->visible != no) 205*1da177e4SLinus Torvalds return def_sym; 206*1da177e4SLinus Torvalds } 207*1da177e4SLinus Torvalds 208*1da177e4SLinus Torvalds /* no choice? reset tristate value */ 209*1da177e4SLinus Torvalds sym->curr.tri = no; 210*1da177e4SLinus Torvalds return NULL; 211*1da177e4SLinus Torvalds } 212*1da177e4SLinus Torvalds 213*1da177e4SLinus Torvalds void sym_calc_value(struct symbol *sym) 214*1da177e4SLinus Torvalds { 215*1da177e4SLinus Torvalds struct symbol_value newval, oldval; 216*1da177e4SLinus Torvalds struct property *prop; 217*1da177e4SLinus Torvalds struct expr *e; 218*1da177e4SLinus Torvalds 219*1da177e4SLinus Torvalds if (!sym) 220*1da177e4SLinus Torvalds return; 221*1da177e4SLinus Torvalds 222*1da177e4SLinus Torvalds if (sym->flags & SYMBOL_VALID) 223*1da177e4SLinus Torvalds return; 224*1da177e4SLinus Torvalds sym->flags |= SYMBOL_VALID; 225*1da177e4SLinus Torvalds 226*1da177e4SLinus Torvalds oldval = sym->curr; 227*1da177e4SLinus Torvalds 228*1da177e4SLinus Torvalds switch (sym->type) { 229*1da177e4SLinus Torvalds case S_INT: 230*1da177e4SLinus Torvalds case S_HEX: 231*1da177e4SLinus Torvalds case S_STRING: 232*1da177e4SLinus Torvalds newval = symbol_empty.curr; 233*1da177e4SLinus Torvalds break; 234*1da177e4SLinus Torvalds case S_BOOLEAN: 235*1da177e4SLinus Torvalds case S_TRISTATE: 236*1da177e4SLinus Torvalds newval = symbol_no.curr; 237*1da177e4SLinus Torvalds break; 238*1da177e4SLinus Torvalds default: 239*1da177e4SLinus Torvalds sym->curr.val = sym->name; 240*1da177e4SLinus Torvalds sym->curr.tri = no; 241*1da177e4SLinus Torvalds return; 242*1da177e4SLinus Torvalds } 243*1da177e4SLinus Torvalds if (!sym_is_choice_value(sym)) 244*1da177e4SLinus Torvalds sym->flags &= ~SYMBOL_WRITE; 245*1da177e4SLinus Torvalds 246*1da177e4SLinus Torvalds sym_calc_visibility(sym); 247*1da177e4SLinus Torvalds 248*1da177e4SLinus Torvalds /* set default if recursively called */ 249*1da177e4SLinus Torvalds sym->curr = newval; 250*1da177e4SLinus Torvalds 251*1da177e4SLinus Torvalds switch (sym_get_type(sym)) { 252*1da177e4SLinus Torvalds case S_BOOLEAN: 253*1da177e4SLinus Torvalds case S_TRISTATE: 254*1da177e4SLinus Torvalds if (sym_is_choice_value(sym) && sym->visible == yes) { 255*1da177e4SLinus Torvalds prop = sym_get_choice_prop(sym); 256*1da177e4SLinus Torvalds newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; 257*1da177e4SLinus Torvalds } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { 258*1da177e4SLinus Torvalds sym->flags |= SYMBOL_WRITE; 259*1da177e4SLinus Torvalds if (sym_has_value(sym)) 260*1da177e4SLinus Torvalds newval.tri = sym->user.tri; 261*1da177e4SLinus Torvalds else if (!sym_is_choice(sym)) { 262*1da177e4SLinus Torvalds prop = sym_get_default_prop(sym); 263*1da177e4SLinus Torvalds if (prop) 264*1da177e4SLinus Torvalds newval.tri = expr_calc_value(prop->expr); 265*1da177e4SLinus Torvalds } 266*1da177e4SLinus Torvalds newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri); 267*1da177e4SLinus Torvalds } else if (!sym_is_choice(sym)) { 268*1da177e4SLinus Torvalds prop = sym_get_default_prop(sym); 269*1da177e4SLinus Torvalds if (prop) { 270*1da177e4SLinus Torvalds sym->flags |= SYMBOL_WRITE; 271*1da177e4SLinus Torvalds newval.tri = expr_calc_value(prop->expr); 272*1da177e4SLinus Torvalds } 273*1da177e4SLinus Torvalds } 274*1da177e4SLinus Torvalds if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) 275*1da177e4SLinus Torvalds newval.tri = yes; 276*1da177e4SLinus Torvalds break; 277*1da177e4SLinus Torvalds case S_STRING: 278*1da177e4SLinus Torvalds case S_HEX: 279*1da177e4SLinus Torvalds case S_INT: 280*1da177e4SLinus Torvalds if (sym->visible != no) { 281*1da177e4SLinus Torvalds sym->flags |= SYMBOL_WRITE; 282*1da177e4SLinus Torvalds if (sym_has_value(sym)) { 283*1da177e4SLinus Torvalds newval.val = sym->user.val; 284*1da177e4SLinus Torvalds break; 285*1da177e4SLinus Torvalds } 286*1da177e4SLinus Torvalds } 287*1da177e4SLinus Torvalds prop = sym_get_default_prop(sym); 288*1da177e4SLinus Torvalds if (prop) { 289*1da177e4SLinus Torvalds struct symbol *ds = prop_get_symbol(prop); 290*1da177e4SLinus Torvalds if (ds) { 291*1da177e4SLinus Torvalds sym->flags |= SYMBOL_WRITE; 292*1da177e4SLinus Torvalds sym_calc_value(ds); 293*1da177e4SLinus Torvalds newval.val = ds->curr.val; 294*1da177e4SLinus Torvalds } 295*1da177e4SLinus Torvalds } 296*1da177e4SLinus Torvalds break; 297*1da177e4SLinus Torvalds default: 298*1da177e4SLinus Torvalds ; 299*1da177e4SLinus Torvalds } 300*1da177e4SLinus Torvalds 301*1da177e4SLinus Torvalds sym->curr = newval; 302*1da177e4SLinus Torvalds if (sym_is_choice(sym) && newval.tri == yes) 303*1da177e4SLinus Torvalds sym->curr.val = sym_calc_choice(sym); 304*1da177e4SLinus Torvalds 305*1da177e4SLinus Torvalds if (memcmp(&oldval, &sym->curr, sizeof(oldval))) 306*1da177e4SLinus Torvalds sym_set_changed(sym); 307*1da177e4SLinus Torvalds if (modules_sym == sym) 308*1da177e4SLinus Torvalds modules_val = modules_sym->curr.tri; 309*1da177e4SLinus Torvalds 310*1da177e4SLinus Torvalds if (sym_is_choice(sym)) { 311*1da177e4SLinus Torvalds int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); 312*1da177e4SLinus Torvalds prop = sym_get_choice_prop(sym); 313*1da177e4SLinus Torvalds for (e = prop->expr; e; e = e->left.expr) { 314*1da177e4SLinus Torvalds e->right.sym->flags |= flags; 315*1da177e4SLinus Torvalds if (flags & SYMBOL_CHANGED) 316*1da177e4SLinus Torvalds sym_set_changed(e->right.sym); 317*1da177e4SLinus Torvalds } 318*1da177e4SLinus Torvalds } 319*1da177e4SLinus Torvalds } 320*1da177e4SLinus Torvalds 321*1da177e4SLinus Torvalds void sym_clear_all_valid(void) 322*1da177e4SLinus Torvalds { 323*1da177e4SLinus Torvalds struct symbol *sym; 324*1da177e4SLinus Torvalds int i; 325*1da177e4SLinus Torvalds 326*1da177e4SLinus Torvalds for_all_symbols(i, sym) 327*1da177e4SLinus Torvalds sym->flags &= ~SYMBOL_VALID; 328*1da177e4SLinus Torvalds sym_change_count++; 329*1da177e4SLinus Torvalds if (modules_sym) 330*1da177e4SLinus Torvalds sym_calc_value(modules_sym); 331*1da177e4SLinus Torvalds } 332*1da177e4SLinus Torvalds 333*1da177e4SLinus Torvalds void sym_set_changed(struct symbol *sym) 334*1da177e4SLinus Torvalds { 335*1da177e4SLinus Torvalds struct property *prop; 336*1da177e4SLinus Torvalds 337*1da177e4SLinus Torvalds sym->flags |= SYMBOL_CHANGED; 338*1da177e4SLinus Torvalds for (prop = sym->prop; prop; prop = prop->next) { 339*1da177e4SLinus Torvalds if (prop->menu) 340*1da177e4SLinus Torvalds prop->menu->flags |= MENU_CHANGED; 341*1da177e4SLinus Torvalds } 342*1da177e4SLinus Torvalds } 343*1da177e4SLinus Torvalds 344*1da177e4SLinus Torvalds void sym_set_all_changed(void) 345*1da177e4SLinus Torvalds { 346*1da177e4SLinus Torvalds struct symbol *sym; 347*1da177e4SLinus Torvalds int i; 348*1da177e4SLinus Torvalds 349*1da177e4SLinus Torvalds for_all_symbols(i, sym) 350*1da177e4SLinus Torvalds sym_set_changed(sym); 351*1da177e4SLinus Torvalds } 352*1da177e4SLinus Torvalds 353*1da177e4SLinus Torvalds bool sym_tristate_within_range(struct symbol *sym, tristate val) 354*1da177e4SLinus Torvalds { 355*1da177e4SLinus Torvalds int type = sym_get_type(sym); 356*1da177e4SLinus Torvalds 357*1da177e4SLinus Torvalds if (sym->visible == no) 358*1da177e4SLinus Torvalds return false; 359*1da177e4SLinus Torvalds 360*1da177e4SLinus Torvalds if (type != S_BOOLEAN && type != S_TRISTATE) 361*1da177e4SLinus Torvalds return false; 362*1da177e4SLinus Torvalds 363*1da177e4SLinus Torvalds if (type == S_BOOLEAN && val == mod) 364*1da177e4SLinus Torvalds return false; 365*1da177e4SLinus Torvalds if (sym->visible <= sym->rev_dep.tri) 366*1da177e4SLinus Torvalds return false; 367*1da177e4SLinus Torvalds if (sym_is_choice_value(sym) && sym->visible == yes) 368*1da177e4SLinus Torvalds return val == yes; 369*1da177e4SLinus Torvalds return val >= sym->rev_dep.tri && val <= sym->visible; 370*1da177e4SLinus Torvalds } 371*1da177e4SLinus Torvalds 372*1da177e4SLinus Torvalds bool sym_set_tristate_value(struct symbol *sym, tristate val) 373*1da177e4SLinus Torvalds { 374*1da177e4SLinus Torvalds tristate oldval = sym_get_tristate_value(sym); 375*1da177e4SLinus Torvalds 376*1da177e4SLinus Torvalds if (oldval != val && !sym_tristate_within_range(sym, val)) 377*1da177e4SLinus Torvalds return false; 378*1da177e4SLinus Torvalds 379*1da177e4SLinus Torvalds if (sym->flags & SYMBOL_NEW) { 380*1da177e4SLinus Torvalds sym->flags &= ~SYMBOL_NEW; 381*1da177e4SLinus Torvalds sym_set_changed(sym); 382*1da177e4SLinus Torvalds } 383*1da177e4SLinus Torvalds if (sym_is_choice_value(sym) && val == yes) { 384*1da177e4SLinus Torvalds struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 385*1da177e4SLinus Torvalds 386*1da177e4SLinus Torvalds cs->user.val = sym; 387*1da177e4SLinus Torvalds cs->flags &= ~SYMBOL_NEW; 388*1da177e4SLinus Torvalds } 389*1da177e4SLinus Torvalds 390*1da177e4SLinus Torvalds sym->user.tri = val; 391*1da177e4SLinus Torvalds if (oldval != val) { 392*1da177e4SLinus Torvalds sym_clear_all_valid(); 393*1da177e4SLinus Torvalds if (sym == modules_sym) 394*1da177e4SLinus Torvalds sym_set_all_changed(); 395*1da177e4SLinus Torvalds } 396*1da177e4SLinus Torvalds 397*1da177e4SLinus Torvalds return true; 398*1da177e4SLinus Torvalds } 399*1da177e4SLinus Torvalds 400*1da177e4SLinus Torvalds tristate sym_toggle_tristate_value(struct symbol *sym) 401*1da177e4SLinus Torvalds { 402*1da177e4SLinus Torvalds tristate oldval, newval; 403*1da177e4SLinus Torvalds 404*1da177e4SLinus Torvalds oldval = newval = sym_get_tristate_value(sym); 405*1da177e4SLinus Torvalds do { 406*1da177e4SLinus Torvalds switch (newval) { 407*1da177e4SLinus Torvalds case no: 408*1da177e4SLinus Torvalds newval = mod; 409*1da177e4SLinus Torvalds break; 410*1da177e4SLinus Torvalds case mod: 411*1da177e4SLinus Torvalds newval = yes; 412*1da177e4SLinus Torvalds break; 413*1da177e4SLinus Torvalds case yes: 414*1da177e4SLinus Torvalds newval = no; 415*1da177e4SLinus Torvalds break; 416*1da177e4SLinus Torvalds } 417*1da177e4SLinus Torvalds if (sym_set_tristate_value(sym, newval)) 418*1da177e4SLinus Torvalds break; 419*1da177e4SLinus Torvalds } while (oldval != newval); 420*1da177e4SLinus Torvalds return newval; 421*1da177e4SLinus Torvalds } 422*1da177e4SLinus Torvalds 423*1da177e4SLinus Torvalds bool sym_string_valid(struct symbol *sym, const char *str) 424*1da177e4SLinus Torvalds { 425*1da177e4SLinus Torvalds signed char ch; 426*1da177e4SLinus Torvalds 427*1da177e4SLinus Torvalds switch (sym->type) { 428*1da177e4SLinus Torvalds case S_STRING: 429*1da177e4SLinus Torvalds return true; 430*1da177e4SLinus Torvalds case S_INT: 431*1da177e4SLinus Torvalds ch = *str++; 432*1da177e4SLinus Torvalds if (ch == '-') 433*1da177e4SLinus Torvalds ch = *str++; 434*1da177e4SLinus Torvalds if (!isdigit(ch)) 435*1da177e4SLinus Torvalds return false; 436*1da177e4SLinus Torvalds if (ch == '0' && *str != 0) 437*1da177e4SLinus Torvalds return false; 438*1da177e4SLinus Torvalds while ((ch = *str++)) { 439*1da177e4SLinus Torvalds if (!isdigit(ch)) 440*1da177e4SLinus Torvalds return false; 441*1da177e4SLinus Torvalds } 442*1da177e4SLinus Torvalds return true; 443*1da177e4SLinus Torvalds case S_HEX: 444*1da177e4SLinus Torvalds if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) 445*1da177e4SLinus Torvalds str += 2; 446*1da177e4SLinus Torvalds ch = *str++; 447*1da177e4SLinus Torvalds do { 448*1da177e4SLinus Torvalds if (!isxdigit(ch)) 449*1da177e4SLinus Torvalds return false; 450*1da177e4SLinus Torvalds } while ((ch = *str++)); 451*1da177e4SLinus Torvalds return true; 452*1da177e4SLinus Torvalds case S_BOOLEAN: 453*1da177e4SLinus Torvalds case S_TRISTATE: 454*1da177e4SLinus Torvalds switch (str[0]) { 455*1da177e4SLinus Torvalds case 'y': case 'Y': 456*1da177e4SLinus Torvalds case 'm': case 'M': 457*1da177e4SLinus Torvalds case 'n': case 'N': 458*1da177e4SLinus Torvalds return true; 459*1da177e4SLinus Torvalds } 460*1da177e4SLinus Torvalds return false; 461*1da177e4SLinus Torvalds default: 462*1da177e4SLinus Torvalds return false; 463*1da177e4SLinus Torvalds } 464*1da177e4SLinus Torvalds } 465*1da177e4SLinus Torvalds 466*1da177e4SLinus Torvalds bool sym_string_within_range(struct symbol *sym, const char *str) 467*1da177e4SLinus Torvalds { 468*1da177e4SLinus Torvalds struct property *prop; 469*1da177e4SLinus Torvalds int val; 470*1da177e4SLinus Torvalds 471*1da177e4SLinus Torvalds switch (sym->type) { 472*1da177e4SLinus Torvalds case S_STRING: 473*1da177e4SLinus Torvalds return sym_string_valid(sym, str); 474*1da177e4SLinus Torvalds case S_INT: 475*1da177e4SLinus Torvalds if (!sym_string_valid(sym, str)) 476*1da177e4SLinus Torvalds return false; 477*1da177e4SLinus Torvalds prop = sym_get_range_prop(sym); 478*1da177e4SLinus Torvalds if (!prop) 479*1da177e4SLinus Torvalds return true; 480*1da177e4SLinus Torvalds val = strtol(str, NULL, 10); 481*1da177e4SLinus Torvalds return val >= strtol(prop->expr->left.sym->name, NULL, 10) && 482*1da177e4SLinus Torvalds val <= strtol(prop->expr->right.sym->name, NULL, 10); 483*1da177e4SLinus Torvalds case S_HEX: 484*1da177e4SLinus Torvalds if (!sym_string_valid(sym, str)) 485*1da177e4SLinus Torvalds return false; 486*1da177e4SLinus Torvalds prop = sym_get_range_prop(sym); 487*1da177e4SLinus Torvalds if (!prop) 488*1da177e4SLinus Torvalds return true; 489*1da177e4SLinus Torvalds val = strtol(str, NULL, 16); 490*1da177e4SLinus Torvalds return val >= strtol(prop->expr->left.sym->name, NULL, 16) && 491*1da177e4SLinus Torvalds val <= strtol(prop->expr->right.sym->name, NULL, 16); 492*1da177e4SLinus Torvalds case S_BOOLEAN: 493*1da177e4SLinus Torvalds case S_TRISTATE: 494*1da177e4SLinus Torvalds switch (str[0]) { 495*1da177e4SLinus Torvalds case 'y': case 'Y': 496*1da177e4SLinus Torvalds return sym_tristate_within_range(sym, yes); 497*1da177e4SLinus Torvalds case 'm': case 'M': 498*1da177e4SLinus Torvalds return sym_tristate_within_range(sym, mod); 499*1da177e4SLinus Torvalds case 'n': case 'N': 500*1da177e4SLinus Torvalds return sym_tristate_within_range(sym, no); 501*1da177e4SLinus Torvalds } 502*1da177e4SLinus Torvalds return false; 503*1da177e4SLinus Torvalds default: 504*1da177e4SLinus Torvalds return false; 505*1da177e4SLinus Torvalds } 506*1da177e4SLinus Torvalds } 507*1da177e4SLinus Torvalds 508*1da177e4SLinus Torvalds bool sym_set_string_value(struct symbol *sym, const char *newval) 509*1da177e4SLinus Torvalds { 510*1da177e4SLinus Torvalds const char *oldval; 511*1da177e4SLinus Torvalds char *val; 512*1da177e4SLinus Torvalds int size; 513*1da177e4SLinus Torvalds 514*1da177e4SLinus Torvalds switch (sym->type) { 515*1da177e4SLinus Torvalds case S_BOOLEAN: 516*1da177e4SLinus Torvalds case S_TRISTATE: 517*1da177e4SLinus Torvalds switch (newval[0]) { 518*1da177e4SLinus Torvalds case 'y': case 'Y': 519*1da177e4SLinus Torvalds return sym_set_tristate_value(sym, yes); 520*1da177e4SLinus Torvalds case 'm': case 'M': 521*1da177e4SLinus Torvalds return sym_set_tristate_value(sym, mod); 522*1da177e4SLinus Torvalds case 'n': case 'N': 523*1da177e4SLinus Torvalds return sym_set_tristate_value(sym, no); 524*1da177e4SLinus Torvalds } 525*1da177e4SLinus Torvalds return false; 526*1da177e4SLinus Torvalds default: 527*1da177e4SLinus Torvalds ; 528*1da177e4SLinus Torvalds } 529*1da177e4SLinus Torvalds 530*1da177e4SLinus Torvalds if (!sym_string_within_range(sym, newval)) 531*1da177e4SLinus Torvalds return false; 532*1da177e4SLinus Torvalds 533*1da177e4SLinus Torvalds if (sym->flags & SYMBOL_NEW) { 534*1da177e4SLinus Torvalds sym->flags &= ~SYMBOL_NEW; 535*1da177e4SLinus Torvalds sym_set_changed(sym); 536*1da177e4SLinus Torvalds } 537*1da177e4SLinus Torvalds 538*1da177e4SLinus Torvalds oldval = sym->user.val; 539*1da177e4SLinus Torvalds size = strlen(newval) + 1; 540*1da177e4SLinus Torvalds if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { 541*1da177e4SLinus Torvalds size += 2; 542*1da177e4SLinus Torvalds sym->user.val = val = malloc(size); 543*1da177e4SLinus Torvalds *val++ = '0'; 544*1da177e4SLinus Torvalds *val++ = 'x'; 545*1da177e4SLinus Torvalds } else if (!oldval || strcmp(oldval, newval)) 546*1da177e4SLinus Torvalds sym->user.val = val = malloc(size); 547*1da177e4SLinus Torvalds else 548*1da177e4SLinus Torvalds return true; 549*1da177e4SLinus Torvalds 550*1da177e4SLinus Torvalds strcpy(val, newval); 551*1da177e4SLinus Torvalds free((void *)oldval); 552*1da177e4SLinus Torvalds sym_clear_all_valid(); 553*1da177e4SLinus Torvalds 554*1da177e4SLinus Torvalds return true; 555*1da177e4SLinus Torvalds } 556*1da177e4SLinus Torvalds 557*1da177e4SLinus Torvalds const char *sym_get_string_value(struct symbol *sym) 558*1da177e4SLinus Torvalds { 559*1da177e4SLinus Torvalds tristate val; 560*1da177e4SLinus Torvalds 561*1da177e4SLinus Torvalds switch (sym->type) { 562*1da177e4SLinus Torvalds case S_BOOLEAN: 563*1da177e4SLinus Torvalds case S_TRISTATE: 564*1da177e4SLinus Torvalds val = sym_get_tristate_value(sym); 565*1da177e4SLinus Torvalds switch (val) { 566*1da177e4SLinus Torvalds case no: 567*1da177e4SLinus Torvalds return "n"; 568*1da177e4SLinus Torvalds case mod: 569*1da177e4SLinus Torvalds return "m"; 570*1da177e4SLinus Torvalds case yes: 571*1da177e4SLinus Torvalds return "y"; 572*1da177e4SLinus Torvalds } 573*1da177e4SLinus Torvalds break; 574*1da177e4SLinus Torvalds default: 575*1da177e4SLinus Torvalds ; 576*1da177e4SLinus Torvalds } 577*1da177e4SLinus Torvalds return (const char *)sym->curr.val; 578*1da177e4SLinus Torvalds } 579*1da177e4SLinus Torvalds 580*1da177e4SLinus Torvalds bool sym_is_changable(struct symbol *sym) 581*1da177e4SLinus Torvalds { 582*1da177e4SLinus Torvalds return sym->visible > sym->rev_dep.tri; 583*1da177e4SLinus Torvalds } 584*1da177e4SLinus Torvalds 585*1da177e4SLinus Torvalds struct symbol *sym_lookup(const char *name, int isconst) 586*1da177e4SLinus Torvalds { 587*1da177e4SLinus Torvalds struct symbol *symbol; 588*1da177e4SLinus Torvalds const char *ptr; 589*1da177e4SLinus Torvalds char *new_name; 590*1da177e4SLinus Torvalds int hash = 0; 591*1da177e4SLinus Torvalds 592*1da177e4SLinus Torvalds if (name) { 593*1da177e4SLinus Torvalds if (name[0] && !name[1]) { 594*1da177e4SLinus Torvalds switch (name[0]) { 595*1da177e4SLinus Torvalds case 'y': return &symbol_yes; 596*1da177e4SLinus Torvalds case 'm': return &symbol_mod; 597*1da177e4SLinus Torvalds case 'n': return &symbol_no; 598*1da177e4SLinus Torvalds } 599*1da177e4SLinus Torvalds } 600*1da177e4SLinus Torvalds for (ptr = name; *ptr; ptr++) 601*1da177e4SLinus Torvalds hash += *ptr; 602*1da177e4SLinus Torvalds hash &= 0xff; 603*1da177e4SLinus Torvalds 604*1da177e4SLinus Torvalds for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 605*1da177e4SLinus Torvalds if (!strcmp(symbol->name, name)) { 606*1da177e4SLinus Torvalds if ((isconst && symbol->flags & SYMBOL_CONST) || 607*1da177e4SLinus Torvalds (!isconst && !(symbol->flags & SYMBOL_CONST))) 608*1da177e4SLinus Torvalds return symbol; 609*1da177e4SLinus Torvalds } 610*1da177e4SLinus Torvalds } 611*1da177e4SLinus Torvalds new_name = strdup(name); 612*1da177e4SLinus Torvalds } else { 613*1da177e4SLinus Torvalds new_name = NULL; 614*1da177e4SLinus Torvalds hash = 256; 615*1da177e4SLinus Torvalds } 616*1da177e4SLinus Torvalds 617*1da177e4SLinus Torvalds symbol = malloc(sizeof(*symbol)); 618*1da177e4SLinus Torvalds memset(symbol, 0, sizeof(*symbol)); 619*1da177e4SLinus Torvalds symbol->name = new_name; 620*1da177e4SLinus Torvalds symbol->type = S_UNKNOWN; 621*1da177e4SLinus Torvalds symbol->flags = SYMBOL_NEW; 622*1da177e4SLinus Torvalds if (isconst) 623*1da177e4SLinus Torvalds symbol->flags |= SYMBOL_CONST; 624*1da177e4SLinus Torvalds 625*1da177e4SLinus Torvalds symbol->next = symbol_hash[hash]; 626*1da177e4SLinus Torvalds symbol_hash[hash] = symbol; 627*1da177e4SLinus Torvalds 628*1da177e4SLinus Torvalds return symbol; 629*1da177e4SLinus Torvalds } 630*1da177e4SLinus Torvalds 631*1da177e4SLinus Torvalds struct symbol *sym_find(const char *name) 632*1da177e4SLinus Torvalds { 633*1da177e4SLinus Torvalds struct symbol *symbol = NULL; 634*1da177e4SLinus Torvalds const char *ptr; 635*1da177e4SLinus Torvalds int hash = 0; 636*1da177e4SLinus Torvalds 637*1da177e4SLinus Torvalds if (!name) 638*1da177e4SLinus Torvalds return NULL; 639*1da177e4SLinus Torvalds 640*1da177e4SLinus Torvalds if (name[0] && !name[1]) { 641*1da177e4SLinus Torvalds switch (name[0]) { 642*1da177e4SLinus Torvalds case 'y': return &symbol_yes; 643*1da177e4SLinus Torvalds case 'm': return &symbol_mod; 644*1da177e4SLinus Torvalds case 'n': return &symbol_no; 645*1da177e4SLinus Torvalds } 646*1da177e4SLinus Torvalds } 647*1da177e4SLinus Torvalds for (ptr = name; *ptr; ptr++) 648*1da177e4SLinus Torvalds hash += *ptr; 649*1da177e4SLinus Torvalds hash &= 0xff; 650*1da177e4SLinus Torvalds 651*1da177e4SLinus Torvalds for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 652*1da177e4SLinus Torvalds if (!strcmp(symbol->name, name) && 653*1da177e4SLinus Torvalds !(symbol->flags & SYMBOL_CONST)) 654*1da177e4SLinus Torvalds break; 655*1da177e4SLinus Torvalds } 656*1da177e4SLinus Torvalds 657*1da177e4SLinus Torvalds return symbol; 658*1da177e4SLinus Torvalds } 659*1da177e4SLinus Torvalds 660*1da177e4SLinus Torvalds struct symbol **sym_re_search(const char *pattern) 661*1da177e4SLinus Torvalds { 662*1da177e4SLinus Torvalds struct symbol *sym, **sym_arr = NULL; 663*1da177e4SLinus Torvalds int i, cnt, size; 664*1da177e4SLinus Torvalds regex_t re; 665*1da177e4SLinus Torvalds 666*1da177e4SLinus Torvalds cnt = size = 0; 667*1da177e4SLinus Torvalds /* Skip if empty */ 668*1da177e4SLinus Torvalds if (strlen(pattern) == 0) 669*1da177e4SLinus Torvalds return NULL; 670*1da177e4SLinus Torvalds if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) 671*1da177e4SLinus Torvalds return NULL; 672*1da177e4SLinus Torvalds 673*1da177e4SLinus Torvalds for_all_symbols(i, sym) { 674*1da177e4SLinus Torvalds if (sym->flags & SYMBOL_CONST || !sym->name) 675*1da177e4SLinus Torvalds continue; 676*1da177e4SLinus Torvalds if (regexec(&re, sym->name, 0, NULL, 0)) 677*1da177e4SLinus Torvalds continue; 678*1da177e4SLinus Torvalds if (cnt + 1 >= size) { 679*1da177e4SLinus Torvalds void *tmp = sym_arr; 680*1da177e4SLinus Torvalds size += 16; 681*1da177e4SLinus Torvalds sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); 682*1da177e4SLinus Torvalds if (!sym_arr) { 683*1da177e4SLinus Torvalds free(tmp); 684*1da177e4SLinus Torvalds return NULL; 685*1da177e4SLinus Torvalds } 686*1da177e4SLinus Torvalds } 687*1da177e4SLinus Torvalds sym_arr[cnt++] = sym; 688*1da177e4SLinus Torvalds } 689*1da177e4SLinus Torvalds if (sym_arr) 690*1da177e4SLinus Torvalds sym_arr[cnt] = NULL; 691*1da177e4SLinus Torvalds regfree(&re); 692*1da177e4SLinus Torvalds 693*1da177e4SLinus Torvalds return sym_arr; 694*1da177e4SLinus Torvalds } 695*1da177e4SLinus Torvalds 696*1da177e4SLinus Torvalds 697*1da177e4SLinus Torvalds struct symbol *sym_check_deps(struct symbol *sym); 698*1da177e4SLinus Torvalds 699*1da177e4SLinus Torvalds static struct symbol *sym_check_expr_deps(struct expr *e) 700*1da177e4SLinus Torvalds { 701*1da177e4SLinus Torvalds struct symbol *sym; 702*1da177e4SLinus Torvalds 703*1da177e4SLinus Torvalds if (!e) 704*1da177e4SLinus Torvalds return NULL; 705*1da177e4SLinus Torvalds switch (e->type) { 706*1da177e4SLinus Torvalds case E_OR: 707*1da177e4SLinus Torvalds case E_AND: 708*1da177e4SLinus Torvalds sym = sym_check_expr_deps(e->left.expr); 709*1da177e4SLinus Torvalds if (sym) 710*1da177e4SLinus Torvalds return sym; 711*1da177e4SLinus Torvalds return sym_check_expr_deps(e->right.expr); 712*1da177e4SLinus Torvalds case E_NOT: 713*1da177e4SLinus Torvalds return sym_check_expr_deps(e->left.expr); 714*1da177e4SLinus Torvalds case E_EQUAL: 715*1da177e4SLinus Torvalds case E_UNEQUAL: 716*1da177e4SLinus Torvalds sym = sym_check_deps(e->left.sym); 717*1da177e4SLinus Torvalds if (sym) 718*1da177e4SLinus Torvalds return sym; 719*1da177e4SLinus Torvalds return sym_check_deps(e->right.sym); 720*1da177e4SLinus Torvalds case E_SYMBOL: 721*1da177e4SLinus Torvalds return sym_check_deps(e->left.sym); 722*1da177e4SLinus Torvalds default: 723*1da177e4SLinus Torvalds break; 724*1da177e4SLinus Torvalds } 725*1da177e4SLinus Torvalds printf("Oops! How to check %d?\n", e->type); 726*1da177e4SLinus Torvalds return NULL; 727*1da177e4SLinus Torvalds } 728*1da177e4SLinus Torvalds 729*1da177e4SLinus Torvalds struct symbol *sym_check_deps(struct symbol *sym) 730*1da177e4SLinus Torvalds { 731*1da177e4SLinus Torvalds struct symbol *sym2; 732*1da177e4SLinus Torvalds struct property *prop; 733*1da177e4SLinus Torvalds 734*1da177e4SLinus Torvalds if (sym->flags & SYMBOL_CHECK_DONE) 735*1da177e4SLinus Torvalds return NULL; 736*1da177e4SLinus Torvalds if (sym->flags & SYMBOL_CHECK) { 737*1da177e4SLinus Torvalds printf("Warning! Found recursive dependency: %s", sym->name); 738*1da177e4SLinus Torvalds return sym; 739*1da177e4SLinus Torvalds } 740*1da177e4SLinus Torvalds 741*1da177e4SLinus Torvalds sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 742*1da177e4SLinus Torvalds sym2 = sym_check_expr_deps(sym->rev_dep.expr); 743*1da177e4SLinus Torvalds if (sym2) 744*1da177e4SLinus Torvalds goto out; 745*1da177e4SLinus Torvalds 746*1da177e4SLinus Torvalds for (prop = sym->prop; prop; prop = prop->next) { 747*1da177e4SLinus Torvalds if (prop->type == P_CHOICE || prop->type == P_SELECT) 748*1da177e4SLinus Torvalds continue; 749*1da177e4SLinus Torvalds sym2 = sym_check_expr_deps(prop->visible.expr); 750*1da177e4SLinus Torvalds if (sym2) 751*1da177e4SLinus Torvalds goto out; 752*1da177e4SLinus Torvalds if (prop->type != P_DEFAULT || sym_is_choice(sym)) 753*1da177e4SLinus Torvalds continue; 754*1da177e4SLinus Torvalds sym2 = sym_check_expr_deps(prop->expr); 755*1da177e4SLinus Torvalds if (sym2) 756*1da177e4SLinus Torvalds goto out; 757*1da177e4SLinus Torvalds } 758*1da177e4SLinus Torvalds out: 759*1da177e4SLinus Torvalds if (sym2) 760*1da177e4SLinus Torvalds printf(" %s", sym->name); 761*1da177e4SLinus Torvalds sym->flags &= ~SYMBOL_CHECK; 762*1da177e4SLinus Torvalds return sym2; 763*1da177e4SLinus Torvalds } 764*1da177e4SLinus Torvalds 765*1da177e4SLinus Torvalds struct property *prop_alloc(enum prop_type type, struct symbol *sym) 766*1da177e4SLinus Torvalds { 767*1da177e4SLinus Torvalds struct property *prop; 768*1da177e4SLinus Torvalds struct property **propp; 769*1da177e4SLinus Torvalds 770*1da177e4SLinus Torvalds prop = malloc(sizeof(*prop)); 771*1da177e4SLinus Torvalds memset(prop, 0, sizeof(*prop)); 772*1da177e4SLinus Torvalds prop->type = type; 773*1da177e4SLinus Torvalds prop->sym = sym; 774*1da177e4SLinus Torvalds prop->file = current_file; 775*1da177e4SLinus Torvalds prop->lineno = zconf_lineno(); 776*1da177e4SLinus Torvalds 777*1da177e4SLinus Torvalds /* append property to the prop list of symbol */ 778*1da177e4SLinus Torvalds if (sym) { 779*1da177e4SLinus Torvalds for (propp = &sym->prop; *propp; propp = &(*propp)->next) 780*1da177e4SLinus Torvalds ; 781*1da177e4SLinus Torvalds *propp = prop; 782*1da177e4SLinus Torvalds } 783*1da177e4SLinus Torvalds 784*1da177e4SLinus Torvalds return prop; 785*1da177e4SLinus Torvalds } 786*1da177e4SLinus Torvalds 787*1da177e4SLinus Torvalds struct symbol *prop_get_symbol(struct property *prop) 788*1da177e4SLinus Torvalds { 789*1da177e4SLinus Torvalds if (prop->expr && (prop->expr->type == E_SYMBOL || 790*1da177e4SLinus Torvalds prop->expr->type == E_CHOICE)) 791*1da177e4SLinus Torvalds return prop->expr->left.sym; 792*1da177e4SLinus Torvalds return NULL; 793*1da177e4SLinus Torvalds } 794*1da177e4SLinus Torvalds 795*1da177e4SLinus Torvalds const char *prop_get_type_name(enum prop_type type) 796*1da177e4SLinus Torvalds { 797*1da177e4SLinus Torvalds switch (type) { 798*1da177e4SLinus Torvalds case P_PROMPT: 799*1da177e4SLinus Torvalds return "prompt"; 800*1da177e4SLinus Torvalds case P_COMMENT: 801*1da177e4SLinus Torvalds return "comment"; 802*1da177e4SLinus Torvalds case P_MENU: 803*1da177e4SLinus Torvalds return "menu"; 804*1da177e4SLinus Torvalds case P_DEFAULT: 805*1da177e4SLinus Torvalds return "default"; 806*1da177e4SLinus Torvalds case P_CHOICE: 807*1da177e4SLinus Torvalds return "choice"; 808*1da177e4SLinus Torvalds case P_SELECT: 809*1da177e4SLinus Torvalds return "select"; 810*1da177e4SLinus Torvalds case P_RANGE: 811*1da177e4SLinus Torvalds return "range"; 812*1da177e4SLinus Torvalds case P_UNKNOWN: 813*1da177e4SLinus Torvalds break; 814*1da177e4SLinus Torvalds } 815*1da177e4SLinus Torvalds return "unknown"; 816*1da177e4SLinus Torvalds } 817