home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / scripts / kconfig / conf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-21  |  11.6 KB  |  627 lines

  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. }
  627.