source: MondoRescue/branches/2.2.5/mindi-busybox/scripts/kconfig/conf.c

Last change on this file was 1765, checked in by Bruno Cornec, 13 years ago

Update to busybox 1.7.2

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