linux/scripts/kconfig/symbol.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
   3 * Released under the terms of the GNU GPL v2.0.
   4 */
   5
   6#include <ctype.h>
   7#include <stdlib.h>
   8#include <string.h>
   9#include <regex.h>
  10#include <sys/utsname.h>
  11
  12#define LKC_DIRECT_LINK
  13#include "lkc.h"
  14
  15struct symbol symbol_yes = {
  16        .name = "y",
  17        .curr = { "y", yes },
  18        .flags = SYMBOL_CONST|SYMBOL_VALID,
  19}, symbol_mod = {
  20        .name = "m",
  21        .curr = { "m", mod },
  22        .flags = SYMBOL_CONST|SYMBOL_VALID,
  23}, symbol_no = {
  24        .name = "n",
  25        .curr = { "n", no },
  26        .flags = SYMBOL_CONST|SYMBOL_VALID,
  27}, symbol_empty = {
  28        .name = "",
  29        .curr = { "", no },
  30        .flags = SYMBOL_VALID,
  31};
  32
  33struct symbol *sym_defconfig_list;
  34struct symbol *modules_sym;
  35tristate modules_val;
  36
  37struct expr *sym_env_list;
  38
  39static void sym_add_default(struct symbol *sym, const char *def)
  40{
  41        struct property *prop = prop_alloc(P_DEFAULT, sym);
  42
  43        prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
  44}
  45
  46void sym_init(void)
  47{
  48        struct symbol *sym;
  49        struct utsname uts;
  50        static bool inited = false;
  51
  52        if (inited)
  53                return;
  54        inited = true;
  55
  56        uname(&uts);
  57
  58        sym = sym_lookup("UNAME_RELEASE", 0);
  59        sym->type = S_STRING;
  60        sym->flags |= SYMBOL_AUTO;
  61        sym_add_default(sym, uts.release);
  62}
  63
  64enum symbol_type sym_get_type(struct symbol *sym)
  65{
  66        enum symbol_type type = sym->type;
  67
  68        if (type == S_TRISTATE) {
  69                if (sym_is_choice_value(sym) && sym->visible == yes)
  70                        type = S_BOOLEAN;
  71                else if (modules_val == no)
  72                        type = S_BOOLEAN;
  73        }
  74        return type;
  75}
  76
  77const char *sym_type_name(enum symbol_type type)
  78{
  79        switch (type) {
  80        case S_BOOLEAN:
  81                return "boolean";
  82        case S_TRISTATE:
  83                return "tristate";
  84        case S_INT:
  85                return "integer";
  86        case S_HEX:
  87                return "hex";
  88        case S_STRING:
  89                return "string";
  90        case S_UNKNOWN:
  91                return "unknown";
  92        case S_OTHER:
  93                break;
  94        }
  95        return "???";
  96}
  97
  98struct property *sym_get_choice_prop(struct symbol *sym)
  99{
 100        struct property *prop;
 101
 102        for_all_choices(sym, prop)
 103                return prop;
 104        return NULL;
 105}
 106
 107struct property *sym_get_env_prop(struct symbol *sym)
 108{
 109        struct property *prop;
 110
 111        for_all_properties(sym, prop, P_ENV)
 112                return prop;
 113        return NULL;
 114}
 115
 116struct property *sym_get_default_prop(struct symbol *sym)
 117{
 118        struct property *prop;
 119
 120        for_all_defaults(sym, prop) {
 121                prop->visible.tri = expr_calc_value(prop->visible.expr);
 122                if (prop->visible.tri != no)
 123                        return prop;
 124        }
 125        return NULL;
 126}
 127
 128static struct property *sym_get_range_prop(struct symbol *sym)
 129{
 130        struct property *prop;
 131
 132        for_all_properties(sym, prop, P_RANGE) {
 133                prop->visible.tri = expr_calc_value(prop->visible.expr);
 134                if (prop->visible.tri != no)
 135                        return prop;
 136        }
 137        return NULL;
 138}
 139
 140static int sym_get_range_val(struct symbol *sym, int base)
 141{
 142        sym_calc_value(sym);
 143        switch (sym->type) {
 144        case S_INT:
 145                base = 10;
 146                break;
 147        case S_HEX:
 148                base = 16;
 149                break;
 150        default:
 151                break;
 152        }
 153        return strtol(sym->curr.val, NULL, base);
 154}
 155
 156static void sym_validate_range(struct symbol *sym)
 157{
 158        struct property *prop;
 159        int base, val, val2;
 160        char str[64];
 161
 162        switch (sym->type) {
 163        case S_INT:
 164                base = 10;
 165                break;
 166        case S_HEX:
 167                base = 16;
 168                break;
 169        default:
 170                return;
 171        }
 172        prop = sym_get_range_prop(sym);
 173        if (!prop)
 174                return;
 175        val = strtol(sym->curr.val, NULL, base);
 176        val2 = sym_get_range_val(prop->expr->left.sym, base);
 177        if (val >= val2) {
 178                val2 = sym_get_range_val(prop->expr->right.sym, base);
 179                if (val <= val2)
 180                        return;
 181        }
 182        if (sym->type == S_INT)
 183                sprintf(str, "%d", val2);
 184        else
 185                sprintf(str, "0x%x", val2);
 186        sym->curr.val = strdup(str);
 187}
 188
 189static void sym_calc_visibility(struct symbol *sym)
 190{
 191        struct property *prop;
 192        tristate tri;
 193
 194        /* any prompt visible? */
 195        tri = no;
 196        for_all_prompts(sym, prop) {
 197                prop->visible.tri = expr_calc_value(prop->visible.expr);
 198                tri = EXPR_OR(tri, prop->visible.tri);
 199        }
 200        if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
 201                tri = yes;
 202        if (sym->visible != tri) {
 203                sym->visible = tri;
 204                sym_set_changed(sym);
 205        }
 206        if (sym_is_choice_value(sym))
 207                return;
 208        /* defaulting to "yes" if no explicit "depends on" are given */
 209        tri = yes;
 210        if (sym->dir_dep.expr)
 211                tri = expr_calc_value(sym->dir_dep.expr);
 212        if (tri == mod)
 213                tri = yes;
 214        if (sym->dir_dep.tri != tri) {
 215                sym->dir_dep.tri = tri;
 216                sym_set_changed(sym);
 217        }
 218        tri = no;
 219        if (sym->rev_dep.expr)
 220                tri = expr_calc_value(sym->rev_dep.expr);
 221        if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
 222                tri = yes;
 223        if (sym->rev_dep.tri != tri) {
 224                sym->rev_dep.tri = tri;
 225                sym_set_changed(sym);
 226        }
 227}
 228
 229/*
 230 * Find the default symbol for a choice.
 231 * First try the default values for the choice symbol
 232 * Next locate the first visible choice value
 233 * Return NULL if none was found
 234 */
 235struct symbol *sym_choice_default(struct symbol *sym)
 236{
 237        struct symbol *def_sym;
 238        struct property *prop;
 239        struct expr *e;
 240
 241        /* any of the defaults visible? */
 242        for_all_defaults(sym, prop) {
 243                prop->visible.tri = expr_calc_value(prop->visible.expr);
 244                if (prop->visible.tri == no)
 245                        continue;
 246                def_sym = prop_get_symbol(prop);
 247                if (def_sym->visible != no)
 248                        return def_sym;
 249        }
 250
 251        /* just get the first visible value */
 252        prop = sym_get_choice_prop(sym);
 253        expr_list_for_each_sym(prop->expr, e, def_sym)
 254                if (def_sym->visible != no)
 255                        return def_sym;
 256
 257        /* failed to locate any defaults */
 258        return NULL;
 259}
 260
 261static struct symbol *sym_calc_choice(struct symbol *sym)
 262{
 263        struct symbol *def_sym;
 264        struct property *prop;
 265        struct expr *e;
 266
 267        /* first calculate all choice values' visibilities */
 268        prop = sym_get_choice_prop(sym);
 269        expr_list_for_each_sym(prop->expr, e, def_sym)
 270                sym_calc_visibility(def_sym);
 271
 272        /* is the user choice visible? */
 273        def_sym = sym->def[S_DEF_USER].val;
 274        if (def_sym && def_sym->visible != no)
 275                return def_sym;
 276
 277        def_sym = sym_choice_default(sym);
 278
 279        if (def_sym == NULL)
 280                /* no choice? reset tristate value */
 281                sym->curr.tri = no;
 282
 283        return def_sym;
 284}
 285
 286void sym_calc_value(struct symbol *sym)
 287{
 288        struct symbol_value newval, oldval;
 289        struct property *prop;
 290        struct expr *e;
 291
 292        if (!sym)
 293                return;
 294
 295        if (sym->flags & SYMBOL_VALID)
 296                return;
 297        sym->flags |= SYMBOL_VALID;
 298
 299        oldval = sym->curr;
 300
 301        switch (sym->type) {
 302        case S_INT:
 303        case S_HEX:
 304        case S_STRING:
 305                newval = symbol_empty.curr;
 306                break;
 307        case S_BOOLEAN:
 308        case S_TRISTATE:
 309                newval = symbol_no.curr;
 310                break;
 311        default:
 312                sym->curr.val = sym->name;
 313                sym->curr.tri = no;
 314                return;
 315        }
 316        if (!sym_is_choice_value(sym))
 317                sym->flags &= ~SYMBOL_WRITE;
 318
 319        sym_calc_visibility(sym);
 320
 321        /* set default if recursively called */
 322        sym->curr = newval;
 323
 324        switch (sym_get_type(sym)) {
 325        case S_BOOLEAN:
 326        case S_TRISTATE:
 327                if (sym_is_choice_value(sym) && sym->visible == yes) {
 328                        prop = sym_get_choice_prop(sym);
 329                        newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
 330                } else {
 331                        if (sym->visible != no) {
 332                                /* if the symbol is visible use the user value
 333                                 * if available, otherwise try the default value
 334                                 */
 335                                sym->flags |= SYMBOL_WRITE;
 336                                if (sym_has_value(sym)) {
 337                                        newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
 338                                                              sym->visible);
 339                                        goto calc_newval;
 340                                }
 341                        }
 342                        if (sym->rev_dep.tri != no)
 343                                sym->flags |= SYMBOL_WRITE;
 344                        if (!sym_is_choice(sym)) {
 345                                prop = sym_get_default_prop(sym);
 346                                if (prop) {
 347                                        sym->flags |= SYMBOL_WRITE;
 348                                        newval.tri = EXPR_AND(expr_calc_value(prop->expr),
 349                                                              prop->visible.tri);
 350                                }
 351                        }
 352                calc_newval:
 353#if 0
 354                        if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
 355                                fprintf(stderr, "warning: (");
 356                                expr_fprint(sym->rev_dep.expr, stderr);
 357                                fprintf(stderr, ") selects %s which has unmet direct dependencies (",
 358                                        sym->name);
 359                                expr_fprint(sym->dir_dep.expr, stderr);
 360                                fprintf(stderr, ")\n");
 361                        }
 362#endif
 363                        newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
 364                }
 365                if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
 366                        newval.tri = yes;
 367                break;
 368        case S_STRING:
 369        case S_HEX:
 370        case S_INT:
 371                if (sym->visible != no) {
 372                        sym->flags |= SYMBOL_WRITE;
 373                        if (sym_has_value(sym)) {
 374                                newval.val = sym->def[S_DEF_USER].val;
 375                                break;
 376                        }
 377                }
 378                prop = sym_get_default_prop(sym);
 379                if (prop) {
 380                        struct symbol *ds = prop_get_symbol(prop);
 381                        if (ds) {
 382                                sym->flags |= SYMBOL_WRITE;
 383                                sym_calc_value(ds);
 384                                newval.val = ds->curr.val;
 385                        }
 386                }
 387                break;
 388        default:
 389                ;
 390        }
 391
 392        sym->curr = newval;
 393        if (sym_is_choice(sym) && newval.tri == yes)
 394                sym->curr.val = sym_calc_choice(sym);
 395        sym_validate_range(sym);
 396
 397        if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
 398                sym_set_changed(sym);
 399                if (modules_sym == sym) {
 400                        sym_set_all_changed();
 401                        modules_val = modules_sym->curr.tri;
 402                }
 403        }
 404
 405        if (sym_is_choice(sym)) {
 406                struct symbol *choice_sym;
 407
 408                prop = sym_get_choice_prop(sym);
 409                expr_list_for_each_sym(prop->expr, e, choice_sym) {
 410                        if ((sym->flags & SYMBOL_WRITE) &&
 411                            choice_sym->visible != no)
 412                                choice_sym->flags |= SYMBOL_WRITE;
 413                        if (sym->flags & SYMBOL_CHANGED)
 414                                sym_set_changed(choice_sym);
 415                }
 416        }
 417
 418        if (sym->flags & SYMBOL_AUTO)
 419                sym->flags &= ~SYMBOL_WRITE;
 420}
 421
 422void sym_clear_all_valid(void)
 423{
 424        struct symbol *sym;
 425        int i;
 426
 427        for_all_symbols(i, sym)
 428                sym->flags &= ~SYMBOL_VALID;
 429        sym_add_change_count(1);
 430        if (modules_sym)
 431                sym_calc_value(modules_sym);
 432}
 433
 434void sym_set_changed(struct symbol *sym)
 435{
 436        struct property *prop;
 437
 438        sym->flags |= SYMBOL_CHANGED;
 439        for (prop = sym->prop; prop; prop = prop->next) {
 440                if (prop->menu)
 441                        prop->menu->flags |= MENU_CHANGED;
 442        }
 443}
 444
 445void sym_set_all_changed(void)
 446{
 447        struct symbol *sym;
 448        int i;
 449
 450        for_all_symbols(i, sym)
 451                sym_set_changed(sym);
 452}
 453
 454bool sym_tristate_within_range(struct symbol *sym, tristate val)
 455{
 456        int type = sym_get_type(sym);
 457
 458        if (sym->visible == no)
 459                return false;
 460
 461        if (type != S_BOOLEAN && type != S_TRISTATE)
 462                return false;
 463
 464        if (type == S_BOOLEAN && val == mod)
 465                return false;
 466        if (sym->visible <= sym->rev_dep.tri)
 467                return false;
 468        if (sym_is_choice_value(sym) && sym->visible == yes)
 469                return val == yes;
 470        return val >= sym->rev_dep.tri && val <= sym->visible;
 471}
 472
 473bool sym_set_tristate_value(struct symbol *sym, tristate val)
 474{
 475        tristate oldval = sym_get_tristate_value(sym);
 476
 477        if (oldval != val && !sym_tristate_within_range(sym, val))
 478                return false;
 479
 480        if (!(sym->flags & SYMBOL_DEF_USER)) {
 481                sym->flags |= SYMBOL_DEF_USER;
 482                sym_set_changed(sym);
 483        }
 484        /*
 485         * setting a choice value also resets the new flag of the choice
 486         * symbol and all other choice values.
 487         */
 488        if (sym_is_choice_value(sym) && val == yes) {
 489                struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
 490                struct property *prop;
 491                struct expr *e;
 492
 493                cs->def[S_DEF_USER].val = sym;
 494                cs->flags |= SYMBOL_DEF_USER;
 495                prop = sym_get_choice_prop(cs);
 496                for (e = prop->expr; e; e = e->left.expr) {
 497                        if (e->right.sym->visible != no)
 498                                e->right.sym->flags |= SYMBOL_DEF_USER;
 499                }
 500        }
 501
 502        sym->def[S_DEF_USER].tri = val;
 503        if (oldval != val)
 504                sym_clear_all_valid();
 505
 506        return true;
 507}
 508
 509tristate sym_toggle_tristate_value(struct symbol *sym)
 510{
 511        tristate oldval, newval;
 512
 513        oldval = newval = sym_get_tristate_value(sym);
 514        do {
 515                switch (newval) {
 516                case no:
 517                        newval = mod;
 518                        break;
 519                case mod:
 520                        newval = yes;
 521                        break;
 522                case yes:
 523                        newval = no;
 524                        break;
 525                }
 526                if (sym_set_tristate_value(sym, newval))
 527                        break;
 528        } while (oldval != newval);
 529        return newval;
 530}
 531
 532bool sym_string_valid(struct symbol *sym, const char *str)
 533{
 534        signed char ch;
 535
 536        switch (sym->type) {
 537        case S_STRING:
 538                return true;
 539        case S_INT:
 540                ch = *str++;
 541                if (ch == '-')
 542                        ch = *str++;
 543                if (!isdigit(ch))
 544                        return false;
 545                if (ch == '0' && *str != 0)
 546                        return false;
 547                while ((ch = *str++)) {
 548                        if (!isdigit(ch))
 549                                return false;
 550                }
 551                return true;
 552        case S_HEX:
 553                if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
 554                        str += 2;
 555                ch = *str++;
 556                do {
 557                        if (!isxdigit(ch))
 558                                return false;
 559                } while ((ch = *str++));
 560                return true;
 561        case S_BOOLEAN:
 562        case S_TRISTATE:
 563                switch (str[0]) {
 564                case 'y': case 'Y':
 565                case 'm': case 'M':
 566                case 'n': case 'N':
 567                        return true;
 568                }
 569                return false;
 570        default:
 571                return false;
 572        }
 573}
 574
 575bool sym_string_within_range(struct symbol *sym, const char *str)
 576{
 577        struct property *prop;
 578        int val;
 579
 580        switch (sym->type) {
 581        case S_STRING:
 582                return sym_string_valid(sym, str);
 583        case S_INT:
 584                if (!sym_string_valid(sym, str))
 585                        return false;
 586                prop = sym_get_range_prop(sym);
 587                if (!prop)
 588                        return true;
 589                val = strtol(str, NULL, 10);
 590                return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
 591                       val <= sym_get_range_val(prop->expr->right.sym, 10);
 592        case S_HEX:
 593                if (!sym_string_valid(sym, str))
 594                        return false;
 595                prop = sym_get_range_prop(sym);
 596                if (!prop)
 597                        return true;
 598                val = strtol(str, NULL, 16);
 599                return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
 600                       val <= sym_get_range_val(prop->expr->right.sym, 16);
 601        case S_BOOLEAN:
 602        case S_TRISTATE:
 603                switch (str[0]) {
 604                case 'y': case 'Y':
 605                        return sym_tristate_within_range(sym, yes);
 606                case 'm': case 'M':
 607                        return sym_tristate_within_range(sym, mod);
 608                case 'n': case 'N':
 609                        return sym_tristate_within_range(sym, no);
 610                }
 611                return false;
 612        default:
 613                return false;
 614        }
 615}
 616
 617bool sym_set_string_value(struct symbol *sym, const char *newval)
 618{
 619        const char *oldval;
 620        char *val;
 621        int size;
 622
 623        switch (sym->type) {
 624        case S_BOOLEAN:
 625        case S_TRISTATE:
 626                switch (newval[0]) {
 627                case 'y': case 'Y':
 628                        return sym_set_tristate_value(sym, yes);
 629                case 'm': case 'M':
 630                        return sym_set_tristate_value(sym, mod);
 631                case 'n': case 'N':
 632                        return sym_set_tristate_value(sym, no);
 633                }
 634                return false;
 635        default:
 636                ;
 637        }
 638
 639        if (!sym_string_within_range(sym, newval))
 640                return false;
 641
 642        if (!(sym->flags & SYMBOL_DEF_USER)) {
 643                sym->flags |= SYMBOL_DEF_USER;
 644                sym_set_changed(sym);
 645        }
 646
 647        oldval = sym->def[S_DEF_USER].val;
 648        size = strlen(newval) + 1;
 649        if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
 650                size += 2;
 651                sym->def[S_DEF_USER].val = val = malloc(size);
 652                *val++ = '0';
 653                *val++ = 'x';
 654        } else if (!oldval || strcmp(oldval, newval))
 655                sym->def[S_DEF_USER].val = val = malloc(size);
 656        else
 657                return true;
 658
 659        strcpy(val, newval);
 660        free((void *)oldval);
 661        sym_clear_all_valid();
 662
 663        return true;
 664}
 665
 666/*
 667 * Find the default value associated to a symbol.
 668 * For tristate symbol handle the modules=n case
 669 * in which case "m" becomes "y".
 670 * If the symbol does not have any default then fallback
 671 * to the fixed default values.
 672 */
 673const char *sym_get_string_default(struct symbol *sym)
 674{
 675        struct property *prop;
 676        struct symbol *ds;
 677        const char *str;
 678        tristate val;
 679
 680        sym_calc_visibility(sym);
 681        sym_calc_value(modules_sym);
 682        val = symbol_no.curr.tri;
 683        str = symbol_empty.curr.val;
 684
 685        /* If symbol has a default value look it up */
 686        prop = sym_get_default_prop(sym);
 687        if (prop != NULL) {
 688                switch (sym->type) {
 689                case S_BOOLEAN:
 690                case S_TRISTATE:
 691                        /* The visibility imay limit the value from yes => mod */
 692                        val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
 693                        break;
 694                default:
 695                        /*
 696                         * The following fails to handle the situation
 697                         * where a default value is further limited by
 698                         * the valid range.
 699                         */
 700                        ds = prop_get_symbol(prop);
 701                        if (ds != NULL) {
 702                                sym_calc_value(ds);
 703                                str = (const char *)ds->curr.val;
 704                        }
 705                }
 706        }
 707
 708        /* Handle select statements */
 709        val = EXPR_OR(val, sym->rev_dep.tri);
 710
 711        /* transpose mod to yes if modules are not enabled */
 712        if (val == mod)
 713                if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
 714                        val = yes;
 715
 716        /* transpose mod to yes if type is bool */
 717        if (sym->type == S_BOOLEAN && val == mod)
 718                val = yes;
 719
 720        switch (sym->type) {
 721        case S_BOOLEAN:
 722        case S_TRISTATE:
 723                switch (val) {
 724                case no: return "n";
 725                case mod: return "m";
 726                case yes: return "y";
 727                }
 728        case S_INT:
 729        case S_HEX:
 730                return str;
 731        case S_STRING:
 732                return str;
 733        case S_OTHER:
 734        case S_UNKNOWN:
 735                break;
 736        }
 737        return "";
 738}
 739
 740const char *sym_get_string_value(struct symbol *sym)
 741{
 742        tristate val;
 743
 744        switch (sym->type) {
 745        case S_BOOLEAN:
 746        case S_TRISTATE:
 747                val = sym_get_tristate_value(sym);
 748                switch (val) {
 749                case no:
 750                        return "n";
 751                case mod:
 752                        return "m";
 753                case yes:
 754                        return "y";
 755                }
 756                break;
 757        default:
 758                ;
 759        }
 760        return (const char *)sym->curr.val;
 761}
 762
 763bool sym_is_changable(struct symbol *sym)
 764{
 765        return sym->visible > sym->rev_dep.tri;
 766}
 767
 768static unsigned strhash(const char *s)
 769{
 770        /* fnv32 hash */
 771        unsigned hash = 2166136261U;
 772        for (; *s; s++)
 773                hash = (hash ^ *s) * 0x01000193;
 774        return hash;
 775}
 776
 777struct symbol *sym_lookup(const char *name, int flags)
 778{
 779        struct symbol *symbol;
 780        char *new_name;
 781        int hash;
 782
 783        if (name) {
 784                if (name[0] && !name[1]) {
 785                        switch (name[0]) {
 786                        case 'y': return &symbol_yes;
 787                        case 'm': return &symbol_mod;
 788                        case 'n': return &symbol_no;
 789                        }
 790                }
 791                hash = strhash(name) % SYMBOL_HASHSIZE;
 792
 793                for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
 794                        if (symbol->name &&
 795                            !strcmp(symbol->name, name) &&
 796                            (flags ? symbol->flags & flags
 797                                   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
 798                                return symbol;
 799                }
 800                new_name = strdup(name);
 801        } else {
 802                new_name = NULL;
 803                hash = 0;
 804        }
 805
 806        symbol = malloc(sizeof(*symbol));
 807        memset(symbol, 0, sizeof(*symbol));
 808        symbol->name = new_name;
 809        symbol->type = S_UNKNOWN;
 810        symbol->flags |= flags;
 811
 812        symbol->next = symbol_hash[hash];
 813        symbol_hash[hash] = symbol;
 814
 815        return symbol;
 816}
 817
 818struct symbol *sym_find(const char *name)
 819{
 820        struct symbol *symbol = NULL;
 821        int hash = 0;
 822
 823        if (!name)
 824                return NULL;
 825
 826        if (name[0] && !name[1]) {
 827                switch (name[0]) {
 828                case 'y': return &symbol_yes;
 829                case 'm': return &symbol_mod;
 830                case 'n': return &symbol_no;
 831                }
 832        }
 833        hash = strhash(name) % SYMBOL_HASHSIZE;
 834
 835        for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
 836                if (symbol->name &&
 837                    !strcmp(symbol->name, name) &&
 838                    !(symbol->flags & SYMBOL_CONST))
 839                                break;
 840        }
 841
 842        return symbol;
 843}
 844
 845struct symbol **sym_re_search(const char *pattern)
 846{
 847        struct symbol *sym, **sym_arr = NULL;
 848        int i, cnt, size;
 849        regex_t re;
 850
 851        cnt = size = 0;
 852        /* Skip if empty */
 853        if (strlen(pattern) == 0)
 854                return NULL;
 855        if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
 856                return NULL;
 857
 858        for_all_symbols(i, sym) {
 859                if (sym->flags & SYMBOL_CONST || !sym->name)
 860                        continue;
 861                if (regexec(&re, sym->name, 0, NULL, 0))
 862                        continue;
 863                if (cnt + 1 >= size) {
 864                        void *tmp = sym_arr;
 865                        size += 16;
 866                        sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
 867                        if (!sym_arr) {
 868                                free(tmp);
 869                                return NULL;
 870                        }
 871                }
 872                sym_calc_value(sym);
 873                sym_arr[cnt++] = sym;
 874        }
 875        if (sym_arr)
 876                sym_arr[cnt] = NULL;
 877        regfree(&re);
 878
 879        return sym_arr;
 880}
 881
 882/*
 883 * When we check for recursive dependencies we use a stack to save
 884 * current state so we can print out relevant info to user.
 885 * The entries are located on the call stack so no need to free memory.
 886 * Note inser() remove() must always match to properly clear the stack.
 887 */
 888static struct dep_stack {
 889        struct dep_stack *prev, *next;
 890        struct symbol *sym;
 891        struct property *prop;
 892        struct expr *expr;
 893} *check_top;
 894
 895static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
 896{
 897        memset(stack, 0, sizeof(*stack));
 898        if (check_top)
 899                check_top->next = stack;
 900        stack->prev = check_top;
 901        stack->sym = sym;
 902        check_top = stack;
 903}
 904
 905static void dep_stack_remove(void)
 906{
 907        check_top = check_top->prev;
 908        if (check_top)
 909                check_top->next = NULL;
 910}
 911
 912/*
 913 * Called when we have detected a recursive dependency.
 914 * check_top point to the top of the stact so we use
 915 * the ->prev pointer to locate the bottom of the stack.
 916 */
 917static void sym_check_print_recursive(struct symbol *last_sym)
 918{
 919        struct dep_stack *stack;
 920        struct symbol *sym, *next_sym;
 921        struct menu *menu = NULL;
 922        struct property *prop;
 923        struct dep_stack cv_stack;
 924
 925        if (sym_is_choice_value(last_sym)) {
 926                dep_stack_insert(&cv_stack, last_sym);
 927                last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
 928        }
 929
 930        for (stack = check_top; stack != NULL; stack = stack->prev)
 931                if (stack->sym == last_sym)
 932                        break;
 933        if (!stack) {
 934                fprintf(stderr, "unexpected recursive dependency error\n");
 935                return;
 936        }
 937
 938        for (; stack; stack = stack->next) {
 939                sym = stack->sym;
 940                next_sym = stack->next ? stack->next->sym : last_sym;
 941                prop = stack->prop;
 942                if (prop == NULL)
 943                        prop = stack->sym->prop;
 944
 945                /* for choice values find the menu entry (used below) */
 946                if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
 947                        for (prop = sym->prop; prop; prop = prop->next) {
 948                                menu = prop->menu;
 949                                if (prop->menu)
 950                                        break;
 951                        }
 952                }
 953                if (stack->sym == last_sym)
 954                        fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
 955                                prop->file->name, prop->lineno);
 956                if (stack->expr) {
 957                        fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
 958                                prop->file->name, prop->lineno,
 959                                sym->name ? sym->name : "<choice>",
 960                                prop_get_type_name(prop->type),
 961                                next_sym->name ? next_sym->name : "<choice>");
 962                } else if (stack->prop) {
 963                        fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
 964                                prop->file->name, prop->lineno,
 965                                sym->name ? sym->name : "<choice>",
 966                                next_sym->name ? next_sym->name : "<choice>");
 967                } else if (sym_is_choice(sym)) {
 968                        fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
 969                                menu->file->name, menu->lineno,
 970                                sym->name ? sym->name : "<choice>",
 971                                next_sym->name ? next_sym->name : "<choice>");
 972                } else if (sym_is_choice_value(sym)) {
 973                        fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
 974                                menu->file->name, menu->lineno,
 975                                sym->name ? sym->name : "<choice>",
 976                                next_sym->name ? next_sym->name : "<choice>");
 977                } else {
 978                        fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
 979                                prop->file->name, prop->lineno,
 980                                sym->name ? sym->name : "<choice>",
 981                                next_sym->name ? next_sym->name : "<choice>");
 982                }
 983        }
 984
 985        if (check_top == &cv_stack)
 986                dep_stack_remove();
 987}
 988
 989static struct symbol *sym_check_expr_deps(struct expr *e)
 990{
 991        struct symbol *sym;
 992
 993        if (!e)
 994                return NULL;
 995        switch (e->type) {
 996        case E_OR:
 997        case E_AND:
 998                sym = sym_check_expr_deps(e->left.expr);
 999                if (sym)
1000                        return sym;
1001                return sym_check_expr_deps(e->right.expr);
1002        case E_NOT:
1003                return sym_check_expr_deps(e->left.expr);
1004        case E_EQUAL:
1005        case E_UNEQUAL:
1006                sym = sym_check_deps(e->left.sym);
1007                if (sym)
1008                        return sym;
1009                return sym_check_deps(e->right.sym);
1010        case E_SYMBOL:
1011                return sym_check_deps(e->left.sym);
1012        default:
1013                break;
1014        }
1015        printf("Oops! How to check %d?\n", e->type);
1016        return NULL;
1017}
1018
1019/* return NULL when dependencies are OK */
1020static struct symbol *sym_check_sym_deps(struct symbol *sym)
1021{
1022        struct symbol *sym2;
1023        struct property *prop;
1024        struct dep_stack stack;
1025
1026        dep_stack_insert(&stack, sym);
1027
1028        sym2 = sym_check_expr_deps(sym->rev_dep.expr);
1029        if (sym2)
1030                goto out;
1031
1032        for (prop = sym->prop; prop; prop = prop->next) {
1033                if (prop->type == P_CHOICE || prop->type == P_SELECT)
1034                        continue;
1035                stack.prop = prop;
1036                sym2 = sym_check_expr_deps(prop->visible.expr);
1037                if (sym2)
1038                        break;
1039                if (prop->type != P_DEFAULT || sym_is_choice(sym))
1040                        continue;
1041                stack.expr = prop->expr;
1042                sym2 = sym_check_expr_deps(prop->expr);
1043                if (sym2)
1044                        break;
1045                stack.expr = NULL;
1046        }
1047
1048out:
1049        dep_stack_remove();
1050
1051        return sym2;
1052}
1053
1054static struct symbol *sym_check_choice_deps(struct symbol *choice)
1055{
1056        struct symbol *sym, *sym2;
1057        struct property *prop;
1058        struct expr *e;
1059        struct dep_stack stack;
1060
1061        dep_stack_insert(&stack, choice);
1062
1063        prop = sym_get_choice_prop(choice);
1064        expr_list_for_each_sym(prop->expr, e, sym)
1065                sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
1066
1067        choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
1068        sym2 = sym_check_sym_deps(choice);
1069        choice->flags &= ~SYMBOL_CHECK;
1070        if (sym2)
1071                goto out;
1072
1073        expr_list_for_each_sym(prop->expr, e, sym) {
1074                sym2 = sym_check_sym_deps(sym);
1075                if (sym2)
1076                        break;
1077        }
1078out:
1079        expr_list_for_each_sym(prop->expr, e, sym)
1080                sym->flags &= ~SYMBOL_CHECK;
1081
1082        if (sym2 && sym_is_choice_value(sym2) &&
1083            prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
1084                sym2 = choice;
1085
1086        dep_stack_remove();
1087
1088        return sym2;
1089}
1090
1091struct symbol *sym_check_deps(struct symbol *sym)
1092{
1093        struct symbol *sym2;
1094        struct property *prop;
1095
1096        if (sym->flags & SYMBOL_CHECK) {
1097                sym_check_print_recursive(sym);
1098                return sym;
1099        }
1100        if (sym->flags & SYMBOL_CHECKED)
1101                return NULL;
1102
1103        if (sym_is_choice_value(sym)) {
1104                struct dep_stack stack;
1105
1106                /* for choice groups start the check with main choice symbol */
1107                dep_stack_insert(&stack, sym);
1108                prop = sym_get_choice_prop(sym);
1109                sym2 = sym_check_deps(prop_get_symbol(prop));
1110                dep_stack_remove();
1111        } else if (sym_is_choice(sym)) {
1112                sym2 = sym_check_choice_deps(sym);
1113        } else {
1114                sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
1115                sym2 = sym_check_sym_deps(sym);
1116                sym->flags &= ~SYMBOL_CHECK;
1117        }
1118
1119        if (sym2 && sym2 == sym)
1120                sym2 = NULL;
1121
1122        return sym2;
1123}
1124
1125struct property *prop_alloc(enum prop_type type, struct symbol *sym)
1126{
1127        struct property *prop;
1128        struct property **propp;
1129
1130        prop = malloc(sizeof(*prop));
1131        memset(prop, 0, sizeof(*prop));
1132        prop->type = type;
1133        prop->sym = sym;
1134        prop->file = current_file;
1135        prop->lineno = zconf_lineno();
1136
1137        /* append property to the prop list of symbol */
1138        if (sym) {
1139                for (propp = &sym->prop; *propp; propp = &(*propp)->next)
1140                        ;
1141                *propp = prop;
1142        }
1143
1144        return prop;
1145}
1146
1147struct symbol *prop_get_symbol(struct property *prop)
1148{
1149        if (prop->expr && (prop->expr->type == E_SYMBOL ||
1150                           prop->expr->type == E_LIST))
1151                return prop->expr->left.sym;
1152        return NULL;
1153}
1154
1155const char *prop_get_type_name(enum prop_type type)
1156{
1157        switch (type) {
1158        case P_PROMPT:
1159                return "prompt";
1160        case P_ENV:
1161                return "env";
1162        case P_COMMENT:
1163                return "comment";
1164        case P_MENU:
1165                return "menu";
1166        case P_DEFAULT:
1167                return "default";
1168        case P_CHOICE:
1169                return "choice";
1170        case P_SELECT:
1171                return "select";
1172        case P_RANGE:
1173                return "range";
1174        case P_SYMBOL:
1175                return "symbol";
1176        case P_UNKNOWN:
1177                break;
1178        }
1179        return "unknown";
1180}
1181
1182static void prop_add_env(const char *env)
1183{
1184        struct symbol *sym, *sym2;
1185        struct property *prop;
1186        char *p;
1187
1188        sym = current_entry->sym;
1189        sym->flags |= SYMBOL_AUTO;
1190        for_all_properties(sym, prop, P_ENV) {
1191                sym2 = prop_get_symbol(prop);
1192                if (strcmp(sym2->name, env))
1193                        menu_warn(current_entry, "redefining environment symbol from %s",
1194                                  sym2->name);
1195                return;
1196        }
1197
1198        prop = prop_alloc(P_ENV, sym);
1199        prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
1200
1201        sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
1202        sym_env_list->right.sym = sym;
1203
1204        p = getenv(env);
1205        if (p)
1206                sym_add_default(sym, p);
1207        else
1208                menu_warn(current_entry, "environment variable %s undefined", env);
1209}
1210