base/config/kconfig/conf.c

Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 00003 * Released under the terms of the GNU GPL v2.0. 00004 */ 00005 00006 #include <ctype.h> 00007 #include <stdlib.h> 00008 #include <string.h> 00009 #include <unistd.h> 00010 #include <time.h> 00011 #include <sys/stat.h> 00012 00013 #define LKC_DIRECT_LINK 00014 #include "lkc.h" 00015 00016 static void conf(struct menu *menu); 00017 static void check_conf(struct menu *menu); 00018 00019 enum { 00020 ask_all, 00021 ask_new, 00022 ask_silent, 00023 set_default, 00024 set_yes, 00025 set_mod, 00026 set_no, 00027 set_random 00028 } input_mode = ask_all; 00029 char *defconfig_file; 00030 00031 static int indent = 1; 00032 static int valid_stdin = 1; 00033 static int conf_cnt; 00034 static char line[128]; 00035 static struct menu *rootEntry; 00036 00037 static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; 00038 00039 static void strip(char *str) 00040 { 00041 char *p = str; 00042 int l; 00043 00044 while ((isspace(*p))) 00045 p++; 00046 l = strlen(p); 00047 if (p != str) 00048 memmove(str, p, l + 1); 00049 if (!l) 00050 return; 00051 p = str + l - 1; 00052 while ((isspace(*p))) 00053 *p-- = 0; 00054 } 00055 00056 static void check_stdin(void) 00057 { 00058 if (!valid_stdin && input_mode == ask_silent) { 00059 printf("aborted!\n\n"); 00060 printf("Console input/output is redirected. "); 00061 printf("Run 'make oldconfig' to update configuration.\n\n"); 00062 exit(1); 00063 } 00064 } 00065 00066 static void conf_askvalue(struct symbol *sym, const char *def) 00067 { 00068 enum symbol_type type = sym_get_type(sym); 00069 tristate val; 00070 00071 if (!sym_has_value(sym)) 00072 printf("(NEW) "); 00073 00074 line[0] = '\n'; 00075 line[1] = 0; 00076 00077 if (!sym_is_changable(sym)) { 00078 printf("%s\n", def); 00079 line[0] = '\n'; 00080 line[1] = 0; 00081 return; 00082 } 00083 00084 switch (input_mode) { 00085 case ask_new: 00086 case ask_silent: 00087 if (sym_has_value(sym)) { 00088 printf("%s\n", def); 00089 return; 00090 } 00091 check_stdin(); 00092 case ask_all: 00093 fflush(stdout); 00094 fgets(line, 128, stdin); 00095 return; 00096 case set_default: 00097 printf("%s\n", def); 00098 return; 00099 default: 00100 break; 00101 } 00102 00103 switch (type) { 00104 case S_INT: 00105 case S_HEX: 00106 case S_STRING: 00107 printf("%s\n", def); 00108 return; 00109 default: 00110 ; 00111 } 00112 switch (input_mode) { 00113 case set_yes: 00114 if (sym_tristate_within_range(sym, yes)) { 00115 line[0] = 'y'; 00116 line[1] = '\n'; 00117 line[2] = 0; 00118 break; 00119 } 00120 case set_mod: 00121 if (type == S_TRISTATE) { 00122 if (sym_tristate_within_range(sym, mod)) { 00123 line[0] = 'm'; 00124 line[1] = '\n'; 00125 line[2] = 0; 00126 break; 00127 } 00128 } else { 00129 if (sym_tristate_within_range(sym, yes)) { 00130 line[0] = 'y'; 00131 line[1] = '\n'; 00132 line[2] = 0; 00133 break; 00134 } 00135 } 00136 case set_no: 00137 if (sym_tristate_within_range(sym, no)) { 00138 line[0] = 'n'; 00139 line[1] = '\n'; 00140 line[2] = 0; 00141 break; 00142 } 00143 case set_random: 00144 do { 00145 val = (tristate)(random() % 3); 00146 } while (!sym_tristate_within_range(sym, val)); 00147 switch (val) { 00148 case no: line[0] = 'n'; break; 00149 case mod: line[0] = 'm'; break; 00150 case yes: line[0] = 'y'; break; 00151 } 00152 line[1] = '\n'; 00153 line[2] = 0; 00154 break; 00155 default: 00156 break; 00157 } 00158 printf("%s", line); 00159 } 00160 00161 int conf_string(struct menu *menu) 00162 { 00163 struct symbol *sym = menu->sym; 00164 const char *def, *help; 00165 00166 while (1) { 00167 printf("%*s%s ", indent - 1, "", menu->prompt->text); 00168 printf("(%s) ", sym->name); 00169 def = sym_get_string_value(sym); 00170 if (sym_get_string_value(sym)) 00171 printf("[%s] ", def); 00172 conf_askvalue(sym, def); 00173 switch (line[0]) { 00174 case '\n': 00175 break; 00176 case '?': 00177 /* print help */ 00178 if (line[1] == 0) { 00179 help = nohelp_text; 00180 if (menu->sym->help) 00181 help = menu->sym->help; 00182 printf("\n%s\n", menu->sym->help); 00183 def = NULL; 00184 break; 00185 } 00186 default: 00187 line[strlen(line)-1] = 0; 00188 def = line; 00189 } 00190 if (def && sym_set_string_value(sym, def)) 00191 return 0; 00192 } 00193 } 00194 00195 static int conf_sym(struct menu *menu) 00196 { 00197 struct symbol *sym = menu->sym; 00198 int type; 00199 tristate oldval, newval; 00200 const char *help; 00201 00202 while (1) { 00203 printf("%*s%s ", indent - 1, "", menu->prompt->text); 00204 if (sym->name) 00205 printf("(%s) ", sym->name); 00206 type = sym_get_type(sym); 00207 putchar('['); 00208 oldval = sym_get_tristate_value(sym); 00209 switch (oldval) { 00210 case no: 00211 putchar('N'); 00212 break; 00213 case mod: 00214 putchar('M'); 00215 break; 00216 case yes: 00217 putchar('Y'); 00218 break; 00219 } 00220 if (oldval != no && sym_tristate_within_range(sym, no)) 00221 printf("/n"); 00222 if (oldval != mod && sym_tristate_within_range(sym, mod)) 00223 printf("/m"); 00224 if (oldval != yes && sym_tristate_within_range(sym, yes)) 00225 printf("/y"); 00226 if (sym->help) 00227 printf("/?"); 00228 printf("] "); 00229 conf_askvalue(sym, sym_get_string_value(sym)); 00230 strip(line); 00231 00232 switch (line[0]) { 00233 case 'n': 00234 case 'N': 00235 newval = no; 00236 if (!line[1] || !strcmp(&line[1], "o")) 00237 break; 00238 continue; 00239 case 'm': 00240 case 'M': 00241 newval = mod; 00242 if (!line[1]) 00243 break; 00244 continue; 00245 case 'y': 00246 case 'Y': 00247 newval = yes; 00248 if (!line[1] || !strcmp(&line[1], "es")) 00249 break; 00250 continue; 00251 case 0: 00252 newval = oldval; 00253 break; 00254 case '?': 00255 goto help; 00256 default: 00257 continue; 00258 } 00259 if (sym_set_tristate_value(sym, newval)) 00260 return 0; 00261 help: 00262 help = nohelp_text; 00263 if (sym->help) 00264 help = sym->help; 00265 printf("\n%s\n", help); 00266 } 00267 } 00268 00269 static int conf_choice(struct menu *menu) 00270 { 00271 struct symbol *sym, *def_sym; 00272 struct menu *child; 00273 int type; 00274 bool is_new; 00275 00276 sym = menu->sym; 00277 type = sym_get_type(sym); 00278 is_new = !sym_has_value(sym); 00279 if (sym_is_changable(sym)) { 00280 conf_sym(menu); 00281 sym_calc_value(sym); 00282 switch (sym_get_tristate_value(sym)) { 00283 case no: 00284 return 1; 00285 case mod: 00286 return 0; 00287 case yes: 00288 break; 00289 } 00290 } else { 00291 switch (sym_get_tristate_value(sym)) { 00292 case no: 00293 return 1; 00294 case mod: 00295 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 00296 return 0; 00297 case yes: 00298 break; 00299 } 00300 } 00301 00302 while (1) { 00303 int cnt, def; 00304 00305 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 00306 def_sym = sym_get_choice_value(sym); 00307 cnt = def = 0; 00308 line[0] = '0'; 00309 line[1] = 0; 00310 for (child = menu->list; child; child = child->next) { 00311 if (!menu_is_visible(child)) 00312 continue; 00313 if (!child->sym) { 00314 printf("%*c %s\n", indent, '*', menu_get_prompt(child)); 00315 continue; 00316 } 00317 cnt++; 00318 if (child->sym == def_sym) { 00319 def = cnt; 00320 printf("%*c", indent, '>'); 00321 } else 00322 printf("%*c", indent, ' '); 00323 printf(" %d. %s", cnt, menu_get_prompt(child)); 00324 if (child->sym->name) 00325 printf(" (%s)", child->sym->name); 00326 if (!sym_has_value(child->sym)) 00327 printf(" (NEW)"); 00328 printf("\n"); 00329 } 00330 printf("%*schoice", indent - 1, ""); 00331 if (cnt == 1) { 00332 printf("[1]: 1\n"); 00333 goto conf_childs; 00334 } 00335 printf("[1-%d", cnt); 00336 if (sym->help) 00337 printf("?"); 00338 printf("]: "); 00339 switch (input_mode) { 00340 case ask_new: 00341 case ask_silent: 00342 if (!is_new) { 00343 cnt = def; 00344 printf("%d\n", cnt); 00345 break; 00346 } 00347 check_stdin(); 00348 case ask_all: 00349 fflush(stdout); 00350 fgets(line, 128, stdin); 00351 strip(line); 00352 if (line[0] == '?') { 00353 printf("\n%s\n", menu->sym->help ? 00354 menu->sym->help : nohelp_text); 00355 continue; 00356 } 00357 if (!line[0]) 00358 cnt = def; 00359 else if (isdigit(line[0])) 00360 cnt = atoi(line); 00361 else 00362 continue; 00363 break; 00364 case set_random: 00365 def = (random() % cnt) + 1; 00366 case set_default: 00367 case set_yes: 00368 case set_mod: 00369 case set_no: 00370 cnt = def; 00371 printf("%d\n", cnt); 00372 break; 00373 } 00374 00375 conf_childs: 00376 for (child = menu->list; child; child = child->next) { 00377 if (!child->sym || !menu_is_visible(child)) 00378 continue; 00379 if (!--cnt) 00380 break; 00381 } 00382 if (!child) 00383 continue; 00384 if (line[strlen(line) - 1] == '?') { 00385 printf("\n%s\n", child->sym->help ? 00386 child->sym->help : nohelp_text); 00387 continue; 00388 } 00389 sym_set_choice_value(sym, child->sym); 00390 if (child->list) { 00391 indent += 2; 00392 conf(child->list); 00393 indent -= 2; 00394 } 00395 return 1; 00396 } 00397 } 00398 00399 static void conf(struct menu *menu) 00400 { 00401 struct symbol *sym; 00402 struct property *prop; 00403 struct menu *child; 00404 00405 if (!menu_is_visible(menu)) 00406 return; 00407 00408 sym = menu->sym; 00409 prop = menu->prompt; 00410 if (prop) { 00411 const char *prompt; 00412 00413 switch (prop->type) { 00414 case P_MENU: 00415 if (input_mode == ask_silent && rootEntry != menu) { 00416 check_conf(menu); 00417 return; 00418 } 00419 case P_COMMENT: 00420 prompt = menu_get_prompt(menu); 00421 if (prompt) 00422 printf("%*c\n%*c %s\n%*c\n", 00423 indent, '*', 00424 indent, '*', prompt, 00425 indent, '*'); 00426 default: 00427 ; 00428 } 00429 } 00430 00431 if (!sym) 00432 goto conf_childs; 00433 00434 if (sym_is_choice(sym)) { 00435 conf_choice(menu); 00436 if (sym->curr.tri != mod) 00437 return; 00438 goto conf_childs; 00439 } 00440 00441 switch (sym->type) { 00442 case S_INT: 00443 case S_HEX: 00444 case S_STRING: 00445 conf_string(menu); 00446 break; 00447 default: 00448 conf_sym(menu); 00449 break; 00450 } 00451 00452 conf_childs: 00453 if (sym) 00454 indent += 2; 00455 for (child = menu->list; child; child = child->next) 00456 conf(child); 00457 if (sym) 00458 indent -= 2; 00459 } 00460 00461 static void check_conf(struct menu *menu) 00462 { 00463 struct symbol *sym; 00464 struct menu *child; 00465 00466 if (!menu_is_visible(menu)) 00467 return; 00468 00469 sym = menu->sym; 00470 if (sym) { 00471 if (sym_is_changable(sym) && !sym_has_value(sym)) { 00472 if (!conf_cnt++) 00473 printf("*\n* Restart config...\n*\n"); 00474 rootEntry = menu_get_parent_menu(menu); 00475 conf(rootEntry); 00476 } 00477 if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod) 00478 return; 00479 } 00480 00481 for (child = menu->list; child; child = child->next) 00482 check_conf(child); 00483 } 00484 00485 int main(int ac, char **av) 00486 { 00487 int i = 1; 00488 const char *name; 00489 struct stat tmpstat; 00490 00491 if (ac > i && av[i][0] == '-') { 00492 switch (av[i++][1]) { 00493 case 'o': 00494 input_mode = ask_new; 00495 break; 00496 case 's': 00497 input_mode = ask_silent; 00498 valid_stdin = isatty(0) && isatty(1) && isatty(2); 00499 break; 00500 case 'd': 00501 input_mode = set_default; 00502 break; 00503 case 'D': 00504 input_mode = set_default; 00505 defconfig_file = av[i++]; 00506 if (!defconfig_file) { 00507 printf("%s: No default config file specified\n", 00508 av[0]); 00509 exit(1); 00510 } 00511 break; 00512 case 'n': 00513 input_mode = set_no; 00514 break; 00515 case 'm': 00516 input_mode = set_mod; 00517 break; 00518 case 'y': 00519 input_mode = set_yes; 00520 break; 00521 case 'r': 00522 input_mode = set_random; 00523 srandom(time(NULL)); 00524 break; 00525 case 'h': 00526 case '?': 00527 printf("%s [-o|-s] config\n", av[0]); 00528 exit(0); 00529 } 00530 } 00531 name = av[i]; 00532 if (!name) { 00533 printf("%s: Kconfig file missing\n", av[0]); 00534 } 00535 conf_parse(name); 00536 //zconfdump(stdout); 00537 switch (input_mode) { 00538 case set_default: 00539 if (!defconfig_file) 00540 defconfig_file = conf_get_default_confname(); 00541 if (conf_read(defconfig_file)) { 00542 printf("***\n" 00543 "*** Can't find default configuration \"%s\"!\n" 00544 "***\n", defconfig_file); 00545 exit(1); 00546 } 00547 break; 00548 case ask_silent: 00549 if (stat("../../../.rtai_config", &tmpstat)) { 00550 printf("***\n" 00551 "*** You have not yet configured RTAI!\n" 00552 "***\n" 00553 "*** Please run some configurator (e.g. \"make oldconfig\" or\n" 00554 "*** \"make menuconfig\" or \"make xconfig\").\n" 00555 "***\n"); 00556 exit(1); 00557 } 00558 case ask_all: 00559 case ask_new: 00560 conf_read(NULL); 00561 break; 00562 default: 00563 break; 00564 } 00565 00566 if (input_mode != ask_silent) { 00567 rootEntry = &rootmenu; 00568 conf(&rootmenu); 00569 if (input_mode == ask_all) { 00570 input_mode = ask_silent; 00571 valid_stdin = 1; 00572 } 00573 } 00574 do { 00575 conf_cnt = 0; 00576 check_conf(&rootmenu); 00577 } while (conf_cnt); 00578 conf_write(NULL); 00579 return 0; 00580 }

Generated on Thu Nov 20 11:49:47 2008 for RTAI API by doxygen 1.3.8