00001
00002
00003
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
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
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 }