2018-12-18 21:13:35 +09:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2005-04-16 15:20:36 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef LKC_H
|
|
|
|
|
#define LKC_H
|
|
|
|
|
|
2020-10-29 17:51:51 +02:00
|
|
|
#include <assert.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
#include "expr.h"
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "lkc_proto.h"
|
|
|
|
|
|
|
|
|
|
#define SRCTREE "srctree"
|
|
|
|
|
|
2010-08-14 23:57:43 -04:00
|
|
|
#ifndef CONFIG_
|
|
|
|
|
#define CONFIG_ "CONFIG_"
|
|
|
|
|
#endif
|
2012-10-20 01:06:24 +02:00
|
|
|
static inline const char *CONFIG_prefix(void)
|
|
|
|
|
{
|
2012-10-20 01:06:25 +02:00
|
|
|
return getenv( "CONFIG_" ) ?: CONFIG_;
|
2012-10-20 01:06:24 +02:00
|
|
|
}
|
|
|
|
|
#undef CONFIG_
|
|
|
|
|
#define CONFIG_ CONFIG_prefix()
|
2005-11-08 21:34:51 -08:00
|
|
|
|
2018-03-23 02:00:14 +09:00
|
|
|
extern int yylineno;
|
2005-04-16 15:20:36 -07:00
|
|
|
void zconfdump(FILE *out);
|
|
|
|
|
void zconf_starthelp(void);
|
|
|
|
|
FILE *zconf_fopen(const char *name);
|
|
|
|
|
void zconf_initscan(const char *name);
|
|
|
|
|
void zconf_nextfile(const char *name);
|
|
|
|
|
|
|
|
|
|
/* confdata.c */
|
2024-02-03 00:58:04 +09:00
|
|
|
extern struct gstr autoconf_cmd;
|
2007-04-01 22:29:38 +02:00
|
|
|
const char *conf_get_configname(void);
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2010-08-04 16:01:02 -06:00
|
|
|
/* confdata.c and expr.c */
|
|
|
|
|
static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
|
|
|
|
|
{
|
2011-11-23 13:05:53 -05:00
|
|
|
assert(len != 0);
|
|
|
|
|
|
|
|
|
|
if (fwrite(str, len, count, out) != count)
|
|
|
|
|
fprintf(stderr, "Error in writing or end of file.\n");
|
2010-08-04 16:01:02 -06:00
|
|
|
}
|
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
/* util.c */
|
2024-02-03 00:58:22 +09:00
|
|
|
unsigned int strhash(const char *s);
|
2024-02-03 00:58:16 +09:00
|
|
|
const char *file_lookup(const char *name);
|
2012-11-06 14:32:08 +00:00
|
|
|
void *xmalloc(size_t size);
|
|
|
|
|
void *xcalloc(size_t nmemb, size_t size);
|
2018-02-09 01:19:07 +09:00
|
|
|
void *xrealloc(void *p, size_t size);
|
2018-02-17 03:38:31 +09:00
|
|
|
char *xstrdup(const char *s);
|
kconfig: reference environment variables directly and remove 'option env='
To get access to environment variables, Kconfig needs to define a
symbol using "option env=" syntax. It is tedious to add a symbol entry
for each environment variable given that we need to define much more
such as 'CC', 'AS', 'srctree' etc. to evaluate the compiler capability
in Kconfig.
Adding '$' for symbol references is grammatically inconsistent.
Looking at the code, the symbols prefixed with 'S' are expanded by:
- conf_expand_value()
This is used to expand 'arch/$ARCH/defconfig' and 'defconfig_list'
- sym_expand_string_value()
This is used to expand strings in 'source' and 'mainmenu'
All of them are fixed values independent of user configuration. So,
they can be changed into the direct expansion instead of symbols.
This change makes the code much cleaner. The bounce symbols 'SRCARCH',
'ARCH', 'SUBARCH', 'KERNELVERSION' are gone.
sym_init() hard-coding 'UNAME_RELEASE' is also gone. 'UNAME_RELEASE'
should be replaced with an environment variable.
ARCH_DEFCONFIG is a normal symbol, so it should be simply referenced
without '$' prefix.
The new syntax is addicted by Make. The variable reference needs
parentheses, like $(FOO), but you can omit them for single-letter
variables, like $F. Yet, in Makefiles, people tend to use the
parenthetical form for consistency / clarification.
At this moment, only the environment variable is supported, but I will
extend the concept of 'variable' later on.
The variables are expanded in the lexer so we can simplify the token
handling on the parser side.
For example, the following code works.
[Example code]
config MY_TOOLCHAIN_LIST
string
default "My tools: CC=$(CC), AS=$(AS), CPP=$(CPP)"
[Result]
$ make -s alldefconfig && tail -n 1 .config
CONFIG_MY_TOOLCHAIN_LIST="My tools: CC=gcc, AS=as, CPP=gcc -E"
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
2018-05-28 18:21:40 +09:00
|
|
|
char *xstrndup(const char *s, size_t n);
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2019-01-24 19:47:29 +09:00
|
|
|
/* lexer.l */
|
2018-12-21 17:33:05 +09:00
|
|
|
int yylex(void);
|
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
struct gstr {
|
|
|
|
|
size_t len;
|
|
|
|
|
char *s;
|
2009-12-20 00:29:49 -08:00
|
|
|
/*
|
|
|
|
|
* when max_width is not zero long lines in string s (if any) get
|
|
|
|
|
* wrapped not to exceed the max_width value
|
|
|
|
|
*/
|
|
|
|
|
int max_width;
|
2005-04-16 15:20:36 -07:00
|
|
|
};
|
|
|
|
|
struct gstr str_new(void);
|
|
|
|
|
void str_free(struct gstr *gs);
|
|
|
|
|
void str_append(struct gstr *gs, const char *s);
|
|
|
|
|
void str_printf(struct gstr *gs, const char *fmt, ...);
|
2022-11-13 19:59:42 +09:00
|
|
|
char *str_get(struct gstr *gs);
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2020-09-09 07:16:38 +09:00
|
|
|
/* menu.c */
|
2024-04-21 18:02:51 +09:00
|
|
|
struct menu *menu_next(struct menu *menu, struct menu *root);
|
|
|
|
|
#define menu_for_each_sub_entry(menu, root) \
|
|
|
|
|
for (menu = menu_next(root, root); menu; menu = menu_next(menu, root))
|
|
|
|
|
#define menu_for_each_entry(menu) \
|
|
|
|
|
menu_for_each_sub_entry(menu, &rootmenu)
|
2020-09-09 07:16:38 +09:00
|
|
|
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);
|
|
|
|
|
void menu_add_dep(struct expr *dep);
|
|
|
|
|
void menu_add_visibility(struct expr *dep);
|
|
|
|
|
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
|
|
|
|
|
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
|
|
|
|
|
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
|
2024-03-23 17:51:01 +09:00
|
|
|
void menu_finalize(void);
|
2020-09-09 07:16:38 +09:00
|
|
|
void menu_set_type(int type);
|
|
|
|
|
|
|
|
|
|
extern struct menu rootmenu;
|
|
|
|
|
|
|
|
|
|
bool menu_is_empty(struct menu *menu);
|
|
|
|
|
bool menu_is_visible(struct menu *menu);
|
|
|
|
|
bool menu_has_prompt(struct menu *menu);
|
|
|
|
|
const char *menu_get_prompt(struct menu *menu);
|
|
|
|
|
struct menu *menu_get_parent_menu(struct menu *menu);
|
2023-07-16 13:55:07 +09:00
|
|
|
int get_jump_key_char(void);
|
2020-09-09 07:16:38 +09:00
|
|
|
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
|
|
|
|
|
void menu_get_ext_help(struct menu *menu, struct gstr *help);
|
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
/* symbol.c */
|
|
|
|
|
void sym_clear_all_valid(void);
|
2010-07-31 23:35:32 +02:00
|
|
|
struct symbol *sym_choice_default(struct symbol *sym);
|
2018-12-21 17:33:04 +09:00
|
|
|
struct property *sym_get_range_prop(struct symbol *sym);
|
2010-07-31 23:35:34 +02:00
|
|
|
const char *sym_get_string_default(struct symbol *sym);
|
2005-04-16 15:20:36 -07:00
|
|
|
struct symbol *sym_check_deps(struct symbol *sym);
|
|
|
|
|
struct symbol *prop_get_symbol(struct property *prop);
|
|
|
|
|
|
|
|
|
|
static inline tristate sym_get_tristate_value(struct symbol *sym)
|
|
|
|
|
{
|
|
|
|
|
return sym->curr.tri;
|
|
|
|
|
}
|
|
|
|
|
|
kconfig: refactor choice value calculation
Handling choices has always been in a PITA in Kconfig.
For example, fixes and reverts were repeated for randconfig with
KCONFIG_ALLCONFIG:
- 422c809f03f0 ("kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG")
- 23a5dfdad22a ("Revert "kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG"")
- 8357b48549e1 ("kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG")
- 490f16171119 ("Revert "kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG"")
As these commits pointed out, randconfig does not randomize choices when
KCONFIG_ALLCONFIG is used. This issue still remains.
[Test Case]
choice
prompt "choose"
config A
bool "A"
config B
bool "B"
endchoice
$ echo > all.config
$ make KCONFIG_ALLCONFIG=1 randconfig
The output is always as follows:
CONFIG_A=y
# CONFIG_B is not set
Not only randconfig, but other all*config variants are also broken with
KCONFIG_ALLCONFIG.
With the same Kconfig,
$ echo '# CONFIG_A is not set' > all.config
$ make KCONFIG_ALLCONFIG=1 allyesconfig
You will get this:
CONFIG_A=y
# CONFIG_B is not set
This is incorrect because it does not respect all.config.
The correct output should be:
# CONFIG_A is not set
CONFIG_B=y
To handle user inputs more accurately, this commit refactors the code
based on the following principles:
- When a user value is given, Kconfig must set it immediately.
Do not defer it by setting SYMBOL_NEED_SET_CHOICE_VALUES.
- The SYMBOL_DEF_USER flag must not be cleared, unless a new config
file is loaded. Kconfig must not forget user inputs.
In addition, user values for choices must be managed with priority.
If user inputs conflict within a choice block, the newest value wins.
The values given by randconfig have lower priority than explicit user
inputs.
This commit implements it by using a linked list. Every time a choice
block gets a new input, it is moved to the top of the list.
Let me explain how it works.
Let's say, we have a choice block that consists of five symbols:
A, B, C, D, and E.
Initially, the linked list looks like this:
A(=?) --> B(=?) --> C(=?) --> D(=?) --> E(=?)
Suppose randconfig is executed with the following KCONFIG_ALLCONFIG:
CONFIG_C=y
# CONFIG_A is not set
CONFIG_D=y
First, CONFIG_C=y is read. C is set to 'y' and moved to the top.
C(=y) --> A(=?) --> B(=?) --> D(=?) --> E(=?)
Next, '# CONFIG_A is not set' is read. A is set to 'n' and moved to
the top.
A(=n) --> C(=y) --> B(=?) --> D(=?) --> E(=?)
Then, 'CONFIG_D=y' is read. D is set to 'y' and moved to the top.
D(=y) --> A(=n) --> C(=y) --> B(=?) --> E(=?)
Lastly, randconfig shuffles the order of the remaining symbols,
resulting in:
D(=y) --> A(=n) --> C(=y) --> B(=y) --> E(=y)
or
D(=y) --> A(=n) --> C(=y) --> E(=y) --> B(=y)
When calculating the output, the linked list is traversed and the first
visible symbol with 'y' is taken. In this case, it is D if visible.
If D is hidden by 'depends on', the next node, A, is examined. Since
it is already specified as 'n', it is skipped. Next, C is checked, and
selected if it is visible.
If C is also invisible, either B or E is chosen as a result of the
randomization.
If B and E are also invisible, the linked list is traversed in the
reverse order, and the least prioritized 'n' symbol is chosen. It is
A in this case.
Now, Kconfig remembers all user values. This is a big difference from
the previous implementation, where Kconfig would forget CONFIG_C=y when
CONFIG_D=y appeared in the same input file.
The new appaorch respects user-specified values as much as possible.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
2024-06-18 19:35:21 +09:00
|
|
|
struct symbol *sym_get_choice_value(struct symbol *sym);
|
2005-04-16 15:20:36 -07:00
|
|
|
|
|
|
|
|
static inline bool sym_is_choice(struct symbol *sym)
|
|
|
|
|
{
|
2024-04-23 01:10:54 +09:00
|
|
|
/* A choice is a symbol with no name */
|
|
|
|
|
return sym->name == NULL;
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool sym_is_choice_value(struct symbol *sym)
|
|
|
|
|
{
|
|
|
|
|
return sym->flags & SYMBOL_CHOICEVAL ? true : false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool sym_has_value(struct symbol *sym)
|
|
|
|
|
{
|
2006-06-08 22:12:42 -07:00
|
|
|
return sym->flags & SYMBOL_DEF_USER ? true : false;
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif /* LKC_H */
|