OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [extra/] [config/] [conf.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*
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
 
16
static void conf(struct menu *menu);
17
static void check_conf(struct menu *menu);
18
 
19
enum {
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;
29
 
30
static int indent = 1;
31
static int valid_stdin = 1;
32
static int conf_cnt;
33
static char line[128];
34
static struct menu *rootEntry;
35
 
36
static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
37
 
38
static void strip(char *str)
39
{
40
        char *p = str;
41
        int l;
42
 
43
        while ((isspace(*p)))
44
                p++;
45
        l = strlen(p);
46
        if (p != str)
47
                memmove(str, p, l + 1);
48
        if (!l)
49
                return;
50
        p = str + l - 1;
51
        while ((isspace(*p)))
52
                *p-- = 0;
53
}
54
 
55
static void check_stdin(void)
56
{
57
        if (!valid_stdin && input_mode == ask_silent) {
58
                printf("aborted!\n\n");
59
                printf("Console input/output is redirected. ");
60
                printf("Run 'make oldconfig' to update configuration.\n\n");
61
                exit(1);
62
        }
63
}
64
 
65
static void conf_askvalue(struct symbol *sym, const char *def)
66
{
67
        enum symbol_type type = sym_get_type(sym);
68
        tristate val;
69
 
70
        if (!sym_has_value(sym))
71
                printf("(NEW) ");
72
 
73
        line[0] = '\n';
74
        line[1] = 0;
75
 
76
        if (!sym_is_changable(sym)) {
77
                printf("%s\n", def);
78
                line[0] = '\n';
79
                line[1] = 0;
80
                return;
81
        }
82
 
83
        switch (input_mode) {
84
        case ask_new:
85
        case ask_silent:
86
                if (sym_has_value(sym)) {
87
                        printf("%s\n", def);
88
                        return;
89
                }
90
                check_stdin();
91
        case ask_all:
92
                fflush(stdout);
93
                fgets(line, 128, stdin);
94
                return;
95
        case set_default:
96
                printf("%s\n", def);
97
                return;
98
        default:
99
                break;
100
        }
101
 
102
        switch (type) {
103
        case S_INT:
104
        case S_HEX:
105
        case S_STRING:
106
                printf("%s\n", def);
107
                return;
108
        default:
109
                ;
110
        }
111
        switch (input_mode) {
112
        case set_yes:
113
                if (sym_tristate_within_range(sym, yes)) {
114
                        line[0] = 'y';
115
                        line[1] = '\n';
116
                        line[2] = 0;
117
                        break;
118
                }
119
        case set_mod:
120
                if (type == S_TRISTATE) {
121
                        if (sym_tristate_within_range(sym, mod)) {
122
                                line[0] = 'm';
123
                                line[1] = '\n';
124
                                line[2] = 0;
125
                                break;
126
                        }
127
                } else {
128
                        if (sym_tristate_within_range(sym, yes)) {
129
                                line[0] = 'y';
130
                                line[1] = '\n';
131
                                line[2] = 0;
132
                                break;
133
                        }
134
                }
135
        case set_no:
136
                if (sym_tristate_within_range(sym, no)) {
137
                        line[0] = 'n';
138
                        line[1] = '\n';
139
                        line[2] = 0;
140
                        break;
141
                }
142
        case set_random:
143
                do {
144
                        val = (tristate)(random() % 3);
145
                } while (!sym_tristate_within_range(sym, val));
146
                switch (val) {
147
                case no: line[0] = 'n'; break;
148
                case mod: line[0] = 'm'; break;
149
                case yes: line[0] = 'y'; break;
150
                }
151
                line[1] = '\n';
152
                line[2] = 0;
153
                break;
154
        default:
155
                break;
156
        }
157
        printf("%s", line);
158
}
159
 
160
int conf_string(struct menu *menu)
161
{
162
        struct symbol *sym = menu->sym;
163
        const char *def, *help;
164
 
165
        while (1) {
166
                printf("%*s%s ", indent - 1, "", menu->prompt->text);
167
                printf("(%s) ", sym->name);
168
                def = sym_get_string_value(sym);
169
                if (sym_get_string_value(sym))
170
                        printf("[%s] ", def);
171
                conf_askvalue(sym, def);
172
                switch (line[0]) {
173
                case '\n':
174
                        break;
175
                case '?':
176
                        /* print help */
177
                        if (line[1] == 0) {
178
                                help = nohelp_text;
179
                                if (menu->sym->help)
180
                                        help = menu->sym->help;
181
                                printf("\n%s\n", menu->sym->help);
182
                                def = NULL;
183
                                break;
184
                        }
185
                default:
186
                        line[strlen(line)-1] = 0;
187
                        def = line;
188
                }
189
                if (def && sym_set_string_value(sym, def))
190
                        return 0;
191
        }
192
}
193
 
194
static int conf_sym(struct menu *menu)
195
{
196
        struct symbol *sym = menu->sym;
197
        int type;
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
                type = 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;
260
help:
261
                help = nohelp_text;
262
                if (sym->help)
263
                        help = sym->help;
264
                printf("\n%s\n", help);
265
        }
266
}
267
 
268
static int conf_choice(struct menu *menu)
269
{
270
        struct symbol *sym, *def_sym;
271
        struct menu *child;
272
        int type;
273
        bool is_new;
274
 
275
        sym = menu->sym;
276
        type = sym_get_type(sym);
277
        is_new = !sym_has_value(sym);
278
        if (sym_is_changable(sym)) {
279
                conf_sym(menu);
280
                sym_calc_value(sym);
281
                switch (sym_get_tristate_value(sym)) {
282
                case no:
283
                        return 1;
284
                case mod:
285
                        return 0;
286
                case yes:
287
                        break;
288
                }
289
        } else {
290
                switch (sym_get_tristate_value(sym)) {
291
                case no:
292
                        return 1;
293
                case mod:
294
                        printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
295
                        return 0;
296
                case yes:
297
                        break;
298
                }
299
        }
300
 
301
        while (1) {
302
                int cnt, def;
303
 
304
                printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
305
                def_sym = sym_get_choice_value(sym);
306
                cnt = def = 0;
307
                line[0] = '0';
308
                line[1] = 0;
309
                for (child = menu->list; child; child = child->next) {
310
                        if (!menu_is_visible(child))
311
                                continue;
312
                        if (!child->sym) {
313
                                printf("%*c %s\n", indent, '*', menu_get_prompt(child));
314
                                continue;
315
                        }
316
                        cnt++;
317
                        if (child->sym == def_sym) {
318
                                def = cnt;
319
                                printf("%*c", indent, '>');
320
                        } else
321
                                printf("%*c", indent, ' ');
322
                        printf(" %d. %s", cnt, menu_get_prompt(child));
323
                        if (child->sym->name)
324
                                printf(" (%s)", child->sym->name);
325
                        if (!sym_has_value(child->sym))
326
                                printf(" (NEW)");
327
                        printf("\n");
328
                }
329
                printf("%*schoice", indent - 1, "");
330
                if (cnt == 1) {
331
                        printf("[1]: 1\n");
332
                        goto conf_childs;
333
                }
334
                printf("[1-%d", cnt);
335
                if (sym->help)
336
                        printf("?");
337
                printf("]: ");
338
                switch (input_mode) {
339
                case ask_new:
340
                case ask_silent:
341
                        if (!is_new) {
342
                                cnt = def;
343
                                printf("%d\n", cnt);
344
                                break;
345
                        }
346
                        check_stdin();
347
                case ask_all:
348
                        fflush(stdout);
349
                        fgets(line, 128, stdin);
350
                        strip(line);
351
                        if (line[0] == '?') {
352
                                printf("\n%s\n", menu->sym->help ?
353
                                        menu->sym->help : nohelp_text);
354
                                continue;
355
                        }
356
                        if (!line[0])
357
                                cnt = def;
358
                        else if (isdigit(line[0]))
359
                                cnt = atoi(line);
360
                        else
361
                                continue;
362
                        break;
363
                case set_random:
364
                        def = (random() % cnt) + 1;
365
                case set_default:
366
                case set_yes:
367
                case set_mod:
368
                case set_no:
369
                        cnt = def;
370
                        printf("%d\n", cnt);
371
                        break;
372
                }
373
 
374
        conf_childs:
375
                for (child = menu->list; child; child = child->next) {
376
                        if (!child->sym || !menu_is_visible(child))
377
                                continue;
378
                        if (!--cnt)
379
                                break;
380
                }
381
                if (!child)
382
                        continue;
383
                if (line[strlen(line) - 1] == '?') {
384
                        printf("\n%s\n", child->sym->help ?
385
                                child->sym->help : nohelp_text);
386
                        continue;
387
                }
388
                sym_set_choice_value(sym, child->sym);
389
                if (child->list) {
390
                        indent += 2;
391
                        conf(child->list);
392
                        indent -= 2;
393
                }
394
                return 1;
395
        }
396
}
397
 
398
static void conf(struct menu *menu)
399
{
400
        struct symbol *sym;
401
        struct property *prop;
402
        struct menu *child;
403
 
404
        if (!menu_is_visible(menu))
405
                return;
406
 
407
        sym = menu->sym;
408
        prop = menu->prompt;
409
        if (prop) {
410
                const char *prompt;
411
 
412
                switch (prop->type) {
413
                case P_MENU:
414
                        if (input_mode == ask_silent && rootEntry != menu) {
415
                                check_conf(menu);
416
                                return;
417
                        }
418
                case P_COMMENT:
419
                        prompt = menu_get_prompt(menu);
420
                        if (prompt)
421
                                printf("%*c\n%*c %s\n%*c\n",
422
                                        indent, '*',
423
                                        indent, '*', prompt,
424
                                        indent, '*');
425
                default:
426
                        ;
427
                }
428
        }
429
 
430
        if (!sym)
431
                goto conf_childs;
432
 
433
        if (sym_is_choice(sym)) {
434
                conf_choice(menu);
435
                if (sym->curr.tri != mod)
436
                        return;
437
                goto conf_childs;
438
        }
439
 
440
        switch (sym->type) {
441
        case S_INT:
442
        case S_HEX:
443
        case S_STRING:
444
                conf_string(menu);
445
                break;
446
        default:
447
                conf_sym(menu);
448
                break;
449
        }
450
 
451
conf_childs:
452
        if (sym)
453
                indent += 2;
454
        for (child = menu->list; child; child = child->next)
455
                conf(child);
456
        if (sym)
457
                indent -= 2;
458
}
459
 
460
static void check_conf(struct menu *menu)
461
{
462
        struct symbol *sym;
463
        struct menu *child;
464
 
465
        if (!menu_is_visible(menu))
466
                return;
467
 
468
        sym = menu->sym;
469
        if (sym) {
470
                if (sym_is_changable(sym) && !sym_has_value(sym)) {
471
                        if (!conf_cnt++)
472
                                printf("*\n* Restart config...\n*\n");
473
                        rootEntry = menu_get_parent_menu(menu);
474
                        conf(rootEntry);
475
                }
476
                if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
477
                        return;
478
        }
479
 
480
        for (child = menu->list; child; child = child->next)
481
                check_conf(child);
482
}
483
 
484
int main(int ac, char **av)
485
{
486
        const char *name;
487
        struct stat tmpstat;
488
 
489
        if (ac > 1 && av[1][0] == '-') {
490
                switch (av[1][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 'n':
502
                        input_mode = set_no;
503
                        break;
504
                case 'm':
505
                        input_mode = set_mod;
506
                        break;
507
                case 'y':
508
                        input_mode = set_yes;
509
                        break;
510
                case 'r':
511
                        input_mode = set_random;
512
                        srandom(time(NULL));
513
                        break;
514
                case 'h':
515
                case '?':
516
                        printf("%s [-o|-s] config\n", av[0]);
517
                        exit(0);
518
                }
519
                name = av[2];
520
        } else
521
                name = av[1];
522
        conf_parse(name);
523
        //zconfdump(stdout);
524
        switch (input_mode) {
525
        case set_default:
526
                name = conf_get_default_confname();
527
                if (conf_read(name)) {
528
                        printf("***\n"
529
                                "*** Can't find default configuration \"%s\"!\n"
530
                                "***\n", name);
531
                        exit(1);
532
                }
533
                break;
534
        case ask_silent:
535
                if (stat(".config", &tmpstat)) {
536
                        printf("***\n"
537
                                "*** You have not yet configured uClibc!\n"
538
                                "***\n"
539
                                "*** Please run some configurator (e.g. \"make config\" or\n"
540
                                "*** \"make oldconfig\" or \"make menuconfig\").\n"
541
                                "***\n");
542
                        exit(1);
543
                }
544
        case ask_all:
545
        case ask_new:
546
                conf_read(NULL);
547
                break;
548
        default:
549
                break;
550
        }
551
 
552
        if (input_mode != ask_silent) {
553
                rootEntry = &rootmenu;
554
                conf(&rootmenu);
555
                if (input_mode == ask_all) {
556
                        input_mode = ask_silent;
557
                        valid_stdin = 1;
558
                }
559
        }
560
        do {
561
                conf_cnt = 0;
562
                check_conf(&rootmenu);
563
        } while (conf_cnt);
564
        conf_write(NULL);
565
        return 0;
566
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.