|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.