diff options
-rw-r--r-- | Documentation/kbuild/kconfig-language.txt | 8 | ||||
-rw-r--r-- | Kconfig | 8 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | arch/sh/Kconfig | 4 | ||||
-rw-r--r-- | arch/sparc/Kconfig | 4 | ||||
-rw-r--r-- | arch/um/Kconfig.common | 4 | ||||
-rw-r--r-- | arch/x86/Kconfig | 4 | ||||
-rw-r--r-- | arch/x86/um/Kconfig | 6 | ||||
-rw-r--r-- | init/Kconfig | 16 | ||||
-rw-r--r-- | scripts/kconfig/confdata.c | 33 | ||||
-rw-r--r-- | scripts/kconfig/kconf_id.c | 1 | ||||
-rw-r--r-- | scripts/kconfig/lkc.h | 5 | ||||
-rw-r--r-- | scripts/kconfig/lkc_proto.h | 6 | ||||
-rw-r--r-- | scripts/kconfig/menu.c | 3 | ||||
-rw-r--r-- | scripts/kconfig/preprocess.c | 238 | ||||
-rw-r--r-- | scripts/kconfig/symbol.c | 56 | ||||
-rw-r--r-- | scripts/kconfig/util.c | 29 | ||||
-rw-r--r-- | scripts/kconfig/zconf.l | 67 | ||||
-rw-r--r-- | scripts/kconfig/zconf.y | 2 |
19 files changed, 343 insertions, 154 deletions
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index f5b9493f04ad..0e966e8f9ec7 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt | |||
@@ -198,14 +198,6 @@ applicable everywhere (see syntax). | |||
198 | enables the third modular state for all config symbols. | 198 | enables the third modular state for all config symbols. |
199 | At most one symbol may have the "modules" option set. | 199 | At most one symbol may have the "modules" option set. |
200 | 200 | ||
201 | - "env"=<value> | ||
202 | This imports the environment variable into Kconfig. It behaves like | ||
203 | a default, except that the value comes from the environment, this | ||
204 | also means that the behaviour when mixing it with normal defaults is | ||
205 | undefined at this point. The symbol is currently not exported back | ||
206 | to the build environment (if this is desired, it can be done via | ||
207 | another symbol). | ||
208 | |||
209 | - "allnoconfig_y" | 201 | - "allnoconfig_y" |
210 | This declares the symbol as one that should have the value y when | 202 | This declares the symbol as one that should have the value y when |
211 | using "allnoconfig". Used for symbols that hide other symbols. | 203 | using "allnoconfig". Used for symbols that hide other symbols. |
@@ -3,10 +3,6 @@ | |||
3 | # For a description of the syntax of this configuration file, | 3 | # For a description of the syntax of this configuration file, |
4 | # see Documentation/kbuild/kconfig-language.txt. | 4 | # see Documentation/kbuild/kconfig-language.txt. |
5 | # | 5 | # |
6 | mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration" | 6 | mainmenu "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration" |
7 | 7 | ||
8 | config SRCARCH | 8 | source "arch/$(SRCARCH)/Kconfig" |
9 | string | ||
10 | option env="SRCARCH" | ||
11 | |||
12 | source "arch/$SRCARCH/Kconfig" | ||
@@ -284,7 +284,8 @@ include scripts/Kbuild.include | |||
284 | # Read KERNELRELEASE from include/config/kernel.release (if it exists) | 284 | # Read KERNELRELEASE from include/config/kernel.release (if it exists) |
285 | KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) | 285 | KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) |
286 | KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) | 286 | KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) |
287 | export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION | 287 | UNAME_RELEASE := $(shell uname --release) |
288 | export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION UNAME_RELEASE | ||
288 | 289 | ||
289 | # SUBARCH tells the usermode build what the underlying arch is. That is set | 290 | # SUBARCH tells the usermode build what the underlying arch is. That is set |
290 | # first, and if a usermode build is happening, the "ARCH=um" on the command | 291 | # first, and if a usermode build is happening, the "ARCH=um" on the command |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 1851eaeee131..c8400e34e255 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -58,7 +58,7 @@ config SUPERH | |||
58 | <http://www.linux-sh.org/>. | 58 | <http://www.linux-sh.org/>. |
59 | 59 | ||
60 | config SUPERH32 | 60 | config SUPERH32 |
61 | def_bool ARCH = "sh" | 61 | def_bool "$(ARCH)" = "sh" |
62 | select HAVE_KPROBES | 62 | select HAVE_KPROBES |
63 | select HAVE_KRETPROBES | 63 | select HAVE_KRETPROBES |
64 | select HAVE_IOREMAP_PROT if MMU && !X2TLB | 64 | select HAVE_IOREMAP_PROT if MMU && !X2TLB |
@@ -77,7 +77,7 @@ config SUPERH32 | |||
77 | select HAVE_CC_STACKPROTECTOR | 77 | select HAVE_CC_STACKPROTECTOR |
78 | 78 | ||
79 | config SUPERH64 | 79 | config SUPERH64 |
80 | def_bool ARCH = "sh64" | 80 | def_bool "$(ARCH)" = "sh64" |
81 | select HAVE_EXIT_THREAD | 81 | select HAVE_EXIT_THREAD |
82 | select KALLSYMS | 82 | select KALLSYMS |
83 | 83 | ||
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 8767e45f1b2b..df7410cb1608 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config 64BIT | 1 | config 64BIT |
2 | bool "64-bit kernel" if ARCH = "sparc" | 2 | bool "64-bit kernel" if "$(ARCH)" = "sparc" |
3 | default ARCH = "sparc64" | 3 | default "$(ARCH)" = "sparc64" |
4 | help | 4 | help |
5 | SPARC is a family of RISC microprocessors designed and marketed by | 5 | SPARC is a family of RISC microprocessors designed and marketed by |
6 | Sun Microsystems, incorporated. They are very widely found in Sun | 6 | Sun Microsystems, incorporated. They are very widely found in Sun |
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index c68add8df3ae..07f84c842cc3 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common | |||
@@ -54,10 +54,6 @@ config HZ | |||
54 | int | 54 | int |
55 | default 100 | 55 | default 100 |
56 | 56 | ||
57 | config SUBARCH | ||
58 | string | ||
59 | option env="SUBARCH" | ||
60 | |||
61 | config NR_CPUS | 57 | config NR_CPUS |
62 | int | 58 | int |
63 | range 1 1 | 59 | range 1 1 |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c07f492b871a..22365050ef5e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1,8 +1,8 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | # Select 32 or 64 bit | 2 | # Select 32 or 64 bit |
3 | config 64BIT | 3 | config 64BIT |
4 | bool "64-bit kernel" if ARCH = "x86" | 4 | bool "64-bit kernel" if "$(ARCH)" = "x86" |
5 | default ARCH != "i386" | 5 | default "$(ARCH)" != "i386" |
6 | ---help--- | 6 | ---help--- |
7 | Say yes to build a 64-bit kernel - formerly known as x86_64 | 7 | Say yes to build a 64-bit kernel - formerly known as x86_64 |
8 | Say no to build a 32-bit kernel - formerly known as i386 | 8 | Say no to build a 32-bit kernel - formerly known as i386 |
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig index 13ed827c7c66..6a15c4dcc746 100644 --- a/arch/x86/um/Kconfig +++ b/arch/x86/um/Kconfig | |||
@@ -1,5 +1,5 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | mainmenu "User Mode Linux/$SUBARCH $KERNELVERSION Kernel Configuration" | 2 | mainmenu "User Mode Linux/$(SUBARCH) $(KERNELVERSION) Kernel Configuration" |
3 | 3 | ||
4 | source "arch/um/Kconfig.common" | 4 | source "arch/um/Kconfig.common" |
5 | 5 | ||
@@ -16,8 +16,8 @@ config UML_X86 | |||
16 | select GENERIC_FIND_FIRST_BIT | 16 | select GENERIC_FIND_FIRST_BIT |
17 | 17 | ||
18 | config 64BIT | 18 | config 64BIT |
19 | bool "64-bit kernel" if SUBARCH = "x86" | 19 | bool "64-bit kernel" if "$(SUBARCH)" = "x86" |
20 | default SUBARCH != "i386" | 20 | default "$(SUBARCH)" != "i386" |
21 | 21 | ||
22 | config X86_32 | 22 | config X86_32 |
23 | def_bool !64BIT | 23 | def_bool !64BIT |
diff --git a/init/Kconfig b/init/Kconfig index 15aae32e0719..1217fc62ca61 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1,20 +1,12 @@ | |||
1 | config ARCH | ||
2 | string | ||
3 | option env="ARCH" | ||
4 | |||
5 | config KERNELVERSION | ||
6 | string | ||
7 | option env="KERNELVERSION" | ||
8 | |||
9 | config DEFCONFIG_LIST | 1 | config DEFCONFIG_LIST |
10 | string | 2 | string |
11 | depends on !UML | 3 | depends on !UML |
12 | option defconfig_list | 4 | option defconfig_list |
13 | default "/lib/modules/$UNAME_RELEASE/.config" | 5 | default "/lib/modules/$(UNAME_RELEASE)/.config" |
14 | default "/etc/kernel-config" | 6 | default "/etc/kernel-config" |
15 | default "/boot/config-$UNAME_RELEASE" | 7 | default "/boot/config-$(UNAME_RELEASE)" |
16 | default "$ARCH_DEFCONFIG" | 8 | default ARCH_DEFCONFIG |
17 | default "arch/$ARCH/defconfig" | 9 | default "arch/$(ARCH)/defconfig" |
18 | 10 | ||
19 | config CONSTRUCTORS | 11 | config CONSTRUCTORS |
20 | bool | 12 | bool |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 569217168e96..5f87ad561b08 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -30,7 +30,7 @@ static void conf_message(const char *fmt, ...) | |||
30 | static const char *conf_filename; | 30 | static const char *conf_filename; |
31 | static int conf_lineno, conf_warnings; | 31 | static int conf_lineno, conf_warnings; |
32 | 32 | ||
33 | const char conf_defname[] = "arch/$ARCH/defconfig"; | 33 | const char conf_defname[] = "arch/$(ARCH)/defconfig"; |
34 | 34 | ||
35 | static void conf_warning(const char *fmt, ...) | 35 | static void conf_warning(const char *fmt, ...) |
36 | { | 36 | { |
@@ -81,39 +81,13 @@ const char *conf_get_autoconfig_name(void) | |||
81 | return name ? name : "include/config/auto.conf"; | 81 | return name ? name : "include/config/auto.conf"; |
82 | } | 82 | } |
83 | 83 | ||
84 | static char *conf_expand_value(const char *in) | ||
85 | { | ||
86 | struct symbol *sym; | ||
87 | const char *src; | ||
88 | static char res_value[SYMBOL_MAXLENGTH]; | ||
89 | char *dst, name[SYMBOL_MAXLENGTH]; | ||
90 | |||
91 | res_value[0] = 0; | ||
92 | dst = name; | ||
93 | while ((src = strchr(in, '$'))) { | ||
94 | strncat(res_value, in, src - in); | ||
95 | src++; | ||
96 | dst = name; | ||
97 | while (isalnum(*src) || *src == '_') | ||
98 | *dst++ = *src++; | ||
99 | *dst = 0; | ||
100 | sym = sym_lookup(name, 0); | ||
101 | sym_calc_value(sym); | ||
102 | strcat(res_value, sym_get_string_value(sym)); | ||
103 | in = src; | ||
104 | } | ||
105 | strcat(res_value, in); | ||
106 | |||
107 | return res_value; | ||
108 | } | ||
109 | |||
110 | char *conf_get_default_confname(void) | 84 | char *conf_get_default_confname(void) |
111 | { | 85 | { |
112 | struct stat buf; | 86 | struct stat buf; |
113 | static char fullname[PATH_MAX+1]; | 87 | static char fullname[PATH_MAX+1]; |
114 | char *env, *name; | 88 | char *env, *name; |
115 | 89 | ||
116 | name = conf_expand_value(conf_defname); | 90 | name = expand_string(conf_defname); |
117 | env = getenv(SRCTREE); | 91 | env = getenv(SRCTREE); |
118 | if (env) { | 92 | if (env) { |
119 | sprintf(fullname, "%s/%s", env, name); | 93 | sprintf(fullname, "%s/%s", env, name); |
@@ -274,7 +248,8 @@ int conf_read_simple(const char *name, int def) | |||
274 | if (expr_calc_value(prop->visible.expr) == no || | 248 | if (expr_calc_value(prop->visible.expr) == no || |
275 | prop->expr->type != E_SYMBOL) | 249 | prop->expr->type != E_SYMBOL) |
276 | continue; | 250 | continue; |
277 | name = conf_expand_value(prop->expr->left.sym->name); | 251 | sym_calc_value(prop->expr->left.sym); |
252 | name = sym_get_string_value(prop->expr->left.sym); | ||
278 | in = zconf_fopen(name); | 253 | in = zconf_fopen(name); |
279 | if (in) { | 254 | if (in) { |
280 | conf_message("using defaults found in %s", | 255 | conf_message("using defaults found in %s", |
diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c index 3ea9c5f9f730..b3e0ea0ac732 100644 --- a/scripts/kconfig/kconf_id.c +++ b/scripts/kconfig/kconf_id.c | |||
@@ -32,7 +32,6 @@ static struct kconf_id kconf_id_array[] = { | |||
32 | { "on", T_ON, TF_PARAM }, | 32 | { "on", T_ON, TF_PARAM }, |
33 | { "modules", T_OPT_MODULES, TF_OPTION }, | 33 | { "modules", T_OPT_MODULES, TF_OPTION }, |
34 | { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, | 34 | { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, |
35 | { "env", T_OPT_ENV, TF_OPTION }, | ||
36 | { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, | 35 | { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, |
37 | }; | 36 | }; |
38 | 37 | ||
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 2628bc6a2141..ed3ff88e60ba 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h | |||
@@ -44,7 +44,6 @@ enum conf_def_mode { | |||
44 | 44 | ||
45 | #define T_OPT_MODULES 1 | 45 | #define T_OPT_MODULES 1 |
46 | #define T_OPT_DEFCONFIG_LIST 2 | 46 | #define T_OPT_DEFCONFIG_LIST 2 |
47 | #define T_OPT_ENV 3 | ||
48 | #define T_OPT_ALLNOCONFIG_Y 4 | 47 | #define T_OPT_ALLNOCONFIG_Y 4 |
49 | 48 | ||
50 | struct kconf_id { | 49 | struct kconf_id { |
@@ -103,6 +102,7 @@ void *xmalloc(size_t size); | |||
103 | void *xcalloc(size_t nmemb, size_t size); | 102 | void *xcalloc(size_t nmemb, size_t size); |
104 | void *xrealloc(void *p, size_t size); | 103 | void *xrealloc(void *p, size_t size); |
105 | char *xstrdup(const char *s); | 104 | char *xstrdup(const char *s); |
105 | char *xstrndup(const char *s, size_t n); | ||
106 | 106 | ||
107 | struct gstr { | 107 | struct gstr { |
108 | size_t len; | 108 | size_t len; |
@@ -120,9 +120,6 @@ void str_printf(struct gstr *gs, const char *fmt, ...); | |||
120 | const char *str_get(struct gstr *gs); | 120 | const char *str_get(struct gstr *gs); |
121 | 121 | ||
122 | /* symbol.c */ | 122 | /* symbol.c */ |
123 | extern struct expr *sym_env_list; | ||
124 | |||
125 | void sym_init(void); | ||
126 | void sym_clear_all_valid(void); | 123 | void sym_clear_all_valid(void); |
127 | struct symbol *sym_choice_default(struct symbol *sym); | 124 | struct symbol *sym_choice_default(struct symbol *sym); |
128 | const char *sym_get_string_default(struct symbol *sym); | 125 | const char *sym_get_string_default(struct symbol *sym); |
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 9dc8abfb1dc3..9f465fe1ca85 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h | |||
@@ -49,5 +49,11 @@ const char * sym_get_string_value(struct symbol *sym); | |||
49 | 49 | ||
50 | const char * prop_get_type_name(enum prop_type type); | 50 | const char * prop_get_type_name(enum prop_type type); |
51 | 51 | ||
52 | /* preprocess.c */ | ||
53 | void env_write_dep(FILE *f, const char *auto_conf_name); | ||
54 | char *expand_string(const char *in); | ||
55 | char *expand_dollar(const char **str); | ||
56 | char *expand_one_token(const char **str); | ||
57 | |||
52 | /* expr.c */ | 58 | /* expr.c */ |
53 | void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); | 59 | void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); |
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 068a4e4db20a..379a119dcd1e 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c | |||
@@ -214,9 +214,6 @@ void menu_add_option(int token, char *arg) | |||
214 | zconf_error("trying to redefine defconfig symbol"); | 214 | zconf_error("trying to redefine defconfig symbol"); |
215 | sym_defconfig_list->flags |= SYMBOL_AUTO; | 215 | sym_defconfig_list->flags |= SYMBOL_AUTO; |
216 | break; | 216 | break; |
217 | case T_OPT_ENV: | ||
218 | prop_add_env(arg); | ||
219 | break; | ||
220 | case T_OPT_ALLNOCONFIG_Y: | 217 | case T_OPT_ALLNOCONFIG_Y: |
221 | current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; | 218 | current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; |
222 | break; | 219 | break; |
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c new file mode 100644 index 000000000000..a2eb2eb02929 --- /dev/null +++ b/scripts/kconfig/preprocess.c | |||
@@ -0,0 +1,238 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // | ||
3 | // Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com> | ||
4 | |||
5 | #include <stdarg.h> | ||
6 | #include <stdbool.h> | ||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | |||
11 | #include "list.h" | ||
12 | |||
13 | static void __attribute__((noreturn)) pperror(const char *format, ...) | ||
14 | { | ||
15 | va_list ap; | ||
16 | |||
17 | fprintf(stderr, "%s:%d: ", current_file->name, yylineno); | ||
18 | va_start(ap, format); | ||
19 | vfprintf(stderr, format, ap); | ||
20 | va_end(ap); | ||
21 | fprintf(stderr, "\n"); | ||
22 | |||
23 | exit(1); | ||
24 | } | ||
25 | |||
26 | /* | ||
27 | * Environment variables | ||
28 | */ | ||
29 | static LIST_HEAD(env_list); | ||
30 | |||
31 | struct env { | ||
32 | char *name; | ||
33 | char *value; | ||
34 | struct list_head node; | ||
35 | }; | ||
36 | |||
37 | static void env_add(const char *name, const char *value) | ||
38 | { | ||
39 | struct env *e; | ||
40 | |||
41 | e = xmalloc(sizeof(*e)); | ||
42 | e->name = xstrdup(name); | ||
43 | e->value = xstrdup(value); | ||
44 | |||
45 | list_add_tail(&e->node, &env_list); | ||
46 | } | ||
47 | |||
48 | static void env_del(struct env *e) | ||
49 | { | ||
50 | list_del(&e->node); | ||
51 | free(e->name); | ||
52 | free(e->value); | ||
53 | free(e); | ||
54 | } | ||
55 | |||
56 | /* The returned pointer must be freed when done */ | ||
57 | static char *env_expand(const char *name) | ||
58 | { | ||
59 | struct env *e; | ||
60 | const char *value; | ||
61 | |||
62 | if (!*name) | ||
63 | return NULL; | ||
64 | |||
65 | list_for_each_entry(e, &env_list, node) { | ||
66 | if (!strcmp(name, e->name)) | ||
67 | return xstrdup(e->value); | ||
68 | } | ||
69 | |||
70 | value = getenv(name); | ||
71 | if (!value) | ||
72 | return NULL; | ||
73 | |||
74 | /* | ||
75 | * We need to remember all referenced environment variables. | ||
76 | * They will be written out to include/config/auto.conf.cmd | ||
77 | */ | ||
78 | env_add(name, value); | ||
79 | |||
80 | return xstrdup(value); | ||
81 | } | ||
82 | |||
83 | void env_write_dep(FILE *f, const char *autoconfig_name) | ||
84 | { | ||
85 | struct env *e, *tmp; | ||
86 | |||
87 | list_for_each_entry_safe(e, tmp, &env_list, node) { | ||
88 | fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value); | ||
89 | fprintf(f, "%s: FORCE\n", autoconfig_name); | ||
90 | fprintf(f, "endif\n"); | ||
91 | env_del(e); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static char *eval_clause(const char *str, size_t len) | ||
96 | { | ||
97 | char *tmp, *name, *res; | ||
98 | |||
99 | tmp = xstrndup(str, len); | ||
100 | |||
101 | name = expand_string(tmp); | ||
102 | |||
103 | res = env_expand(name); | ||
104 | if (res) | ||
105 | goto free; | ||
106 | |||
107 | res = xstrdup(""); | ||
108 | free: | ||
109 | free(name); | ||
110 | free(tmp); | ||
111 | |||
112 | return res; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Expand a string that follows '$' | ||
117 | * | ||
118 | * For example, if the input string is | ||
119 | * ($(FOO)$($(BAR)))$(BAZ) | ||
120 | * this helper evaluates | ||
121 | * $($(FOO)$($(BAR))) | ||
122 | * and returns a new string containing the expansion (note that the string is | ||
123 | * recursively expanded), also advancing 'str' to point to the next character | ||
124 | * after the corresponding closing parenthesis, in this case, *str will be | ||
125 | * $(BAR) | ||
126 | */ | ||
127 | char *expand_dollar(const char **str) | ||
128 | { | ||
129 | const char *p = *str; | ||
130 | const char *q; | ||
131 | int nest = 0; | ||
132 | |||
133 | /* | ||
134 | * In Kconfig, variable references always start with "$(". | ||
135 | * Neither single-letter variables as in $A nor curly braces as in ${CC} | ||
136 | * are supported. '$' not followed by '(' loses its special meaning. | ||
137 | */ | ||
138 | if (*p != '(') { | ||
139 | *str = p; | ||
140 | return xstrdup("$"); | ||
141 | } | ||
142 | |||
143 | p++; | ||
144 | q = p; | ||
145 | while (*q) { | ||
146 | if (*q == '(') { | ||
147 | nest++; | ||
148 | } else if (*q == ')') { | ||
149 | if (nest-- == 0) | ||
150 | break; | ||
151 | } | ||
152 | q++; | ||
153 | } | ||
154 | |||
155 | if (!*q) | ||
156 | pperror("unterminated reference to '%s': missing ')'", p); | ||
157 | |||
158 | /* Advance 'str' to after the expanded initial portion of the string */ | ||
159 | *str = q + 1; | ||
160 | |||
161 | return eval_clause(p, q - p); | ||
162 | } | ||
163 | |||
164 | static char *__expand_string(const char **str, bool (*is_end)(char c)) | ||
165 | { | ||
166 | const char *in, *p; | ||
167 | char *expansion, *out; | ||
168 | size_t in_len, out_len; | ||
169 | |||
170 | out = xmalloc(1); | ||
171 | *out = 0; | ||
172 | out_len = 1; | ||
173 | |||
174 | p = in = *str; | ||
175 | |||
176 | while (1) { | ||
177 | if (*p == '$') { | ||
178 | in_len = p - in; | ||
179 | p++; | ||
180 | expansion = expand_dollar(&p); | ||
181 | out_len += in_len + strlen(expansion); | ||
182 | out = xrealloc(out, out_len); | ||
183 | strncat(out, in, in_len); | ||
184 | strcat(out, expansion); | ||
185 | free(expansion); | ||
186 | in = p; | ||
187 | continue; | ||
188 | } | ||
189 | |||
190 | if (is_end(*p)) | ||
191 | break; | ||
192 | |||
193 | p++; | ||
194 | } | ||
195 | |||
196 | in_len = p - in; | ||
197 | out_len += in_len; | ||
198 | out = xrealloc(out, out_len); | ||
199 | strncat(out, in, in_len); | ||
200 | |||
201 | /* Advance 'str' to the end character */ | ||
202 | *str = p; | ||
203 | |||
204 | return out; | ||
205 | } | ||
206 | |||
207 | static bool is_end_of_str(char c) | ||
208 | { | ||
209 | return !c; | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * Expand variables in the given string. Undefined variables | ||
214 | * expand to an empty string. | ||
215 | * The returned string must be freed when done. | ||
216 | */ | ||
217 | char *expand_string(const char *in) | ||
218 | { | ||
219 | return __expand_string(&in, is_end_of_str); | ||
220 | } | ||
221 | |||
222 | static bool is_end_of_token(char c) | ||
223 | { | ||
224 | /* Why are '.' and '/' valid characters for symbols? */ | ||
225 | return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/'); | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * Expand variables in a token. The parsing stops when a token separater | ||
230 | * (in most cases, it is a whitespace) is encountered. 'str' is updated to | ||
231 | * point to the next character. | ||
232 | * | ||
233 | * The returned string must be freed when done. | ||
234 | */ | ||
235 | char *expand_one_token(const char **str) | ||
236 | { | ||
237 | return __expand_string(str, is_end_of_token); | ||
238 | } | ||
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index f0b2e3b3102d..2460648a581a 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -33,33 +33,6 @@ struct symbol *sym_defconfig_list; | |||
33 | struct symbol *modules_sym; | 33 | struct symbol *modules_sym; |
34 | tristate modules_val; | 34 | tristate modules_val; |
35 | 35 | ||
36 | struct expr *sym_env_list; | ||
37 | |||
38 | static void sym_add_default(struct symbol *sym, const char *def) | ||
39 | { | ||
40 | struct property *prop = prop_alloc(P_DEFAULT, sym); | ||
41 | |||
42 | prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); | ||
43 | } | ||
44 | |||
45 | void sym_init(void) | ||
46 | { | ||
47 | struct symbol *sym; | ||
48 | struct utsname uts; | ||
49 | static bool inited = false; | ||
50 | |||
51 | if (inited) | ||
52 | return; | ||
53 | inited = true; | ||
54 | |||
55 | uname(&uts); | ||
56 | |||
57 | sym = sym_lookup("UNAME_RELEASE", 0); | ||
58 | sym->type = S_STRING; | ||
59 | sym->flags |= SYMBOL_AUTO; | ||
60 | sym_add_default(sym, uts.release); | ||
61 | } | ||
62 | |||
63 | enum symbol_type sym_get_type(struct symbol *sym) | 36 | enum symbol_type sym_get_type(struct symbol *sym) |
64 | { | 37 | { |
65 | enum symbol_type type = sym->type; | 38 | enum symbol_type type = sym->type; |
@@ -1401,32 +1374,3 @@ const char *prop_get_type_name(enum prop_type type) | |||
1401 | } | 1374 | } |
1402 | return "unknown"; | 1375 | return "unknown"; |
1403 | } | 1376 | } |
1404 | |||
1405 | static void prop_add_env(const char *env) | ||
1406 | { | ||
1407 | struct symbol *sym, *sym2; | ||
1408 | struct property *prop; | ||
1409 | char *p; | ||
1410 | |||
1411 | sym = current_entry->sym; | ||
1412 | sym->flags |= SYMBOL_AUTO; | ||
1413 | for_all_properties(sym, prop, P_ENV) { | ||
1414 | sym2 = prop_get_symbol(prop); | ||
1415 | if (strcmp(sym2->name, env)) | ||
1416 | menu_warn(current_entry, "redefining environment symbol from %s", | ||
1417 | sym2->name); | ||
1418 | return; | ||
1419 | } | ||
1420 | |||
1421 | prop = prop_alloc(P_ENV, sym); | ||
1422 | prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); | ||
1423 | |||
1424 | sym_env_list = expr_alloc_one(E_LIST, sym_env_list); | ||
1425 | sym_env_list->right.sym = sym; | ||
1426 | |||
1427 | p = getenv(env); | ||
1428 | if (p) | ||
1429 | sym_add_default(sym, p); | ||
1430 | else | ||
1431 | menu_warn(current_entry, "environment variable %s undefined", env); | ||
1432 | } | ||
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index c6f6e21b809f..703ee4904613 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c | |||
@@ -34,8 +34,6 @@ struct file *file_lookup(const char *name) | |||
34 | /* write a dependency file as used by kbuild to track dependencies */ | 34 | /* write a dependency file as used by kbuild to track dependencies */ |
35 | int file_write_dep(const char *name) | 35 | int file_write_dep(const char *name) |
36 | { | 36 | { |
37 | struct symbol *sym, *env_sym; | ||
38 | struct expr *e; | ||
39 | struct file *file; | 37 | struct file *file; |
40 | FILE *out; | 38 | FILE *out; |
41 | 39 | ||
@@ -54,21 +52,7 @@ int file_write_dep(const char *name) | |||
54 | fprintf(out, "\n%s: \\\n" | 52 | fprintf(out, "\n%s: \\\n" |
55 | "\t$(deps_config)\n\n", conf_get_autoconfig_name()); | 53 | "\t$(deps_config)\n\n", conf_get_autoconfig_name()); |
56 | 54 | ||
57 | expr_list_for_each_sym(sym_env_list, e, sym) { | 55 | env_write_dep(out, conf_get_autoconfig_name()); |
58 | struct property *prop; | ||
59 | const char *value; | ||
60 | |||
61 | prop = sym_get_env_prop(sym); | ||
62 | env_sym = prop_get_symbol(prop); | ||
63 | if (!env_sym) | ||
64 | continue; | ||
65 | value = getenv(env_sym->name); | ||
66 | if (!value) | ||
67 | value = ""; | ||
68 | fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); | ||
69 | fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); | ||
70 | fprintf(out, "endif\n"); | ||
71 | } | ||
72 | 56 | ||
73 | fprintf(out, "\n$(deps_config): ;\n"); | 57 | fprintf(out, "\n$(deps_config): ;\n"); |
74 | fclose(out); | 58 | fclose(out); |
@@ -165,3 +149,14 @@ char *xstrdup(const char *s) | |||
165 | fprintf(stderr, "Out of memory.\n"); | 149 | fprintf(stderr, "Out of memory.\n"); |
166 | exit(1); | 150 | exit(1); |
167 | } | 151 | } |
152 | |||
153 | char *xstrndup(const char *s, size_t n) | ||
154 | { | ||
155 | char *p; | ||
156 | |||
157 | p = strndup(s, n); | ||
158 | if (p) | ||
159 | return p; | ||
160 | fprintf(stderr, "Out of memory.\n"); | ||
161 | exit(1); | ||
162 | } | ||
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 045093d827e1..b3855909913c 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l | |||
@@ -1,6 +1,5 @@ | |||
1 | %option nostdinit noyywrap never-interactive full ecs | 1 | %option nostdinit noyywrap never-interactive full ecs |
2 | %option 8bit nodefault yylineno | 2 | %option 8bit nodefault yylineno |
3 | %option noinput | ||
4 | %x COMMAND HELP STRING PARAM | 3 | %x COMMAND HELP STRING PARAM |
5 | %{ | 4 | %{ |
6 | /* | 5 | /* |
@@ -35,6 +34,8 @@ struct buffer *current_buf; | |||
35 | 34 | ||
36 | static int last_ts, first_ts; | 35 | static int last_ts, first_ts; |
37 | 36 | ||
37 | static char *expand_token(const char *in, size_t n); | ||
38 | static void append_expanded_string(const char *in); | ||
38 | static void zconf_endhelp(void); | 39 | static void zconf_endhelp(void); |
39 | static void zconf_endfile(void); | 40 | static void zconf_endfile(void); |
40 | 41 | ||
@@ -147,6 +148,13 @@ n [A-Za-z0-9_-] | |||
147 | yylval.string = text; | 148 | yylval.string = text; |
148 | return T_WORD; | 149 | return T_WORD; |
149 | } | 150 | } |
151 | ({n}|[/.$])+ { | ||
152 | /* this token includes at least one '$' */ | ||
153 | yylval.string = expand_token(yytext, yyleng); | ||
154 | if (strlen(yylval.string)) | ||
155 | return T_WORD; | ||
156 | free(yylval.string); | ||
157 | } | ||
150 | #.* /* comment */ | 158 | #.* /* comment */ |
151 | \\\n ; | 159 | \\\n ; |
152 | [[:blank:]]+ | 160 | [[:blank:]]+ |
@@ -157,12 +165,13 @@ n [A-Za-z0-9_-] | |||
157 | } | 165 | } |
158 | 166 | ||
159 | <STRING>{ | 167 | <STRING>{ |
160 | [^'"\\\n]+/\n { | 168 | "$".* append_expanded_string(yytext); |
169 | [^$'"\\\n]+/\n { | ||
161 | append_string(yytext, yyleng); | 170 | append_string(yytext, yyleng); |
162 | yylval.string = text; | 171 | yylval.string = text; |
163 | return T_WORD_QUOTE; | 172 | return T_WORD_QUOTE; |
164 | } | 173 | } |
165 | [^'"\\\n]+ { | 174 | [^$'"\\\n]+ { |
166 | append_string(yytext, yyleng); | 175 | append_string(yytext, yyleng); |
167 | } | 176 | } |
168 | \\.?/\n { | 177 | \\.?/\n { |
@@ -249,6 +258,58 @@ n [A-Za-z0-9_-] | |||
249 | } | 258 | } |
250 | 259 | ||
251 | %% | 260 | %% |
261 | static char *expand_token(const char *in, size_t n) | ||
262 | { | ||
263 | char *out; | ||
264 | int c; | ||
265 | char c2; | ||
266 | const char *rest, *end; | ||
267 | |||
268 | new_string(); | ||
269 | append_string(in, n); | ||
270 | |||
271 | /* get the whole line because we do not know the end of token. */ | ||
272 | while ((c = input()) != EOF) { | ||
273 | if (c == '\n') { | ||
274 | unput(c); | ||
275 | break; | ||
276 | } | ||
277 | c2 = c; | ||
278 | append_string(&c2, 1); | ||
279 | } | ||
280 | |||
281 | rest = text; | ||
282 | out = expand_one_token(&rest); | ||
283 | |||
284 | /* push back unused characters to the input stream */ | ||
285 | end = rest + strlen(rest); | ||
286 | while (end > rest) | ||
287 | unput(*--end); | ||
288 | |||
289 | free(text); | ||
290 | |||
291 | return out; | ||
292 | } | ||
293 | |||
294 | static void append_expanded_string(const char *str) | ||
295 | { | ||
296 | const char *end; | ||
297 | char *res; | ||
298 | |||
299 | str++; | ||
300 | |||
301 | res = expand_dollar(&str); | ||
302 | |||
303 | /* push back unused characters to the input stream */ | ||
304 | end = str + strlen(str); | ||
305 | while (end > str) | ||
306 | unput(*--end); | ||
307 | |||
308 | append_string(res, strlen(res)); | ||
309 | |||
310 | free(res); | ||
311 | } | ||
312 | |||
252 | void zconf_starthelp(void) | 313 | void zconf_starthelp(void) |
253 | { | 314 | { |
254 | new_string(); | 315 | new_string(); |
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 8bfaaf853d23..031b2e24ae00 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y | |||
@@ -534,7 +534,6 @@ void conf_parse(const char *name) | |||
534 | 534 | ||
535 | zconf_initscan(name); | 535 | zconf_initscan(name); |
536 | 536 | ||
537 | sym_init(); | ||
538 | _menu_init(); | 537 | _menu_init(); |
539 | 538 | ||
540 | if (getenv("ZCONF_DEBUG")) | 539 | if (getenv("ZCONF_DEBUG")) |
@@ -780,3 +779,4 @@ void zconfdump(FILE *out) | |||
780 | #include "expr.c" | 779 | #include "expr.c" |
781 | #include "symbol.c" | 780 | #include "symbol.c" |
782 | #include "menu.c" | 781 | #include "menu.c" |
782 | #include "preprocess.c" | ||