Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


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