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 / confdata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-21  |  11.4 KB  |  531 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 <sys/stat.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.  
  14. #define LKC_DIRECT_LINK
  15. #include "lkc.h"
  16.  
  17. static void conf_warning(const char *fmt, ...)
  18.     __attribute__ ((format (printf, 1, 2)));
  19.  
  20. static const char *conf_filename;
  21. static int conf_lineno, conf_warnings, conf_unsaved;
  22.  
  23. const char conf_def_filename[] = ".config";
  24.  
  25. const char conf_defname[] = "arch/$ARCH/defconfig";
  26.  
  27. const char *conf_confnames[] = {
  28.     ".config",
  29.     "/lib/modules/$UNAME_RELEASE/.config",
  30.     "/etc/kernel-config",
  31.     "/boot/config-$UNAME_RELEASE",
  32.     conf_defname,
  33.     NULL,
  34. };
  35.  
  36. static void conf_warning(const char *fmt, ...)
  37. {
  38.     va_list ap;
  39.     va_start(ap, fmt);
  40.     fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
  41.     vfprintf(stderr, fmt, ap);
  42.     fprintf(stderr, "\n");
  43.     va_end(ap);
  44.     conf_warnings++;
  45. }
  46.  
  47. static char *conf_expand_value(const char *in)
  48. {
  49.     struct symbol *sym;
  50.     const char *src;
  51.     static char res_value[SYMBOL_MAXLENGTH];
  52.     char *dst, name[SYMBOL_MAXLENGTH];
  53.  
  54.     res_value[0] = 0;
  55.     dst = name;
  56.     while ((src = strchr(in, '$'))) {
  57.         strncat(res_value, in, src - in);
  58.         src++;
  59.         dst = name;
  60.         while (isalnum(*src) || *src == '_')
  61.             *dst++ = *src++;
  62.         *dst = 0;
  63.         sym = sym_lookup(name, 0);
  64.         sym_calc_value(sym);
  65.         strcat(res_value, sym_get_string_value(sym));
  66.         in = src;
  67.     }
  68.     strcat(res_value, in);
  69.  
  70.     return res_value;
  71. }
  72.  
  73. char *conf_get_default_confname(void)
  74. {
  75.     struct stat buf;
  76.     static char fullname[PATH_MAX+1];
  77.     char *env, *name;
  78.  
  79.     name = conf_expand_value(conf_defname);
  80.     env = getenv(SRCTREE);
  81.     if (env) {
  82.         sprintf(fullname, "%s/%s", env, name);
  83.         if (!stat(fullname, &buf))
  84.             return fullname;
  85.     }
  86.     return name;
  87. }
  88.  
  89. int conf_read_simple(const char *name)
  90. {
  91.     FILE *in = NULL;
  92.     char line[1024];
  93.     char *p, *p2;
  94.     struct symbol *sym;
  95.     int i;
  96.  
  97.     if (name) {
  98.         in = zconf_fopen(name);
  99.     } else {
  100.         const char **names = conf_confnames;
  101.         while ((name = *names++)) {
  102.             name = conf_expand_value(name);
  103.             in = zconf_fopen(name);
  104.             if (in) {
  105.                 printf(_("#\n"
  106.                          "# using defaults found in %s\n"
  107.                          "#\n"), name);
  108.                 break;
  109.             }
  110.         }
  111.     }
  112.     if (!in)
  113.         return 1;
  114.  
  115.     conf_filename = name;
  116.     conf_lineno = 0;
  117.     conf_warnings = 0;
  118.     conf_unsaved = 0;
  119.  
  120.     for_all_symbols(i, sym) {
  121.         sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
  122.         if (sym_is_choice(sym))
  123.             sym->flags &= ~SYMBOL_NEW;
  124.         sym->flags &= ~SYMBOL_VALID;
  125.         switch (sym->type) {
  126.         case S_INT:
  127.         case S_HEX:
  128.         case S_STRING:
  129.             if (sym->user.val)
  130.                 free(sym->user.val);
  131.         default:
  132.             sym->user.val = NULL;
  133.             sym->user.tri = no;
  134.         }
  135.     }
  136.  
  137.     while (fgets(line, sizeof(line), in)) {
  138.         conf_lineno++;
  139.         sym = NULL;
  140.         switch (line[0]) {
  141.         case '#':
  142.             if (memcmp(line + 2, "CONFIG_", 7))
  143.                 continue;
  144.             p = strchr(line + 9, ' ');
  145.             if (!p)
  146.                 continue;
  147.             *p++ = 0;
  148.             if (strncmp(p, "is not set", 10))
  149.                 continue;
  150.             sym = sym_find(line + 9);
  151.             if (!sym) {
  152.                 conf_warning("trying to assign nonexistent symbol %s", line + 9);
  153.                 break;
  154.             } else if (!(sym->flags & SYMBOL_NEW)) {
  155.                 conf_warning("trying to reassign symbol %s", sym->name);
  156.                 break;
  157.             }
  158.             switch (sym->type) {
  159.             case S_BOOLEAN:
  160.             case S_TRISTATE:
  161.                 sym->user.tri = no;
  162.                 sym->flags &= ~SYMBOL_NEW;
  163.                 break;
  164.             default:
  165.                 ;
  166.             }
  167.             break;
  168.         case 'C':
  169.             if (memcmp(line, "CONFIG_", 7)) {
  170.                 conf_warning("unexpected data");
  171.                 continue;
  172.             }
  173.             p = strchr(line + 7, '=');
  174.             if (!p)
  175.                 continue;
  176.             *p++ = 0;
  177.             p2 = strchr(p, '\n');
  178.             if (p2)
  179.                 *p2 = 0;
  180.             sym = sym_find(line + 7);
  181.             if (!sym) {
  182.                 conf_warning("trying to assign nonexistent symbol %s", line + 7);
  183.                 break;
  184.             } else if (!(sym->flags & SYMBOL_NEW)) {
  185.                 conf_warning("trying to reassign symbol %s", sym->name);
  186.                 break;
  187.             }
  188.             switch (sym->type) {
  189.             case S_TRISTATE:
  190.                 if (p[0] == 'm') {
  191.                     sym->user.tri = mod;
  192.                     sym->flags &= ~SYMBOL_NEW;
  193.                     break;
  194.                 }
  195.             case S_BOOLEAN:
  196.                 if (p[0] == 'y') {
  197.                     sym->user.tri = yes;
  198.                     sym->flags &= ~SYMBOL_NEW;
  199.                     break;
  200.                 }
  201.                 if (p[0] == 'n') {
  202.                     sym->user.tri = no;
  203.                     sym->flags &= ~SYMBOL_NEW;
  204.                     break;
  205.                 }
  206.                 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
  207.                 break;
  208.             case S_STRING:
  209.                 if (*p++ != '"')
  210.                     break;
  211.                 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
  212.                     if (*p2 == '"') {
  213.                         *p2 = 0;
  214.                         break;
  215.                     }
  216.                     memmove(p2, p2 + 1, strlen(p2));
  217.                 }
  218.                 if (!p2) {
  219.                     conf_warning("invalid string found");
  220.                     continue;
  221.                 }
  222.             case S_INT:
  223.             case S_HEX:
  224.                 if (sym_string_valid(sym, p)) {
  225.                     sym->user.val = strdup(p);
  226.                     sym->flags &= ~SYMBOL_NEW;
  227.                 } else {
  228.                     conf_warning("symbol value '%s' invalid for %s", p, sym->name);
  229.                     continue;
  230.                 }
  231.                 break;
  232.             default:
  233.                 ;
  234.             }
  235.             break;
  236.         case '\n':
  237.             break;
  238.         default:
  239.             conf_warning("unexpected data");
  240.             continue;
  241.         }
  242.         if (sym && sym_is_choice_value(sym)) {
  243.             struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
  244.             switch (sym->user.tri) {
  245.             case no:
  246.                 break;
  247.             case mod:
  248.                 if (cs->user.tri == yes) {
  249.                     conf_warning("%s creates inconsistent choice state", sym->name);
  250.                     cs->flags |= SYMBOL_NEW;
  251.                 }
  252.                 break;
  253.             case yes:
  254.                 if (cs->user.tri != no) {
  255.                     conf_warning("%s creates inconsistent choice state", sym->name);
  256.                     cs->flags |= SYMBOL_NEW;
  257.                 } else
  258.                     cs->user.val = sym;
  259.                 break;
  260.             }
  261.             cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
  262.         }
  263.     }
  264.     fclose(in);
  265.  
  266.     if (modules_sym)
  267.         sym_calc_value(modules_sym);
  268.     return 0;
  269. }
  270.  
  271. int conf_read(const char *name)
  272. {
  273.     struct symbol *sym;
  274.     struct property *prop;
  275.     struct expr *e;
  276.     int i;
  277.  
  278.     if (conf_read_simple(name))
  279.         return 1;
  280.  
  281.     for_all_symbols(i, sym) {
  282.         sym_calc_value(sym);
  283.         if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
  284.             goto sym_ok;
  285.         if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
  286.             /* check that calculated value agrees with saved value */
  287.             switch (sym->type) {
  288.             case S_BOOLEAN:
  289.             case S_TRISTATE:
  290.                 if (sym->user.tri != sym_get_tristate_value(sym))
  291.                     break;
  292.                 if (!sym_is_choice(sym))
  293.                     goto sym_ok;
  294.             default:
  295.                 if (!strcmp(sym->curr.val, sym->user.val))
  296.                     goto sym_ok;
  297.                 break;
  298.             }
  299.         } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
  300.             /* no previous value and not saved */
  301.             goto sym_ok;
  302.         conf_unsaved++;
  303.         /* maybe print value in verbose mode... */
  304.     sym_ok:
  305.         if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
  306.             if (sym->visible == no)
  307.                 sym->flags |= SYMBOL_NEW;
  308.             switch (sym->type) {
  309.             case S_STRING:
  310.             case S_INT:
  311.             case S_HEX:
  312.                 if (!sym_string_within_range(sym, sym->user.val)) {
  313.                     sym->flags |= SYMBOL_NEW;
  314.                     sym->flags &= ~SYMBOL_VALID;
  315.                 }
  316.             default:
  317.                 break;
  318.             }
  319.         }
  320.         if (!sym_is_choice(sym))
  321.             continue;
  322.         prop = sym_get_choice_prop(sym);
  323.         for (e = prop->expr; e; e = e->left.expr)
  324.             if (e->right.sym->visible != no)
  325.                 sym->flags |= e->right.sym->flags & SYMBOL_NEW;
  326.     }
  327.  
  328.     sym_change_count = conf_warnings || conf_unsaved;
  329.  
  330.     return 0;
  331. }
  332.  
  333. int conf_write(const char *name)
  334. {
  335.     FILE *out, *out_h;
  336.     struct symbol *sym;
  337.     struct menu *menu;
  338.     const char *basename;
  339.     char dirname[128], tmpname[128], newname[128];
  340.     int type, l;
  341.     const char *str;
  342.     time_t now;
  343.     int use_timestamp = 1;
  344.     char *env;
  345.  
  346.     dirname[0] = 0;
  347.     if (name && name[0]) {
  348.         struct stat st;
  349.         char *slash;
  350.  
  351.         if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
  352.             strcpy(dirname, name);
  353.             strcat(dirname, "/");
  354.             basename = conf_def_filename;
  355.         } else if ((slash = strrchr(name, '/'))) {
  356.             int size = slash - name + 1;
  357.             memcpy(dirname, name, size);
  358.             dirname[size] = 0;
  359.             if (slash[1])
  360.                 basename = slash + 1;
  361.             else
  362.                 basename = conf_def_filename;
  363.         } else
  364.             basename = name;
  365.     } else
  366.         basename = conf_def_filename;
  367.  
  368.     sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
  369.     out = fopen(newname, "w");
  370.     if (!out)
  371.         return 1;
  372.     out_h = NULL;
  373.     if (!name) {
  374.         out_h = fopen(".tmpconfig.h", "w");
  375.         if (!out_h)
  376.             return 1;
  377.         file_write_dep(NULL);
  378.     }
  379.     sym = sym_lookup("KERNELVERSION", 0);
  380.     sym_calc_value(sym);
  381.     time(&now);
  382.     env = getenv("KCONFIG_NOTIMESTAMP");
  383.     if (env && *env)
  384.         use_timestamp = 0;
  385.  
  386.     fprintf(out, _("#\n"
  387.                "# Automatically generated make config: don't edit\n"
  388.                "# Linux kernel version: %s\n"
  389.                "%s%s"
  390.                "#\n"),
  391.              sym_get_string_value(sym),
  392.              use_timestamp ? "# " : "",
  393.              use_timestamp ? ctime(&now) : "");
  394.     if (out_h)
  395.         fprintf(out_h, "/*\n"
  396.                    " * Automatically generated C config: don't edit\n"
  397.                    " * Linux kernel version: %s\n"
  398.                    "%s%s"
  399.                    " */\n"
  400.                    "#define AUTOCONF_INCLUDED\n",
  401.                    sym_get_string_value(sym),
  402.                    use_timestamp ? " * " : "",
  403.                    use_timestamp ? ctime(&now) : "");
  404.  
  405.     if (!sym_change_count)
  406.         sym_clear_all_valid();
  407.  
  408.     menu = rootmenu.list;
  409.     while (menu) {
  410.         sym = menu->sym;
  411.         if (!sym) {
  412.             if (!menu_is_visible(menu))
  413.                 goto next;
  414.             str = menu_get_prompt(menu);
  415.             fprintf(out, "\n"
  416.                      "#\n"
  417.                      "# %s\n"
  418.                      "#\n", str);
  419.             if (out_h)
  420.                 fprintf(out_h, "\n"
  421.                            "/*\n"
  422.                            " * %s\n"
  423.                            " */\n", str);
  424.         } else if (!(sym->flags & SYMBOL_CHOICE)) {
  425.             sym_calc_value(sym);
  426.             if (!(sym->flags & SYMBOL_WRITE))
  427.                 goto next;
  428.             sym->flags &= ~SYMBOL_WRITE;
  429.             type = sym->type;
  430.             if (type == S_TRISTATE) {
  431.                 sym_calc_value(modules_sym);
  432.                 if (modules_sym->curr.tri == no)
  433.                     type = S_BOOLEAN;
  434.             }
  435.             switch (type) {
  436.             case S_BOOLEAN:
  437.             case S_TRISTATE:
  438.                 switch (sym_get_tristate_value(sym)) {
  439.                 case no:
  440.                     fprintf(out, "# CONFIG_%s is not set\n", sym->name);
  441.                     if (out_h)
  442.                         fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
  443.                     break;
  444.                 case mod:
  445.                     fprintf(out, "CONFIG_%s=m\n", sym->name);
  446.                     if (out_h)
  447.                         fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
  448.                     break;
  449.                 case yes:
  450.                     fprintf(out, "CONFIG_%s=y\n", sym->name);
  451.                     if (out_h)
  452.                         fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
  453.                     break;
  454.                 }
  455.                 break;
  456.             case S_STRING:
  457.                 // fix me
  458.                 str = sym_get_string_value(sym);
  459.                 fprintf(out, "CONFIG_%s=\"", sym->name);
  460.                 if (out_h)
  461.                     fprintf(out_h, "#define CONFIG_%s \"", sym->name);
  462.                 do {
  463.                     l = strcspn(str, "\"\\");
  464.                     if (l) {
  465.                         fwrite(str, l, 1, out);
  466.                         if (out_h)
  467.                             fwrite(str, l, 1, out_h);
  468.                     }
  469.                     str += l;
  470.                     while (*str == '\\' || *str == '"') {
  471.                         fprintf(out, "\\%c", *str);
  472.                         if (out_h)
  473.                             fprintf(out_h, "\\%c", *str);
  474.                         str++;
  475.                     }
  476.                 } while (*str);
  477.                 fputs("\"\n", out);
  478.                 if (out_h)
  479.                     fputs("\"\n", out_h);
  480.                 break;
  481.             case S_HEX:
  482.                 str = sym_get_string_value(sym);
  483.                 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
  484.                     fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
  485.                     if (out_h)
  486.                         fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
  487.                     break;
  488.                 }
  489.             case S_INT:
  490.                 str = sym_get_string_value(sym);
  491.                 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
  492.                 if (out_h)
  493.                     fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
  494.                 break;
  495.             }
  496.         }
  497.  
  498.     next:
  499.         if (menu->list) {
  500.             menu = menu->list;
  501.             continue;
  502.         }
  503.         if (menu->next)
  504.             menu = menu->next;
  505.         else while ((menu = menu->parent)) {
  506.             if (menu->next) {
  507.                 menu = menu->next;
  508.                 break;
  509.             }
  510.         }
  511.     }
  512.     fclose(out);
  513.     if (out_h) {
  514.         fclose(out_h);
  515.         rename(".tmpconfig.h", "include/linux/autoconf.h");
  516.     }
  517.     if (!name || basename != conf_def_filename) {
  518.         if (!name)
  519.             name = conf_def_filename;
  520.         sprintf(tmpname, "%s.old", name);
  521.         rename(name, tmpname);
  522.     }
  523.     sprintf(tmpname, "%s%s", dirname, basename);
  524.     if (rename(newname, tmpname))
  525.         return 1;
  526.  
  527.     sym_change_count = 0;
  528.  
  529.     return 0;
  530. }
  531.