ia64/linux-2.6.18-xen.hg

annotate scripts/kconfig/conf.c @ 0:831230e53067

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