util/kconfig: Uprev to Linux 6.6's kconfig

Upstream reimplemented KCONFIG_STRICT, just calling it KCONFIG_WERROR.
Therefore, adapt our build system and documentation. Upstream is less
strict at this time, but there's a proposed patch that got imported.

TEST=`util/abuild/abuild -C` output (config.h and
config.build) remains the same. Also, the failure type fixed in
https://review.coreboot.org/c/coreboot/+/11272 can be detected,
which I tested by manually breaking our Kconfig in a similar way.

Change-Id: I322fb08a2f7308b93cff71a5dd4136f1a998773b
Signed-off-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79259
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
Reviewed-by: Felix Singer <service+coreboot-gerrit@felixsinger.de>
This commit is contained in:
Patrick Georgi 2023-11-20 19:49:29 +01:00
parent 47282a90de
commit 0eab62b9cf
25 changed files with 406 additions and 449 deletions

View File

@ -69,9 +69,6 @@ These variables are typically set in the makefiles or on the make command line.
These variables were added to Kconfig specifically for coreboot and are not
included in the Linux version.
- KCONFIG_STRICT=value. Define to enable warnings as errors. This is enabled
in coreboot, and should not be changed.
- KCONFIG_NEGATIVES=value. Define to show negative values in the autoconf.h file
(build/config.h). This is enabled in coreboot, and should not be changed.
@ -102,6 +99,9 @@ included in the Linux version.
- KCONFIG_SPLITCONFIG=”directory name for individual SYMBOL.h files”.
coreboot sets this to $(obj)/config.
- KCONFIG_WERROR=value. Define to enable warnings as errors. This is enabled
in coreboot, and should not be changed.
#### Used only for make menuconfig
- MENUCONFIG_MODE=single_menu. Set to "single_menu" to enable. All other
values disable the option. This makes submenus appear below the menu option
@ -1160,10 +1160,6 @@ saved .config file. As always, a 'select' statement overrides any specified
- coreboot has added the glob operator '*' for the 'source' keyword.
- coreboots Kconfig always defines variables except for strings. In other
Kconfig implementations, bools set to false/0/no are not defined.
- coreboots version of Kconfig adds the KCONFIG_STRICT environment variable to
error out if there are any issues in the Kconfig files. In the Linux kernel,
Kconfig will generate a warning, but will still output an updated .config or
config.h file.
## Kconfig Editor Highlighting

View File

@ -29,13 +29,15 @@ KCONFIG_DEPENDENCIES := $(obj)/auto.conf.cmd
KCONFIG_SPLITCONFIG := $(obj)/config/
KCONFIG_TRISTATE := $(obj)/tristate.conf
KCONFIG_NEGATIVES := 1
KCONFIG_STRICT := 1
KCONFIG_WERROR:= 1
KCONFIG_WARN_UNKNOWN_SYMBOLS:= 1
KCONFIG_PACKAGE := CB.Config
KCONFIG_MAKEFILE_REAL ?= $(objk)/Makefile.real
COREBOOT_EXPORTS += KCONFIG_CONFIG KCONFIG_AUTOHEADER KCONFIG_AUTOCONFIG
COREBOOT_EXPORTS += KCONFIG_DEPENDENCIES KCONFIG_SPLITCONFIG KCONFIG_TRISTATE
COREBOOT_EXPORTS += KCONFIG_NEGATIVES KCONFIG_STRICT
COREBOOT_EXPORTS += KCONFIG_NEGATIVES KCONFIG_WERROR
COREBOOT_EXPORTS += KCONFIG_WARN_UNKNOWN_SYMBOLS
COREBOOT_EXPORTS += KCONFIG_AUTOADS KCONFIG_PACKAGE
# Make does not offer a recursive wildcard function, so here's one:

View File

@ -93,11 +93,13 @@ endif
%_defconfig: $(obj)/conf
$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
configfiles = $(wildcard $(srctree)/kernel/configs/$(1) $(srctree)/arch/$(SRCARCH)/configs/$(1))
all-config-fragments = $(call configfiles,*.config)
config-fragments = $(call configfiles,$@)
%.config: $(obj)/conf
$(if $(call configfiles),, $(error No configuration exists for this target on this architecture))
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles)
$(if $(config-fragments),, $(error $@ fragment does not exists on this architecture))
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(config-fragments)
$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
PHONY += tinyconfig
@ -115,6 +117,7 @@ clean-files += tests/.cache
# Help text used by make help
help:
@echo 'Configuration targets:'
@echo ' config - Update current config utilising a line-oriented program'
@echo ' nconfig - Update current config utilising a ncurses menu based program'
@echo ' menuconfig - Update current config utilising a menu based program'
@ -141,6 +144,12 @@ help:
@echo ' default value without prompting'
@echo ' tinyconfig - Configure the tiniest possible kernel'
@echo ' testconfig - Run Kconfig unit tests (requires python3 and pytest)'
@echo ''
@echo 'Configuration topic targets:'
@$(foreach f, $(all-config-fragments), \
if help=$$(grep -m1 '^# Help: ' $(f)); then \
printf ' %-25s - %s\n' '$(notdir $(f))' "$${help#*: }"; \
fi;)
# ===========================================================================
# object files used by all kconfig flavours

View File

@ -16,8 +16,6 @@
#include "lkc.h"
int kconfig_warnings = 0;
static void conf(struct menu *menu);
static void check_conf(struct menu *menu);
@ -722,7 +720,6 @@ int main(int ac, char **av)
const char *progname = av[0];
int opt;
const char *name, *defconfig_file = NULL /* gcc uninit */;
char *env;
int no_conf_write = 0;
tty_stdio = isatty(0) && isatty(1);
@ -830,13 +827,6 @@ int main(int ac, char **av)
break;
}
env = getenv("KCONFIG_STRICT");
if (env && *env && kconfig_warnings) {
fprintf(stderr, "\n*** ERROR: %d warnings encountered, and "
"warnings are errors.\n\n", kconfig_warnings);
exit(1);
}
if (sync_kconfig) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {

View File

@ -370,7 +370,11 @@ int conf_read_simple(const char *name, int def)
char *p, *p2;
struct symbol *sym;
int i, def_flags;
const char *warn_unknown;
const char *werror;
warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
werror = getenv("KCONFIG_WERROR");
if (name) {
in = zconf_fopen(name);
} else {
@ -458,9 +462,10 @@ load:
if (def == S_DEF_USER) {
sym = sym_find(line + 2 + strlen(CONFIG_));
if (!sym) {
conf_message(
"ignoring nonexistent symbol %s",
if (warn_unknown)
conf_warning("unknown symbol: %s",
line + 2 + strlen(CONFIG_));
conf_set_changed(true);
continue;
}
@ -495,7 +500,7 @@ load:
sym = sym_find(line + strlen(CONFIG_));
if (!sym) {
if (def == S_DEF_AUTO)
if (def == S_DEF_AUTO) {
/*
* Reading from include/config/auto.conf
* If CONFIG_FOO previously existed in
@ -503,8 +508,13 @@ load:
* include/config/FOO must be touched.
*/
conf_touch_dep(line + strlen(CONFIG_));
else
} else {
if (warn_unknown)
conf_warning("unknown symbol: %s",
line + strlen(CONFIG_));
conf_set_changed(true);
}
continue;
}
@ -544,7 +554,10 @@ load:
free(line);
fclose(in);
kconfig_warnings += conf_warnings;
if (conf_warnings && werror) {
fprintf(stderr, "\nERROR: %d warnings encountered, and warnings are errors.\n\n", conf_warnings);
exit(1);
}
return 0;
}

View File

@ -275,7 +275,6 @@ struct jump_key {
struct list_head entries;
size_t offset;
struct menu *target;
int index;
};
extern struct file *file_list;

View File

@ -40,9 +40,6 @@ void zconf_nextfiles(const char *name);
int zconf_lineno(void);
const char *zconf_curname(void);
/* conf.c */
extern int kconfig_warnings;
/* confdata.c */
const char *conf_get_configname(void);
void set_all_choice_values(struct symbol *csym);
@ -105,6 +102,7 @@ const char *menu_get_prompt(struct menu *menu);
struct menu *menu_get_parent_menu(struct menu *menu);
bool menu_has_help(struct menu *menu);
const char *menu_get_help(struct menu *menu);
int get_jump_key_char(void);
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
void menu_get_ext_help(struct menu *menu, struct gstr *help);

View File

@ -196,13 +196,9 @@ int first_alpha(const char *string, const char *exempt);
int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void
*_data);
int dialog_textbox(const char *title, char *tbuf, int initial_height,
int initial_width, int *keys, int *_vscroll, int *_hscroll,
update_text_fn update_text, void *data);
int dialog_textbox(const char *title, const char *tbuf, int initial_height,
int initial_width, int *_vscroll, int *_hscroll,
int (*extra_key_cb)(int, size_t, size_t, void *), void *data);
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,

View File

@ -10,8 +10,8 @@
static int hscroll;
static int begin_reached, end_reached, page_length;
static char *buf;
static char *page;
static const char *buf, *page;
static size_t start, end;
/*
* Go back 'n' lines in text. Called by dialog_textbox().
@ -98,21 +98,10 @@ static void print_line(WINDOW *win, int row, int width)
/*
* Print a new page of text.
*/
static void print_page(WINDOW *win, int height, int width, update_text_fn
update_text, void *data)
static void print_page(WINDOW *win, int height, int width)
{
int i, passed_end = 0;
if (update_text) {
char *end;
for (i = 0; i < height; i++)
get_line();
end = page;
back_lines(height);
update_text(buf, page - buf, end - buf, data);
}
page_length = 0;
for (i = 0; i < height; i++) {
print_line(win, i, width);
@ -142,24 +131,26 @@ static void print_position(WINDOW *win)
* refresh window content
*/
static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
int cur_y, int cur_x, update_text_fn update_text,
void *data)
int cur_y, int cur_x)
{
print_page(box, boxh, boxw, update_text, data);
start = page - buf;
print_page(box, boxh, boxw);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
end = page - buf;
}
/*
* Display text from a file in a dialog box.
*
* keys is a null-terminated array
* update_text() may not add or remove any '\n' or '\0' in tbuf
*/
int dialog_textbox(const char *title, char *tbuf, int initial_height,
int initial_width, int *keys, int *_vscroll, int *_hscroll,
update_text_fn update_text, void *data)
int dialog_textbox(const char *title, const char *tbuf, int initial_height,
int initial_width, int *_vscroll, int *_hscroll,
int (*extra_key_cb)(int, size_t, size_t, void *), void *data)
{
int i, x, y, cur_x, cur_y, key = 0;
int height, width, boxh, boxw;
@ -239,8 +230,7 @@ do_resize:
/* Print first page of text */
attr_clear(box, boxh, boxw, dlg.dialog.atr);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
while (!done) {
key = wgetch(dialog);
@ -259,8 +249,7 @@ do_resize:
begin_reached = 1;
page = buf;
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x, update_text,
data);
cur_y, cur_x);
}
break;
case 'G': /* Last page */
@ -270,8 +259,7 @@ do_resize:
/* point to last char in buf */
page = buf + strlen(buf);
back_lines(boxh);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
break;
case 'K': /* Previous line */
case 'k':
@ -280,8 +268,7 @@ do_resize:
break;
back_lines(page_length + 1);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
break;
case 'B': /* Previous page */
case 'b':
@ -290,8 +277,7 @@ do_resize:
if (begin_reached)
break;
back_lines(page_length + boxh);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
break;
case 'J': /* Next line */
case 'j':
@ -300,8 +286,7 @@ do_resize:
break;
back_lines(page_length - 1);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
break;
case KEY_NPAGE: /* Next page */
case ' ':
@ -310,8 +295,7 @@ do_resize:
break;
begin_reached = 0;
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
@ -326,8 +310,7 @@ do_resize:
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
break;
case 'L': /* Scroll right */
case 'l':
@ -337,8 +320,7 @@ do_resize:
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
break;
case KEY_ESC:
if (on_key_esc(dialog) == KEY_ESC)
@ -351,14 +333,12 @@ do_resize:
on_key_resize();
goto do_resize;
default:
for (i = 0; keys[i]; i++) {
if (key == keys[i]) {
if (extra_key_cb && extra_key_cb(key, start, end, data)) {
done = true;
break;
}
}
}
}
delwin(box);
delwin(dialog);
if (_vscroll) {

View File

@ -22,10 +22,6 @@
#include "lkc.h"
#include "lxdialog/dialog.h"
#define JUMP_NB 9
int kconfig_warnings = 0;
static const char mconf_readme[] =
"Overview\n"
"--------\n"
@ -290,6 +286,7 @@ static int single_menu_mode;
static int show_all_options;
static int save_and_exit;
static int silent;
static int jump_key_char;
static void conf(struct menu *menu, struct menu *active_menu);
@ -350,19 +347,19 @@ static void reset_subtitle(void)
set_dialog_subtitles(subtitles);
}
static int show_textbox_ext(const char *title, char *text, int r, int c, int
*keys, int *vscroll, int *hscroll, update_text_fn
update_text, void *data)
static int show_textbox_ext(const char *title, const char *text, int r, int c,
int *vscroll, int *hscroll,
int (*extra_key_cb)(int, size_t, size_t, void *),
void *data)
{
dialog_clear();
return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
update_text, data);
return dialog_textbox(title, text, r, c, vscroll, hscroll,
extra_key_cb, data);
}
static void show_textbox(const char *title, const char *text, int r, int c)
{
show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
NULL, NULL);
show_textbox_ext(title, text, r, c, NULL, NULL, NULL, NULL);
}
static void show_helptext(const char *title, const char *text)
@ -383,35 +380,54 @@ static void show_help(struct menu *menu)
struct search_data {
struct list_head *head;
struct menu **targets;
int *keys;
struct menu *target;
};
static void update_text(char *buf, size_t start, size_t end, void *_data)
static int next_jump_key(int key)
{
if (key < '1' || key > '9')
return '1';
key++;
if (key > '9')
key = '1';
return key;
}
static int handle_search_keys(int key, size_t start, size_t end, void *_data)
{
struct search_data *data = _data;
struct jump_key *pos;
int k = 0;
int index = 0;
if (key < '1' || key > '9')
return 0;
list_for_each_entry(pos, data->head, entries) {
if (pos->offset >= start && pos->offset < end) {
char header[4];
index = next_jump_key(index);
if (k < JUMP_NB) {
int key = '0' + (pos->index % JUMP_NB) + 1;
if (pos->offset < start)
continue;
sprintf(header, "(%c)", key);
data->keys[k] = key;
data->targets[k] = pos->target;
k++;
} else {
sprintf(header, " ");
}
if (pos->offset >= end)
break;
memcpy(buf + pos->offset, header, sizeof(header) - 1);
if (key == index) {
data->target = pos->target;
return 1;
}
}
data->keys[k] = 0;
return 0;
}
int get_jump_key_char(void)
{
jump_key_char = next_jump_key(jump_key_char);
return jump_key_char;
}
static void search_conf(void)
@ -458,24 +474,21 @@ again:
sym_arr = sym_re_search(dialog_input);
do {
LIST_HEAD(head);
struct menu *targets[JUMP_NB];
int keys[JUMP_NB + 1], i;
struct search_data data = {
.head = &head,
.targets = targets,
.keys = keys,
};
struct jump_key *pos, *tmp;
jump_key_char = 0;
res = get_relations_str(sym_arr, &head);
set_subtitle();
dres = show_textbox_ext("Search Results", str_get(&res), 0, 0,
keys, &vscroll, &hscroll, &update_text,
&data);
&vscroll, &hscroll,
handle_search_keys, &data);
again = false;
for (i = 0; i < JUMP_NB && keys[i]; i++)
if (dres == keys[i]) {
conf(targets[i]->parent, targets[i]);
if (dres >= '1' && dres <= '9') {
assert(data.target != NULL);
conf(data.target->parent, data.target);
again = true;
}
str_free(&res);
@ -945,7 +958,6 @@ static void conf_message_callback(const char *s)
static int handle_exit(void)
{
int res;
char *env;
save_and_exit = 1;
reset_subtitle();
@ -960,13 +972,6 @@ static int handle_exit(void)
end_dialog(saved_x, saved_y);
env = getenv("KCONFIG_STRICT");
if (env && *env && kconfig_warnings) {
fprintf(stderr, "\n*** ERROR: %d warnings encountered, and "
"warnings are errors.\n\n", kconfig_warnings);
res = 2;
}
switch (res) {
case 0:
if (conf_write(filename)) {

View File

@ -701,6 +701,11 @@ static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix)
}
}
int __attribute__((weak)) get_jump_key_char(void)
{
return -1;
}
static void get_prompt_str(struct gstr *r, struct property *prop,
struct list_head *head)
{
@ -730,24 +735,27 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
}
if (head && location) {
jump = xmalloc(sizeof(struct jump_key));
jump->target = location;
if (list_empty(head))
jump->index = 0;
else
jump->index = list_entry(head->prev, struct jump_key,
entries)->index + 1;
list_add_tail(&jump->entries, head);
}
str_printf(r, " Location:\n");
for (j = 4; --i >= 0; j += 2) {
for (j = 0; --i >= 0; j++) {
int jk = -1;
int indent = 2 * j + 4;
menu = submenu[i];
if (jump && menu == location)
if (jump && menu == location) {
jump->offset = strlen(r->s);
str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
jk = get_jump_key_char();
}
if (jk >= 0) {
str_printf(r, "(%c)", jk);
indent -= 3;
}
str_printf(r, "%*c-> %s", indent, ' ', menu_get_prompt(menu));
if (menu->sym) {
str_printf(r, " (%s [=%s])", menu->sym->name ?
menu->sym->name : "<choice>",

View File

@ -15,8 +15,6 @@
#include "nconf.h"
#include <ctype.h>
int kconfig_warnings = 0;
static const char nconf_global_help[] =
"Help windows\n"
"------------\n"
@ -222,7 +220,7 @@ search_help[] =
"Location:\n"
" -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
" -> PCI support (PCI [ = y])\n"
" -> PCI access mode (<choice> [ = y])\n"
"(1) -> PCI access mode (<choice> [ = y])\n"
"Selects: LIBCRC32\n"
"Selected by: BAR\n"
"-----------------------------------------------------------------\n"
@ -233,9 +231,13 @@ search_help[] =
"o The 'Depends on:' line lists symbols that need to be defined for\n"
" this symbol to be visible and selectable in the menu.\n"
"o The 'Location:' lines tell, where in the menu structure this symbol\n"
" is located. A location followed by a [ = y] indicates that this is\n"
" is located.\n"
" A location followed by a [ = y] indicates that this is\n"
" a selectable menu item, and the current value is displayed inside\n"
" brackets.\n"
" Press the key in the (#) prefix to jump directly to that\n"
" location. You will be returned to the current search results\n"
" after exiting this new menu.\n"
"o The 'Selects:' line tells, what symbol will be automatically selected\n"
" if this symbol is selected (y or m).\n"
"o The 'Selected by' line tells what symbol has selected this symbol.\n"
@ -277,7 +279,9 @@ static const char *current_instructions = menu_instructions;
static char *dialog_input_result;
static int dialog_input_result_len;
static int jump_key_char;
static void selected_conf(struct menu *menu, struct menu *active_menu);
static void conf(struct menu *menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
@ -647,8 +651,6 @@ static void set_config_filename(const char *config_filename)
static int do_exit(void)
{
int res;
char *env;
if (!conf_get_changed()) {
global_exit = 1;
return 0;
@ -664,15 +666,6 @@ static int do_exit(void)
return -1;
}
env = getenv("KCONFIG_STRICT");
if (env && *env && kconfig_warnings) {
btn_dialog(main_window,
"\nWarnings encountered, and warnings are errors.\n\n",
1,
"<OK>");
res = 2;
}
/* if we got here, the user really wants to exit */
switch (res) {
case 0:
@ -698,6 +691,57 @@ static int do_exit(void)
return 0;
}
struct search_data {
struct list_head *head;
struct menu *target;
};
static int next_jump_key(int key)
{
if (key < '1' || key > '9')
return '1';
key++;
if (key > '9')
key = '1';
return key;
}
static int handle_search_keys(int key, size_t start, size_t end, void *_data)
{
struct search_data *data = _data;
struct jump_key *pos;
int index = 0;
if (key < '1' || key > '9')
return 0;
list_for_each_entry(pos, data->head, entries) {
index = next_jump_key(index);
if (pos->offset < start)
continue;
if (pos->offset >= end)
break;
if (key == index) {
data->target = pos->target;
return 1;
}
}
return 0;
}
int get_jump_key_char(void)
{
jump_key_char = next_jump_key(jump_key_char);
return jump_key_char;
}
static void search_conf(void)
{
@ -705,7 +749,8 @@ static void search_conf(void)
struct gstr res;
struct gstr title;
char *dialog_input;
int dres;
int dres, vscroll = 0, hscroll = 0;
bool again;
title = str_new();
str_printf( &title, "Enter (sub)string or regexp to search for "
@ -734,11 +779,28 @@ again:
dialog_input += strlen(CONFIG_);
sym_arr = sym_re_search(dialog_input);
res = get_relations_str(sym_arr, NULL);
free(sym_arr);
show_scroll_win(main_window,
"Search Results", str_get(&res));
do {
LIST_HEAD(head);
struct search_data data = {
.head = &head,
.target = NULL,
};
jump_key_char = 0;
res = get_relations_str(sym_arr, &head);
dres = show_scroll_win_ext(main_window,
"Search Results", str_get(&res),
&vscroll, &hscroll,
handle_search_keys, &data);
again = false;
if (dres >= '1' && dres <= '9') {
assert(data.target != NULL);
selected_conf(data.target->parent, data.target);
again = true;
}
str_free(&res);
} while (again);
free(sym_arr);
str_free(&title);
}
@ -1075,10 +1137,15 @@ static int do_match(int key, struct match_state *state, int *ans)
}
static void conf(struct menu *menu)
{
selected_conf(menu, NULL);
}
static void selected_conf(struct menu *menu, struct menu *active_menu)
{
struct menu *submenu = NULL;
struct symbol *sym;
int res;
int i, res;
int current_index = 0;
int last_top_row = 0;
struct match_state match_state = {
@ -1094,6 +1161,19 @@ static void conf(struct menu *menu)
if (!child_count)
break;
if (active_menu != NULL) {
for (i = 0; i < items_num; i++) {
struct mitem *mcur;
mcur = (struct mitem *) item_userptr(curses_menu_items[i]);
if ((struct menu *) mcur->usrptr == active_menu) {
current_index = i;
break;
}
}
active_menu = NULL;
}
show_menu(menu_get_prompt(menu), menu_instructions,
current_index, &last_top_row);
keypad((menu_win(curses_menu)), TRUE);

View File

@ -497,10 +497,17 @@ void refresh_all_windows(WINDOW *main_window)
refresh();
}
/* layman's scrollable window... */
void show_scroll_win(WINDOW *main_window,
const char *title,
const char *text)
{
(void)show_scroll_win_ext(main_window, title, (char *)text, NULL, NULL, NULL, NULL);
}
/* layman's scrollable window... */
int show_scroll_win_ext(WINDOW *main_window, const char *title, char *text,
int *vscroll, int *hscroll,
extra_key_cb_fn extra_key_cb, void *data)
{
int res;
int total_lines = get_line_no(text);
@ -514,6 +521,12 @@ void show_scroll_win(WINDOW *main_window,
WINDOW *win;
WINDOW *pad;
PANEL *panel;
bool done = false;
if (hscroll)
start_x = *hscroll;
if (vscroll)
start_y = *vscroll;
getmaxyx(stdscr, lines, columns);
@ -549,8 +562,7 @@ void show_scroll_win(WINDOW *main_window,
panel = new_panel(win);
/* handle scrolling */
do {
while (!done) {
copywin(pad, win, start_y, start_x, 2, 2, text_lines,
text_cols, 0);
print_in_middle(win,
@ -593,8 +605,18 @@ void show_scroll_win(WINDOW *main_window,
case 'l':
start_x++;
break;
default:
if (extra_key_cb) {
size_t start = (get_line(text, start_y) - text);
size_t end = (get_line(text, start_y + text_lines) - text);
if (extra_key_cb(res, start, end, data)) {
done = true;
break;
}
if (res == 10 || res == 27 || res == 'q' ||
}
}
if (res == 0 || res == 10 || res == 27 || res == 'q' ||
res == KEY_F(F_HELP) || res == KEY_F(F_BACK) ||
res == KEY_F(F_EXIT))
break;
@ -606,9 +628,14 @@ void show_scroll_win(WINDOW *main_window,
start_x = 0;
if (start_x >= total_cols-text_cols)
start_x = total_cols-text_cols;
} while (res);
}
if (hscroll)
*hscroll = start_x;
if (vscroll)
*vscroll = start_y;
del_panel(panel);
delwin(win);
refresh_all_windows(main_window);
return res;
}

View File

@ -67,6 +67,8 @@ typedef enum {
void set_colors(void);
typedef int (*extra_key_cb_fn)(int, size_t, size_t, void *);
/* this changes the windows attributes !!! */
void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs);
int get_line_length(const char *line);
@ -78,6 +80,9 @@ int dialog_inputbox(WINDOW *main_window,
const char *title, const char *prompt,
const char *init, char **resultp, int *result_len);
void refresh_all_windows(WINDOW *main_window);
int show_scroll_win_ext(WINDOW *main_window, const char *title, char *text,
int *vscroll, int *hscroll,
extra_key_cb_fn extra_key_cb, void *data);
void show_scroll_win(WINDOW *main_window,
const char *title,
const char *text);

View File

@ -1,43 +1,18 @@
From c822f47921feb53b97f48f3aa8d1e843f5099c63 Mon Sep 17 00:00:00 2001
From: Stefan Reinauer <stefan.reinauer@coreboot.org>
Date: Fri, 17 Jul 2015 17:26:48 -0700
Subject: [PATCH] Kconfig: Add KCONFIG_STRICT mode
This is basically a -Werror mode for Kconfig. When exporting
KCONFIG_STRICT in the Makefile, warnings in Kconfig will produce
errors instead.
This will make it easier to spot unclean Kconfig files, settings
and dependencies.
Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
---
util/kconfig/confdata.c | 8 ++++++++
1 file changed, 8 insertions(+)
Make KCONFIG_WERROR more verbose.
Index: kconfig/confdata.c
===================================================================
--- kconfig.orig/confdata.c
+++ kconfig/confdata.c
@@ -437,6 +437,7 @@ load:
if (def == S_DEF_USER) {
sym = sym_find(line + 2 + strlen(CONFIG_));
if (!sym) {
+ conf_warning("trying to assign non-existent symbol %s", line + strlen(CONFIG_));
conf_set_changed(true);
continue;
}
@@ -519,6 +520,13 @@ load:
}
@@ -533,8 +533,10 @@ load:
free(line);
fclose(in);
+
+ name = getenv("KCONFIG_STRICT");
+ if (name && *name && conf_warnings) {
- if (conf_warnings && werror)
+ if (conf_warnings && werror) {
+ fprintf(stderr, "\nERROR: %d warnings encountered, and warnings are errors.\n\n", conf_warnings);
+ return 1;
exit(1);
+ }
+
return 0;
}

View File

@ -40,7 +40,7 @@ Index: kconfig/confdata.c
static void conf_default_message_callback(const char *s)
{
printf("#\n# ");
@@ -447,7 +457,7 @@ load:
@@ -454,7 +464,7 @@ load:
sym->type = S_BOOLEAN;
}
if (sym->flags & def_flags) {
@ -49,7 +49,7 @@ Index: kconfig/confdata.c
}
switch (sym->type) {
case S_BOOLEAN:
@@ -486,7 +496,7 @@ load:
@@ -498,7 +508,7 @@ load:
}
if (sym->flags & def_flags) {
@ -58,7 +58,7 @@ Index: kconfig/confdata.c
}
if (conf_set_sym_val(sym, def, def_flags, p))
continue;
@@ -511,7 +521,7 @@ load:
@@ -523,7 +533,7 @@ load:
break;
case yes:
if (cs->def[def].tri != no)

View File

@ -1,37 +0,0 @@
From 2796443d5a2194400e56e6762e0f748ed0f0470c Mon Sep 17 00:00:00 2001
From: Martin Roth <martinroth@google.com>
Date: Wed, 10 Feb 2016 16:06:00 -0700
Subject: [PATCH] util/kconfig: Ignore extra symbols in configs instead of
failing
When updating an old .config file that has a symbol that has been
removed from the current Kconfig tree, kconfig will generate a warning
and fail to save the updated file. This is incredibly annoying, and
not the goal when trying to eliminate Kconfig warnings.
Instead of generating a warning, just print a message that it's being
ignored. This will remove the offending symbol, while allowing the
updated config file to be saved.
Split the change from 1 line to 3 lines to keep it at 80 characters.
Signed-off-by: Martin Roth <martinroth@google.com>
---
util/kconfig/confdata.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Index: kconfig/confdata.c
===================================================================
--- kconfig.orig/confdata.c
+++ kconfig/confdata.c
@@ -447,7 +447,9 @@ load:
if (def == S_DEF_USER) {
sym = sym_find(line + 2 + strlen(CONFIG_));
if (!sym) {
- conf_warning("trying to assign non-existent symbol %s", line + strlen(CONFIG_));
+ conf_message(
+ "ignoring nonexistent symbol %s",
+ line + 2 + strlen(CONFIG_));
conf_set_changed(true);
continue;
}

View File

@ -1,189 +1,71 @@
From af6c23be63d14860c8c1f0d9fcbc020f7c11d84d Mon Sep 17 00:00:00 2001
From: Stefan Reinauer <reinauer@chromium.org>
Date: Thu, 20 Aug 2015 11:19:34 -0700
Subject: [PATCH] kconfig: Allow KCONFIG_STRICT outside of confdata.c
From: Sergey Senozhatsky <senozhatsky@chromium.org>
To: Masahiro Yamada <masahiroy@kernel.org>
Cc: Patrick Georgi <pgeorgi@google.com>, linux-kbuild@vger.kernel.org,
linux-kernel@vger.kernel.org,
Sergey Senozhatsky <senozhatsky@chromium.org>,
Stefan Reinauer <reinauer@google.com>
Subject: [PATCH] kconfig: WERROR unmet symbol dependency
Date: Wed, 22 Nov 2023 12:47:45 +0900
Message-ID: <20231122034753.1446513-1-senozhatsky@chromium.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
List-ID: <linux-kernel.vger.kernel.org>
X-Mailing-List: linux-kernel@vger.kernel.org
To catch dependency errors in symbol.c (such as the ones
fixed by I51b4ee326f082c6a656a813ee5772e9c34f5c343) we need
to check for global kconfig warnings before saving config
files.
When KCONFIG_WERROR env variable is set treat unmet direct
symbol dependency as a terminal condition (error).
This patch will produce errors for wrong dependencies and
add catching of errors to conf, nconf and mconf. Sorry,
gconf users, you will have to wait.
Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Suggested-by: Stefan Reinauer <reinauer@google.com>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
util/kconfig/conf.c | 10 ++++++++++
util/kconfig/confdata.c | 6 +-----
util/kconfig/lkc.h | 3 +++
util/kconfig/mconf.c | 10 ++++++++++
util/kconfig/nconf.c | 13 +++++++++++++
util/kconfig/qconf.cc | 2 ++
util/kconfig/symbol.c | 1 +
7 files changed, 40 insertions(+), 5 deletions(-)
Index: kconfig/conf.c
===================================================================
--- kconfig.orig/conf.c
+++ kconfig/conf.c
@@ -16,6 +16,8 @@
#include "lkc.h"
+int kconfig_warnings = 0;
+
static void conf(struct menu *menu);
static void check_conf(struct menu *menu);
@@ -720,6 +722,7 @@ int main(int ac, char **av)
const char *progname = av[0];
int opt;
const char *name, *defconfig_file = NULL /* gcc uninit */;
+ char *env;
int no_conf_write = 0;
tty_stdio = isatty(0) && isatty(1);
@@ -827,6 +830,13 @@ int main(int ac, char **av)
break;
}
+ env = getenv("KCONFIG_STRICT");
+ if (env && *env && kconfig_warnings) {
+ fprintf(stderr, "\n*** ERROR: %d warnings encountered, and "
+ "warnings are errors.\n\n", kconfig_warnings);
+ exit(1);
+ }
+
if (sync_kconfig) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
Index: kconfig/confdata.c
===================================================================
--- kconfig.orig/confdata.c
+++ kconfig/confdata.c
@@ -537,11 +537,7 @@ load:
free(line);
fclose(in);
- name = getenv("KCONFIG_STRICT");
- if (name && *name && conf_warnings) {
- fprintf(stderr, "\nERROR: %d warnings encountered, and warnings are errors.\n\n", conf_warnings);
- return 1;
- }
+ kconfig_warnings += conf_warnings;
return 0;
}
Index: kconfig/lkc.h
===================================================================
--- kconfig.orig/lkc.h
+++ kconfig/lkc.h
@@ -39,6 +39,9 @@ void zconf_nextfile(const char *name);
int zconf_lineno(void);
const char *zconf_curname(void);
+/* conf.c */
+extern int kconfig_warnings;
+
/* confdata.c */
const char *conf_get_configname(void);
void set_all_choice_values(struct symbol *csym);
Index: kconfig/mconf.c
===================================================================
--- kconfig.orig/mconf.c
+++ kconfig/mconf.c
@@ -24,6 +24,8 @@
#define JUMP_NB 9
+int kconfig_warnings = 0;
+
static const char mconf_readme[] =
"Overview\n"
"--------\n"
@@ -943,6 +945,7 @@ static void conf_message_callback(const
static int handle_exit(void)
{
int res;
+ char *env;
save_and_exit = 1;
reset_subtitle();
@@ -957,6 +960,13 @@ static int handle_exit(void)
end_dialog(saved_x, saved_y);
+ env = getenv("KCONFIG_STRICT");
+ if (env && *env && kconfig_warnings) {
+ fprintf(stderr, "\n*** ERROR: %d warnings encountered, and "
+ "warnings are errors.\n\n", kconfig_warnings);
+ res = 2;
+ }
+
switch (res) {
case 0:
if (conf_write(filename)) {
Index: kconfig/nconf.c
===================================================================
--- kconfig.orig/nconf.c
+++ kconfig/nconf.c
@@ -15,6 +15,8 @@
#include "nconf.h"
#include <ctype.h>
+int kconfig_warnings = 0;
+
static const char nconf_global_help[] =
"Help windows\n"
"------------\n"
@@ -645,6 +647,8 @@ static void set_config_filename(const ch
static int do_exit(void)
{
int res;
+ char *env;
+
if (!conf_get_changed()) {
global_exit = 1;
return 0;
@@ -660,6 +664,15 @@ static int do_exit(void)
return -1;
}
+ env = getenv("KCONFIG_STRICT");
+ if (env && *env && kconfig_warnings) {
+ btn_dialog(main_window,
+ "\nWarnings encountered, and warnings are errors.\n\n",
+ 1,
+ "<OK>");
+ res = 2;
+ }
+
/* if we got here, the user really wants to exit */
switch (res) {
case 0:
Index: kconfig/qconf.cc
===================================================================
--- kconfig.orig/qconf.cc
+++ kconfig/qconf.cc
@@ -26,6 +26,8 @@
#include "images.h"
+int kconfig_warnings = 0;
+
static QApplication *configApp;
static ConfigSettings *configSettings;
scripts/kconfig/symbol.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
Index: kconfig/symbol.c
===================================================================
--- kconfig.orig/symbol.c
+++ kconfig/symbol.c
@@ -319,6 +319,7 @@ static void sym_warn_unmet_dep(struct sy
@@ -37,6 +37,7 @@ static struct symbol symbol_empty = {
struct symbol *modules_sym;
static tristate modules_val;
+static int sym_warnings;
enum symbol_type sym_get_type(struct symbol *sym)
{
@@ -319,12 +320,14 @@ static void sym_warn_unmet_dep(struct sy
" Selected by [m]:\n");
fputs(str_get(&gs), stderr);
+ kconfig_warnings++;
+ sym_warnings++;
}
void sym_calc_value(struct symbol *sym)
{
struct symbol_value newval, oldval;
struct property *prop;
+ const char *werror;
struct expr *e;
if (!sym)
@@ -340,8 +343,9 @@ void sym_calc_value(struct symbol *sym)
sym_calc_value(prop_get_symbol(prop));
}
+ werror = getenv("KCONFIG_WERROR");
+ sym_warnings = 0;
sym->flags |= SYMBOL_VALID;
-
oldval = sym->curr;
switch (sym->type) {
@@ -432,6 +436,9 @@ void sym_calc_value(struct symbol *sym)
;
}
+ if (sym_warnings && werror)
+ exit(1);
+
sym->curr = newval;
if (sym_is_choice(sym) && newval.tri == yes)
sym->curr.val = sym_calc_choice(sym);

View File

@ -14,7 +14,7 @@ Index: kconfig/confdata.c
===================================================================
--- kconfig.orig/confdata.c
+++ kconfig/confdata.c
@@ -725,7 +725,12 @@ static void print_symbol_for_dotconfig(F
@@ -738,7 +738,12 @@ static void print_symbol_for_dotconfig(F
static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
{
@ -28,7 +28,7 @@ Index: kconfig/confdata.c
}
void print_symbol_for_listconfig(struct symbol *sym)
@@ -750,6 +755,10 @@ static void print_symbol_for_c(FILE *fp,
@@ -763,6 +768,10 @@ static void print_symbol_for_c(FILE *fp,
case S_TRISTATE:
switch (*val) {
case 'n':
@ -39,7 +39,7 @@ Index: kconfig/confdata.c
return;
case 'm':
sym_suffix = "_MODULE";
@@ -761,6 +770,12 @@ static void print_symbol_for_c(FILE *fp,
@@ -774,6 +783,12 @@ static void print_symbol_for_c(FILE *fp,
case S_HEX:
if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
val_prefix = "0x";
@ -52,7 +52,7 @@ Index: kconfig/confdata.c
break;
case S_STRING:
escaped = escape_string_value(val);
@@ -1177,8 +1192,9 @@ static int __conf_write_autoconf(const c
@@ -1190,8 +1205,9 @@ static int __conf_write_autoconf(const c
conf_write_heading(file, comment_style);

View File

@ -35,7 +35,7 @@ Index: kconfig/confdata.c
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
{
char *p2;
@@ -1093,19 +1100,19 @@ static int conf_write_autoconf_cmd(const
@@ -1106,19 +1113,19 @@ static int conf_write_autoconf_cmd(const
static int conf_touch_deps(void)
{

View File

@ -2,7 +2,6 @@
0002-Kconfig-Change-symbol-override-from-warning-to-notic.patch
0003-util-kconfig-conf.c-Fix-newline-in-error-printf.patch
0004-src-util-Use-NULL-instead-of-0-for-pointer.patch
0005-util-kconfig-Ignore-extra-symbols-in-configs-instead.patch
0006-util-kconfig-Set-parameter-of-mkdir-to-only-one-for-.patch
0007-kconfig-Allow-KCONFIG_STRICT-outside-of-confdata.c.patch
0008-kconfig-Add-wildcard-support-for-source.patch

View File

@ -396,6 +396,9 @@ static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
p++;
}
if (new_argc >= FUNCTION_MAX_ARGS)
pperror("too many function arguments");
new_argv[new_argc++] = prev;
/*

View File

@ -5,7 +5,8 @@ cflags=$1
libs=$2
bin=$3
PKG="Qt5Core Qt5Gui Qt5Widgets"
PKG5="Qt5Core Qt5Gui Qt5Widgets"
PKG6="Qt6Core Qt6Gui Qt6Widgets"
if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then
echo >&2 "*"
@ -14,16 +15,26 @@ if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then
exit 1
fi
if ${HOSTPKG_CONFIG} --exists $PKG; then
${HOSTPKG_CONFIG} --cflags ${PKG} > ${cflags}
${HOSTPKG_CONFIG} --libs ${PKG} > ${libs}
if ${HOSTPKG_CONFIG} --exists $PKG6; then
${HOSTPKG_CONFIG} --cflags ${PKG6} > ${cflags}
# Qt6 requires C++17.
echo -std=c++17 >> ${cflags}
${HOSTPKG_CONFIG} --libs ${PKG6} > ${libs}
${HOSTPKG_CONFIG} --variable=libexecdir Qt6Core > ${bin}
exit 0
fi
if ${HOSTPKG_CONFIG} --exists $PKG5; then
${HOSTPKG_CONFIG} --cflags ${PKG5} > ${cflags}
${HOSTPKG_CONFIG} --libs ${PKG5} > ${libs}
${HOSTPKG_CONFIG} --variable=host_bins Qt5Core > ${bin}
exit 0
fi
echo >&2 "*"
echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}."
echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH"
echo >&2 "* You need $PKG"
echo >&2 "* Could not find Qt6 or Qt5 via ${HOSTPKG_CONFIG}."
echo >&2 "* Please install Qt6 or Qt5 and make sure it's in PKG_CONFIG_PATH"
echo >&2 "* You need $PKG6 for Qt6"
echo >&2 "* You need $PKG5 for Qt5"
echo >&2 "*"
exit 1

View File

@ -5,10 +5,10 @@
*/
#include <QAction>
#include <QActionGroup>
#include <QApplication>
#include <QCloseEvent>
#include <QDebug>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QLabel>
#include <QLayout>
@ -16,6 +16,8 @@
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QRegularExpression>
#include <QScreen>
#include <QToolBar>
#include <stdlib.h>
@ -26,8 +28,6 @@
#include "images.h"
int kconfig_warnings = 0;
static QApplication *configApp;
static ConfigSettings *configSettings;
@ -1128,7 +1128,7 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
QString ConfigInfoView::print_filter(const QString &str)
{
QRegExp re("[<>&\"\\n]");
QRegularExpression re("[<>&\"\\n]");
QString res = str;
for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
switch (res[i].toLatin1()) {
@ -1324,15 +1324,15 @@ ConfigMainWindow::ConfigMainWindow(void)
int width, height;
char title[256];
QDesktopWidget *d = configApp->desktop();
snprintf(title, sizeof(title), "%s%s",
rootmenu.prompt->text,
""
);
setWindowTitle(title);
width = configSettings->value("/window width", d->width() - 64).toInt();
height = configSettings->value("/window height", d->height() - 64).toInt();
QRect g = configApp->primaryScreen()->geometry();
width = configSettings->value("/window width", g.width() - 64).toInt();
height = configSettings->value("/window height", g.height() - 64).toInt();
resize(width, height);
x = configSettings->value("/window x");
y = configSettings->value("/window y");
@ -1381,17 +1381,17 @@ ConfigMainWindow::ConfigMainWindow(void)
this, &ConfigMainWindow::goBack);
QAction *quitAction = new QAction("&Quit", this);
quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
quitAction->setShortcut(Qt::CTRL | Qt::Key_Q);
connect(quitAction, &QAction::triggered,
this, &ConfigMainWindow::close);
QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
loadAction->setShortcut(Qt::CTRL | Qt::Key_L);
connect(loadAction, &QAction::triggered,
this, &ConfigMainWindow::loadConfig);
saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
saveAction->setShortcut(Qt::CTRL | Qt::Key_S);
connect(saveAction, &QAction::triggered,
this, &ConfigMainWindow::saveConfig);
@ -1405,7 +1405,7 @@ ConfigMainWindow::ConfigMainWindow(void)
connect(saveAsAction, &QAction::triggered,
this, &ConfigMainWindow::saveConfigAs);
QAction *searchAction = new QAction("&Find", this);
searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
searchAction->setShortcut(Qt::CTRL | Qt::Key_F);
connect(searchAction, &QAction::triggered,
this, &ConfigMainWindow::searchConfig);
singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
@ -1752,11 +1752,21 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
e->accept();
return;
}
QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
mb.setButtonText(QMessageBox::Yes, "&Save Changes");
mb.setButtonText(QMessageBox::No, "&Discard Changes");
mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
QMessageBox mb(QMessageBox::Icon::Warning, "qconf",
"Save configuration?");
QPushButton *yb = mb.addButton(QMessageBox::Yes);
QPushButton *db = mb.addButton(QMessageBox::No);
QPushButton *cb = mb.addButton(QMessageBox::Cancel);
yb->setText("&Save Changes");
db->setText("&Discard Changes");
cb->setText("Cancel Exit");
mb.setDefaultButton(yb);
mb.setEscapeButton(cb);
switch (mb.exec()) {
case QMessageBox::Yes:
if (saveConfig())

View File

@ -37,6 +37,7 @@ static struct symbol symbol_empty = {
struct symbol *modules_sym;
static tristate modules_val;
static int sym_warnings;
enum symbol_type sym_get_type(struct symbol *sym)
{
@ -319,13 +320,14 @@ static void sym_warn_unmet_dep(struct symbol *sym)
" Selected by [m]:\n");
fputs(str_get(&gs), stderr);
kconfig_warnings++;
sym_warnings++;
}
void sym_calc_value(struct symbol *sym)
{
struct symbol_value newval, oldval;
struct property *prop;
const char *werror;
struct expr *e;
if (!sym)
@ -341,8 +343,9 @@ void sym_calc_value(struct symbol *sym)
sym_calc_value(prop_get_symbol(prop));
}
werror = getenv("KCONFIG_WERROR");
sym_warnings = 0;
sym->flags |= SYMBOL_VALID;
oldval = sym->curr;
switch (sym->type) {
@ -433,6 +436,9 @@ void sym_calc_value(struct symbol *sym)
;
}
if (sym_warnings && werror)
exit(1);
sym->curr = newval;
if (sym_is_choice(sym) && newval.tri == yes)
sym->curr.val = sym_calc_choice(sym);