kconfig: environment symbol support
authorRoman Zippel <zippel@linux-m68k.org>
Mon, 14 Jan 2008 03:50:54 +0000 (04:50 +0100)
committerSam Ravnborg <sam@ravnborg.org>
Mon, 28 Jan 2008 22:14:39 +0000 (23:14 +0100)
Add the possibility to import a value from the environment into kconfig
via the option syntax. Beside flexibility this has the advantage
providing proper dependencies.
Documented the options syntax.

Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Documentation/kbuild/kconfig-language.txt
scripts/kconfig/expr.h
scripts/kconfig/lkc.h
scripts/kconfig/menu.c
scripts/kconfig/qconf.cc
scripts/kconfig/symbol.c
scripts/kconfig/util.c
scripts/kconfig/zconf.gperf
scripts/kconfig/zconf.hash.c_shipped

index 53ca12f7999fdaf2137336584adead3c5adeb6e9..a43fcc68e171ab96491599959314c7039a7b2525 100644 (file)
@@ -127,6 +127,27 @@ applicable everywhere (see syntax).
   used to help visually separate configuration logic from help within
   the file as an aid to developers.
 
+- misc options: "option" <symbol>[=<value>]
+  Various less common options can be defined via this option syntax,
+  which can modify the behaviour of the menu entry and its config
+  symbol. These options are currently possible:
+
+  - "defconfig_list"
+    This declares a list of default entries which can be used when
+    looking for the default configuration (which is used when the main
+    .config doesn't exists yet.)
+
+  - "modules"
+    This declares the symbol to be used as the MODULES symbol, which
+    enables the third modular state for all config symbols.
+
+  - "env"=<value>
+    This imports the environment variable into Kconfig. It behaves like
+    a default, except that the value comes from the environment, this
+    also means that the behaviour when mixing it with normal defaults is
+    undefined at this point. The symbol is currently not exported back
+    to the build environment (if this is desired, it can be done via
+    another symbol).
 
 Menu dependencies
 -----------------
index b6f922c77e0ba11b5b0454954d45f526eab30535..9d4cba1c001d9ec5f48a365a2d864e1b2f3f467a 100644 (file)
@@ -106,7 +106,8 @@ struct symbol {
 #define SYMBOL_HASHMASK                0xff
 
 enum prop_type {
-       P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+       P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE,
+       P_SELECT, P_RANGE, P_ENV
 };
 
 struct property {
index 8a07ee4f6bd486a8cb18fec1297ef1f21dc08e82..4bc68f20a73c4ab8ac9364133ee57e5cd5655375 100644 (file)
@@ -44,6 +44,7 @@ extern "C" {
 
 #define T_OPT_MODULES          1
 #define T_OPT_DEFCONFIG_LIST   2
+#define T_OPT_ENV              3
 
 struct kconf_id {
        int name;
@@ -74,6 +75,7 @@ void kconfig_load(void);
 
 /* menu.c */
 void menu_init(void);
+void menu_warn(struct menu *menu, const char *fmt, ...);
 struct menu *menu_add_menu(void);
 void menu_end_menu(void);
 void menu_add_entry(struct symbol *sym);
@@ -103,6 +105,8 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
 const char *str_get(struct gstr *gs);
 
 /* symbol.c */
+extern struct expr *sym_env_list;
+
 void sym_init(void);
 void sym_clear_all_valid(void);
 void sym_set_all_changed(void);
@@ -110,6 +114,7 @@ void sym_set_changed(struct symbol *sym);
 struct symbol *sym_check_deps(struct symbol *sym);
 struct property *prop_alloc(enum prop_type type, struct symbol *sym);
 struct symbol *prop_get_symbol(struct property *prop);
+struct property *sym_get_env_prop(struct symbol *sym);
 
 static inline tristate sym_get_tristate_value(struct symbol *sym)
 {
index 3637d1057e13d2f99e8ecd5a4add72dc212345b2..e6ef171e5b142e19c10af5c2b4a17260c78ace26 100644 (file)
@@ -15,7 +15,7 @@ static struct menu **last_entry_ptr;
 struct file *file_list;
 struct file *current_file;
 
-static void menu_warn(struct menu *menu, const char *fmt, ...)
+void menu_warn(struct menu *menu, const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
@@ -172,6 +172,9 @@ void menu_add_option(int token, char *arg)
                else if (sym_defconfig_list != current_entry->sym)
                        zconf_error("trying to redefine defconfig symbol");
                break;
+       case T_OPT_ENV:
+               prop_add_env(arg);
+               break;
        }
 }
 
index 9fe27ca8a1923cdc02bf5a852db7e22d9e27a2c7..5d0fd38b089b937614dee19073ec9a2657b26d22 100644 (file)
@@ -1088,7 +1088,11 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
                        debug += "</a><br>";
                        break;
                case P_DEFAULT:
-                       debug += "default: ";
+               case P_SELECT:
+               case P_RANGE:
+               case P_ENV:
+                       debug += prop_get_type_name(prop->type);
+                       debug += ": ";
                        expr_print(prop->expr, expr_print_help, &debug, E_NONE);
                        debug += "<br>";
                        break;
@@ -1099,16 +1103,6 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
                                debug += "<br>";
                        }
                        break;
-               case P_SELECT:
-                       debug += "select: ";
-                       expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-                       debug += "<br>";
-                       break;
-               case P_RANGE:
-                       debug += "range: ";
-                       expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-                       debug += "<br>";
-                       break;
                default:
                        debug += "unknown property: ";
                        debug += prop_get_type_name(prop->type);
index a7dfc82fc858c2dee7985a2fd2f762e7dbd5714a..99e3d02d1cfc26b2b0d8489377860d62b4fe7807 100644 (file)
@@ -34,6 +34,8 @@ struct symbol *sym_defconfig_list;
 struct symbol *modules_sym;
 tristate modules_val;
 
+struct expr *sym_env_list;
+
 void sym_add_default(struct symbol *sym, const char *def)
 {
        struct property *prop = prop_alloc(P_DEFAULT, sym);
@@ -117,6 +119,15 @@ struct property *sym_get_choice_prop(struct symbol *sym)
        return NULL;
 }
 
+struct property *sym_get_env_prop(struct symbol *sym)
+{
+       struct property *prop;
+
+       for_all_properties(sym, prop, P_ENV)
+               return prop;
+       return NULL;
+}
+
 struct property *sym_get_default_prop(struct symbol *sym)
 {
        struct property *prop;
@@ -346,6 +357,9 @@ void sym_calc_value(struct symbol *sym)
                ;
        }
 
+       if (sym->flags & SYMBOL_AUTO)
+               sym->flags &= ~SYMBOL_WRITE;
+
        sym->curr = newval;
        if (sym_is_choice(sym) && newval.tri == yes)
                sym->curr.val = sym_calc_choice(sym);
@@ -860,6 +874,8 @@ const char *prop_get_type_name(enum prop_type type)
        switch (type) {
        case P_PROMPT:
                return "prompt";
+       case P_ENV:
+               return "env";
        case P_COMMENT:
                return "comment";
        case P_MENU:
@@ -877,3 +893,32 @@ const char *prop_get_type_name(enum prop_type type)
        }
        return "unknown";
 }
+
+void prop_add_env(const char *env)
+{
+       struct symbol *sym, *sym2;
+       struct property *prop;
+       char *p;
+
+       sym = current_entry->sym;
+       sym->flags |= SYMBOL_AUTO;
+       for_all_properties(sym, prop, P_ENV) {
+               sym2 = prop_get_symbol(prop);
+               if (strcmp(sym2->name, env))
+                       menu_warn(current_entry, "redefining environment symbol from %s",
+                                 sym2->name);
+               return;
+       }
+
+       prop = prop_alloc(P_ENV, sym);
+       prop->expr = expr_alloc_symbol(sym_lookup(env, 1));
+
+       sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
+       sym_env_list->right.sym = sym;
+
+       p = getenv(env);
+       if (p)
+               sym_add_default(sym, p);
+       else
+               menu_warn(current_entry, "environment variable %s undefined", env);
+}
index e1cad924c0a41ab6fa1e8f917c0c01198419b549..f8e73c039dc880984f96aa8cadd4e43edaa6baba 100644 (file)
@@ -29,6 +29,8 @@ struct file *file_lookup(const char *name)
 /* write a dependency file as used by kbuild to track dependencies */
 int file_write_dep(const char *name)
 {
+       struct symbol *sym, *env_sym;
+       struct expr *e;
        struct file *file;
        FILE *out;
 
@@ -45,8 +47,25 @@ int file_write_dep(const char *name)
                        fprintf(out, "\t%s\n", file->name);
        }
        fprintf(out, "\ninclude/config/auto.conf: \\\n"
-                    "\t$(deps_config)\n\n"
-                    "$(deps_config): ;\n");
+                    "\t$(deps_config)\n\n");
+
+       expr_list_for_each_sym(sym_env_list, e, sym) {
+               struct property *prop;
+               const char *value;
+
+               prop = sym_get_env_prop(sym);
+               env_sym = prop_get_symbol(prop);
+               if (!env_sym)
+                       continue;
+               value = getenv(env_sym->name);
+               if (!value)
+                       value = "";
+               fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
+               fprintf(out, "include/config/auto.conf: FORCE\n");
+               fprintf(out, "endif\n");
+       }
+
+       fprintf(out, "\n$(deps_config): ;\n");
        fclose(out);
        rename("..config.tmp", name);
        return 0;
index 93538e567bda8e31943b857a3b50e567fa5c691a..4051639c090077534d0fd4159f098124d65af140 100644 (file)
@@ -41,4 +41,5 @@ option,               T_OPTION,       TF_COMMAND
 on,            T_ON,           TF_PARAM
 modules,       T_OPT_MODULES,  TF_OPTION
 defconfig_list,        T_OPT_DEFCONFIG_LIST,TF_OPTION
+env,           T_OPT_ENV,      TF_OPTION
 %%
index ab28b18153a7a6bb4fcb7d7b0c24b919610c94d3..c9d26bc1a214a81cd6793a8a475f6a205067ea9b 100644 (file)
@@ -53,10 +53,10 @@ kconf_id_hash (register const char *str, register unsigned int len)
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 18, 11,  5,
+      49, 49, 49, 49, 49, 49, 49, 35, 35,  5,
        0,  0,  5, 49,  5, 20, 49, 49,  5, 20,
-       5,  0, 30, 49,  0, 15,  0, 10, 49, 49,
-      25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+       5,  0, 30, 49,  0, 15,  0, 10,  0, 49,
+      10, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
@@ -89,6 +89,7 @@ kconf_id_hash (register const char *str, register unsigned int len)
 struct kconf_id_strings_t
   {
     char kconf_id_strings_str2[sizeof("on")];
+    char kconf_id_strings_str3[sizeof("env")];
     char kconf_id_strings_str5[sizeof("endif")];
     char kconf_id_strings_str6[sizeof("option")];
     char kconf_id_strings_str7[sizeof("endmenu")];
@@ -99,30 +100,31 @@ struct kconf_id_strings_t
     char kconf_id_strings_str12[sizeof("default")];
     char kconf_id_strings_str13[sizeof("def_bool")];
     char kconf_id_strings_str14[sizeof("help")];
-    char kconf_id_strings_str15[sizeof("bool")];
     char kconf_id_strings_str16[sizeof("config")];
     char kconf_id_strings_str17[sizeof("def_tristate")];
-    char kconf_id_strings_str18[sizeof("boolean")];
+    char kconf_id_strings_str18[sizeof("hex")];
     char kconf_id_strings_str19[sizeof("defconfig_list")];
     char kconf_id_strings_str21[sizeof("string")];
     char kconf_id_strings_str22[sizeof("if")];
     char kconf_id_strings_str23[sizeof("int")];
-    char kconf_id_strings_str24[sizeof("enable")];
     char kconf_id_strings_str26[sizeof("select")];
     char kconf_id_strings_str27[sizeof("modules")];
     char kconf_id_strings_str28[sizeof("tristate")];
     char kconf_id_strings_str29[sizeof("menu")];
     char kconf_id_strings_str31[sizeof("source")];
     char kconf_id_strings_str32[sizeof("comment")];
-    char kconf_id_strings_str33[sizeof("hex")];
     char kconf_id_strings_str35[sizeof("menuconfig")];
     char kconf_id_strings_str36[sizeof("prompt")];
     char kconf_id_strings_str37[sizeof("depends")];
+    char kconf_id_strings_str39[sizeof("bool")];
+    char kconf_id_strings_str41[sizeof("enable")];
+    char kconf_id_strings_str42[sizeof("boolean")];
     char kconf_id_strings_str48[sizeof("mainmenu")];
   };
 static struct kconf_id_strings_t kconf_id_strings_contents =
   {
     "on",
+    "env",
     "endif",
     "option",
     "endmenu",
@@ -133,25 +135,25 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
     "default",
     "def_bool",
     "help",
-    "bool",
     "config",
     "def_tristate",
-    "boolean",
+    "hex",
     "defconfig_list",
     "string",
     "if",
     "int",
-    "enable",
     "select",
     "modules",
     "tristate",
     "menu",
     "source",
     "comment",
-    "hex",
     "menuconfig",
     "prompt",
     "depends",
+    "bool",
+    "enable",
+    "boolean",
     "mainmenu"
   };
 #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
@@ -163,7 +165,7 @@ kconf_id_lookup (register const char *str, register unsigned int len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 31,
+      TOTAL_KEYWORDS = 32,
       MIN_WORD_LENGTH = 2,
       MAX_WORD_LENGTH = 14,
       MIN_HASH_VALUE = 2,
@@ -174,7 +176,8 @@ kconf_id_lookup (register const char *str, register unsigned int len)
     {
       {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,            T_ON,           TF_PARAM},
-      {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3,            T_OPT_ENV,      TF_OPTION},
+      {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5,            T_ENDIF,        TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6,            T_OPTION,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7,    T_ENDMENU,      TF_COMMAND},
@@ -185,17 +188,16 @@ kconf_id_lookup (register const char *str, register unsigned int len)
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12,   T_DEFAULT,      TF_COMMAND, S_UNKNOWN},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13,   T_DEFAULT,      TF_COMMAND, S_BOOLEAN},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14,           T_HELP,         TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15,           T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16,           T_CONFIG,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17,   T_DEFAULT,      TF_COMMAND, S_TRISTATE},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,   T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,           T_TYPE,         TF_COMMAND, S_HEX},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19,   T_OPT_DEFCONFIG_LIST,TF_OPTION},
       {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,           T_TYPE,         TF_COMMAND, S_STRING},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,           T_IF,           TF_COMMAND|TF_PARAM},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,           T_TYPE,         TF_COMMAND, S_INT},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24,           T_SELECT,       TF_COMMAND},
-      {-1},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,           T_SELECT,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,   T_OPT_MODULES,  TF_OPTION},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,   T_TYPE,         TF_COMMAND, S_TRISTATE},
@@ -203,13 +205,16 @@ kconf_id_lookup (register const char *str, register unsigned int len)
       {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,           T_SOURCE,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32,   T_COMMENT,      TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,           T_TYPE,         TF_COMMAND, S_HEX},
-      {-1},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,   T_MENUCONFIG,   TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,           T_PROMPT,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,   T_DEPENDS,      TF_COMMAND},
-      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
       {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39,           T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,           T_SELECT,       TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,   T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {-1}, {-1}, {-1}, {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48,   T_MAINMENU,     TF_COMMAND}
     };