source: menu/conf.c@ c88b48d

ablfs
Last change on this file since c88b48d was 743414b, checked in by Pierre Labastie <pierre@…>, 13 years ago

Changes slightly the code in menu directory so that "conf"
and "mconf" build without issuing warnings

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