From ae3abb9ee4f475023254711becc2eeacfe631925 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 27 Feb 2026 08:57:48 -0600 Subject: [PATCH] resync with 4.19 Signed-off-by: Tom Rini --- scripts/kconfig/Makefile | 18 ++++++- scripts/kconfig/conf.c | 38 ++++++++----- scripts/kconfig/confdata.c | 31 ++++++----- scripts/kconfig/expr.c | 2 +- scripts/kconfig/gconf.c | 41 +++++++++++++- scripts/kconfig/list.h | 4 +- scripts/kconfig/lkc.h | 1 + scripts/kconfig/lkc_proto.h | 2 +- scripts/kconfig/lxdialog/checklist.c | 15 +++++- scripts/kconfig/lxdialog/dialog.h | 16 +++++- scripts/kconfig/lxdialog/inputbox.c | 15 +++++- scripts/kconfig/lxdialog/menubox.c | 15 +++++- scripts/kconfig/lxdialog/textbox.c | 16 +++++- scripts/kconfig/lxdialog/util.c | 15 +++++- scripts/kconfig/lxdialog/yesno.c | 15 +++++- scripts/kconfig/mconf.c | 1 + scripts/kconfig/menu.c | 1 + scripts/kconfig/merge_config.sh | 11 ++-- scripts/kconfig/nconf.c | 3 ++ scripts/kconfig/nconf.gui.c | 5 ++ scripts/kconfig/qconf.cc | 2 + scripts/kconfig/symbol.c | 2 +- .../tests/err_recursive_dep/expected_stderr | 14 ++--- .../tests/preprocess/builtin_func/Kconfig | 27 ++++++++++ .../tests/preprocess/builtin_func/__init__.py | 9 ++++ .../preprocess/builtin_func/expected_stderr | 5 ++ .../preprocess/builtin_func/expected_stdout | 1 + .../preprocess/circular_expansion/Kconfig | 5 ++ .../preprocess/circular_expansion/__init__.py | 11 ++++ .../circular_expansion/expected_stderr | 1 + .../kconfig/tests/preprocess/escape/Kconfig | 44 +++++++++++++++ .../tests/preprocess/escape/__init__.py | 8 +++ .../tests/preprocess/escape/expected_stderr | 10 ++++ .../kconfig/tests/preprocess/variable/Kconfig | 53 +++++++++++++++++++ .../tests/preprocess/variable/__init__.py | 8 +++ .../tests/preprocess/variable/expected_stderr | 9 ++++ 36 files changed, 418 insertions(+), 56 deletions(-) create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/expected_stdout create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/escape/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/escape/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/escape/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/variable/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/variable/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/variable/expected_stderr diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index abc34f60d15..4be95c7ac57 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -50,7 +50,7 @@ build_xconfig: $(obj)/qconf localyesconfig localmodconfig: $(obj)/conf $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config - $(Q)if [ -f .config ]; then \ + $(Q)if [ -f .config ]; then \ cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ mv -f .tmp.config .config; \ @@ -74,7 +74,21 @@ PHONY += $(simple-targets) $(simple-targets): $(obj)/conf $< $(silent) --$@ $(Kconfig) -PHONY += savedefconfig defconfig +PHONY += oldnoconfig silentoldconfig savedefconfig defconfig + +# oldnoconfig is an alias of olddefconfig, because people already are dependent +# on its behavior (sets new symbols to their default value but not 'n') with the +# counter-intuitive name. +oldnoconfig: olddefconfig + @echo " WARNING: \"oldnoconfig\" target will be removed after Linux 4.19" + @echo " Please use \"olddefconfig\" instead, which is an alias." + +# We do not expect manual invokcation of "silentoldcofig" (or "syncconfig"). +silentoldconfig: syncconfig + @echo " WARNING: \"silentoldconfig\" has been renamed to \"syncconfig\"" + @echo " and is now an internal implementation detail." + @echo " What you want is probably \"oldconfig\"." + @echo " \"silentoldconfig\" will be removed after Linux 4.19" savedefconfig: $(obj)/conf $< $(silent) --$@=defconfig $(Kconfig) diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 376f796f674..7b2b3726066 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -460,6 +460,12 @@ static struct option long_opts[] = { {"randconfig", no_argument, NULL, randconfig}, {"listnewconfig", no_argument, NULL, listnewconfig}, {"olddefconfig", no_argument, NULL, olddefconfig}, + /* + * oldnoconfig is an alias of olddefconfig, because people already + * are dependent on its behavior(sets new symbols to their default + * value but not 'n') with the counter-intuitive name. + */ + {"oldnoconfig", no_argument, NULL, olddefconfig}, {NULL, 0, NULL, 0} }; @@ -474,6 +480,7 @@ static void conf_usage(const char *progname) printf(" --syncconfig Similar to oldconfig but generates configuration in\n" " include/{generated/,config/}\n"); printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n"); + printf(" --oldnoconfig An alias of olddefconfig\n"); printf(" --defconfig New config with default defined in \n"); printf(" --savedefconfig Save the minimal current configuration to \n"); printf(" --allnoconfig New config where all options are answered with no\n"); @@ -684,29 +691,32 @@ int main(int ac, char **av) break; } - if (sync_kconfig) { - /* syncconfig is used during the build so we shall update autoconf. - * All other commands are only used to generate a config. - */ - if (!no_conf_write && conf_write(NULL)) { - fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); - exit(1); - } - if (conf_write_autoconf()) { - fprintf(stderr, "\n*** Error during update of the configuration.\n\n"); - return 1; - } - } else if (input_mode == savedefconfig) { + if (input_mode == savedefconfig) { if (conf_write_defconfig(defconfig_file)) { fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n", defconfig_file); return 1; } } else if (input_mode != listnewconfig) { - if (conf_write(NULL)) { + if (!no_conf_write && conf_write(NULL)) { fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); exit(1); } + + /* + * Create auto.conf if it does not exist. + * This prevents GNU Make 4.1 or older from emitting + * "include/config/auto.conf: No such file or directory" + * in the top-level Makefile + * + * syncconfig always creates or updates auto.conf because it is + * used during the build. + */ + if (conf_write_autoconf(sync_kconfig) && sync_kconfig) { + fprintf(stderr, + "\n*** Error during sync of the configuration.\n\n"); + return 1; + } } return 0; } diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d587b10d7f8..91d0a5c014a 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -197,14 +197,18 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) case S_STRING: if (*p++ != '"') break; - /* Last char has to be a '"' */ - if (p[strlen(p) - 1] != '"') { + for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { + if (*p2 == '"') { + *p2 = 0; + break; + } + memmove(p2, p2 + 1, strlen(p2)); + } + if (!p2) { if (def != S_DEF_AUTO) conf_warning("invalid string found"); return 1; } - /* Overwrite '"' with \0 for string termination */ - p[strlen(p) - 1] = 0; /* fall through */ case S_INT: case S_HEX: @@ -663,7 +667,6 @@ static void conf_write_symbol(FILE *fp, struct symbol *sym, struct conf_printer *printer, void *printer_arg) { const char *str; - char *str2; switch (sym->type) { case S_OTHER: @@ -671,10 +674,9 @@ static void conf_write_symbol(FILE *fp, struct symbol *sym, break; case S_STRING: str = sym_get_string_value(sym); - str2 = xmalloc(strlen(str) + 3); - sprintf(str2, "\"%s\"", str); - printer->print_symbol(fp, sym, str2, printer_arg); - free((void *)str2); + str = sym_escape_string_value(str); + printer->print_symbol(fp, sym, str, printer_arg); + free((void *)str); break; default: str = sym_get_string_value(sym); @@ -1011,13 +1013,17 @@ out: return res; } -int conf_write_autoconf(void) +int conf_write_autoconf(int overwrite) { struct symbol *sym; const char *name; + const char *autoconf_name = conf_get_autoconfig_name(); FILE *out, *tristate, *out_h; int i; + if (!overwrite && is_present(autoconf_name)) + return 0; + sym_clear_all_valid(); conf_write_dep("include/config/auto.conf.cmd"); @@ -1080,14 +1086,13 @@ int conf_write_autoconf(void) if (rename(".tmpconfig_tristate", name)) return 1; - name = conf_get_autoconfig_name(); - if (make_parent_dir(name)) + if (make_parent_dir(autoconf_name)) return 1; /* * This must be the last step, kbuild has a dependency on auto.conf * and this marks the successful completion of the previous steps. */ - if (rename(".tmpconfig", name)) + if (rename(".tmpconfig", autoconf_name)) return 1; return 0; diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 9f79bdfaaa5..e1a39e90841 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -894,7 +894,7 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym) default: ; } - return false; + return false; } /* diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index aee993a778f..36f578415c4 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -360,8 +360,10 @@ void init_right_tree(void) gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); } + /* Utility Functions */ + static void text_insert_help(struct menu *menu) { GtkTextBuffer *buffer; @@ -386,6 +388,7 @@ static void text_insert_help(struct menu *menu) str_free(&help); } + static void text_insert_msg(const char *title, const char *message) { GtkTextBuffer *buffer; @@ -406,6 +409,7 @@ static void text_insert_msg(const char *title, const char *message) NULL); } + /* Main Windows Callbacks */ void on_save_activate(GtkMenuItem * menuitem, gpointer user_data); @@ -453,11 +457,13 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, return FALSE; } + void on_window1_destroy(GtkObject * object, gpointer user_data) { gtk_main_quit(); } + void on_window1_size_request(GtkWidget * widget, GtkRequisition * requisition, gpointer user_data) @@ -477,8 +483,10 @@ on_window1_size_request(GtkWidget * widget, gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3); } + /* Menu & Toolbar Callbacks */ + static void load_filename(GtkFileSelection * file_selector, gpointer user_data) { @@ -512,12 +520,15 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) gtk_widget_show(fs); } + void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) { if (conf_write(NULL)) text_insert_msg("Error", "Unable to save configuration !"); + conf_write_autoconf(0); } + static void store_filename(GtkFileSelection * file_selector, gpointer user_data) { @@ -551,12 +562,14 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) gtk_widget_show(fs); } + void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data) { if (!on_window1_delete_event(NULL, NULL, NULL)) gtk_widget_destroy(GTK_WIDGET(main_wnd)); } + void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkTreeViewColumn *col; @@ -567,6 +580,7 @@ void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data) gtk_tree_view_column_set_visible(col, show_name); } + void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkTreeViewColumn *col; @@ -584,6 +598,7 @@ void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data) } + void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkTreeViewColumn *col; @@ -594,6 +609,7 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) gtk_tree_view_column_set_visible(col, show_value); } + void on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data) { @@ -602,6 +618,7 @@ on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data) display_tree(&rootmenu); /* instead of update_tree to speed-up */ } + void on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data) { @@ -610,6 +627,7 @@ on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data) display_tree(&rootmenu); /* instead of update_tree to speed-up */ } + void on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) { @@ -618,10 +636,11 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) display_tree(&rootmenu); /* instead of update_tree to speed-up */ } + void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; - const gchar *intro_text = + const gchar *intro_text = "Welcome to gkc, the GTK+ graphical configuration tool\n" "For each option, a blank box indicates the feature is disabled, a\n" "check indicates it is enabled, and a dot indicates that it is to\n" @@ -648,6 +667,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) gtk_widget_show_all(dialog); } + void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; @@ -665,6 +685,7 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) gtk_widget_show_all(dialog); } + void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; @@ -683,6 +704,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) gtk_widget_show_all(dialog); } + void on_back_clicked(GtkButton * button, gpointer user_data) { enum prop_type ptype; @@ -697,11 +719,13 @@ void on_back_clicked(GtkButton * button, gpointer user_data) gtk_widget_set_sensitive(back_btn, FALSE); } + void on_load_clicked(GtkButton * button, gpointer user_data) { on_load1_activate(NULL, user_data); } + void on_single_clicked(GtkButton * button, gpointer user_data) { view_mode = SINGLE_VIEW; @@ -710,6 +734,7 @@ void on_single_clicked(GtkButton * button, gpointer user_data) display_tree_part(); } + void on_split_clicked(GtkButton * button, gpointer user_data) { gint w, h; @@ -725,6 +750,7 @@ void on_split_clicked(GtkButton * button, gpointer user_data) gtk_widget_set_sensitive(back_btn, FALSE); } + void on_full_clicked(GtkButton * button, gpointer user_data) { view_mode = FULL_VIEW; @@ -735,16 +761,19 @@ void on_full_clicked(GtkButton * button, gpointer user_data) gtk_widget_set_sensitive(back_btn, FALSE); } + void on_collapse_clicked(GtkButton * button, gpointer user_data) { gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); } + void on_expand_clicked(GtkButton * button, gpointer user_data) { gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); } + /* CTree Callbacks */ /* Change hex/int/string value in the cell */ @@ -846,6 +875,7 @@ static gint column2index(GtkTreeViewColumn * column) return -1; } + /* User click: update choice (full) or goes down (single) */ gboolean on_treeview2_button_press_event(GtkWidget * widget, @@ -947,6 +977,7 @@ on_treeview2_key_press_event(GtkWidget * widget, return FALSE; } + /* Row selection changed: update help */ void on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data) @@ -962,6 +993,7 @@ on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data) } } + /* User click: display sub-tree in the right frame. */ gboolean on_treeview1_button_press_event(GtkWidget * widget, @@ -1001,6 +1033,7 @@ on_treeview1_button_press_event(GtkWidget * widget, return FALSE; } + /* Fill a row of strings */ static gchar **fill_row(struct menu *menu) { @@ -1125,6 +1158,7 @@ static gchar **fill_row(struct menu *menu) return row; } + /* Set the node content with a row of strings */ static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row) { @@ -1160,6 +1194,7 @@ static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row) g_object_unref(pix); } + /* Add a node to the tree */ static void place_node(struct menu *menu, char **row) { @@ -1170,6 +1205,7 @@ static void place_node(struct menu *menu, char **row) set_node(node, menu, row); } + /* Find a node in the GTK+ tree */ static GtkTreeIter found; @@ -1205,6 +1241,7 @@ GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, return NULL; } + /* * Update the tree by adding/removing entries * Does not change other nodes @@ -1293,6 +1330,7 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) } } + /* Display the whole tree (single/split/full view) */ static void display_tree(struct menu *menu) { @@ -1402,6 +1440,7 @@ void fixup_rootmenu(struct menu *menu) } } + /* Main */ int main(int ac, char *av[]) { diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h index 9f1d16a43c2..45cb237ab7e 100644 --- a/scripts/kconfig/list.h +++ b/scripts/kconfig/list.h @@ -20,10 +20,12 @@ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) + struct list_head { struct list_head *next, *prev; }; + #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ @@ -46,7 +48,7 @@ struct list_head { */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 2daf47f57cc..9eb7c837cd8 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -131,6 +131,7 @@ static inline tristate sym_get_tristate_value(struct symbol *sym) return sym->curr.tri; } + static inline struct symbol *sym_get_choice_value(struct symbol *sym) { return (struct symbol *)sym->curr.val; diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index cf4510a2bdc..86c267540cc 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -7,7 +7,7 @@ int conf_read(const char *name); int conf_read_simple(const char *name, int); int conf_write_defconfig(const char *name); int conf_write(const char *name); -int conf_write_autoconf(void); +int conf_write_autoconf(int overwrite); bool conf_get_changed(void); void conf_set_changed_callback(void (*fn)(void)); void conf_set_message_callback(void (*fn)(const char *s)); diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index fd161cfff12..2e96323ad11 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0+ /* * checklist.c -- implements the checklist box * @@ -6,6 +5,20 @@ * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index 7675c4702ac..0b00be5abaa 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h @@ -1,8 +1,21 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ /* * dialog.h -- common declarations for all dialog modules * * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include @@ -213,6 +226,7 @@ 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, diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index 611945611bf..fe82ff6d744 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -1,9 +1,22 @@ -// SPDX-License-Identifier: GPL-2.0+ /* * inputbox.c -- implements the input box * * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 58c2f8afe59..d70cab36137 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -1,9 +1,22 @@ -// SPDX-License-Identifier: GPL-2.0+ /* * menubox.c -- implements the menu box * * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 12e68c0fb64..88d2818ed95 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -1,9 +1,22 @@ -// SPDX-License-Identifier: GPL-2.0+ /* * textbox.c -- implements the text box * * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" @@ -33,6 +46,7 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, wrefresh(dialog); } + /* * Display text from a file in a dialog box. * diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index 1b490d4af0d..f7abdeb92af 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c @@ -1,9 +1,22 @@ -// SPDX-License-Identifier: GPL-2.0+ /* * util.c * * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c index bcaac9b7bab..cd1223c903d 100644 --- a/scripts/kconfig/lxdialog/yesno.c +++ b/scripts/kconfig/lxdialog/yesno.c @@ -1,9 +1,22 @@ -// SPDX-License-Identifier: GPL-2.0+ /* * yesno.c -- implements the yes/no box * * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index c1b38747c14..143c05fec16 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -973,6 +973,7 @@ static int handle_exit(void) "\n\n"); return 1; } + conf_write_autoconf(0); /* fall through */ case -1: if (!silent) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 0fe7f3255af..4cf15d449c0 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -853,6 +853,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) return res; } + void menu_get_ext_help(struct menu *menu, struct gstr *help) { struct symbol *sym = menu->sym; diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 0ef90649964..67d13144763 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -33,15 +33,12 @@ usage() { echo " -n use allnoconfig instead of alldefconfig" echo " -r list redundant entries when merging fragments" echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead." - echo - echo "Used prefix: '$CONFIG_PREFIX'. You can redefine it with \$CONFIG_ environment variable." } RUNMAKE=true ALLTARGET=alldefconfig WARNREDUN=false OUTPUT=. -CONFIG_PREFIX=${CONFIG_-CONFIG_} while true; do case $1 in @@ -102,9 +99,7 @@ if [ ! -r "$INITFILE" ]; then fi MERGE_LIST=$* -SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p" -SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p" - +SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) echo "Using $INITFILE as base" @@ -117,7 +112,7 @@ for MERGE_FILE in $MERGE_LIST ; do echo "The merge file '$MERGE_FILE' does not exist. Exit." >&2 exit 1 fi - CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE) + CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) for CFG in $CFG_LIST ; do grep -q -w $CFG $TMP_FILE || continue @@ -160,7 +155,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET # Check all specified config values took (might have missed-dependency issues) -for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do +for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG") diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index ca878212f0a..1ef232ae5ab 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -674,6 +674,7 @@ static int do_exit(void) "Your configuration changes were NOT saved.", 1, ""); + conf_write_autoconf(0); break; default: btn_dialog( @@ -687,6 +688,7 @@ static int do_exit(void) return 0; } + static void search_conf(void) { struct symbol **sym_arr; @@ -730,6 +732,7 @@ again: str_free(&title); } + static void build_conf(struct menu *menu) { struct symbol *sym; diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 2a3b853e7ea..88874acfda3 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -143,6 +143,7 @@ void set_colors(void) } } + /* this changes the windows attributes !!! */ void print_in_middle(WINDOW *win, int starty, @@ -153,6 +154,7 @@ void print_in_middle(WINDOW *win, { int length, x, y; float temp; + if (win == NULL) win = stdscr; getyx(win, y, x); @@ -254,6 +256,7 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) int i, x, y; int res = -1; + va_start(ap, btn_num); for (i = 0; i < btn_num; i++) { btn = va_arg(ap, char *); @@ -277,6 +280,7 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) y = (getmaxy(stdscr)-(msg_lines+4))/2; x = (getmaxx(stdscr)-(total_width+4))/2; + /* create the windows */ if (btn_num > 0) win_rows = msg_lines+4; @@ -311,6 +315,7 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) set_menu_mark(menu, ""); post_menu(menu); + touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(win))) { diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 0c3fa940568..ef4310f2558 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1534,6 +1534,8 @@ bool ConfigMainWindow::saveConfig(void) QMessageBox::information(this, "qconf", "Unable to save configuration!"); return false; } + conf_write_autoconf(0); + return true; } diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 5245804bb33..703b9b899ee 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -1117,7 +1117,7 @@ static void sym_check_print_recursive(struct symbol *last_sym) } fprintf(stderr, - "For a resolution refer to Documentation/kbuild/kconfig-language.rst\n" + "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n" "subsection \"Kconfig recursive dependency limitations\"\n" "\n"); diff --git a/scripts/kconfig/tests/err_recursive_dep/expected_stderr b/scripts/kconfig/tests/err_recursive_dep/expected_stderr index c9f4abf9a79..84679b10465 100644 --- a/scripts/kconfig/tests/err_recursive_dep/expected_stderr +++ b/scripts/kconfig/tests/err_recursive_dep/expected_stderr @@ -1,38 +1,38 @@ Kconfig:11:error: recursive dependency detected! Kconfig:11: symbol B is selected by B -For a resolution refer to Documentation/kbuild/kconfig-language.rst +For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" Kconfig:5:error: recursive dependency detected! Kconfig:5: symbol A depends on A -For a resolution refer to Documentation/kbuild/kconfig-language.rst +For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" Kconfig:17:error: recursive dependency detected! Kconfig:17: symbol C1 depends on C2 Kconfig:21: symbol C2 depends on C1 -For a resolution refer to Documentation/kbuild/kconfig-language.rst +For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" Kconfig:32:error: recursive dependency detected! Kconfig:32: symbol D2 is selected by D1 Kconfig:27: symbol D1 depends on D2 -For a resolution refer to Documentation/kbuild/kconfig-language.rst +For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" Kconfig:37:error: recursive dependency detected! Kconfig:37: symbol E1 depends on E2 Kconfig:42: symbol E2 is implied by E1 -For a resolution refer to Documentation/kbuild/kconfig-language.rst +For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" Kconfig:60:error: recursive dependency detected! Kconfig:60: symbol G depends on G -For a resolution refer to Documentation/kbuild/kconfig-language.rst +For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" Kconfig:51:error: recursive dependency detected! Kconfig:51: symbol F2 depends on F1 Kconfig:49: symbol F1 default value contains F2 -For a resolution refer to Documentation/kbuild/kconfig-language.rst +For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" diff --git a/scripts/kconfig/tests/preprocess/builtin_func/Kconfig b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig new file mode 100644 index 00000000000..baa32882791 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 + +# 'info' prints the argument to stdout. +$(info,hello world 0) + +# 'warning-if', if the first argument is y, sends the second argument to stderr, +# and the message is prefixed with the current file name and line number. +$(warning-if,y,hello world 1) + +# 'error-if' is similar, but it terminates the parsing immediately. +# The following is just no-op since the first argument is not y. +$(error-if,n,this should not be printed) + +# Shorthand +warning = $(warning-if,y,$(1)) + +# 'shell' executes a command, and returns its stdout. +$(warning,$(shell,echo hello world 3)) + +# Every newline in the output is replaced with a space, +# but any trailing newlines are deleted. +$(warning,$(shell,printf 'hello\nworld\n\n4\n\n\n')) + +# 'filename' is expanded to the currently parsed file name, +# 'lineno' to the line number. +$(warning,filename=$(filename)) +$(warning,lineno=$(lineno)) diff --git a/scripts/kconfig/tests/preprocess/builtin_func/__init__.py b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py new file mode 100644 index 00000000000..2e53ba08fca --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Built-in function tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stdout_contains('expected_stdout') + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr new file mode 100644 index 00000000000..33ea9ca3840 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr @@ -0,0 +1,5 @@ +Kconfig:8: hello world 1 +Kconfig:18: hello world 3 +Kconfig:22: hello world 4 +Kconfig:26: filename=Kconfig +Kconfig:27: lineno=27 diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout new file mode 100644 index 00000000000..82de3a7e97d --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout @@ -0,0 +1 @@ +hello world 0 diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig new file mode 100644 index 00000000000..6838997c23b --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +X = $(Y) +Y = $(X) +$(info $(X)) diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py new file mode 100644 index 00000000000..419bda3e075 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Detect circular variable expansion. + +If a recursively expanded variable references itself (eventually), +it should fail with an error message. +""" + +def test(conf): + assert conf.oldaskconfig() != 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr new file mode 100644 index 00000000000..cde68fa989d --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr @@ -0,0 +1 @@ +Kconfig:5: Recursive variable 'X' references itself (eventually) diff --git a/scripts/kconfig/tests/preprocess/escape/Kconfig b/scripts/kconfig/tests/preprocess/escape/Kconfig new file mode 100644 index 00000000000..4e3f4444554 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/Kconfig @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# You can not pass commas directly to a function since they are treated as +# delimiters. You can use the following trick to do so. +comma := , +$(warning,hello$(comma) world) + +# Like Make, single quotes, double quotes, spaces are treated verbatim. +# The following prints the text as-is. +$(warning, ' " '" ' ''' "'") + +# Unlike Make, '$' has special meaning only when it is followed by '('. +# No need to escape '$' itself. +$(warning,$) +$(warning,$$) +$ := 1 +$(warning,$($)) + +# You need a trick to escape '$' followed by '(' +# The following should print "$(X)". It should not be expanded further. +dollar := $ +$(warning,$(dollar)(X)) + +# You need a trick to treat unbalanced parentheses. +# The following should print "(". +left_paren := ( +$(warning,$(left_paren)) + +# A simple expanded should not be expanded multiple times. +# The following should print "$(X)". It should not be expanded further. +Y := $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(X)" as well. +Y = $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(". +# It should not be emit "unterminated reference" error. +unterminated := $(dollar)( +$(warning,$(unterminated)) diff --git a/scripts/kconfig/tests/preprocess/escape/__init__.py b/scripts/kconfig/tests/preprocess/escape/__init__.py new file mode 100644 index 00000000000..7ee8e747f54 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Escape sequence tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/escape/expected_stderr b/scripts/kconfig/tests/preprocess/escape/expected_stderr new file mode 100644 index 00000000000..1c00957ddaa --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/expected_stderr @@ -0,0 +1,10 @@ +Kconfig:9: hello, world +Kconfig:13: ' " '" ' ''' "'" +Kconfig:17: $ +Kconfig:18: $$ +Kconfig:20: 1 +Kconfig:25: $(X) +Kconfig:30: ( +Kconfig:35: $(X) +Kconfig:39: $(X) +Kconfig:44: $( diff --git a/scripts/kconfig/tests/preprocess/variable/Kconfig b/scripts/kconfig/tests/preprocess/variable/Kconfig new file mode 100644 index 00000000000..9ce2f95cbd2 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/Kconfig @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# Simply expanded variable. +X := 1 +SIMPLE := $(X) +X := 2 +$(warning,SIMPLE = $(SIMPLE)) + +# Recursively expanded variable. +X := 1 +RECURSIVE = $(X) +X := 2 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Append something to a simply expanded variable. +Y := 3 +SIMPLE += $(Y) +Y := 4 +$(warning,SIMPLE = $(SIMPLE)) + +# Append something to a recursively expanded variable. +Y := 3 +RECURSIVE += $(Y) +Y := 4 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Use += operator to an undefined variable. +# This works as a recursively expanded variable. +Y := 3 +UNDEFINED_VARIABLE += $(Y) +Y := 4 +$(warning,UNDEFINED_VARIABLE = $(UNDEFINED_VARIABLE)) + +# You can use variable references for the lefthand side of assignment statement. +X := A +Y := B +$(X)$(Y) := 5 +$(warning,AB = $(AB)) + +# User-defined function. +greeting = $(1), my name is $(2). +$(warning,$(greeting,Hello,John)) + +# The number of arguments is not checked for user-defined functions. +# If some arguments are optional, it is useful to pass fewer parameters. +# $(2) will be blank in this case. +$(warning,$(greeting,Hello)) + +# Unreferenced parameters are just ignored. +$(warning,$(greeting,Hello,John,ignored,ignored)) diff --git a/scripts/kconfig/tests/preprocess/variable/__init__.py b/scripts/kconfig/tests/preprocess/variable/__init__.py new file mode 100644 index 00000000000..e88b1708d6d --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Variable and user-defined function tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/variable/expected_stderr b/scripts/kconfig/tests/preprocess/variable/expected_stderr new file mode 100644 index 00000000000..a4841c3fdff --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/expected_stderr @@ -0,0 +1,9 @@ +Kconfig:10: SIMPLE = 1 +Kconfig:16: RECURSIVE = 2 +Kconfig:22: SIMPLE = 1 3 +Kconfig:28: RECURSIVE = 2 4 +Kconfig:35: UNDEFINED_VARIABLE = 4 +Kconfig:41: AB = 5 +Kconfig:45: Hello, my name is John. +Kconfig:50: Hello, my name is . +Kconfig:53: Hello, my name is John.