Annotation of qemu/roms/seabios/tools/kconfig/conf.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2002 Roman Zippel <[email protected]>
                      3:  * Released under the terms of the GNU GPL v2.0.
                      4:  */
                      5: 
                      6: #include <locale.h>
                      7: #include <ctype.h>
                      8: #include <stdio.h>
                      9: #include <stdlib.h>
                     10: #include <string.h>
                     11: #include <time.h>
                     12: #include <unistd.h>
                     13: #include <getopt.h>
                     14: #include <sys/stat.h>
                     15: #include <sys/time.h>
                     16: 
                     17: #define LKC_DIRECT_LINK
                     18: #include "lkc.h"
                     19: 
                     20: static void conf(struct menu *menu);
                     21: static void check_conf(struct menu *menu);
                     22: 
                     23: enum input_mode {
                     24:        oldaskconfig,
                     25:        silentoldconfig,
                     26:        oldconfig,
                     27:        allnoconfig,
                     28:        allyesconfig,
                     29:        allmodconfig,
                     30:        alldefconfig,
                     31:        randconfig,
                     32:        defconfig,
                     33:        savedefconfig,
                     34:        listnewconfig,
                     35:        oldnoconfig,
                     36: } input_mode = oldaskconfig;
                     37: 
                     38: char *defconfig_file;
                     39: 
                     40: static int indent = 1;
                     41: static int valid_stdin = 1;
                     42: static int sync_kconfig;
                     43: static int conf_cnt;
                     44: static char line[128];
                     45: static struct menu *rootEntry;
                     46: 
                     47: static void print_help(struct menu *menu)
                     48: {
                     49:        struct gstr help = str_new();
                     50: 
                     51:        menu_get_ext_help(menu, &help);
                     52: 
                     53:        printf("\n%s\n", str_get(&help));
                     54:        str_free(&help);
                     55: }
                     56: 
                     57: static void strip(char *str)
                     58: {
                     59:        char *p = str;
                     60:        int l;
                     61: 
                     62:        while ((isspace(*p)))
                     63:                p++;
                     64:        l = strlen(p);
                     65:        if (p != str)
                     66:                memmove(str, p, l + 1);
                     67:        if (!l)
                     68:                return;
                     69:        p = str + l - 1;
                     70:        while ((isspace(*p)))
                     71:                *p-- = 0;
                     72: }
                     73: 
                     74: static void check_stdin(void)
                     75: {
                     76:        if (!valid_stdin) {
                     77:                printf(_("aborted!\n\n"));
                     78:                printf(_("Console input/output is redirected. "));
                     79:                printf(_("Run 'make oldconfig' to update configuration.\n\n"));
                     80:                exit(1);
                     81:        }
                     82: }
                     83: 
                     84: static int conf_askvalue(struct symbol *sym, const char *def)
                     85: {
                     86:        enum symbol_type type = sym_get_type(sym);
                     87: 
                     88:        if (!sym_has_value(sym))
                     89:                printf(_("(NEW) "));
                     90: 
                     91:        line[0] = '\n';
                     92:        line[1] = 0;
                     93: 
                     94:        if (!sym_is_changable(sym)) {
                     95:                printf("%s\n", def);
                     96:                line[0] = '\n';
                     97:                line[1] = 0;
                     98:                return 0;
                     99:        }
                    100: 
                    101:        switch (input_mode) {
                    102:        case oldconfig:
                    103:        case silentoldconfig:
                    104:                if (sym_has_value(sym)) {
                    105:                        printf("%s\n", def);
                    106:                        return 0;
                    107:                }
                    108:                check_stdin();
                    109:        case oldaskconfig:
                    110:                fflush(stdout);
                    111:                xfgets(line, 128, stdin);
                    112:                return 1;
                    113:        default:
                    114:                break;
                    115:        }
                    116: 
                    117:        switch (type) {
                    118:        case S_INT:
                    119:        case S_HEX:
                    120:        case S_STRING:
                    121:                printf("%s\n", def);
                    122:                return 1;
                    123:        default:
                    124:                ;
                    125:        }
                    126:        printf("%s", line);
                    127:        return 1;
                    128: }
                    129: 
                    130: static int conf_string(struct menu *menu)
                    131: {
                    132:        struct symbol *sym = menu->sym;
                    133:        const char *def;
                    134: 
                    135:        while (1) {
                    136:                printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
                    137:                printf("(%s) ", sym->name);
                    138:                def = sym_get_string_value(sym);
                    139:                if (sym_get_string_value(sym))
                    140:                        printf("[%s] ", def);
                    141:                if (!conf_askvalue(sym, def))
                    142:                        return 0;
                    143:                switch (line[0]) {
                    144:                case '\n':
                    145:                        break;
                    146:                case '?':
                    147:                        /* print help */
                    148:                        if (line[1] == '\n') {
                    149:                                print_help(menu);
                    150:                                def = NULL;
                    151:                                break;
                    152:                        }
                    153:                default:
                    154:                        line[strlen(line)-1] = 0;
                    155:                        def = line;
                    156:                }
                    157:                if (def && sym_set_string_value(sym, def))
                    158:                        return 0;
                    159:        }
                    160: }
                    161: 
                    162: static int conf_sym(struct menu *menu)
                    163: {
                    164:        struct symbol *sym = menu->sym;
                    165:        tristate oldval, newval;
                    166: 
                    167:        while (1) {
                    168:                printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
                    169:                if (sym->name)
                    170:                        printf("(%s) ", sym->name);
                    171:                putchar('[');
                    172:                oldval = sym_get_tristate_value(sym);
                    173:                switch (oldval) {
                    174:                case no:
                    175:                        putchar('N');
                    176:                        break;
                    177:                case mod:
                    178:                        putchar('M');
                    179:                        break;
                    180:                case yes:
                    181:                        putchar('Y');
                    182:                        break;
                    183:                }
                    184:                if (oldval != no && sym_tristate_within_range(sym, no))
                    185:                        printf("/n");
                    186:                if (oldval != mod && sym_tristate_within_range(sym, mod))
                    187:                        printf("/m");
                    188:                if (oldval != yes && sym_tristate_within_range(sym, yes))
                    189:                        printf("/y");
                    190:                if (menu_has_help(menu))
                    191:                        printf("/?");
                    192:                printf("] ");
                    193:                if (!conf_askvalue(sym, sym_get_string_value(sym)))
                    194:                        return 0;
                    195:                strip(line);
                    196: 
                    197:                switch (line[0]) {
                    198:                case 'n':
                    199:                case 'N':
                    200:                        newval = no;
                    201:                        if (!line[1] || !strcmp(&line[1], "o"))
                    202:                                break;
                    203:                        continue;
                    204:                case 'm':
                    205:                case 'M':
                    206:                        newval = mod;
                    207:                        if (!line[1])
                    208:                                break;
                    209:                        continue;
                    210:                case 'y':
                    211:                case 'Y':
                    212:                        newval = yes;
                    213:                        if (!line[1] || !strcmp(&line[1], "es"))
                    214:                                break;
                    215:                        continue;
                    216:                case 0:
                    217:                        newval = oldval;
                    218:                        break;
                    219:                case '?':
                    220:                        goto help;
                    221:                default:
                    222:                        continue;
                    223:                }
                    224:                if (sym_set_tristate_value(sym, newval))
                    225:                        return 0;
                    226: help:
                    227:                print_help(menu);
                    228:        }
                    229: }
                    230: 
                    231: static int conf_choice(struct menu *menu)
                    232: {
                    233:        struct symbol *sym, *def_sym;
                    234:        struct menu *child;
                    235:        bool is_new;
                    236: 
                    237:        sym = menu->sym;
                    238:        is_new = !sym_has_value(sym);
                    239:        if (sym_is_changable(sym)) {
                    240:                conf_sym(menu);
                    241:                sym_calc_value(sym);
                    242:                switch (sym_get_tristate_value(sym)) {
                    243:                case no:
                    244:                        return 1;
                    245:                case mod:
                    246:                        return 0;
                    247:                case yes:
                    248:                        break;
                    249:                }
                    250:        } else {
                    251:                switch (sym_get_tristate_value(sym)) {
                    252:                case no:
                    253:                        return 1;
                    254:                case mod:
                    255:                        printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
                    256:                        return 0;
                    257:                case yes:
                    258:                        break;
                    259:                }
                    260:        }
                    261: 
                    262:        while (1) {
                    263:                int cnt, def;
                    264: 
                    265:                printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
                    266:                def_sym = sym_get_choice_value(sym);
                    267:                cnt = def = 0;
                    268:                line[0] = 0;
                    269:                for (child = menu->list; child; child = child->next) {
                    270:                        if (!menu_is_visible(child))
                    271:                                continue;
                    272:                        if (!child->sym) {
                    273:                                printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
                    274:                                continue;
                    275:                        }
                    276:                        cnt++;
                    277:                        if (child->sym == def_sym) {
                    278:                                def = cnt;
                    279:                                printf("%*c", indent, '>');
                    280:                        } else
                    281:                                printf("%*c", indent, ' ');
                    282:                        printf(" %d. %s", cnt, _(menu_get_prompt(child)));
                    283:                        if (child->sym->name)
                    284:                                printf(" (%s)", child->sym->name);
                    285:                        if (!sym_has_value(child->sym))
                    286:                                printf(_(" (NEW)"));
                    287:                        printf("\n");
                    288:                }
                    289:                printf(_("%*schoice"), indent - 1, "");
                    290:                if (cnt == 1) {
                    291:                        printf("[1]: 1\n");
                    292:                        goto conf_childs;
                    293:                }
                    294:                printf("[1-%d", cnt);
                    295:                if (menu_has_help(menu))
                    296:                        printf("?");
                    297:                printf("]: ");
                    298:                switch (input_mode) {
                    299:                case oldconfig:
                    300:                case silentoldconfig:
                    301:                        if (!is_new) {
                    302:                                cnt = def;
                    303:                                printf("%d\n", cnt);
                    304:                                break;
                    305:                        }
                    306:                        check_stdin();
                    307:                case oldaskconfig:
                    308:                        fflush(stdout);
                    309:                        xfgets(line, 128, stdin);
                    310:                        strip(line);
                    311:                        if (line[0] == '?') {
                    312:                                print_help(menu);
                    313:                                continue;
                    314:                        }
                    315:                        if (!line[0])
                    316:                                cnt = def;
                    317:                        else if (isdigit(line[0]))
                    318:                                cnt = atoi(line);
                    319:                        else
                    320:                                continue;
                    321:                        break;
                    322:                default:
                    323:                        break;
                    324:                }
                    325: 
                    326:        conf_childs:
                    327:                for (child = menu->list; child; child = child->next) {
                    328:                        if (!child->sym || !menu_is_visible(child))
                    329:                                continue;
                    330:                        if (!--cnt)
                    331:                                break;
                    332:                }
                    333:                if (!child)
                    334:                        continue;
                    335:                if (line[strlen(line) - 1] == '?') {
                    336:                        print_help(child);
                    337:                        continue;
                    338:                }
                    339:                sym_set_choice_value(sym, child->sym);
                    340:                for (child = child->list; child; child = child->next) {
                    341:                        indent += 2;
                    342:                        conf(child);
                    343:                        indent -= 2;
                    344:                }
                    345:                return 1;
                    346:        }
                    347: }
                    348: 
                    349: static void conf(struct menu *menu)
                    350: {
                    351:        struct symbol *sym;
                    352:        struct property *prop;
                    353:        struct menu *child;
                    354: 
                    355:        if (!menu_is_visible(menu))
                    356:                return;
                    357: 
                    358:        sym = menu->sym;
                    359:        prop = menu->prompt;
                    360:        if (prop) {
                    361:                const char *prompt;
                    362: 
                    363:                switch (prop->type) {
                    364:                case P_MENU:
                    365:                        if ((input_mode == silentoldconfig ||
                    366:                             input_mode == listnewconfig ||
                    367:                             input_mode == oldnoconfig) &&
                    368:                            rootEntry != menu) {
                    369:                                check_conf(menu);
                    370:                                return;
                    371:                        }
                    372:                case P_COMMENT:
                    373:                        prompt = menu_get_prompt(menu);
                    374:                        if (prompt)
                    375:                                printf("%*c\n%*c %s\n%*c\n",
                    376:                                        indent, '*',
                    377:                                        indent, '*', _(prompt),
                    378:                                        indent, '*');
                    379:                default:
                    380:                        ;
                    381:                }
                    382:        }
                    383: 
                    384:        if (!sym)
                    385:                goto conf_childs;
                    386: 
                    387:        if (sym_is_choice(sym)) {
                    388:                conf_choice(menu);
                    389:                if (sym->curr.tri != mod)
                    390:                        return;
                    391:                goto conf_childs;
                    392:        }
                    393: 
                    394:        switch (sym->type) {
                    395:        case S_INT:
                    396:        case S_HEX:
                    397:        case S_STRING:
                    398:                conf_string(menu);
                    399:                break;
                    400:        default:
                    401:                conf_sym(menu);
                    402:                break;
                    403:        }
                    404: 
                    405: conf_childs:
                    406:        if (sym)
                    407:                indent += 2;
                    408:        for (child = menu->list; child; child = child->next)
                    409:                conf(child);
                    410:        if (sym)
                    411:                indent -= 2;
                    412: }
                    413: 
                    414: static void check_conf(struct menu *menu)
                    415: {
                    416:        struct symbol *sym;
                    417:        struct menu *child;
                    418: 
                    419:        if (!menu_is_visible(menu))
                    420:                return;
                    421: 
                    422:        sym = menu->sym;
                    423:        if (sym && !sym_has_value(sym)) {
                    424:                if (sym_is_changable(sym) ||
                    425:                    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
                    426:                        if (input_mode == listnewconfig) {
                    427:                                if (sym->name && !sym_is_choice_value(sym)) {
                    428:                                        printf("%s%s\n", CONFIG_, sym->name);
                    429:                                }
                    430:                        } else if (input_mode != oldnoconfig) {
                    431:                                if (!conf_cnt++)
                    432:                                        printf(_("*\n* Restart config...\n*\n"));
                    433:                                rootEntry = menu_get_parent_menu(menu);
                    434:                                conf(rootEntry);
                    435:                        }
                    436:                }
                    437:        }
                    438: 
                    439:        for (child = menu->list; child; child = child->next)
                    440:                check_conf(child);
                    441: }
                    442: 
                    443: static struct option long_opts[] = {
                    444:        {"oldaskconfig",    no_argument,       NULL, oldaskconfig},
                    445:        {"oldconfig",       no_argument,       NULL, oldconfig},
                    446:        {"silentoldconfig", no_argument,       NULL, silentoldconfig},
                    447:        {"defconfig",       optional_argument, NULL, defconfig},
                    448:        {"savedefconfig",   required_argument, NULL, savedefconfig},
                    449:        {"allnoconfig",     no_argument,       NULL, allnoconfig},
                    450:        {"allyesconfig",    no_argument,       NULL, allyesconfig},
                    451:        {"allmodconfig",    no_argument,       NULL, allmodconfig},
                    452:        {"alldefconfig",    no_argument,       NULL, alldefconfig},
                    453:        {"randconfig",      no_argument,       NULL, randconfig},
                    454:        {"listnewconfig",   no_argument,       NULL, listnewconfig},
                    455:        {"oldnoconfig",     no_argument,       NULL, oldnoconfig},
                    456:        {NULL, 0, NULL, 0}
                    457: };
                    458: 
                    459: int main(int ac, char **av)
                    460: {
                    461:        int opt;
                    462:        const char *name;
                    463:        struct stat tmpstat;
                    464: 
                    465:        setlocale(LC_ALL, "");
                    466:        bindtextdomain(PACKAGE, LOCALEDIR);
                    467:        textdomain(PACKAGE);
                    468: 
                    469:        while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) {
                    470:                input_mode = (enum input_mode)opt;
                    471:                switch (opt) {
                    472:                case silentoldconfig:
                    473:                        sync_kconfig = 1;
                    474:                        break;
                    475:                case defconfig:
                    476:                case savedefconfig:
                    477:                        defconfig_file = optarg;
                    478:                        break;
                    479:                case randconfig:
                    480:                {
                    481:                        struct timeval now;
                    482:                        unsigned int seed;
                    483: 
                    484:                        /*
                    485:                         * Use microseconds derived seed,
                    486:                         * compensate for systems where it may be zero
                    487:                         */
                    488:                        gettimeofday(&now, NULL);
                    489: 
                    490:                        seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
                    491:                        srand(seed);
                    492:                        break;
                    493:                }
                    494:                case '?':
                    495:                        fprintf(stderr, _("See README for usage info\n"));
                    496:                        exit(1);
                    497:                        break;
                    498:                }
                    499:        }
                    500:        if (ac == optind) {
                    501:                printf(_("%s: Kconfig file missing\n"), av[0]);
                    502:                exit(1);
                    503:        }
                    504:        name = av[optind];
                    505:        conf_parse(name);
                    506:        //zconfdump(stdout);
                    507:        if (sync_kconfig) {
                    508:                name = conf_get_configname();
                    509:                if (stat(name, &tmpstat)) {
                    510:                        fprintf(stderr, _("***\n"
                    511:                                "*** Configuration file \"%s\" not found!\n"
                    512:                                "***\n"
                    513:                                "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
                    514:                                "*** \"make menuconfig\" or \"make xconfig\").\n"
                    515:                                "***\n"), name);
                    516:                        exit(1);
                    517:                }
                    518:        }
                    519: 
                    520:        switch (input_mode) {
                    521:        case defconfig:
                    522:                if (!defconfig_file)
                    523:                        defconfig_file = conf_get_default_confname();
                    524:                if (conf_read(defconfig_file)) {
                    525:                        printf(_("***\n"
                    526:                                "*** Can't find default configuration \"%s\"!\n"
                    527:                                "***\n"), defconfig_file);
                    528:                        exit(1);
                    529:                }
                    530:                break;
                    531:        case savedefconfig:
                    532:        case silentoldconfig:
                    533:        case oldaskconfig:
                    534:        case oldconfig:
                    535:        case listnewconfig:
                    536:        case oldnoconfig:
                    537:                conf_read(NULL);
                    538:                break;
                    539:        case allnoconfig:
                    540:        case allyesconfig:
                    541:        case allmodconfig:
                    542:        case alldefconfig:
                    543:        case randconfig:
                    544:                name = getenv("KCONFIG_ALLCONFIG");
                    545:                if (name && !stat(name, &tmpstat)) {
                    546:                        conf_read_simple(name, S_DEF_USER);
                    547:                        break;
                    548:                }
                    549:                switch (input_mode) {
                    550:                case allnoconfig:       name = "allno.config"; break;
                    551:                case allyesconfig:      name = "allyes.config"; break;
                    552:                case allmodconfig:      name = "allmod.config"; break;
                    553:                case alldefconfig:      name = "alldef.config"; break;
                    554:                case randconfig:        name = "allrandom.config"; break;
                    555:                default: break;
                    556:                }
                    557:                if (!stat(name, &tmpstat))
                    558:                        conf_read_simple(name, S_DEF_USER);
                    559:                else if (!stat("all.config", &tmpstat))
                    560:                        conf_read_simple("all.config", S_DEF_USER);
                    561:                break;
                    562:        default:
                    563:                break;
                    564:        }
                    565: 
                    566:        if (sync_kconfig) {
                    567:                if (conf_get_changed()) {
                    568:                        name = getenv("KCONFIG_NOSILENTUPDATE");
                    569:                        if (name && *name) {
                    570:                                fprintf(stderr,
                    571:                                        _("\n*** The configuration requires explicit update.\n\n"));
                    572:                                return 1;
                    573:                        }
                    574:                }
                    575:                valid_stdin = isatty(0) && isatty(1) && isatty(2);
                    576:        }
                    577: 
                    578:        switch (input_mode) {
                    579:        case allnoconfig:
                    580:                conf_set_all_new_symbols(def_no);
                    581:                break;
                    582:        case allyesconfig:
                    583:                conf_set_all_new_symbols(def_yes);
                    584:                break;
                    585:        case allmodconfig:
                    586:                conf_set_all_new_symbols(def_mod);
                    587:                break;
                    588:        case alldefconfig:
                    589:                conf_set_all_new_symbols(def_default);
                    590:                break;
                    591:        case randconfig:
                    592:                conf_set_all_new_symbols(def_random);
                    593:                break;
                    594:        case defconfig:
                    595:                conf_set_all_new_symbols(def_default);
                    596:                break;
                    597:        case savedefconfig:
                    598:                break;
                    599:        case oldaskconfig:
                    600:                rootEntry = &rootmenu;
                    601:                conf(&rootmenu);
                    602:                input_mode = silentoldconfig;
                    603:                /* fall through */
                    604:        case oldconfig:
                    605:        case listnewconfig:
                    606:        case oldnoconfig:
                    607:        case silentoldconfig:
                    608:                /* Update until a loop caused no more changes */
                    609:                do {
                    610:                        conf_cnt = 0;
                    611:                        check_conf(&rootmenu);
                    612:                } while (conf_cnt &&
                    613:                         (input_mode != listnewconfig &&
                    614:                          input_mode != oldnoconfig));
                    615:                break;
                    616:        }
                    617: 
                    618:        if (sync_kconfig) {
                    619:                /* silentoldconfig is used during the build so we shall update autoconf.
                    620:                 * All other commands are only used to generate a config.
                    621:                 */
                    622:                if (conf_get_changed() && conf_write(NULL)) {
                    623:                        fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
                    624:                        exit(1);
                    625:                }
                    626:                if (conf_write_autoconf()) {
                    627:                        fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
                    628:                        return 1;
                    629:                }
                    630:        } else if (input_mode == savedefconfig) {
                    631:                if (conf_write_defconfig(defconfig_file)) {
                    632:                        fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
                    633:                                defconfig_file);
                    634:                        return 1;
                    635:                }
                    636:        } else if (input_mode != listnewconfig) {
                    637:                if (conf_write(NULL)) {
                    638:                        fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
                    639:                        exit(1);
                    640:                }
                    641:        }
                    642:        return 0;
                    643: }
                    644: /*
                    645:  * Helper function to facilitate fgets() by Jean Sacren.
                    646:  */
                    647: void xfgets(str, size, in)
                    648:        char *str;
                    649:        int size;
                    650:        FILE *in;
                    651: {
                    652:        if (fgets(str, size, in) == NULL)
                    653:                fprintf(stderr, "\nError in reading or end of file.\n");
                    654: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.