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