source: branches/3.2/mindi-busybox/scripts/kconfig/conf.c @ 3232

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