From bbc4db133746d49893c3c9b70ef710747df27441 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Wed, 9 Dec 2020 21:24:45 +1300 Subject: kconfig: Sync with upstream v4.18 This commit introduces the following upstream changes: 73d1c580f92b kconfig: loop boundary condition fix ecd53ac2f2c6 kconfig: handle P_SYMBOL in print_symbol() b2d00d7c61c8 kconfig: fix line numbers for if-entries in menu tree 8593080c0fcf kconfig: fix localmodconfig 2ae89c7a82ea kconfig: Avoid format overflow warning from GCC 8.1 bb6d83dde191 kbuild: Move last word of nconfig help to the previous line d6a0c8a1326b kconfig: Add testconfig into make help output 2bece88f89fa kconfig: test: add Kconfig macro language tests 915f64901eb3 kconfig: error out if a recursive variable references itself a702a6176e2f kconfig: add 'filename' and 'lineno' built-in variables 1d6272e6fe43 kconfig: add 'info', 'warning-if', and 'error-if' built-in functions 82bc8bd82e5c kconfig: expand lefthand side of assignment statement ed2a22f277c6 kconfig: support append assignment operator 1175c02506ff kconfig: support simply expanded variable 9ced3bddec08 kconfig: support user-defined function and recursively expanded variable 9de071536c87 kconfig: begin PARAM state only when seeing a command keyword 2fd5b09c201e kconfig: add 'shell' built-in function e298f3b49def kconfig: add built-in function support 137c0118a900 kconfig: make default prompt of mainmenu less specific 5b31a9746756 kconfig: remove sym_expand_string_value() 96d8e48da55a kconfig: remove string expansion for mainmenu after yyparse() bb222ceeb327 kconfig: remove string expansion in file_lookup() 104daea149c4 kconfig: reference environment variables directly and remove 'option env=' 694c49a7c01c kconfig: drop localization support 1c5af5cf9308 kconfig: refactor ncurses package checks for building mconf and nconf b464ef583dc7 kconfig: refactor GTK+ package checks for building gconf 0b669a5076fd kconfig: refactor Qt package checks for building qconf Signed-off-by: Chris Packham --- kconfig/nconf.c | 148 +++++++++++++++++++++++++++----------------------------- 1 file changed, 72 insertions(+), 76 deletions(-) (limited to 'kconfig/nconf.c') diff --git a/kconfig/nconf.c b/kconfig/nconf.c index be761201..4875f5e3 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -15,7 +15,7 @@ #include "nconf.h" #include -static const char nconf_global_help[] = N_( +static const char nconf_global_help[] = "Help windows\n" "------------\n" "o Global help: Unless in a data entry window, pressing will give \n" @@ -133,8 +133,8 @@ static const char nconf_global_help[] = N_( "\n" "Note that this mode can eventually be a little more CPU expensive than\n" "the default mode, especially with a larger number of unfolded submenus.\n" -"\n"), -menu_no_f_instructions[] = N_( +"\n", +menu_no_f_instructions[] = "Legend: [*] built-in [ ] excluded automatic < > automatic capable.\n" "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" "\n" @@ -150,8 +150,8 @@ menu_no_f_instructions[] = N_( "You do not have function keys support.\n" "Press <1> instead of , <2> instead of , etc.\n" "For verbose global help use key <1>.\n" -"For help related to the current menu entry press or .\n"), -menu_instructions[] = N_( +"For help related to the current menu entry press or .\n", +menu_instructions[] = "Legend: [*] built-in [ ] excluded automatic < > automatic capable.\n" "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" "\n" @@ -166,30 +166,30 @@ menu_instructions[] = N_( "\n" "Pressing <1> may be used instead of , <2> instead of , etc.\n" "For verbose global help press .\n" -"For help related to the current menu entry press or .\n"), -radiolist_instructions[] = N_( +"For help related to the current menu entry press or .\n", +radiolist_instructions[] = "Press , , or to navigate a radiolist, select\n" "with .\n" "For help related to the current entry press or .\n" -"For global help press .\n"), -inputbox_instructions_int[] = N_( +"For global help press .\n", +inputbox_instructions_int[] = "Please enter a decimal value.\n" "Fractions will not be accepted.\n" -"Press to apply, to cancel."), -inputbox_instructions_hex[] = N_( +"Press to apply, to cancel.", +inputbox_instructions_hex[] = "Please enter a hexadecimal value.\n" -"Press to apply, to cancel."), -inputbox_instructions_string[] = N_( +"Press to apply, to cancel.", +inputbox_instructions_string[] = "Please enter a string value.\n" -"Press to apply, to cancel."), -setmod_text[] = N_( +"Press to apply, to cancel.", +setmod_text[] = "This feature depends on another feature which has been configured as\n" -"automatic. As a result, the current feature will be built as automatic too."), -load_config_text[] = N_( +"automatic. As a result, the current feature will be built as automatic too.", +load_config_text[] = "Enter the name of the configuration file you wish to load.\n" "Accept the name shown to restore the configuration you last\n" -"retrieved. Leave empty to abort."), -load_config_help[] = N_( +"retrieved. Leave empty to abort.", +load_config_help[] = "For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" "\n" @@ -197,11 +197,11 @@ load_config_help[] = N_( "default one, entering its name here will allow you to load and modify\n" "that configuration.\n" "\n" -"Leave empty to abort.\n"), -save_config_text[] = N_( +"Leave empty to abort.\n", +save_config_text[] = "Enter a filename to which this configuration should be saved\n" -"as an alternate. Leave empty to abort."), -save_config_help[] = N_( +"as an alternate. Leave empty to abort.", +save_config_help[] = "For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" "\n" @@ -209,8 +209,8 @@ save_config_help[] = N_( "and use the current configuration as an alternate to whatever\n" "configuration options you have selected at that time.\n" "\n" -"Leave empty to abort.\n"), -search_help[] = N_( +"Leave empty to abort.\n", +search_help[] = "Search for symbols (configuration variable names CONFIG_*) and display\n" "their relations. Regular expressions are supported.\n" "Example: Search for \"^FOO\".\n" @@ -247,7 +247,7 @@ search_help[] = N_( "USB => find all symbols containing USB\n" "^USB => find all symbols starting with USB\n" "USB$ => find all symbols ending with USB\n" -"\n"); +"\n"; struct mitem { char str[256]; @@ -391,7 +391,7 @@ static void print_function_line(void) static void handle_f1(int *key, struct menu *current_item) { show_scroll_win(main_window, - _("Global help"), _(nconf_global_help)); + "Global help", nconf_global_help); return; } @@ -406,8 +406,8 @@ static void handle_f2(int *key, struct menu *current_item) static void handle_f3(int *key, struct menu *current_item) { show_scroll_win(main_window, - _("Short help"), - _(current_instructions)); + "Short help", + current_instructions); return; } @@ -415,7 +415,7 @@ static void handle_f3(int *key, struct menu *current_item) static void handle_f4(int *key, struct menu *current_item) { int res = btn_dialog(main_window, - _("Show all symbols?"), + "Show all symbols?", 2, " ", ""); @@ -656,8 +656,8 @@ static int do_exit(void) return 0; } res = btn_dialog(main_window, - _("Do you wish to save your new configuration?\n" - " to cancel and resume nconfig."), + "Do you wish to save your new configuration?\n" + " to cancel and resume nconfig.", 2, " ", ""); @@ -673,15 +673,15 @@ static int do_exit(void) if (res) btn_dialog( main_window, - _("Error during writing of configuration.\n" - "Your configuration changes were NOT saved."), + "Error during writing of configuration.\n" + "Your configuration changes were NOT saved.", 1, ""); break; default: btn_dialog( main_window, - _("Your configuration changes were NOT saved."), + "Your configuration changes were NOT saved.", 1, ""); break; @@ -700,12 +700,12 @@ static void search_conf(void) int dres; title = str_new(); - str_printf( &title, _("Enter (sub)string or regexp to search for " - "(with or without \"%s\")"), CONFIG_); + str_printf( &title, "Enter (sub)string or regexp to search for " + "(with or without \"%s\")", CONFIG_); again: dres = dialog_inputbox(main_window, - _("Search Configuration Parameter"), + "Search Configuration Parameter", str_get(&title), "", &dialog_input_result, &dialog_input_result_len); switch (dres) { @@ -713,7 +713,7 @@ again: break; case 1: show_scroll_win(main_window, - _("Search Configuration"), search_help); + "Search Configuration", search_help); goto again; default: str_free(&title); @@ -729,7 +729,7 @@ again: res = get_relations_str(sym_arr, NULL); free(sym_arr); show_scroll_win(main_window, - _("Search Results"), str_get(&res)); + "Search Results", str_get(&res)); str_free(&res); str_free(&title); } @@ -757,7 +757,7 @@ static void build_conf(struct menu *menu) switch (ptype) { case P_MENU: child_count++; - prompt = _(prompt); + prompt = prompt; if (single_menu_mode) { item_make(menu, 'm', "%s%*c%s", @@ -778,7 +778,7 @@ static void build_conf(struct menu *menu) item_make(menu, ':', " %*c*** %s ***", indent + 1, ' ', - _(prompt)); + prompt); } break; default: @@ -786,7 +786,7 @@ static void build_conf(struct menu *menu) child_count++; item_make(menu, ':', "---%*c%s", indent + 1, ' ', - _(prompt)); + prompt); } } } else @@ -832,11 +832,11 @@ static void build_conf(struct menu *menu) } item_add_str("%*c%s", indent + 1, - ' ', _(menu_get_prompt(menu))); + ' ', menu_get_prompt(menu)); if (val == yes) { if (def_menu) { item_add_str(" (%s)", - _(menu_get_prompt(def_menu))); + menu_get_prompt(def_menu)); item_add_str(" --->"); if (def_menu->list) { indent += 2; @@ -850,7 +850,7 @@ static void build_conf(struct menu *menu) if (menu == current_menu) { item_make(menu, ':', "---%*c%s", indent + 1, - ' ', _(menu_get_prompt(menu))); + ' ', menu_get_prompt(menu)); goto conf_childs; } child_count++; @@ -897,17 +897,17 @@ static void build_conf(struct menu *menu) if (tmp < 0) tmp = 0; item_add_str("%*c%s%s", tmp, ' ', - _(menu_get_prompt(menu)), + menu_get_prompt(menu), (sym_has_value(sym) || !sym_is_changable(sym)) ? "" : - _(" (NEW)")); + " (NEW)"); goto conf_childs; } } item_add_str("%*c%s%s", indent + 1, ' ', - _(menu_get_prompt(menu)), + menu_get_prompt(menu), (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : _(" (NEW)")); + "" : " (NEW)"); if (menu->prompt && menu->prompt->type == P_MENU) { item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); return; @@ -1089,8 +1089,8 @@ static void conf(struct menu *menu) if (!child_count) break; - show_menu(prompt ? _(prompt) : _("Main Menu"), - _(menu_instructions), + show_menu(prompt ? prompt : "Main Menu", + menu_instructions, current_index, &last_top_row); keypad((menu_win(curses_menu)), TRUE); while (!global_exit) { @@ -1230,13 +1230,13 @@ static void show_help(struct menu *menu) help = str_new(); menu_get_ext_help(menu, &help); - show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); + show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help)); str_free(&help); } static void conf_choice(struct menu *menu) { - const char *prompt = _(menu_get_prompt(menu)); + const char *prompt = menu_get_prompt(menu); struct menu *child = NULL; struct symbol *active; int selected_index = 0; @@ -1259,13 +1259,13 @@ static void conf_choice(struct menu *menu) if (child->sym == sym_get_choice_value(menu->sym)) item_make(child, ':', " %s", - _(menu_get_prompt(child))); + menu_get_prompt(child)); else if (child->sym) item_make(child, ':', " %s", - _(menu_get_prompt(child))); + menu_get_prompt(child)); else item_make(child, ':', "*** %s ***", - _(menu_get_prompt(child))); + menu_get_prompt(child)); if (child->sym == active){ last_top_row = top_row(curses_menu); @@ -1273,8 +1273,8 @@ static void conf_choice(struct menu *menu) } i++; } - show_menu(prompt ? _(prompt) : _("Choice Menu"), - _(radiolist_instructions), + show_menu(prompt ? prompt : "Choice Menu", + radiolist_instructions, selected_index, &last_top_row); while (!global_exit) { @@ -1361,19 +1361,19 @@ static void conf_string(struct menu *menu) switch (sym_get_type(menu->sym)) { case S_INT: - heading = _(inputbox_instructions_int); + heading = inputbox_instructions_int; break; case S_HEX: - heading = _(inputbox_instructions_hex); + heading = inputbox_instructions_hex; break; case S_STRING: - heading = _(inputbox_instructions_string); + heading = inputbox_instructions_string; break; default: - heading = _("Internal nconf error!"); + heading = "Internal nconf error!"; } res = dialog_inputbox(main_window, - prompt ? _(prompt) : _("Main Menu"), + prompt ? prompt : "Main Menu", heading, sym_get_string_value(menu->sym), &dialog_input_result, @@ -1384,7 +1384,7 @@ static void conf_string(struct menu *menu) dialog_input_result)) return; btn_dialog(main_window, - _("You have made an invalid entry."), 0); + "You have made an invalid entry.", 0); break; case 1: show_help(menu); @@ -1413,11 +1413,11 @@ static void conf_load(void) sym_set_change_count(1); return; } - btn_dialog(main_window, _("File does not exist!"), 0); + btn_dialog(main_window, "File does not exist!", 0); break; case 1: show_scroll_win(main_window, - _("Load Alternate Configuration"), + "Load Alternate Configuration", load_config_help); break; case KEY_EXIT: @@ -1444,13 +1444,13 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - btn_dialog(main_window, _("Can't create file! " - "Probably a nonexistent directory."), + btn_dialog(main_window, "Can't create file! " + "Probably a nonexistent directory.", 1, ""); break; case 1: show_scroll_win(main_window, - _("Save Alternate Configuration"), + "Save Alternate Configuration", save_config_help); break; case KEY_EXIT: @@ -1483,10 +1483,6 @@ int main(int ac, char **av) int lines, columns; char *mode; - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - if (ac > 1 && strcmp(av[1], "-s") == 0) { /* Silence conf_read() until the real callback is set up */ conf_set_message_callback(NULL); @@ -1544,8 +1540,8 @@ int main(int ac, char **av) /* check for KEY_FUNC(1) */ if (has_key(KEY_F(1)) == FALSE) { show_scroll_win(main_window, - _("Instructions"), - _(menu_no_f_instructions)); + "Instructions", + menu_no_f_instructions); } conf_set_message_callback(conf_message_callback); -- cgit v1.2.3 From df94f6803fe17fd1030ef08ff0463e437b9323b9 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Wed, 9 Dec 2020 21:53:59 +1300 Subject: kconfig: Sync with upstream v4.19 This commit introduces the following upstream changes: fd65465b7016 kconfig: do not require pkg-config on make {menu,n}config bc8d2e20a3eb kconfig: remove a spurious self-assignment 9a9ddcf47831 kconfig: suppress "configuration written to .config" for syncconfig 98a4afbfafd2 kconfig: fix "Can't open ..." in parallel build f498926c47aa kconfig: improve the recursive dependency report 5e8c5299d315 kconfig: report recursive dependency involving 'imply' f1575595d156 kconfig: error out when seeing recursive dependency 4bf6a9af0e91 kconfig: add build-only configurator targets 1880861226c1 kconfig: remove P_ENV property type c151272d1687 kconfig: remove unused sym_get_env_prop() function 56869d45e364 kconfig: fix the rule of mainmenu_stmt symbol 00c864f8903d kconfig: allow all config targets to write auto.conf if missing 16952b77d8b5 kconfig: make syncconfig update .config regardless of sym_change_count 79123b1389cc kconfig: create directories needed for syncconfig by itself adc18acf42a1 kconfig: remove unneeded directory generation from local*config 0608182ad542 kconfig: split out useful helpers in confdata.c a2ff4040151a kconfig: rename file_write_dep and move it to confdata.c 5accd7f3360e kconfig: handle format string before calling conf_message_callback() 693359f7ac90 kconfig: rename SYMBOL_AUTO to SYMBOL_NO_WRITE 4ab3b80159d4 kconfig: check for pkg-config on make {menu,n,g,x}config 8377bd2b9ee1 kbuild: Rename HOST_LOADLIBES to KBUILD_HOSTLDLIBS Signed-off-by: Chris Packham --- kconfig/conf.c | 46 ++++++++++------ kconfig/confdata.c | 156 ++++++++++++++++++++++++++++++++++++++++++---------- kconfig/expr.h | 3 +- kconfig/lkc.h | 2 - kconfig/lkc_proto.h | 4 +- kconfig/mconf.c | 11 ++-- kconfig/menu.c | 2 +- kconfig/nconf.c | 8 +-- kconfig/symbol.c | 71 ++++++++++++++---------- kconfig/util.c | 30 ---------- kconfig/zconf.y | 6 +- 11 files changed, 210 insertions(+), 129 deletions(-) (limited to 'kconfig/nconf.c') diff --git a/kconfig/conf.c b/kconfig/conf.c index abd5238b..a0db354f 100644 --- a/kconfig/conf.c +++ b/kconfig/conf.c @@ -475,6 +475,7 @@ int main(int ac, char **av) int opt; const char *name, *defconfig_file = NULL /* gcc uninit */; struct stat tmpstat; + int no_conf_write = 0; tty_stdio = isatty(0) && isatty(1); @@ -486,6 +487,11 @@ int main(int ac, char **av) input_mode = (enum input_mode)opt; switch (opt) { case syncconfig: + /* + * syncconfig is invoked during the build stage. + * Suppress distracting "configuration written to ..." + */ + conf_set_message_callback(NULL); sync_kconfig = 1; break; case defconfig: @@ -612,13 +618,14 @@ int main(int ac, char **av) } if (sync_kconfig) { - if (conf_get_changed()) { - name = getenv("KCONFIG_NOSILENTUPDATE"); - if (name && *name) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + if (conf_get_changed()) { fprintf(stderr, "\n*** The configuration requires explicit update.\n\n"); return 1; } + no_conf_write = 1; } } @@ -663,30 +670,33 @@ 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 (conf_get_changed() && conf_write(NULL)) { - fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); - exit(1); - } - /* In crosstool-NG, we do not use the autoconf stuff - 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. + */ + /* In crosstool-NG, we do not use the autoconf stuff + 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/kconfig/confdata.c b/kconfig/confdata.c index 39e20974..91d0a5c0 100644 --- a/kconfig/confdata.c +++ b/kconfig/confdata.c @@ -16,6 +16,64 @@ #include "lkc.h" +/* return true if 'path' exists, false otherwise */ +static bool is_present(const char *path) +{ + struct stat st; + + return !stat(path, &st); +} + +/* return true if 'path' exists and it is a directory, false otherwise */ +static bool is_dir(const char *path) +{ + struct stat st; + + if (stat(path, &st)) + return 0; + + return S_ISDIR(st.st_mode); +} + +/* + * Create the parent directory of the given path. + * + * For example, if 'include/config/auto.conf' is given, create 'include/config'. + */ +static int make_parent_dir(const char *path) +{ + char tmp[PATH_MAX + 1]; + char *p; + + strncpy(tmp, path, sizeof(tmp)); + tmp[sizeof(tmp) - 1] = 0; + + /* Remove the base name. Just return if nothing is left */ + p = strrchr(tmp, '/'); + if (!p) + return 0; + *(p + 1) = 0; + + /* Just in case it is an absolute path */ + p = tmp; + while (*p == '/') + p++; + + while ((p = strchr(p, '/'))) { + *p = 0; + + /* skip if the directory exists */ + if (!is_dir(tmp) && mkdir(tmp, 0755)) + return -1; + + *p = '/'; + while (*p == '/') + p++; + } + + return 0; +} + struct conf_printer { void (*print_symbol)(FILE *, struct symbol *, const char *, void *); void (*print_comment)(FILE *, const char *, void *); @@ -43,16 +101,16 @@ static void conf_warning(const char *fmt, ...) conf_warnings++; } -static void conf_default_message_callback(const char *fmt, va_list ap) +static void conf_default_message_callback(const char *s) { printf("#\n# "); - vprintf(fmt, ap); + printf("%s", s); printf("\n#\n"); } -static void (*conf_message_callback) (const char *fmt, va_list ap) = +static void (*conf_message_callback)(const char *s) = conf_default_message_callback; -void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) +void conf_set_message_callback(void (*fn)(const char *s)) { conf_message_callback = fn; } @@ -60,10 +118,15 @@ void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) static void conf_message(const char *fmt, ...) { va_list ap; + char buf[4096]; + + if (!conf_message_callback) + return; va_start(ap, fmt); - if (conf_message_callback) - conf_message_callback(fmt, ap); + + vsnprintf(buf, sizeof(buf), fmt, ap); + conf_message_callback(buf); va_end(ap); } @@ -83,7 +146,6 @@ const char *conf_get_autoconfig_name(void) char *conf_get_default_confname(void) { - struct stat buf; static char fullname[PATH_MAX+1]; char *env, *name; @@ -91,7 +153,7 @@ char *conf_get_default_confname(void) env = getenv(SRCTREE); if (env) { sprintf(fullname, "%s/%s", env, name); - if (!stat(fullname, &buf)) + if (is_present(fullname)) return fullname; } return name; @@ -397,7 +459,7 @@ int conf_read(const char *name) for_all_symbols(i, sym) { sym_calc_value(sym); - if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) + if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) continue; if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { /* check that calculated value agrees with saved value */ @@ -725,10 +787,9 @@ int conf_write(const char *name) dirname[0] = 0; if (name && name[0]) { - struct stat st; char *slash; - if (!stat(name, &st) && S_ISDIR(st.st_mode)) { + if (is_dir(name)) { strcpy(dirname, name); strcat(dirname, "/"); basename = conf_get_configname(); @@ -813,26 +874,59 @@ next: return 0; } +/* write a dependency file as used by kbuild to track dependencies */ +static int conf_write_dep(const char *name) +{ + struct file *file; + FILE *out; + + if (!name) + name = ".kconfig.d"; + out = fopen("..config.tmp", "w"); + if (!out) + return 1; + fprintf(out, "deps_config := \\\n"); + for (file = file_list; file; file = file->next) { + if (file->next) + fprintf(out, "\t%s \\\n", file->name); + else + fprintf(out, "\t%s\n", file->name); + } + fprintf(out, "\n%s: \\\n" + "\t$(deps_config)\n\n", conf_get_autoconfig_name()); + + env_write_dep(out, conf_get_autoconfig_name()); + + fprintf(out, "\n$(deps_config): ;\n"); + fclose(out); + + if (make_parent_dir(name)) + return 1; + rename("..config.tmp", name); + return 0; +} + static int conf_split_config(void) { const char *name; char path[PATH_MAX+1]; char *s, *d, c; struct symbol *sym; - struct stat sb; int res, i, fd; name = conf_get_autoconfig_name(); conf_read_simple(name, S_DEF_AUTO); sym_calc_value(modules_sym); + if (make_parent_dir("include/config/foo.h")) + return 1; if (chdir("include/config")) return 1; res = 0; for_all_symbols(i, sym) { sym_calc_value(sym); - if ((sym->flags & SYMBOL_AUTO) || !sym->name) + if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) continue; if (sym->flags & SYMBOL_WRITE) { if (sym->flags & SYMBOL_DEF_AUTO) { @@ -897,19 +991,12 @@ static int conf_split_config(void) res = 1; break; } - /* - * Create directory components, - * unless they exist already. - */ - d = path; - while ((d = strchr(d, '/'))) { - *d = 0; - if (stat(path, &sb) && mkdir(path, 0755)) { - res = 1; - goto out; - } - *d++ = '/'; + + if (make_parent_dir(path)) { + res = 1; + goto out; } + /* Try it again. */ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { @@ -926,16 +1013,20 @@ 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(); - file_write_dep("include/config/auto.conf.cmd"); + conf_write_dep("include/config/auto.conf.cmd"); if (conf_split_config()) return 1; @@ -982,19 +1073,26 @@ int conf_write_autoconf(void) name = getenv("KCONFIG_AUTOHEADER"); if (!name) name = "include/generated/autoconf.h"; + if (make_parent_dir(name)) + return 1; if (rename(".tmpconfig.h", name)) return 1; + name = getenv("KCONFIG_TRISTATE"); if (!name) name = "include/config/tristate.conf"; + if (make_parent_dir(name)) + return 1; if (rename(".tmpconfig_tristate", name)) return 1; - name = conf_get_autoconfig_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/kconfig/expr.h b/kconfig/expr.h index f63b41b0..7c329e17 100644 --- a/kconfig/expr.h +++ b/kconfig/expr.h @@ -141,7 +141,7 @@ struct symbol { #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_CHANGED 0x0400 /* ? */ -#define SYMBOL_AUTO 0x1000 /* value from environment variable */ +#define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */ #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ #define SYMBOL_WARNED 0x8000 /* warning has been issued */ @@ -185,7 +185,6 @@ enum prop_type { P_SELECT, /* select BAR */ P_IMPLY, /* imply BAR */ P_RANGE, /* range 7..100 (for a symbol) */ - P_ENV, /* value from environment variable */ P_SYMBOL, /* where a symbol is defined */ }; diff --git a/kconfig/lkc.h b/kconfig/lkc.h index ed3ff88e..9eb7c837 100644 --- a/kconfig/lkc.h +++ b/kconfig/lkc.h @@ -97,7 +97,6 @@ void menu_set_type(int type); /* util.c */ struct file *file_lookup(const char *name); -int file_write_dep(const char *name); void *xmalloc(size_t size); void *xcalloc(size_t nmemb, size_t size); void *xrealloc(void *p, size_t size); @@ -126,7 +125,6 @@ const char *sym_get_string_default(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct symbol *prop_get_symbol(struct property *prop); -struct property *sym_get_env_prop(struct symbol *sym); static inline tristate sym_get_tristate_value(struct symbol *sym) { diff --git a/kconfig/lkc_proto.h b/kconfig/lkc_proto.h index a8b7a330..86c26754 100644 --- a/kconfig/lkc_proto.h +++ b/kconfig/lkc_proto.h @@ -7,10 +7,10 @@ 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 *fmt, va_list ap)); +void conf_set_message_callback(void (*fn)(const char *s)); /* menu.c */ extern struct menu rootmenu; diff --git a/kconfig/mconf.c b/kconfig/mconf.c index 9890dd47..c719f604 100644 --- a/kconfig/mconf.c +++ b/kconfig/mconf.c @@ -490,7 +490,6 @@ static void build_conf(struct menu *menu) switch (prop->type) { case P_MENU: child_count++; - prompt = prompt; if (single_menu_mode) { item_make("%s%*c%s", menu->data ? "-->" : "++>", @@ -772,16 +771,13 @@ static void show_helptext(const char *title, const char *text) show_textbox(title, text, 0, 0); } -static void conf_message_callback(const char *fmt, va_list ap) +static void conf_message_callback(const char *s) { - char buf[PATH_MAX+1]; - - vsnprintf(buf, sizeof(buf), fmt, ap); if (save_and_exit) { if (!silent) - printf("%s", buf); + printf("%s", s); } else { - show_textbox(NULL, buf, 6, 60); + show_textbox(NULL, s, 6, 60); } } @@ -977,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/kconfig/menu.c b/kconfig/menu.c index fd919bde..539ff57f 100644 --- a/kconfig/menu.c +++ b/kconfig/menu.c @@ -218,7 +218,7 @@ void menu_add_option(int token, char *arg) sym_defconfig_list = current_entry->sym; else if (sym_defconfig_list != current_entry->sym) zconf_error("trying to redefine defconfig symbol"); - sym_defconfig_list->flags |= SYMBOL_AUTO; + sym_defconfig_list->flags |= SYMBOL_NO_WRITE; break; case T_OPT_ALLNOCONFIG_Y: current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; diff --git a/kconfig/nconf.c b/kconfig/nconf.c index 4875f5e3..93d186ed 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -677,6 +677,7 @@ static int do_exit(void) "Your configuration changes were NOT saved.", 1, ""); + conf_write_autoconf(0); break; default: btn_dialog( @@ -1213,12 +1214,9 @@ static void conf(struct menu *menu) } } -static void conf_message_callback(const char *fmt, va_list ap) +static void conf_message_callback(const char *s) { - char buf[1024]; - - vsnprintf(buf, sizeof(buf), fmt, ap); - btn_dialog(main_window, buf, 1, ""); + btn_dialog(main_window, s, 1, ""); } static void show_help(struct menu *menu) diff --git a/kconfig/symbol.c b/kconfig/symbol.c index 7c9a88e9..703b9b89 100644 --- a/kconfig/symbol.c +++ b/kconfig/symbol.c @@ -76,15 +76,6 @@ struct property *sym_get_choice_prop(struct symbol *sym) return NULL; } -struct property *sym_get_env_prop(struct symbol *sym) -{ - struct property *prop; - - for_all_properties(sym, prop, P_ENV) - return prop; - return NULL; -} - static struct property *sym_get_default_prop(struct symbol *sym) { struct property *prop; @@ -463,7 +454,7 @@ void sym_calc_value(struct symbol *sym) } } - if (sym->flags & SYMBOL_AUTO) + if (sym->flags & SYMBOL_NO_WRITE) sym->flags &= ~SYMBOL_WRITE; if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) @@ -1020,7 +1011,7 @@ static struct dep_stack { struct dep_stack *prev, *next; struct symbol *sym; struct property *prop; - struct expr *expr; + struct expr **expr; } *check_top; static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) @@ -1085,31 +1076,42 @@ static void sym_check_print_recursive(struct symbol *last_sym) fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", prop->file->name, prop->lineno); - if (stack->expr) { - fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", - prop->file->name, prop->lineno, + if (sym_is_choice(sym)) { + fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "", + next_sym->name ? next_sym->name : ""); + } else if (sym_is_choice_value(sym)) { + fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", + menu->file->name, menu->lineno, sym->name ? sym->name : "", - prop_get_type_name(prop->type), next_sym->name ? next_sym->name : ""); - } else if (stack->prop) { + } else if (stack->expr == &sym->dir_dep.expr) { fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", prop->file->name, prop->lineno, sym->name ? sym->name : "", next_sym->name ? next_sym->name : ""); - } else if (sym_is_choice(sym)) { - fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", - menu->file->name, menu->lineno, + } else if (stack->expr == &sym->rev_dep.expr) { + fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", + prop->file->name, prop->lineno, sym->name ? sym->name : "", next_sym->name ? next_sym->name : ""); - } else if (sym_is_choice_value(sym)) { - fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", - menu->file->name, menu->lineno, + } else if (stack->expr == &sym->implied.expr) { + fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n", + prop->file->name, prop->lineno, sym->name ? sym->name : "", next_sym->name ? next_sym->name : ""); + } else if (stack->expr) { + fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "", + prop_get_type_name(prop->type), + next_sym->name ? next_sym->name : ""); } else { - fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", + fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n", prop->file->name, prop->lineno, sym->name ? sym->name : "", + prop_get_type_name(prop->type), next_sym->name ? next_sym->name : ""); } } @@ -1166,12 +1168,26 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) dep_stack_insert(&stack, sym); + stack.expr = &sym->dir_dep.expr; + sym2 = sym_check_expr_deps(sym->dir_dep.expr); + if (sym2) + goto out; + + stack.expr = &sym->rev_dep.expr; sym2 = sym_check_expr_deps(sym->rev_dep.expr); if (sym2) goto out; + stack.expr = &sym->implied.expr; + sym2 = sym_check_expr_deps(sym->implied.expr); + if (sym2) + goto out; + + stack.expr = NULL; + for (prop = sym->prop; prop; prop = prop->next) { - if (prop->type == P_CHOICE || prop->type == P_SELECT) + if (prop->type == P_CHOICE || prop->type == P_SELECT || + prop->type == P_IMPLY) continue; stack.prop = prop; sym2 = sym_check_expr_deps(prop->visible.expr); @@ -1179,7 +1195,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) break; if (prop->type != P_DEFAULT || sym_is_choice(sym)) continue; - stack.expr = prop->expr; + stack.expr = &prop->expr; sym2 = sym_check_expr_deps(prop->expr); if (sym2) break; @@ -1257,9 +1273,6 @@ struct symbol *sym_check_deps(struct symbol *sym) sym->flags &= ~SYMBOL_CHECK; } - if (sym2 && sym2 == sym) - sym2 = NULL; - return sym2; } @@ -1298,8 +1311,6 @@ const char *prop_get_type_name(enum prop_type type) switch (type) { case P_PROMPT: return "prompt"; - case P_ENV: - return "env"; case P_COMMENT: return "comment"; case P_MENU: diff --git a/kconfig/util.c b/kconfig/util.c index a3655947..d999683b 100644 --- a/kconfig/util.c +++ b/kconfig/util.c @@ -29,36 +29,6 @@ struct file *file_lookup(const char *name) return file; } -/* write a dependency file as used by kbuild to track dependencies */ -int file_write_dep(const char *name) -{ - struct file *file; - FILE *out; - - if (!name) - name = ".kconfig.d"; - out = fopen("..config.tmp", "w"); - if (!out) - return 1; - fprintf(out, "deps_config := \\\n"); - for (file = file_list; file; file = file->next) { - if (file->next) - fprintf(out, "\t%s \\\n", file->name); - else - fprintf(out, "\t%s\n", file->name); - } - fprintf(out, "\n%s: \\\n" - "\t$(deps_config)\n\n", conf_get_autoconfig_name()); - - env_write_dep(out, conf_get_autoconfig_name()); - - fprintf(out, "\n$(deps_config): ;\n"); - fclose(out); - rename("..config.tmp", name); - return 0; -} - - /* Allocate initial growable string */ struct gstr str_new(void) { diff --git a/kconfig/zconf.y b/kconfig/zconf.y index 1fd37c97..9d331da6 100644 --- a/kconfig/zconf.y +++ b/kconfig/zconf.y @@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE]; static struct menu *current_menu, *current_entry; %} -%expect 31 +%expect 30 %union { @@ -117,7 +117,7 @@ start: mainmenu_stmt stmt_list | stmt_list; /* mainmenu entry */ -mainmenu_stmt: T_MAINMENU prompt nl +mainmenu_stmt: T_MAINMENU prompt T_EOL { menu_add_prompt(P_MENU, $2, NULL); }; @@ -265,7 +265,7 @@ symbol_option_arg: choice: T_CHOICE word_opt T_EOL { struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); - sym->flags |= SYMBOL_AUTO; + sym->flags |= SYMBOL_NO_WRITE; menu_add_entry(sym); menu_add_expr(P_CHOICE, NULL, NULL); free($2); -- cgit v1.2.3 From 21095fab6712d3a082936b14b93cb6ff29c02872 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Wed, 9 Dec 2020 22:13:29 +1300 Subject: kconfig: Sync with upstream v5.0 This commit introduces the following upstream changes: 2648ca1859bb kconfig: clean generated *conf-cfg files d86271af6460 kconfig: rename generated .*conf-cfg to *conf-cfg ba97df45581f kbuild: use assignment instead of define ... endef for filechk_* rules a5003571e627 kconfig: remove unused "file" field of yylval union f222b7f43661 kconfig: surround dbg_sym_flags with #ifdef DEBUG to fix gconf warning 3b541978562a kconfig: split images.c out of qconf.cc/gconf.c to fix gconf warnings 9abe42371b44 kconfig: add static qualifiers to fix gconf warnings cbafbf7f551c kconfig: split the lexer out of zconf.y 558e78e3ce84 kconfig: split some C files out of zconf.y 0c874100108f kconfig: convert to SPDX License Identifier 979f2b2f7936 kconfig: remove keyword lookup table entirely 4b31a32caf0a kconfig: update current_pos in the second lexer 824fa3b3b5e3 kconfig: switch to ASSIGN_VAL state in the second lexer b3d1d9d3c362 kconfig: stop associating kconf_id with yylval caaebb3c6de3 kconfig: refactor end token rules f5451582c4e2 kconfig: stop supporting '.' and '/' in unquoted words 171a515d0803 kconfig: use T_WORD instead of T_VARIABLE for variables c3d228713b10 kconfig: use specific tokens instead of T_ASSIGN for assignments ce2164ab5831 kconfig: refactor scanning and parsing "option" properties 3c8f317d4cf1 kconfig: use distinct tokens for type and default properties a01e5d242d93 kconfig: remove redundant token defines 4b5ec81bfeda kconfig: rename depends_list to comment_option_list 1f31be9ec0a9 kconfig: loosen the order of "visible" and "depends on" in menu entry 94d4e1b6021b kconfig: remove redundant menu_block rule 4891796c6f83 kconfig: remove redundant if_block rule 2f60e46e605a kconfig: remove grammatically ambiguous option_error 6900ae9eeee3 kconfig: remove grammatically ambiguous "unexpected option" diagnostic 723679339d08 kconfig: warn no new line at end of file 0bcc547ec4b0 kconfig: clean up EOF handling in the lexer cc66bca775ee kconfig: fix ambiguous grammar in terms of new lines 21c5ecf60472 kconfig: refactor pattern matching in STRING state be3c8075978a kconfig: remove unneeded pattern matching to whitespaces 413cd19d81fd kconfig: require T_EOL to reduce visible statement fbac5977d81c kconfig: fix memory leak when EOF is encountered in quotation 77c1c0fa8b14 kconfig: fix file name and line number of warn_ignored_character() 0cbe3ac439bf kconfig: remove k_invalid from expr_parse_string() return type 2aabbed6774f kconfig: remove S_OTHER symbol type and correct dependency tracking 1508fec82e39 kconfig: split out code touching a file to conf_touch_dep() 0849d212e395 kconfig: rename conf_split_config() to conf_touch_deps() 75889e9be78f kconfig: remove unneeded setsym label in conf_read_simple() a9b722847872 scripts/kconfig/merge_config: don't redefine 'y' to 'm' Signed-off-by: Chris Packham --- kconfig/Makefile.am | 19 +-- kconfig/conf.c | 2 +- kconfig/confdata.c | 136 ++++++++++---------- kconfig/expr.c | 18 +-- kconfig/expr.h | 6 +- kconfig/kconf_id.c | 52 -------- kconfig/lkc.h | 25 ++-- kconfig/lxdialog/checklist.c | 15 +-- kconfig/lxdialog/dialog.h | 15 +-- kconfig/lxdialog/inputbox.c | 15 +-- kconfig/lxdialog/menubox.c | 15 +-- kconfig/lxdialog/textbox.c | 15 +-- kconfig/lxdialog/util.c | 15 +-- kconfig/lxdialog/yesno.c | 15 +-- kconfig/mconf.c | 2 +- kconfig/menu.c | 43 +++---- kconfig/nconf.c | 5 +- kconfig/nconf.gui.c | 5 +- kconfig/nconf.h | 5 +- kconfig/preprocess.c | 5 +- kconfig/symbol.c | 7 +- kconfig/util.c | 3 +- kconfig/zconf.l | 235 ++++++++++++++++++---------------- kconfig/zconf.y | 294 +++++++++++++++++-------------------------- 24 files changed, 378 insertions(+), 589 deletions(-) delete mode 100644 kconfig/kconf_id.c (limited to 'kconfig/nconf.c') diff --git a/kconfig/Makefile.am b/kconfig/Makefile.am index 0523ea95..82456060 100644 --- a/kconfig/Makefile.am +++ b/kconfig/Makefile.am @@ -9,22 +9,23 @@ EXTRA_DIST = zconf.y zconf.l \ expr.h list.h lkc.h lkc_proto.h nconf.h lxdialog/dialog.h \ confdata.c expr.c kconf_id.c menu.c symbol.c util.c -CLEANFILES = zconf.lex.c zconf.c -BUILT_SOURCES = zconf.c zconf.lex.c +CLEANFILES = zconf.lex.c zconf.tab.c +BUILT_SOURCES = zconf.lex.c zconf.tab.c -AM_LFLAGS = -L -Pzconf -AM_YFLAGS = -l -b zconf -p zconf +AM_LFLAGS = -L +AM_YFLAGS = -t -l AM_CPPFLAGS = -include config.h -DCONFIG_=\"CT_\" AM_LIBTOOLFLAGS = --tag CC -conf_SOURCES = conf.c zconf.c +conf_SOURCES = conf.c confdata.c expr.c symbol.c preprocess.c zconf.lex.c zconf.tab.c conf_LDADD = $(LIBINTL) -nconf_SOURCES = nconf.c nconf.gui.c zconf.c +nconf_SOURCES = nconf.c nconf.gui.c confdata.c expr.c symbol.c preprocess.c zconf.lex.c zconf.tab.c nconf_CFLAGS = $(CURSES_CFLAGS) nconf_LDADD = $(MENU_LIBS) $(PANEL_LIBS) $(CURSES_LIBS) $(LIBINTL) -mconf_SOURCES = mconf.c zconf.c lxdialog/checklist.c lxdialog/inputbox.c \ +mconf_SOURCES = mconf.c confdata.c expr.c symbol.c preprocess.c zconf.lex.c zconf.tab.c \ + lxdialog/checklist.c lxdialog/inputbox.c \ lxdialog/menubox.c lxdialog/textbox.c lxdialog/util.c \ lxdialog/yesno.c mconf_LDADD = $(CURSES_LIBS) $(LIBINTL) @@ -42,8 +43,8 @@ AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; -zconf.c: zconf.y - $(AM_V_YACC)$(YACCCOMPILE) -o$@ $< +zconf.tab.c: zconf.y + $(AM_V_YACC)$(YACCCOMPILE) -o$@ --defines=zconf.tab.h $< zconf.lex.c: zconf.l $(AM_V_LEX)$(LEXCOMPILE) -o$@ $< diff --git a/kconfig/conf.c b/kconfig/conf.c index 5a795c50..b86c7de8 100644 --- a/kconfig/conf.c +++ b/kconfig/conf.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ #include diff --git a/kconfig/confdata.c b/kconfig/confdata.c index 91d0a5c0..08ba146a 100644 --- a/kconfig/confdata.c +++ b/kconfig/confdata.c @@ -1,12 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ #include #include #include #include +#include #include #include #include @@ -74,6 +75,47 @@ static int make_parent_dir(const char *path) return 0; } +static char depfile_path[PATH_MAX]; +static size_t depfile_prefix_len; + +/* touch depfile for symbol 'name' */ +static int conf_touch_dep(const char *name) +{ + int fd, ret; + const char *s; + char *d, c; + + /* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */ + if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path)) + return -1; + + d = depfile_path + depfile_prefix_len; + s = name; + + while ((c = *s++)) + *d++ = (c == '_') ? '/' : tolower(c); + strcpy(d, ".h"); + + /* Assume directory path already exists. */ + fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + if (errno != ENOENT) + return -1; + + ret = make_parent_dir(depfile_path); + if (ret) + return ret; + + /* Try it again. */ + fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) + return -1; + } + close(fd); + + return 0; +} + struct conf_printer { void (*print_symbol)(FILE *, struct symbol *, const char *, void *); void (*print_comment)(FILE *, const char *, void *); @@ -186,14 +228,6 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) conf_warning("symbol value '%s' invalid for %s", p, sym->name); return 1; - case S_OTHER: - if (*p != '"') { - for (p2 = p; *p2 && !isspace(*p2); p2++) - ; - sym->type = S_STRING; - goto done; - } - /* fall through */ case S_STRING: if (*p++ != '"') break; @@ -212,7 +246,6 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) /* fall through */ case S_INT: case S_HEX: - done: if (sym_string_valid(sym, p)) { sym->def[def].val = xstrdup(p); sym->flags |= def_flags; @@ -363,7 +396,7 @@ load: sym = sym_find(line + 2 + strlen(CONFIG_)); if (!sym) { sym_add_change_count(1); - goto setsym; + continue; } } else { sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); @@ -393,17 +426,22 @@ load: if (*p2 == '\r') *p2 = 0; } - if (def == S_DEF_USER) { - sym = sym_find(line + strlen(CONFIG_)); - if (!sym) { + + sym = sym_find(line + strlen(CONFIG_)); + if (!sym) { + if (def == S_DEF_AUTO) + /* + * Reading from include/config/auto.conf + * If CONFIG_FOO previously existed in + * auto.conf but it is missing now, + * include/config/foo.h must be touched. + */ + conf_touch_dep(line + strlen(CONFIG_)); + else sym_add_change_count(1); - goto setsym; - } - } else { - sym = sym_lookup(line + strlen(CONFIG_), 0); - if (sym->type == S_UNKNOWN) - sym->type = S_OTHER; + continue; } + if (sym->flags & def_flags) { conf_warning("override: reassigning to symbol %s", sym->name); } @@ -416,7 +454,7 @@ load: continue; } -setsym: + if (sym && sym_is_choice_value(sym)) { struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); switch (sym->def[def].tri) { @@ -669,7 +707,6 @@ static void conf_write_symbol(FILE *fp, struct symbol *sym, const char *str; switch (sym->type) { - case S_OTHER: case S_UNKNOWN: break; case S_STRING: @@ -906,24 +943,19 @@ static int conf_write_dep(const char *name) return 0; } -static int conf_split_config(void) +static int conf_touch_deps(void) { const char *name; - char path[PATH_MAX+1]; - char *s, *d, c; struct symbol *sym; - int res, i, fd; + int res, i; + + strcpy(depfile_path, "include/config/"); + depfile_prefix_len = strlen(depfile_path); name = conf_get_autoconfig_name(); conf_read_simple(name, S_DEF_AUTO); sym_calc_value(modules_sym); - if (make_parent_dir("include/config/foo.h")) - return 1; - if (chdir("include/config")) - return 1; - - res = 0; for_all_symbols(i, sym) { sym_calc_value(sym); if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) @@ -975,42 +1007,12 @@ static int conf_split_config(void) * different from 'no'). */ - /* Replace all '_' and append ".h" */ - s = sym->name; - d = path; - while ((c = *s++)) { - c = tolower(c); - *d++ = (c == '_') ? '/' : c; - } - strcpy(d, ".h"); - - /* Assume directory path already exists. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - if (errno != ENOENT) { - res = 1; - break; - } - - if (make_parent_dir(path)) { - res = 1; - goto out; - } - - /* Try it again. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - res = 1; - break; - } - } - close(fd); + res = conf_touch_dep(sym->name); + if (res) + return res; } -out: - if (chdir("../..")) - return 1; - return res; + return 0; } int conf_write_autoconf(int overwrite) @@ -1028,7 +1030,7 @@ int conf_write_autoconf(int overwrite) conf_write_dep("include/config/auto.conf.cmd"); - if (conf_split_config()) + if (conf_touch_deps()) return 1; out = fopen(".tmpconfig", "w"); diff --git a/kconfig/expr.c b/kconfig/expr.c index e1a39e90..77ffff3a 100644 --- a/kconfig/expr.c +++ b/kconfig/expr.c @@ -1,8 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ +#include +#include #include #include #include @@ -980,7 +982,6 @@ enum string_value_kind { k_string, k_signed, k_unsigned, - k_invalid }; union string_value { @@ -1011,13 +1012,10 @@ static enum string_value_kind expr_parse_string(const char *str, val->u = strtoull(str, &tail, 16); kind = k_unsigned; break; - case S_STRING: - case S_UNKNOWN: + default: val->s = strtoll(str, &tail, 0); kind = k_signed; break; - default: - return k_invalid; } return !errno && !*tail && tail > str && isxdigit(tail[-1]) ? kind : k_string; @@ -1073,13 +1071,7 @@ tristate expr_calc_value(struct expr *e) if (k1 == k_string || k2 == k_string) res = strcmp(str1, str2); - else if (k1 == k_invalid || k2 == k_invalid) { - if (e->type != E_EQUAL && e->type != E_UNEQUAL) { - printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2); - return no; - } - res = strcmp(str1, str2); - } else if (k1 == k_unsigned || k2 == k_unsigned) + else if (k1 == k_unsigned || k2 == k_unsigned) res = (lval.u > rval.u) - (lval.u < rval.u); else /* if (k1 == k_signed && k2 == k_signed) */ res = (lval.s > rval.s) - (lval.s < rval.s); diff --git a/kconfig/expr.h b/kconfig/expr.h index 7c329e17..999edb60 100644 --- a/kconfig/expr.h +++ b/kconfig/expr.h @@ -1,6 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ #ifndef EXPR_H @@ -62,7 +62,7 @@ struct symbol_value { }; enum symbol_type { - S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER + S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING }; /* enum values are used as index to symbol.def[] */ @@ -131,7 +131,7 @@ struct symbol { struct expr_value implied; }; -#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) +#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) #define SYMBOL_CONST 0x0001 /* symbol is const */ #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ diff --git a/kconfig/kconf_id.c b/kconfig/kconf_id.c deleted file mode 100644 index b3e0ea0a..00000000 --- a/kconfig/kconf_id.c +++ /dev/null @@ -1,52 +0,0 @@ - -static struct kconf_id kconf_id_array[] = { - { "mainmenu", T_MAINMENU, TF_COMMAND }, - { "menu", T_MENU, TF_COMMAND }, - { "endmenu", T_ENDMENU, TF_COMMAND }, - { "source", T_SOURCE, TF_COMMAND }, - { "choice", T_CHOICE, TF_COMMAND }, - { "endchoice", T_ENDCHOICE, TF_COMMAND }, - { "comment", T_COMMENT, TF_COMMAND }, - { "config", T_CONFIG, TF_COMMAND }, - { "menuconfig", T_MENUCONFIG, TF_COMMAND }, - { "help", T_HELP, TF_COMMAND }, - { "---help---", T_HELP, TF_COMMAND }, - { "if", T_IF, TF_COMMAND|TF_PARAM }, - { "endif", T_ENDIF, TF_COMMAND }, - { "depends", T_DEPENDS, TF_COMMAND }, - { "optional", T_OPTIONAL, TF_COMMAND }, - { "default", T_DEFAULT, TF_COMMAND, S_UNKNOWN }, - { "prompt", T_PROMPT, TF_COMMAND }, - { "tristate", T_TYPE, TF_COMMAND, S_TRISTATE }, - { "def_tristate", T_DEFAULT, TF_COMMAND, S_TRISTATE }, - { "bool", T_TYPE, TF_COMMAND, S_BOOLEAN }, - { "def_bool", T_DEFAULT, TF_COMMAND, S_BOOLEAN }, - { "int", T_TYPE, TF_COMMAND, S_INT }, - { "hex", T_TYPE, TF_COMMAND, S_HEX }, - { "string", T_TYPE, TF_COMMAND, S_STRING }, - { "select", T_SELECT, TF_COMMAND }, - { "imply", T_IMPLY, TF_COMMAND }, - { "range", T_RANGE, TF_COMMAND }, - { "visible", T_VISIBLE, TF_COMMAND }, - { "option", T_OPTION, TF_COMMAND }, - { "on", T_ON, TF_PARAM }, - { "modules", T_OPT_MODULES, TF_OPTION }, - { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, - { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, -}; - -#define KCONF_ID_ARRAY_SIZE (sizeof(kconf_id_array)/sizeof(struct kconf_id)) - -static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len) -{ - int i; - - for (i = 0; i < KCONF_ID_ARRAY_SIZE; i++) { - struct kconf_id *id = kconf_id_array+i; - int l = strlen(id->name); - - if (len == l && !memcmp(str, id->name, len)) - return id; - } - return NULL; -} diff --git a/kconfig/lkc.h b/kconfig/lkc.h index 9eb7c837..531ff7c5 100644 --- a/kconfig/lkc.h +++ b/kconfig/lkc.h @@ -1,6 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ #ifndef LKC_H @@ -30,10 +30,6 @@ static inline const char *CONFIG_prefix(void) #undef CONFIG_ #define CONFIG_ CONFIG_prefix() -#define TF_COMMAND 0x0001 -#define TF_PARAM 0x0002 -#define TF_OPTION 0x0004 - enum conf_def_mode { def_default, def_yes, @@ -42,17 +38,6 @@ enum conf_def_mode { def_random }; -#define T_OPT_MODULES 1 -#define T_OPT_DEFCONFIG_LIST 2 -#define T_OPT_ALLNOCONFIG_Y 4 - -struct kconf_id { - const char *name; - int token; - unsigned int flags; - enum symbol_type stype; -}; - extern int yylineno; void zconfdump(FILE *out); void zconf_starthelp(void); @@ -91,7 +76,9 @@ 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); -void menu_add_option(int token, char *arg); +void menu_add_option_modules(void); +void menu_add_option_defconfig_list(void); +void menu_add_option_allnoconfig_y(void); void menu_finalize(struct menu *parent); void menu_set_type(int type); @@ -103,6 +90,9 @@ void *xrealloc(void *p, size_t size); char *xstrdup(const char *s); char *xstrndup(const char *s, size_t n); +/* zconf.l */ +int yylex(void); + struct gstr { size_t len; char *s; @@ -121,6 +111,7 @@ const char *str_get(struct gstr *gs); /* symbol.c */ void sym_clear_all_valid(void); struct symbol *sym_choice_default(struct symbol *sym); +struct property *sym_get_range_prop(struct symbol *sym); const char *sym_get_string_default(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym); diff --git a/kconfig/lxdialog/checklist.c b/kconfig/lxdialog/checklist.c index 2e96323a..fd161cff 100644 --- a/kconfig/lxdialog/checklist.c +++ b/kconfig/lxdialog/checklist.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * checklist.c -- implements the checklist box * @@ -5,20 +6,6 @@ * 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/kconfig/lxdialog/dialog.h b/kconfig/lxdialog/dialog.h index 0b00be5a..68b565e3 100644 --- a/kconfig/lxdialog/dialog.h +++ b/kconfig/lxdialog/dialog.h @@ -1,21 +1,8 @@ +/* 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 diff --git a/kconfig/lxdialog/inputbox.c b/kconfig/lxdialog/inputbox.c index fe82ff6d..61194561 100644 --- a/kconfig/lxdialog/inputbox.c +++ b/kconfig/lxdialog/inputbox.c @@ -1,22 +1,9 @@ +// 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/kconfig/lxdialog/menubox.c b/kconfig/lxdialog/menubox.c index d70cab36..58c2f8af 100644 --- a/kconfig/lxdialog/menubox.c +++ b/kconfig/lxdialog/menubox.c @@ -1,22 +1,9 @@ +// 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/kconfig/lxdialog/textbox.c b/kconfig/lxdialog/textbox.c index 88d2818e..4e339b12 100644 --- a/kconfig/lxdialog/textbox.c +++ b/kconfig/lxdialog/textbox.c @@ -1,22 +1,9 @@ +// 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" diff --git a/kconfig/lxdialog/util.c b/kconfig/lxdialog/util.c index f7abdeb9..1b490d4a 100644 --- a/kconfig/lxdialog/util.c +++ b/kconfig/lxdialog/util.c @@ -1,22 +1,9 @@ +// 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/kconfig/lxdialog/yesno.c b/kconfig/lxdialog/yesno.c index cd1223c9..bcaac9b7 100644 --- a/kconfig/lxdialog/yesno.c +++ b/kconfig/lxdialog/yesno.c @@ -1,22 +1,9 @@ +// 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/kconfig/mconf.c b/kconfig/mconf.c index c719f604..3d4bd5ef 100644 --- a/kconfig/mconf.c +++ b/kconfig/mconf.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. * * Introduced single menu mode (show all sub-menus in one large tree). * 2002-11-06 Petr Baudis diff --git a/kconfig/menu.c b/kconfig/menu.c index 539ff57f..264ba298 100644 --- a/kconfig/menu.c +++ b/kconfig/menu.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ #include @@ -201,29 +201,26 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); } -void menu_add_option(int token, char *arg) +void menu_add_option_modules(void) { - switch (token) { - case T_OPT_MODULES: - if (modules_sym) - zconf_error("symbol '%s' redefines option 'modules'" - " already defined by symbol '%s'", - current_entry->sym->name, - modules_sym->name - ); - modules_sym = current_entry->sym; - break; - case T_OPT_DEFCONFIG_LIST: - if (!sym_defconfig_list) - sym_defconfig_list = current_entry->sym; - else if (sym_defconfig_list != current_entry->sym) - zconf_error("trying to redefine defconfig symbol"); - sym_defconfig_list->flags |= SYMBOL_NO_WRITE; - break; - case T_OPT_ALLNOCONFIG_Y: - current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; - break; - } + if (modules_sym) + zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'", + current_entry->sym->name, modules_sym->name); + modules_sym = current_entry->sym; +} + +void menu_add_option_defconfig_list(void) +{ + if (!sym_defconfig_list) + sym_defconfig_list = current_entry->sym; + else if (sym_defconfig_list != current_entry->sym) + zconf_error("trying to redefine defconfig symbol"); + sym_defconfig_list->flags |= SYMBOL_NO_WRITE; +} + +void menu_add_option_allnoconfig_y(void) +{ + current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; } static int menu_validate_number(struct symbol *sym, struct symbol *sym2) diff --git a/kconfig/nconf.c b/kconfig/nconf.c index 93d186ed..fb6027af 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2008 Nir Tzachar * * Derived from menuconfig. - * */ #ifndef _GNU_SOURCE #define _GNU_SOURCE diff --git a/kconfig/nconf.gui.c b/kconfig/nconf.gui.c index 88874acf..7be620a1 100644 --- a/kconfig/nconf.gui.c +++ b/kconfig/nconf.gui.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2008 Nir Tzachar * * Derived from menuconfig. - * */ #include "nconf.h" #include "lkc.h" diff --git a/kconfig/nconf.h b/kconfig/nconf.h index 2b9e19f6..fa5245eb 100644 --- a/kconfig/nconf.h +++ b/kconfig/nconf.h @@ -1,9 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (C) 2008 Nir Tzachar * * Derived from menuconfig. - * */ #include diff --git a/kconfig/preprocess.c b/kconfig/preprocess.c index 5ca2df79..592dfbfa 100644 --- a/kconfig/preprocess.c +++ b/kconfig/preprocess.c @@ -2,6 +2,7 @@ // // Copyright (C) 2018 Masahiro Yamada +#include #include #include #include @@ -9,6 +10,7 @@ #include #include "list.h" +#include "lkc.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -555,8 +557,7 @@ char *expand_string(const char *in) static bool is_end_of_token(char c) { - /* Why are '.' and '/' valid characters for symbols? */ - return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/'); + return !(isalnum(c) || c == '_' || c == '-'); } /* diff --git a/kconfig/symbol.c b/kconfig/symbol.c index 703b9b89..1f9266da 100644 --- a/kconfig/symbol.c +++ b/kconfig/symbol.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ #include @@ -61,8 +61,6 @@ const char *sym_type_name(enum symbol_type type) return "string"; case S_UNKNOWN: return "unknown"; - case S_OTHER: - break; } return "???"; } @@ -88,7 +86,7 @@ static struct property *sym_get_default_prop(struct symbol *sym) return NULL; } -static struct property *sym_get_range_prop(struct symbol *sym) +struct property *sym_get_range_prop(struct symbol *sym) { struct property *prop; @@ -757,7 +755,6 @@ const char *sym_get_string_default(struct symbol *sym) return str; case S_STRING: return str; - case S_OTHER: case S_UNKNOWN: break; } diff --git a/kconfig/util.c b/kconfig/util.c index d999683b..29585394 100644 --- a/kconfig/util.c +++ b/kconfig/util.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002-2005 Roman Zippel * Copyright (C) 2002-2005 Sam Ravnborg - * - * Released under the terms of the GNU GPL v2.0. */ #include diff --git a/kconfig/zconf.l b/kconfig/zconf.l index 25bd2b89..b2d0a3b0 100644 --- a/kconfig/zconf.l +++ b/kconfig/zconf.l @@ -1,11 +1,11 @@ -%option nostdinit noyywrap never-interactive full ecs -%option 8bit nodefault yylineno -%x COMMAND HELP STRING PARAM ASSIGN_VAL -%{ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ +%option nostdinit noyywrap never-interactive full ecs +%option 8bit nodefault yylineno +%x ASSIGN_VAL HELP STRING +%{ #include #include @@ -15,6 +15,9 @@ #include #include "lkc.h" +#include "zconf.tab.h" + +#define YY_DECL static int yylex1(void) #define START_STRSIZE 16 @@ -23,6 +26,8 @@ static struct { int lineno; } current_pos; +static int prev_prev_token = T_EOL; +static int prev_token = T_EOL; static char *text; static int text_size, text_asize; @@ -73,7 +78,7 @@ static void warn_ignored_character(char chr) { fprintf(stderr, "%s:%d:warning: ignoring unsupported character '%c'\n", - zconf_curname(), zconf_lineno(), chr); + current_file->name, yylineno, chr); } %} @@ -83,54 +88,73 @@ n [A-Za-z0-9_-] int str = 0; int ts, i; -[ \t]*#.*\n | -[ \t]*\n { - return T_EOL; -} -[ \t]*#.* - - -[ \t]+ { - BEGIN(COMMAND); -} - -. { - unput(yytext[0]); - BEGIN(COMMAND); -} - - -{ - {n}+ { - const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); - current_pos.file = current_file; - current_pos.lineno = yylineno; - if (id && id->flags & TF_COMMAND) { - BEGIN(PARAM); - yylval.id = id; - return id->token; - } - alloc_string(yytext, yyleng); - yylval.string = text; - return T_VARIABLE; - } - ({n}|$)+ { - /* this token includes at least one '$' */ - yylval.string = expand_token(yytext, yyleng); - if (strlen(yylval.string)) - return T_VARIABLE; - free(yylval.string); - } - "=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; } - ":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; } - "+=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; } - [[:blank:]]+ - . warn_ignored_character(*yytext); - \n { - BEGIN(INITIAL); - return T_EOL; - } -} +#.* /* ignore comment */ +[ \t]* /* whitespaces */ +\\\n /* escaped new line */ +\n return T_EOL; +"allnoconfig_y" return T_ALLNOCONFIG_Y; +"bool" return T_BOOL; +"choice" return T_CHOICE; +"comment" return T_COMMENT; +"config" return T_CONFIG; +"def_bool" return T_DEF_BOOL; +"def_tristate" return T_DEF_TRISTATE; +"default" return T_DEFAULT; +"defconfig_list" return T_DEFCONFIG_LIST; +"depends" return T_DEPENDS; +"endchoice" return T_ENDCHOICE; +"endif" return T_ENDIF; +"endmenu" return T_ENDMENU; +"help"|"---help---" return T_HELP; +"hex" return T_HEX; +"if" return T_IF; +"imply" return T_IMPLY; +"int" return T_INT; +"mainmenu" return T_MAINMENU; +"menu" return T_MENU; +"menuconfig" return T_MENUCONFIG; +"modules" return T_MODULES; +"on" return T_ON; +"option" return T_OPTION; +"optional" return T_OPTIONAL; +"prompt" return T_PROMPT; +"range" return T_RANGE; +"select" return T_SELECT; +"source" return T_SOURCE; +"string" return T_STRING; +"tristate" return T_TRISTATE; +"visible" return T_VISIBLE; +"||" return T_OR; +"&&" return T_AND; +"=" return T_EQUAL; +"!=" return T_UNEQUAL; +"<" return T_LESS; +"<=" return T_LESS_EQUAL; +">" return T_GREATER; +">=" return T_GREATER_EQUAL; +"!" return T_NOT; +"(" return T_OPEN_PAREN; +")" return T_CLOSE_PAREN; +":=" return T_COLON_EQUAL; +"+=" return T_PLUS_EQUAL; +\"|\' { + str = yytext[0]; + new_string(); + BEGIN(STRING); + } +{n}+ { + alloc_string(yytext, yyleng); + yylval.string = text; + return T_WORD; + } +({n}|$)+ { + /* this token includes at least one '$' */ + yylval.string = expand_token(yytext, yyleng); + if (strlen(yylval.string)) + return T_WORD; + free(yylval.string); + } +. warn_ignored_character(*yytext); { [^[:blank:]\n]+.* { @@ -142,71 +166,17 @@ n [A-Za-z0-9_-] . } -{ - "&&" return T_AND; - "||" return T_OR; - "(" return T_OPEN_PAREN; - ")" return T_CLOSE_PAREN; - "!" return T_NOT; - "=" return T_EQUAL; - "!=" return T_UNEQUAL; - "<=" return T_LESS_EQUAL; - ">=" return T_GREATER_EQUAL; - "<" return T_LESS; - ">" return T_GREATER; - \"|\' { - str = yytext[0]; - new_string(); - BEGIN(STRING); - } - \n BEGIN(INITIAL); return T_EOL; - ({n}|[/.])+ { - const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); - if (id && id->flags & TF_PARAM) { - yylval.id = id; - return id->token; - } - alloc_string(yytext, yyleng); - yylval.string = text; - return T_WORD; - } - ({n}|[/.$])+ { - /* this token includes at least one '$' */ - yylval.string = expand_token(yytext, yyleng); - if (strlen(yylval.string)) - return T_WORD; - free(yylval.string); - } - #.* /* comment */ - \\\n ; - [[:blank:]]+ - . warn_ignored_character(*yytext); - <> { - BEGIN(INITIAL); - } -} - { "$".* append_expanded_string(yytext); - [^$'"\\\n]+/\n { - append_string(yytext, yyleng); - yylval.string = text; - return T_WORD_QUOTE; - } [^$'"\\\n]+ { append_string(yytext, yyleng); } - \\.?/\n { - append_string(yytext + 1, yyleng - 1); - yylval.string = text; - return T_WORD_QUOTE; - } \\.? { append_string(yytext + 1, yyleng - 1); } \'|\" { if (str == yytext[0]) { - BEGIN(PARAM); + BEGIN(INITIAL); yylval.string = text; return T_WORD_QUOTE; } else @@ -216,11 +186,15 @@ n [A-Za-z0-9_-] fprintf(stderr, "%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + unput('\n'); BEGIN(INITIAL); - return T_EOL; + yylval.string = text; + return T_WORD_QUOTE; } <> { BEGIN(INITIAL); + yylval.string = text; + return T_WORD_QUOTE; } } @@ -271,6 +245,12 @@ n [A-Za-z0-9_-] } <> { + BEGIN(INITIAL); + + if (prev_token != T_EOL && prev_token != T_HELPTEXT) + fprintf(stderr, "%s:%d:warning: no new line at end of file\n", + current_file->name, yylineno); + if (current_file) { zconf_endfile(); return T_EOL; @@ -280,6 +260,41 @@ n [A-Za-z0-9_-] } %% + +/* second stage lexer */ +int yylex(void) +{ + int token; + +repeat: + token = yylex1(); + + if (prev_token == T_EOL || prev_token == T_HELPTEXT) { + if (token == T_EOL) { + /* Do not pass unneeded T_EOL to the parser. */ + goto repeat; + } else { + /* + * For the parser, update file/lineno at the first token + * of each statement. Generally, \n is a statement + * terminator in Kconfig, but it is not always true + * because \n could be escaped by a backslash. + */ + current_pos.file = current_file; + current_pos.lineno = yylineno; + } + } + + if (prev_prev_token == T_EOL && prev_token == T_WORD && + (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL)) + BEGIN(ASSIGN_VAL); + + prev_prev_token = prev_token; + prev_token = token; + + return token; +} + static char *expand_token(const char *in, size_t n) { char *out; diff --git a/kconfig/zconf.y b/kconfig/zconf.y index 9d331da6..60936c76 100644 --- a/kconfig/zconf.y +++ b/kconfig/zconf.y @@ -1,8 +1,8 @@ -%{ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ +%{ #include #include @@ -20,66 +20,68 @@ int cdebug = PRINTD; -int yylex(void); static void yyerror(const char *err); static void zconfprint(const char *err, ...); static void zconf_error(const char *err, ...); -static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); +static bool zconf_endtoken(const char *tokenname, + const char *expected_tokenname); struct symbol *symbol_hash[SYMBOL_HASHSIZE]; static struct menu *current_menu, *current_entry; %} -%expect 30 %union { char *string; - struct file *file; struct symbol *symbol; struct expr *expr; struct menu *menu; - const struct kconf_id *id; + enum symbol_type type; enum variable_flavor flavor; } -%token T_MAINMENU -%token T_MENU -%token T_ENDMENU -%token T_SOURCE -%token T_CHOICE -%token T_ENDCHOICE -%token T_COMMENT -%token T_CONFIG -%token T_MENUCONFIG -%token T_HELP %token T_HELPTEXT -%token T_IF -%token T_ENDIF -%token T_DEPENDS -%token T_OPTIONAL -%token T_PROMPT -%token T_TYPE -%token T_DEFAULT -%token T_SELECT -%token T_IMPLY -%token T_RANGE -%token T_VISIBLE -%token T_OPTION -%token T_ON %token T_WORD %token T_WORD_QUOTE -%token T_UNEQUAL -%token T_LESS -%token T_LESS_EQUAL -%token T_GREATER -%token T_GREATER_EQUAL +%token T_ALLNOCONFIG_Y +%token T_BOOL +%token T_CHOICE %token T_CLOSE_PAREN +%token T_COLON_EQUAL +%token T_COMMENT +%token T_CONFIG +%token T_DEFAULT +%token T_DEFCONFIG_LIST +%token T_DEF_BOOL +%token T_DEF_TRISTATE +%token T_DEPENDS +%token T_ENDCHOICE +%token T_ENDIF +%token T_ENDMENU +%token T_HELP +%token T_HEX +%token T_IF +%token T_IMPLY +%token T_INT +%token T_MAINMENU +%token T_MENU +%token T_MENUCONFIG +%token T_MODULES +%token T_ON %token T_OPEN_PAREN +%token T_OPTION +%token T_OPTIONAL +%token T_PLUS_EQUAL +%token T_PROMPT +%token T_RANGE +%token T_SELECT +%token T_SOURCE +%token T_STRING +%token T_TRISTATE +%token T_VISIBLE %token T_EOL -%token T_VARIABLE -%token T_ASSIGN %token T_ASSIGN_VAL %left T_OR @@ -91,12 +93,13 @@ static struct menu *current_menu, *current_entry; %type prompt %type nonconst_symbol %type symbol +%type type logic_type default %type expr %type if_expr -%type end -%type option_name +%type end %type if_entry menu_entry choice_entry -%type symbol_option_arg word_opt assign_val +%type word_opt assign_val +%type assign_op %destructor { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -105,15 +108,8 @@ static struct menu *current_menu, *current_entry; menu_end_menu(); } if_entry menu_entry choice_entry -%{ -/* Include kconf_id.c here so it can see the token constants. */ -#include "kconf_id.c" -%} - %% -input: nl start | start; - -start: mainmenu_stmt stmt_list | stmt_list; +input: mainmenu_stmt stmt_list | stmt_list; /* mainmenu entry */ @@ -127,22 +123,12 @@ stmt_list: | stmt_list common_stmt | stmt_list choice_stmt | stmt_list menu_stmt - | stmt_list end { zconf_error("unexpected end statement"); } | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } - | stmt_list option_name error T_EOL -{ - zconf_error("unexpected option \"%s\"", $2->name); -} | stmt_list error T_EOL { zconf_error("invalid statement"); } ; -option_name: - T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE -; - common_stmt: - T_EOL - | if_stmt + if_stmt | comment_stmt | config_stmt | menuconfig_stmt @@ -150,12 +136,6 @@ common_stmt: | assignment_stmt ; -option_error: - T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); } - | error T_EOL { zconf_error("invalid option"); } -; - - /* config/menuconfig entry */ config_entry_start: T_CONFIG nonconst_symbol T_EOL @@ -189,19 +169,16 @@ menuconfig_stmt: menuconfig_entry_start config_option_list config_option_list: /* empty */ | config_option_list config_option - | config_option_list symbol_option | config_option_list depends | config_option_list help - | config_option_list option_error - | config_option_list T_EOL ; -config_option: T_TYPE prompt_stmt_opt T_EOL +config_option: type prompt_stmt_opt T_EOL { - menu_set_type($1->stype); + menu_set_type($1); printd(DEBUG_PARSE, "%s:%d:type(%u)\n", zconf_curname(), zconf_lineno(), - $1->stype); + $1); }; config_option: T_PROMPT prompt if_expr T_EOL @@ -210,14 +187,14 @@ config_option: T_PROMPT prompt if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); }; -config_option: T_DEFAULT expr if_expr T_EOL +config_option: default expr if_expr T_EOL { menu_add_expr(P_DEFAULT, $2, $3); - if ($1->stype != S_UNKNOWN) - menu_set_type($1->stype); + if ($1 != S_UNKNOWN) + menu_set_type($1); printd(DEBUG_PARSE, "%s:%d:default(%u)\n", zconf_curname(), zconf_lineno(), - $1->stype); + $1); }; config_option: T_SELECT nonconst_symbol if_expr T_EOL @@ -238,27 +215,20 @@ config_option: T_RANGE symbol symbol if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); }; -symbol_option: T_OPTION symbol_option_list T_EOL -; +config_option: T_OPTION T_MODULES T_EOL +{ + menu_add_option_modules(); +}; -symbol_option_list: - /* empty */ - | symbol_option_list T_WORD symbol_option_arg +config_option: T_OPTION T_DEFCONFIG_LIST T_EOL { - const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); - if (id && id->flags & TF_OPTION) { - menu_add_option(id->token, $3); - free($3); - } - else - zconfprint("warning: ignoring unknown option %s", $2); - free($2); + menu_add_option_defconfig_list(); }; -symbol_option_arg: - /* empty */ { $$ = NULL; } - | T_EQUAL prompt { $$ = $2; } -; +config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL +{ + menu_add_option_allnoconfig_y(); +}; /* choice entry */ @@ -279,7 +249,7 @@ choice_entry: choice choice_option_list choice_end: end { - if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { + if (zconf_endtoken($1, "choice")) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); } @@ -293,8 +263,6 @@ choice_option_list: | choice_option_list choice_option | choice_option_list depends | choice_option_list help - | choice_option_list T_EOL - | choice_option_list option_error ; choice_option: T_PROMPT prompt if_expr T_EOL @@ -303,15 +271,11 @@ choice_option: T_PROMPT prompt if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); }; -choice_option: T_TYPE prompt_stmt_opt T_EOL +choice_option: logic_type prompt_stmt_opt T_EOL { - if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) { - menu_set_type($1->stype); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), - $1->stype); - } else - YYERROR; + menu_set_type($1); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), $1); }; choice_option: T_OPTIONAL T_EOL @@ -322,14 +286,26 @@ choice_option: T_OPTIONAL T_EOL choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL { - if ($1->stype == S_UNKNOWN) { - menu_add_symbol(P_DEFAULT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:default\n", - zconf_curname(), zconf_lineno()); - } else - YYERROR; + menu_add_symbol(P_DEFAULT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:default\n", + zconf_curname(), zconf_lineno()); }; +type: + logic_type + | T_INT { $$ = S_INT; } + | T_HEX { $$ = S_HEX; } + | T_STRING { $$ = S_STRING; } + +logic_type: + T_BOOL { $$ = S_BOOLEAN; } + | T_TRISTATE { $$ = S_TRISTATE; } + +default: + T_DEFAULT { $$ = S_UNKNOWN; } + | T_DEF_BOOL { $$ = S_BOOLEAN; } + | T_DEF_TRISTATE { $$ = S_TRISTATE; } + choice_block: /* empty */ | choice_block common_stmt @@ -347,20 +323,13 @@ if_entry: T_IF expr T_EOL if_end: end { - if (zconf_endtoken($1, T_IF, T_ENDIF)) { + if (zconf_endtoken($1, "if")) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); } }; -if_stmt: if_entry if_block if_end -; - -if_block: - /* empty */ - | if_block common_stmt - | if_block menu_stmt - | if_block choice_stmt +if_stmt: if_entry stmt_list if_end ; /* menu entry */ @@ -372,27 +341,26 @@ menu: T_MENU prompt T_EOL printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); }; -menu_entry: menu visibility_list depends_list +menu_entry: menu menu_option_list { $$ = menu_add_menu(); }; menu_end: end { - if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { + if (zconf_endtoken($1, "menu")) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); } }; -menu_stmt: menu_entry menu_block menu_end +menu_stmt: menu_entry stmt_list menu_end ; -menu_block: +menu_option_list: /* empty */ - | menu_block common_stmt - | menu_block menu_stmt - | menu_block choice_stmt + | menu_option_list visible + | menu_option_list depends ; source_stmt: T_SOURCE prompt T_EOL @@ -411,7 +379,12 @@ comment: T_COMMENT prompt T_EOL printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); }; -comment_stmt: comment depends_list +comment_stmt: comment comment_option_list +; + +comment_option_list: + /* empty */ + | comment_option_list depends ; /* help option */ @@ -440,13 +413,6 @@ help: help_start T_HELPTEXT /* depends option */ -depends_list: - /* empty */ - | depends_list depends - | depends_list T_EOL - | depends_list option_error -; - depends: T_DEPENDS T_ON expr T_EOL { menu_add_dep($3); @@ -454,14 +420,7 @@ depends: T_DEPENDS T_ON expr T_EOL }; /* visibility option */ - -visibility_list: - /* empty */ - | visibility_list visible - | visibility_list T_EOL -; - -visible: T_VISIBLE if_expr +visible: T_VISIBLE if_expr T_EOL { menu_add_visibility($2); }; @@ -479,14 +438,9 @@ prompt: T_WORD | T_WORD_QUOTE ; -end: T_ENDMENU T_EOL { $$ = $1; } - | T_ENDCHOICE T_EOL { $$ = $1; } - | T_ENDIF T_EOL { $$ = $1; } -; - -nl: - T_EOL - | nl T_EOL +end: T_ENDMENU T_EOL { $$ = "menu"; } + | T_ENDCHOICE T_EOL { $$ = "choice"; } + | T_ENDIF T_EOL { $$ = "if"; } ; if_expr: /* empty */ { $$ = NULL; } @@ -518,7 +472,13 @@ word_opt: /* empty */ { $$ = NULL; } /* assignment statement */ -assignment_stmt: T_VARIABLE T_ASSIGN assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } +assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } + +assign_op: + T_EQUAL { $$ = VAR_RECURSIVE; } + | T_COLON_EQUAL { $$ = VAR_SIMPLE; } + | T_PLUS_EQUAL { $$ = VAR_APPEND; } +; assign_val: /* empty */ { $$ = xstrdup(""); }; @@ -535,10 +495,9 @@ void conf_parse(const char *name) zconf_initscan(name); _menu_init(); -#if YYDEBUG + if (getenv("ZCONF_DEBUG")) yydebug = 1; -#endif yyparse(); /* Variables are expanded in the parse phase. We can free them here. */ @@ -564,35 +523,21 @@ void conf_parse(const char *name) sym_set_change_count(1); } -static const char *zconf_tokenname(int token) -{ - switch (token) { - case T_MENU: return "menu"; - case T_ENDMENU: return "endmenu"; - case T_CHOICE: return "choice"; - case T_ENDCHOICE: return "endchoice"; - case T_IF: return "if"; - case T_ENDIF: return "endif"; - case T_DEPENDS: return "depends"; - case T_VISIBLE: return "visible"; - } - return ""; -} - -static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken) +static bool zconf_endtoken(const char *tokenname, + const char *expected_tokenname) { - if (id->token != endtoken) { + if (strcmp(tokenname, expected_tokenname)) { zconf_error("unexpected '%s' within %s block", - id->name, zconf_tokenname(starttoken)); + tokenname, expected_tokenname); yynerrs++; return false; } if (current_menu->file != current_file) { zconf_error("'%s' in different file than '%s'", - id->name, zconf_tokenname(starttoken)); + tokenname, expected_tokenname); fprintf(stderr, "%s:%d: location of the '%s'\n", current_menu->file->name, current_menu->lineno, - zconf_tokenname(starttoken)); + expected_tokenname); yynerrs++; return false; } @@ -782,10 +727,5 @@ void zconfdump(FILE *out) } } -#include "zconf.lex.c" #include "util.c" -#include "confdata.c" -#include "expr.c" -#include "symbol.c" #include "menu.c" -#include "preprocess.c" -- cgit v1.2.3 From d057ba5324a082ba28d3b81f90405fae860bb376 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Wed, 9 Dec 2020 22:22:43 +1300 Subject: kconfig: Sync with upstream v5.1 This commit introduces the following upstream changes: 9c38f1f04408 kconfig/[mn]conf: handle backspace (^H) key c71bb9f86666 kconfig: remove stale lxdialog/.gitignore 8741908b3e29 kconfig: fix 'Save As' menu of xconfig 058507195b53 kbuild: move ".config not found!" message from Kconfig to Makefile 769a1c022678 kconfig: rename zconf.y to parser.y 981e545a698a kconfig: rename zconf.l to lexer.l Signed-off-by: Chris Packham --- kconfig/Makefile.am | 18 +- kconfig/conf.c | 13 - kconfig/expr.h | 2 +- kconfig/lexer.l | 470 ++++++++++++++++++++++++++++ kconfig/lkc.h | 2 +- kconfig/lxdialog/inputbox.c | 3 +- kconfig/nconf.c | 2 +- kconfig/nconf.gui.c | 3 +- kconfig/parser.y | 731 ++++++++++++++++++++++++++++++++++++++++++++ kconfig/zconf.l | 470 ---------------------------- kconfig/zconf.y | 731 -------------------------------------------- 11 files changed, 1217 insertions(+), 1228 deletions(-) create mode 100644 kconfig/lexer.l create mode 100644 kconfig/parser.y delete mode 100644 kconfig/zconf.l delete mode 100644 kconfig/zconf.y (limited to 'kconfig/nconf.c') diff --git a/kconfig/Makefile.am b/kconfig/Makefile.am index 82456060..2db26155 100644 --- a/kconfig/Makefile.am +++ b/kconfig/Makefile.am @@ -5,26 +5,26 @@ transform = s,x,x, pkglibexec_PROGRAMS = conf nconf mconf -EXTRA_DIST = zconf.y zconf.l \ +EXTRA_DIST = parser.y lexer.l \ expr.h list.h lkc.h lkc_proto.h nconf.h lxdialog/dialog.h \ confdata.c expr.c kconf_id.c menu.c symbol.c util.c -CLEANFILES = zconf.lex.c zconf.tab.c -BUILT_SOURCES = zconf.lex.c zconf.tab.c +CLEANFILES = lexer.lex.c parser.tab.c parser.tab.h +BUILT_SOURCES = lexer.lex.c parser.tab.c AM_LFLAGS = -L AM_YFLAGS = -t -l AM_CPPFLAGS = -include config.h -DCONFIG_=\"CT_\" AM_LIBTOOLFLAGS = --tag CC -conf_SOURCES = conf.c confdata.c expr.c symbol.c preprocess.c zconf.lex.c zconf.tab.c +conf_SOURCES = conf.c confdata.c expr.c symbol.c preprocess.c lexer.lex.c parser.tab.c conf_LDADD = $(LIBINTL) -nconf_SOURCES = nconf.c nconf.gui.c confdata.c expr.c symbol.c preprocess.c zconf.lex.c zconf.tab.c +nconf_SOURCES = nconf.c nconf.gui.c confdata.c expr.c symbol.c preprocess.c lexer.lex.c parser.tab.c nconf_CFLAGS = $(CURSES_CFLAGS) nconf_LDADD = $(MENU_LIBS) $(PANEL_LIBS) $(CURSES_LIBS) $(LIBINTL) -mconf_SOURCES = mconf.c confdata.c expr.c symbol.c preprocess.c zconf.lex.c zconf.tab.c \ +mconf_SOURCES = mconf.c confdata.c expr.c symbol.c preprocess.c lexer.lex.c parser.tab.c \ lxdialog/checklist.c lxdialog/inputbox.c \ lxdialog/menubox.c lxdialog/textbox.c lxdialog/util.c \ lxdialog/yesno.c @@ -43,8 +43,8 @@ AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; -zconf.tab.c: zconf.y - $(AM_V_YACC)$(YACCCOMPILE) -o$@ --defines=zconf.tab.h $< +parser.tab.c: parser.y + $(AM_V_YACC)$(YACCCOMPILE) -o$@ --defines=parser.tab.h $< -zconf.lex.c: zconf.l +lexer.lex.c: lexer.l $(AM_V_LEX)$(LEXCOMPILE) -o$@ $< diff --git a/kconfig/conf.c b/kconfig/conf.c index b86c7de8..67e32197 100644 --- a/kconfig/conf.c +++ b/kconfig/conf.c @@ -468,7 +468,6 @@ int main(int ac, char **av) const char *progname = av[0]; int opt; const char *name, *defconfig_file = NULL /* gcc uninit */; - struct stat tmpstat; int no_conf_write = 0; tty_stdio = isatty(0) && isatty(1); @@ -540,18 +539,6 @@ int main(int ac, char **av) name = av[optind]; conf_parse(name); //zconfdump(stdout); - if (sync_kconfig) { - name = conf_get_configname(); - if (stat(name, &tmpstat)) { - fprintf(stderr, "***\n" - "*** Configuration file \"%s\" not found!\n" - "***\n" - "*** Please configure with \"menuconfig\", or use a\n" - "*** pre-existing sample (see list with \"list-samples\").\n" - "***\n", name); - exit(1); - } - } switch (input_mode) { case defconfig: diff --git a/kconfig/expr.h b/kconfig/expr.h index 999edb60..8dde65bc 100644 --- a/kconfig/expr.h +++ b/kconfig/expr.h @@ -172,7 +172,7 @@ struct symbol { * int "BAZ Value" * range 1..255 * - * Please, also check zconf.y:print_symbol() when modifying the + * Please, also check parser.y:print_symbol() when modifying the * list of property types! */ enum prop_type { diff --git a/kconfig/lexer.l b/kconfig/lexer.l new file mode 100644 index 00000000..c9df1c8b --- /dev/null +++ b/kconfig/lexer.l @@ -0,0 +1,470 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2002 Roman Zippel + */ +%option nostdinit noyywrap never-interactive full ecs +%option 8bit nodefault yylineno +%x ASSIGN_VAL HELP STRING +%{ + +#include +#include +#include +#include +#include +#include + +#include "lkc.h" +#include "parser.tab.h" + +#define YY_DECL static int yylex1(void) + +#define START_STRSIZE 16 + +static struct { + struct file *file; + int lineno; +} current_pos; + +static int prev_prev_token = T_EOL; +static int prev_token = T_EOL; +static char *text; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +static int last_ts, first_ts; + +static char *expand_token(const char *in, size_t n); +static void append_expanded_string(const char *in); +static void zconf_endhelp(void); +static void zconf_endfile(void); + +static void new_string(void) +{ + text = xmalloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_size = 0; + *text = 0; +} + +static void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + new_size += START_STRSIZE - 1; + new_size &= -START_STRSIZE; + text = xrealloc(text, new_size); + text_asize = new_size; + } + memcpy(text + text_size, str, size); + text_size += size; + text[text_size] = 0; +} + +static void alloc_string(const char *str, int size) +{ + text = xmalloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} + +static void warn_ignored_character(char chr) +{ + fprintf(stderr, + "%s:%d:warning: ignoring unsupported character '%c'\n", + current_file->name, yylineno, chr); +} +%} + +n [A-Za-z0-9_-] + +%% + int str = 0; + int ts, i; + +#.* /* ignore comment */ +[ \t]* /* whitespaces */ +\\\n /* escaped new line */ +\n return T_EOL; +"allnoconfig_y" return T_ALLNOCONFIG_Y; +"bool" return T_BOOL; +"choice" return T_CHOICE; +"comment" return T_COMMENT; +"config" return T_CONFIG; +"def_bool" return T_DEF_BOOL; +"def_tristate" return T_DEF_TRISTATE; +"default" return T_DEFAULT; +"defconfig_list" return T_DEFCONFIG_LIST; +"depends" return T_DEPENDS; +"endchoice" return T_ENDCHOICE; +"endif" return T_ENDIF; +"endmenu" return T_ENDMENU; +"help"|"---help---" return T_HELP; +"hex" return T_HEX; +"if" return T_IF; +"imply" return T_IMPLY; +"int" return T_INT; +"mainmenu" return T_MAINMENU; +"menu" return T_MENU; +"menuconfig" return T_MENUCONFIG; +"modules" return T_MODULES; +"on" return T_ON; +"option" return T_OPTION; +"optional" return T_OPTIONAL; +"prompt" return T_PROMPT; +"range" return T_RANGE; +"select" return T_SELECT; +"source" return T_SOURCE; +"string" return T_STRING; +"tristate" return T_TRISTATE; +"visible" return T_VISIBLE; +"||" return T_OR; +"&&" return T_AND; +"=" return T_EQUAL; +"!=" return T_UNEQUAL; +"<" return T_LESS; +"<=" return T_LESS_EQUAL; +">" return T_GREATER; +">=" return T_GREATER_EQUAL; +"!" return T_NOT; +"(" return T_OPEN_PAREN; +")" return T_CLOSE_PAREN; +":=" return T_COLON_EQUAL; +"+=" return T_PLUS_EQUAL; +\"|\' { + str = yytext[0]; + new_string(); + BEGIN(STRING); + } +{n}+ { + alloc_string(yytext, yyleng); + yylval.string = text; + return T_WORD; + } +({n}|$)+ { + /* this token includes at least one '$' */ + yylval.string = expand_token(yytext, yyleng); + if (strlen(yylval.string)) + return T_WORD; + free(yylval.string); + } +. warn_ignored_character(*yytext); + +{ + [^[:blank:]\n]+.* { + alloc_string(yytext, yyleng); + yylval.string = text; + return T_ASSIGN_VAL; + } + \n { BEGIN(INITIAL); return T_EOL; } + . +} + +{ + "$".* append_expanded_string(yytext); + [^$'"\\\n]+ { + append_string(yytext, yyleng); + } + \\.? { + append_string(yytext + 1, yyleng - 1); + } + \'|\" { + if (str == yytext[0]) { + BEGIN(INITIAL); + yylval.string = text; + return T_WORD_QUOTE; + } else + append_string(yytext, 1); + } + \n { + fprintf(stderr, + "%s:%d:warning: multi-line strings not supported\n", + zconf_curname(), zconf_lineno()); + unput('\n'); + BEGIN(INITIAL); + yylval.string = text; + return T_WORD_QUOTE; + } + <> { + BEGIN(INITIAL); + yylval.string = text; + return T_WORD_QUOTE; + } +} + +{ + [ \t]+ { + ts = 0; + for (i = 0; i < yyleng; i++) { + if (yytext[i] == '\t') + ts = (ts & ~7) + 8; + else + ts++; + } + last_ts = ts; + if (first_ts) { + if (ts < first_ts) { + zconf_endhelp(); + return T_HELPTEXT; + } + ts -= first_ts; + while (ts > 8) { + append_string(" ", 8); + ts -= 8; + } + append_string(" ", ts); + } + } + [ \t]*\n/[^ \t\n] { + zconf_endhelp(); + return T_HELPTEXT; + } + [ \t]*\n { + append_string("\n", 1); + } + [^ \t\n].* { + while (yyleng) { + if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) + break; + yyleng--; + } + append_string(yytext, yyleng); + if (!first_ts) + first_ts = last_ts; + } + <> { + zconf_endhelp(); + return T_HELPTEXT; + } +} + +<> { + BEGIN(INITIAL); + + if (prev_token != T_EOL && prev_token != T_HELPTEXT) + fprintf(stderr, "%s:%d:warning: no new line at end of file\n", + current_file->name, yylineno); + + if (current_file) { + zconf_endfile(); + return T_EOL; + } + fclose(yyin); + yyterminate(); +} + +%% + +/* second stage lexer */ +int yylex(void) +{ + int token; + +repeat: + token = yylex1(); + + if (prev_token == T_EOL || prev_token == T_HELPTEXT) { + if (token == T_EOL) { + /* Do not pass unneeded T_EOL to the parser. */ + goto repeat; + } else { + /* + * For the parser, update file/lineno at the first token + * of each statement. Generally, \n is a statement + * terminator in Kconfig, but it is not always true + * because \n could be escaped by a backslash. + */ + current_pos.file = current_file; + current_pos.lineno = yylineno; + } + } + + if (prev_prev_token == T_EOL && prev_token == T_WORD && + (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL)) + BEGIN(ASSIGN_VAL); + + prev_prev_token = prev_token; + prev_token = token; + + return token; +} + +static char *expand_token(const char *in, size_t n) +{ + char *out; + int c; + char c2; + const char *rest, *end; + + new_string(); + append_string(in, n); + + /* get the whole line because we do not know the end of token. */ + while ((c = input()) != EOF) { + if (c == '\n') { + unput(c); + break; + } + c2 = c; + append_string(&c2, 1); + } + + rest = text; + out = expand_one_token(&rest); + + /* push back unused characters to the input stream */ + end = rest + strlen(rest); + while (end > rest) + unput(*--end); + + free(text); + + return out; +} + +static void append_expanded_string(const char *str) +{ + const char *end; + char *res; + + str++; + + res = expand_dollar(&str); + + /* push back unused characters to the input stream */ + end = str + strlen(str); + while (end > str) + unput(*--end); + + append_string(res, strlen(res)); + + free(res); +} + +void zconf_starthelp(void) +{ + new_string(); + last_ts = first_ts = 0; + BEGIN(HELP); +} + +static void zconf_endhelp(void) +{ + yylval.string = text; + BEGIN(INITIAL); +} + + +/* + * Try to open specified file with following names: + * ./name + * $(srctree)/name + * The latter is used when srctree is separate from objtree + * when compiling the kernel. + * Return NULL if file is not found. + */ +FILE *zconf_fopen(const char *name) +{ + char *env, fullname[PATH_MAX+1]; + FILE *f; + + f = fopen(name, "r"); + if (!f && name != NULL && name[0] != '/') { + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + f = fopen(fullname, "r"); + } + } + return f; +} + +void zconf_initscan(const char *name) +{ + yyin = zconf_fopen(name); + if (!yyin) { + fprintf(stderr, "can't find file %s\n", name); + exit(1); + } + + current_buf = xmalloc(sizeof(*current_buf)); + memset(current_buf, 0, sizeof(*current_buf)); + + current_file = file_lookup(name); + yylineno = 1; +} + +void zconf_nextfile(const char *name) +{ + struct file *iter; + struct file *file = file_lookup(name); + struct buffer *buf = xmalloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + yyin = zconf_fopen(file->name); + if (!yyin) { + fprintf(stderr, "%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->name); + exit(1); + } + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + current_file->lineno = yylineno; + file->parent = current_file; + + for (iter = current_file; iter; iter = iter->parent) { + if (!strcmp(iter->name, file->name)) { + fprintf(stderr, + "Recursive inclusion detected.\n" + "Inclusion path:\n" + " current file : %s\n", file->name); + iter = file; + do { + iter = iter->parent; + fprintf(stderr, " included from: %s:%d\n", + iter->name, iter->lineno - 1); + } while (strcmp(iter->name, file->name)); + exit(1); + } + } + + yylineno = 1; + current_file = file; +} + +static void zconf_endfile(void) +{ + struct buffer *parent; + + current_file = current_file->parent; + if (current_file) + yylineno = current_file->lineno; + + parent = current_buf->parent; + if (parent) { + fclose(yyin); + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(parent->state); + } + free(current_buf); + current_buf = parent; +} + +int zconf_lineno(void) +{ + return current_pos.lineno; +} + +const char *zconf_curname(void) +{ + return current_pos.file ? current_pos.file->name : ""; +} diff --git a/kconfig/lkc.h b/kconfig/lkc.h index 531ff7c5..d871539e 100644 --- a/kconfig/lkc.h +++ b/kconfig/lkc.h @@ -90,7 +90,7 @@ void *xrealloc(void *p, size_t size); char *xstrdup(const char *s); char *xstrndup(const char *s, size_t n); -/* zconf.l */ +/* lexer.l */ int yylex(void); struct gstr { diff --git a/kconfig/lxdialog/inputbox.c b/kconfig/lxdialog/inputbox.c index 61194561..1dcfb288 100644 --- a/kconfig/lxdialog/inputbox.c +++ b/kconfig/lxdialog/inputbox.c @@ -113,7 +113,8 @@ do_resize: case KEY_DOWN: break; case KEY_BACKSPACE: - case 127: + case 8: /* ^H */ + case 127: /* ^? */ if (pos) { wattrset(dialog, dlg.inputbox.atr); if (input_x == 0) { diff --git a/kconfig/nconf.c b/kconfig/nconf.c index fb6027af..96a6bac0 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -1051,7 +1051,7 @@ static int do_match(int key, struct match_state *state, int *ans) state->match_direction = FIND_NEXT_MATCH_UP; *ans = get_mext_match(state->pattern, state->match_direction); - } else if (key == KEY_BACKSPACE || key == 127) { + } else if (key == KEY_BACKSPACE || key == 8 || key == 127) { state->pattern[strlen(state->pattern)-1] = '\0'; adj_match_dir(&state->match_direction); } else diff --git a/kconfig/nconf.gui.c b/kconfig/nconf.gui.c index 7be620a1..77f525a8 100644 --- a/kconfig/nconf.gui.c +++ b/kconfig/nconf.gui.c @@ -439,7 +439,8 @@ int dialog_inputbox(WINDOW *main_window, case KEY_F(F_EXIT): case KEY_F(F_BACK): break; - case 127: + case 8: /* ^H */ + case 127: /* ^? */ case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], diff --git a/kconfig/parser.y b/kconfig/parser.y new file mode 100644 index 00000000..60936c76 --- /dev/null +++ b/kconfig/parser.y @@ -0,0 +1,731 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2002 Roman Zippel + */ +%{ + +#include +#include +#include +#include +#include +#include + +#include "lkc.h" + +#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) + +#define PRINTD 0x0001 +#define DEBUG_PARSE 0x0002 + +int cdebug = PRINTD; + +static void yyerror(const char *err); +static void zconfprint(const char *err, ...); +static void zconf_error(const char *err, ...); +static bool zconf_endtoken(const char *tokenname, + const char *expected_tokenname); + +struct symbol *symbol_hash[SYMBOL_HASHSIZE]; + +static struct menu *current_menu, *current_entry; + +%} + +%union +{ + char *string; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; + enum symbol_type type; + enum variable_flavor flavor; +} + +%token T_HELPTEXT +%token T_WORD +%token T_WORD_QUOTE +%token T_ALLNOCONFIG_Y +%token T_BOOL +%token T_CHOICE +%token T_CLOSE_PAREN +%token T_COLON_EQUAL +%token T_COMMENT +%token T_CONFIG +%token T_DEFAULT +%token T_DEFCONFIG_LIST +%token T_DEF_BOOL +%token T_DEF_TRISTATE +%token T_DEPENDS +%token T_ENDCHOICE +%token T_ENDIF +%token T_ENDMENU +%token T_HELP +%token T_HEX +%token T_IF +%token T_IMPLY +%token T_INT +%token T_MAINMENU +%token T_MENU +%token T_MENUCONFIG +%token T_MODULES +%token T_ON +%token T_OPEN_PAREN +%token T_OPTION +%token T_OPTIONAL +%token T_PLUS_EQUAL +%token T_PROMPT +%token T_RANGE +%token T_SELECT +%token T_SOURCE +%token T_STRING +%token T_TRISTATE +%token T_VISIBLE +%token T_EOL +%token T_ASSIGN_VAL + +%left T_OR +%left T_AND +%left T_EQUAL T_UNEQUAL +%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL +%nonassoc T_NOT + +%type prompt +%type nonconst_symbol +%type symbol +%type type logic_type default +%type expr +%type if_expr +%type end +%type if_entry menu_entry choice_entry +%type word_opt assign_val +%type assign_op + +%destructor { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + $$->file->name, $$->lineno); + if (current_menu == $$) + menu_end_menu(); +} if_entry menu_entry choice_entry + +%% +input: mainmenu_stmt stmt_list | stmt_list; + +/* mainmenu entry */ + +mainmenu_stmt: T_MAINMENU prompt T_EOL +{ + menu_add_prompt(P_MENU, $2, NULL); +}; + +stmt_list: + /* empty */ + | stmt_list common_stmt + | stmt_list choice_stmt + | stmt_list menu_stmt + | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } + | stmt_list error T_EOL { zconf_error("invalid statement"); } +; + +common_stmt: + if_stmt + | comment_stmt + | config_stmt + | menuconfig_stmt + | source_stmt + | assignment_stmt +; + +/* config/menuconfig entry */ + +config_entry_start: T_CONFIG nonconst_symbol T_EOL +{ + $2->flags |= SYMBOL_OPTIONAL; + menu_add_entry($2); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name); +}; + +config_stmt: config_entry_start config_option_list +{ + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL +{ + $2->flags |= SYMBOL_OPTIONAL; + menu_add_entry($2); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name); +}; + +menuconfig_stmt: menuconfig_entry_start config_option_list +{ + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +config_option_list: + /* empty */ + | config_option_list config_option + | config_option_list depends + | config_option_list help +; + +config_option: type prompt_stmt_opt T_EOL +{ + menu_set_type($1); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + $1); +}; + +config_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +config_option: default expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + if ($1 != S_UNKNOWN) + menu_set_type($1); + printd(DEBUG_PARSE, "%s:%d:default(%u)\n", + zconf_curname(), zconf_lineno(), + $1); +}; + +config_option: T_SELECT nonconst_symbol if_expr T_EOL +{ + menu_add_symbol(P_SELECT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_IMPLY nonconst_symbol if_expr T_EOL +{ + menu_add_symbol(P_IMPLY, $2, $3); + printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_RANGE symbol symbol if_expr T_EOL +{ + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_OPTION T_MODULES T_EOL +{ + menu_add_option_modules(); +}; + +config_option: T_OPTION T_DEFCONFIG_LIST T_EOL +{ + menu_add_option_defconfig_list(); +}; + +config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL +{ + menu_add_option_allnoconfig_y(); +}; + +/* choice entry */ + +choice: T_CHOICE word_opt T_EOL +{ + struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); + sym->flags |= SYMBOL_NO_WRITE; + menu_add_entry(sym); + menu_add_expr(P_CHOICE, NULL, NULL); + free($2); + printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); +}; + +choice_entry: choice choice_option_list +{ + $$ = menu_add_menu(); +}; + +choice_end: end +{ + if (zconf_endtoken($1, "choice")) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +}; + +choice_stmt: choice_entry choice_block choice_end +; + +choice_option_list: + /* empty */ + | choice_option_list choice_option + | choice_option_list depends + | choice_option_list help +; + +choice_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: logic_type prompt_stmt_opt T_EOL +{ + menu_set_type($1); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), $1); +}; + +choice_option: T_OPTIONAL T_EOL +{ + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL +{ + menu_add_symbol(P_DEFAULT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:default\n", + zconf_curname(), zconf_lineno()); +}; + +type: + logic_type + | T_INT { $$ = S_INT; } + | T_HEX { $$ = S_HEX; } + | T_STRING { $$ = S_STRING; } + +logic_type: + T_BOOL { $$ = S_BOOLEAN; } + | T_TRISTATE { $$ = S_TRISTATE; } + +default: + T_DEFAULT { $$ = S_UNKNOWN; } + | T_DEF_BOOL { $$ = S_BOOLEAN; } + | T_DEF_TRISTATE { $$ = S_TRISTATE; } + +choice_block: + /* empty */ + | choice_block common_stmt +; + +/* if entry */ + +if_entry: T_IF expr T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep($2); + $$ = menu_add_menu(); +}; + +if_end: end +{ + if (zconf_endtoken($1, "if")) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +}; + +if_stmt: if_entry stmt_list if_end +; + +/* menu entry */ + +menu: T_MENU prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prompt(P_MENU, $2, NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +}; + +menu_entry: menu menu_option_list +{ + $$ = menu_add_menu(); +}; + +menu_end: end +{ + if (zconf_endtoken($1, "menu")) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +}; + +menu_stmt: menu_entry stmt_list menu_end +; + +menu_option_list: + /* empty */ + | menu_option_list visible + | menu_option_list depends +; + +source_stmt: T_SOURCE prompt T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); + zconf_nextfile($2); + free($2); +}; + +/* comment entry */ + +comment: T_COMMENT prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prompt(P_COMMENT, $2, NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +}; + +comment_stmt: comment comment_option_list +; + +comment_option_list: + /* empty */ + | comment_option_list depends +; + +/* help option */ + +help_start: T_HELP T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +}; + +help: help_start T_HELPTEXT +{ + if (current_entry->help) { + free(current_entry->help); + zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used", + current_entry->sym->name ?: ""); + } + + /* Is the help text empty or all whitespace? */ + if ($2[strspn($2, " \f\n\r\t\v")] == '\0') + zconfprint("warning: '%s' defined with blank help text", + current_entry->sym->name ?: ""); + + current_entry->help = $2; +}; + +/* depends option */ + +depends: T_DEPENDS T_ON expr T_EOL +{ + menu_add_dep($3); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +}; + +/* visibility option */ +visible: T_VISIBLE if_expr T_EOL +{ + menu_add_visibility($2); +}; + +/* prompt statement */ + +prompt_stmt_opt: + /* empty */ + | prompt if_expr +{ + menu_add_prompt(P_PROMPT, $1, $2); +}; + +prompt: T_WORD + | T_WORD_QUOTE +; + +end: T_ENDMENU T_EOL { $$ = "menu"; } + | T_ENDCHOICE T_EOL { $$ = "choice"; } + | T_ENDIF T_EOL { $$ = "if"; } +; + +if_expr: /* empty */ { $$ = NULL; } + | T_IF expr { $$ = $2; } +; + +expr: symbol { $$ = expr_alloc_symbol($1); } + | symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); } + | symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); } + | symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); } + | symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); } + | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } + | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } + | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } + | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } + | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } + | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } +; + +/* For symbol definitions, selects, etc., where quotes are not accepted */ +nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }; + +symbol: nonconst_symbol + | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } +; + +word_opt: /* empty */ { $$ = NULL; } + | T_WORD + +/* assignment statement */ + +assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } + +assign_op: + T_EQUAL { $$ = VAR_RECURSIVE; } + | T_COLON_EQUAL { $$ = VAR_SIMPLE; } + | T_PLUS_EQUAL { $$ = VAR_APPEND; } +; + +assign_val: + /* empty */ { $$ = xstrdup(""); }; + | T_ASSIGN_VAL +; + +%% + +void conf_parse(const char *name) +{ + struct symbol *sym; + int i; + + zconf_initscan(name); + + _menu_init(); + + if (getenv("ZCONF_DEBUG")) + yydebug = 1; + yyparse(); + + /* Variables are expanded in the parse phase. We can free them here. */ + variable_all_del(); + + if (yynerrs) + exit(1); + if (!modules_sym) + modules_sym = sym_find( "n" ); + + if (!menu_has_prompt(&rootmenu)) { + current_entry = &rootmenu; + menu_add_prompt(P_MENU, "Main menu", NULL); + } + + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + if (sym_check_deps(sym)) + yynerrs++; + } + if (yynerrs) + exit(1); + sym_set_change_count(1); +} + +static bool zconf_endtoken(const char *tokenname, + const char *expected_tokenname) +{ + if (strcmp(tokenname, expected_tokenname)) { + zconf_error("unexpected '%s' within %s block", + tokenname, expected_tokenname); + yynerrs++; + return false; + } + if (current_menu->file != current_file) { + zconf_error("'%s' in different file than '%s'", + tokenname, expected_tokenname); + fprintf(stderr, "%s:%d: location of the '%s'\n", + current_menu->file->name, current_menu->lineno, + expected_tokenname); + yynerrs++; + return false; + } + return true; +} + +static void zconfprint(const char *err, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconf_error(const char *err, ...) +{ + va_list ap; + + yynerrs++; + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void yyerror(const char *err) +{ + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +} + +static void print_quoted_string(FILE *out, const char *str) +{ + const char *p; + int len; + + putc('"', out); + while ((p = strchr(str, '"'))) { + len = p - str; + if (len) + fprintf(out, "%.*s", len, str); + fputs("\\\"", out); + str = p + 1; + } + fputs(str, out); + putc('"', out); +} + +static void print_symbol(FILE *out, struct menu *menu) +{ + struct symbol *sym = menu->sym; + struct property *prop; + + if (sym_is_choice(sym)) + fprintf(out, "\nchoice\n"); + else + fprintf(out, "\nconfig %s\n", sym->name); + switch (sym->type) { + case S_BOOLEAN: + fputs(" bool\n", out); + break; + case S_TRISTATE: + fputs(" tristate\n", out); + break; + case S_STRING: + fputs(" string\n", out); + break; + case S_INT: + fputs(" integer\n", out); + break; + case S_HEX: + fputs(" hex\n", out); + break; + default: + fputs(" ???\n", out); + break; + } + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + switch (prop->type) { + case P_PROMPT: + fputs(" prompt ", out); + print_quoted_string(out, prop->text); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_DEFAULT: + fputs( " default ", out); + expr_fprint(prop->expr, out); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_CHOICE: + fputs(" #choice value\n", out); + break; + case P_SELECT: + fputs( " select ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_IMPLY: + fputs( " imply ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_RANGE: + fputs( " range ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_MENU: + fputs( " menu ", out); + print_quoted_string(out, prop->text); + fputc('\n', out); + break; + case P_SYMBOL: + fputs( " symbol ", out); + fprintf(out, "%s\n", prop->sym->name); + break; + default: + fprintf(out, " unknown prop %d!\n", prop->type); + break; + } + } + if (menu->help) { + int len = strlen(menu->help); + while (menu->help[--len] == '\n') + menu->help[len] = 0; + fprintf(out, " help\n%s\n", menu->help); + } +} + +void zconfdump(FILE *out) +{ + struct property *prop; + struct symbol *sym; + struct menu *menu; + + menu = rootmenu.list; + while (menu) { + if ((sym = menu->sym)) + print_symbol(out, menu); + else if ((prop = menu->prompt)) { + switch (prop->type) { + case P_COMMENT: + fputs("\ncomment ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + case P_MENU: + fputs("\nmenu ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + default: + ; + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" depends ", out); + expr_fprint(prop->visible.expr, out); + fputc('\n', out); + } + } + + if (menu->list) + menu = menu->list; + else if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->prompt && menu->prompt->type == P_MENU) + fputs("\nendmenu\n", out); + if (menu->next) { + menu = menu->next; + break; + } + } + } +} + +#include "util.c" +#include "menu.c" diff --git a/kconfig/zconf.l b/kconfig/zconf.l deleted file mode 100644 index b2d0a3b0..00000000 --- a/kconfig/zconf.l +++ /dev/null @@ -1,470 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2002 Roman Zippel - */ -%option nostdinit noyywrap never-interactive full ecs -%option 8bit nodefault yylineno -%x ASSIGN_VAL HELP STRING -%{ - -#include -#include -#include -#include -#include -#include - -#include "lkc.h" -#include "zconf.tab.h" - -#define YY_DECL static int yylex1(void) - -#define START_STRSIZE 16 - -static struct { - struct file *file; - int lineno; -} current_pos; - -static int prev_prev_token = T_EOL; -static int prev_token = T_EOL; -static char *text; -static int text_size, text_asize; - -struct buffer { - struct buffer *parent; - YY_BUFFER_STATE state; -}; - -struct buffer *current_buf; - -static int last_ts, first_ts; - -static char *expand_token(const char *in, size_t n); -static void append_expanded_string(const char *in); -static void zconf_endhelp(void); -static void zconf_endfile(void); - -static void new_string(void) -{ - text = xmalloc(START_STRSIZE); - text_asize = START_STRSIZE; - text_size = 0; - *text = 0; -} - -static void append_string(const char *str, int size) -{ - int new_size = text_size + size + 1; - if (new_size > text_asize) { - new_size += START_STRSIZE - 1; - new_size &= -START_STRSIZE; - text = xrealloc(text, new_size); - text_asize = new_size; - } - memcpy(text + text_size, str, size); - text_size += size; - text[text_size] = 0; -} - -static void alloc_string(const char *str, int size) -{ - text = xmalloc(size + 1); - memcpy(text, str, size); - text[size] = 0; -} - -static void warn_ignored_character(char chr) -{ - fprintf(stderr, - "%s:%d:warning: ignoring unsupported character '%c'\n", - current_file->name, yylineno, chr); -} -%} - -n [A-Za-z0-9_-] - -%% - int str = 0; - int ts, i; - -#.* /* ignore comment */ -[ \t]* /* whitespaces */ -\\\n /* escaped new line */ -\n return T_EOL; -"allnoconfig_y" return T_ALLNOCONFIG_Y; -"bool" return T_BOOL; -"choice" return T_CHOICE; -"comment" return T_COMMENT; -"config" return T_CONFIG; -"def_bool" return T_DEF_BOOL; -"def_tristate" return T_DEF_TRISTATE; -"default" return T_DEFAULT; -"defconfig_list" return T_DEFCONFIG_LIST; -"depends" return T_DEPENDS; -"endchoice" return T_ENDCHOICE; -"endif" return T_ENDIF; -"endmenu" return T_ENDMENU; -"help"|"---help---" return T_HELP; -"hex" return T_HEX; -"if" return T_IF; -"imply" return T_IMPLY; -"int" return T_INT; -"mainmenu" return T_MAINMENU; -"menu" return T_MENU; -"menuconfig" return T_MENUCONFIG; -"modules" return T_MODULES; -"on" return T_ON; -"option" return T_OPTION; -"optional" return T_OPTIONAL; -"prompt" return T_PROMPT; -"range" return T_RANGE; -"select" return T_SELECT; -"source" return T_SOURCE; -"string" return T_STRING; -"tristate" return T_TRISTATE; -"visible" return T_VISIBLE; -"||" return T_OR; -"&&" return T_AND; -"=" return T_EQUAL; -"!=" return T_UNEQUAL; -"<" return T_LESS; -"<=" return T_LESS_EQUAL; -">" return T_GREATER; -">=" return T_GREATER_EQUAL; -"!" return T_NOT; -"(" return T_OPEN_PAREN; -")" return T_CLOSE_PAREN; -":=" return T_COLON_EQUAL; -"+=" return T_PLUS_EQUAL; -\"|\' { - str = yytext[0]; - new_string(); - BEGIN(STRING); - } -{n}+ { - alloc_string(yytext, yyleng); - yylval.string = text; - return T_WORD; - } -({n}|$)+ { - /* this token includes at least one '$' */ - yylval.string = expand_token(yytext, yyleng); - if (strlen(yylval.string)) - return T_WORD; - free(yylval.string); - } -. warn_ignored_character(*yytext); - -{ - [^[:blank:]\n]+.* { - alloc_string(yytext, yyleng); - yylval.string = text; - return T_ASSIGN_VAL; - } - \n { BEGIN(INITIAL); return T_EOL; } - . -} - -{ - "$".* append_expanded_string(yytext); - [^$'"\\\n]+ { - append_string(yytext, yyleng); - } - \\.? { - append_string(yytext + 1, yyleng - 1); - } - \'|\" { - if (str == yytext[0]) { - BEGIN(INITIAL); - yylval.string = text; - return T_WORD_QUOTE; - } else - append_string(yytext, 1); - } - \n { - fprintf(stderr, - "%s:%d:warning: multi-line strings not supported\n", - zconf_curname(), zconf_lineno()); - unput('\n'); - BEGIN(INITIAL); - yylval.string = text; - return T_WORD_QUOTE; - } - <> { - BEGIN(INITIAL); - yylval.string = text; - return T_WORD_QUOTE; - } -} - -{ - [ \t]+ { - ts = 0; - for (i = 0; i < yyleng; i++) { - if (yytext[i] == '\t') - ts = (ts & ~7) + 8; - else - ts++; - } - last_ts = ts; - if (first_ts) { - if (ts < first_ts) { - zconf_endhelp(); - return T_HELPTEXT; - } - ts -= first_ts; - while (ts > 8) { - append_string(" ", 8); - ts -= 8; - } - append_string(" ", ts); - } - } - [ \t]*\n/[^ \t\n] { - zconf_endhelp(); - return T_HELPTEXT; - } - [ \t]*\n { - append_string("\n", 1); - } - [^ \t\n].* { - while (yyleng) { - if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) - break; - yyleng--; - } - append_string(yytext, yyleng); - if (!first_ts) - first_ts = last_ts; - } - <> { - zconf_endhelp(); - return T_HELPTEXT; - } -} - -<> { - BEGIN(INITIAL); - - if (prev_token != T_EOL && prev_token != T_HELPTEXT) - fprintf(stderr, "%s:%d:warning: no new line at end of file\n", - current_file->name, yylineno); - - if (current_file) { - zconf_endfile(); - return T_EOL; - } - fclose(yyin); - yyterminate(); -} - -%% - -/* second stage lexer */ -int yylex(void) -{ - int token; - -repeat: - token = yylex1(); - - if (prev_token == T_EOL || prev_token == T_HELPTEXT) { - if (token == T_EOL) { - /* Do not pass unneeded T_EOL to the parser. */ - goto repeat; - } else { - /* - * For the parser, update file/lineno at the first token - * of each statement. Generally, \n is a statement - * terminator in Kconfig, but it is not always true - * because \n could be escaped by a backslash. - */ - current_pos.file = current_file; - current_pos.lineno = yylineno; - } - } - - if (prev_prev_token == T_EOL && prev_token == T_WORD && - (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL)) - BEGIN(ASSIGN_VAL); - - prev_prev_token = prev_token; - prev_token = token; - - return token; -} - -static char *expand_token(const char *in, size_t n) -{ - char *out; - int c; - char c2; - const char *rest, *end; - - new_string(); - append_string(in, n); - - /* get the whole line because we do not know the end of token. */ - while ((c = input()) != EOF) { - if (c == '\n') { - unput(c); - break; - } - c2 = c; - append_string(&c2, 1); - } - - rest = text; - out = expand_one_token(&rest); - - /* push back unused characters to the input stream */ - end = rest + strlen(rest); - while (end > rest) - unput(*--end); - - free(text); - - return out; -} - -static void append_expanded_string(const char *str) -{ - const char *end; - char *res; - - str++; - - res = expand_dollar(&str); - - /* push back unused characters to the input stream */ - end = str + strlen(str); - while (end > str) - unput(*--end); - - append_string(res, strlen(res)); - - free(res); -} - -void zconf_starthelp(void) -{ - new_string(); - last_ts = first_ts = 0; - BEGIN(HELP); -} - -static void zconf_endhelp(void) -{ - yylval.string = text; - BEGIN(INITIAL); -} - - -/* - * Try to open specified file with following names: - * ./name - * $(srctree)/name - * The latter is used when srctree is separate from objtree - * when compiling the kernel. - * Return NULL if file is not found. - */ -FILE *zconf_fopen(const char *name) -{ - char *env, fullname[PATH_MAX+1]; - FILE *f; - - f = fopen(name, "r"); - if (!f && name != NULL && name[0] != '/') { - env = getenv(SRCTREE); - if (env) { - sprintf(fullname, "%s/%s", env, name); - f = fopen(fullname, "r"); - } - } - return f; -} - -void zconf_initscan(const char *name) -{ - yyin = zconf_fopen(name); - if (!yyin) { - fprintf(stderr, "can't find file %s\n", name); - exit(1); - } - - current_buf = xmalloc(sizeof(*current_buf)); - memset(current_buf, 0, sizeof(*current_buf)); - - current_file = file_lookup(name); - yylineno = 1; -} - -void zconf_nextfile(const char *name) -{ - struct file *iter; - struct file *file = file_lookup(name); - struct buffer *buf = xmalloc(sizeof(*buf)); - memset(buf, 0, sizeof(*buf)); - - current_buf->state = YY_CURRENT_BUFFER; - yyin = zconf_fopen(file->name); - if (!yyin) { - fprintf(stderr, "%s:%d: can't open file \"%s\"\n", - zconf_curname(), zconf_lineno(), file->name); - exit(1); - } - yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); - buf->parent = current_buf; - current_buf = buf; - - current_file->lineno = yylineno; - file->parent = current_file; - - for (iter = current_file; iter; iter = iter->parent) { - if (!strcmp(iter->name, file->name)) { - fprintf(stderr, - "Recursive inclusion detected.\n" - "Inclusion path:\n" - " current file : %s\n", file->name); - iter = file; - do { - iter = iter->parent; - fprintf(stderr, " included from: %s:%d\n", - iter->name, iter->lineno - 1); - } while (strcmp(iter->name, file->name)); - exit(1); - } - } - - yylineno = 1; - current_file = file; -} - -static void zconf_endfile(void) -{ - struct buffer *parent; - - current_file = current_file->parent; - if (current_file) - yylineno = current_file->lineno; - - parent = current_buf->parent; - if (parent) { - fclose(yyin); - yy_delete_buffer(YY_CURRENT_BUFFER); - yy_switch_to_buffer(parent->state); - } - free(current_buf); - current_buf = parent; -} - -int zconf_lineno(void) -{ - return current_pos.lineno; -} - -const char *zconf_curname(void) -{ - return current_pos.file ? current_pos.file->name : ""; -} diff --git a/kconfig/zconf.y b/kconfig/zconf.y deleted file mode 100644 index 60936c76..00000000 --- a/kconfig/zconf.y +++ /dev/null @@ -1,731 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2002 Roman Zippel - */ -%{ - -#include -#include -#include -#include -#include -#include - -#include "lkc.h" - -#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) - -#define PRINTD 0x0001 -#define DEBUG_PARSE 0x0002 - -int cdebug = PRINTD; - -static void yyerror(const char *err); -static void zconfprint(const char *err, ...); -static void zconf_error(const char *err, ...); -static bool zconf_endtoken(const char *tokenname, - const char *expected_tokenname); - -struct symbol *symbol_hash[SYMBOL_HASHSIZE]; - -static struct menu *current_menu, *current_entry; - -%} - -%union -{ - char *string; - struct symbol *symbol; - struct expr *expr; - struct menu *menu; - enum symbol_type type; - enum variable_flavor flavor; -} - -%token T_HELPTEXT -%token T_WORD -%token T_WORD_QUOTE -%token T_ALLNOCONFIG_Y -%token T_BOOL -%token T_CHOICE -%token T_CLOSE_PAREN -%token T_COLON_EQUAL -%token T_COMMENT -%token T_CONFIG -%token T_DEFAULT -%token T_DEFCONFIG_LIST -%token T_DEF_BOOL -%token T_DEF_TRISTATE -%token T_DEPENDS -%token T_ENDCHOICE -%token T_ENDIF -%token T_ENDMENU -%token T_HELP -%token T_HEX -%token T_IF -%token T_IMPLY -%token T_INT -%token T_MAINMENU -%token T_MENU -%token T_MENUCONFIG -%token T_MODULES -%token T_ON -%token T_OPEN_PAREN -%token T_OPTION -%token T_OPTIONAL -%token T_PLUS_EQUAL -%token T_PROMPT -%token T_RANGE -%token T_SELECT -%token T_SOURCE -%token T_STRING -%token T_TRISTATE -%token T_VISIBLE -%token T_EOL -%token T_ASSIGN_VAL - -%left T_OR -%left T_AND -%left T_EQUAL T_UNEQUAL -%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL -%nonassoc T_NOT - -%type prompt -%type nonconst_symbol -%type symbol -%type type logic_type default -%type expr -%type if_expr -%type end -%type if_entry menu_entry choice_entry -%type word_opt assign_val -%type assign_op - -%destructor { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - $$->file->name, $$->lineno); - if (current_menu == $$) - menu_end_menu(); -} if_entry menu_entry choice_entry - -%% -input: mainmenu_stmt stmt_list | stmt_list; - -/* mainmenu entry */ - -mainmenu_stmt: T_MAINMENU prompt T_EOL -{ - menu_add_prompt(P_MENU, $2, NULL); -}; - -stmt_list: - /* empty */ - | stmt_list common_stmt - | stmt_list choice_stmt - | stmt_list menu_stmt - | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } - | stmt_list error T_EOL { zconf_error("invalid statement"); } -; - -common_stmt: - if_stmt - | comment_stmt - | config_stmt - | menuconfig_stmt - | source_stmt - | assignment_stmt -; - -/* config/menuconfig entry */ - -config_entry_start: T_CONFIG nonconst_symbol T_EOL -{ - $2->flags |= SYMBOL_OPTIONAL; - menu_add_entry($2); - printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name); -}; - -config_stmt: config_entry_start config_option_list -{ - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -}; - -menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL -{ - $2->flags |= SYMBOL_OPTIONAL; - menu_add_entry($2); - printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name); -}; - -menuconfig_stmt: menuconfig_entry_start config_option_list -{ - if (current_entry->prompt) - current_entry->prompt->type = P_MENU; - else - zconfprint("warning: menuconfig statement without prompt"); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -}; - -config_option_list: - /* empty */ - | config_option_list config_option - | config_option_list depends - | config_option_list help -; - -config_option: type prompt_stmt_opt T_EOL -{ - menu_set_type($1); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), - $1); -}; - -config_option: T_PROMPT prompt if_expr T_EOL -{ - menu_add_prompt(P_PROMPT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -}; - -config_option: default expr if_expr T_EOL -{ - menu_add_expr(P_DEFAULT, $2, $3); - if ($1 != S_UNKNOWN) - menu_set_type($1); - printd(DEBUG_PARSE, "%s:%d:default(%u)\n", - zconf_curname(), zconf_lineno(), - $1); -}; - -config_option: T_SELECT nonconst_symbol if_expr T_EOL -{ - menu_add_symbol(P_SELECT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); -}; - -config_option: T_IMPLY nonconst_symbol if_expr T_EOL -{ - menu_add_symbol(P_IMPLY, $2, $3); - printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); -}; - -config_option: T_RANGE symbol symbol if_expr T_EOL -{ - menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); - printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); -}; - -config_option: T_OPTION T_MODULES T_EOL -{ - menu_add_option_modules(); -}; - -config_option: T_OPTION T_DEFCONFIG_LIST T_EOL -{ - menu_add_option_defconfig_list(); -}; - -config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL -{ - menu_add_option_allnoconfig_y(); -}; - -/* choice entry */ - -choice: T_CHOICE word_opt T_EOL -{ - struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); - sym->flags |= SYMBOL_NO_WRITE; - menu_add_entry(sym); - menu_add_expr(P_CHOICE, NULL, NULL); - free($2); - printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); -}; - -choice_entry: choice choice_option_list -{ - $$ = menu_add_menu(); -}; - -choice_end: end -{ - if (zconf_endtoken($1, "choice")) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); - } -}; - -choice_stmt: choice_entry choice_block choice_end -; - -choice_option_list: - /* empty */ - | choice_option_list choice_option - | choice_option_list depends - | choice_option_list help -; - -choice_option: T_PROMPT prompt if_expr T_EOL -{ - menu_add_prompt(P_PROMPT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -}; - -choice_option: logic_type prompt_stmt_opt T_EOL -{ - menu_set_type($1); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), $1); -}; - -choice_option: T_OPTIONAL T_EOL -{ - current_entry->sym->flags |= SYMBOL_OPTIONAL; - printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); -}; - -choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL -{ - menu_add_symbol(P_DEFAULT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:default\n", - zconf_curname(), zconf_lineno()); -}; - -type: - logic_type - | T_INT { $$ = S_INT; } - | T_HEX { $$ = S_HEX; } - | T_STRING { $$ = S_STRING; } - -logic_type: - T_BOOL { $$ = S_BOOLEAN; } - | T_TRISTATE { $$ = S_TRISTATE; } - -default: - T_DEFAULT { $$ = S_UNKNOWN; } - | T_DEF_BOOL { $$ = S_BOOLEAN; } - | T_DEF_TRISTATE { $$ = S_TRISTATE; } - -choice_block: - /* empty */ - | choice_block common_stmt -; - -/* if entry */ - -if_entry: T_IF expr T_EOL -{ - printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); - menu_add_entry(NULL); - menu_add_dep($2); - $$ = menu_add_menu(); -}; - -if_end: end -{ - if (zconf_endtoken($1, "if")) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); - } -}; - -if_stmt: if_entry stmt_list if_end -; - -/* menu entry */ - -menu: T_MENU prompt T_EOL -{ - menu_add_entry(NULL); - menu_add_prompt(P_MENU, $2, NULL); - printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); -}; - -menu_entry: menu menu_option_list -{ - $$ = menu_add_menu(); -}; - -menu_end: end -{ - if (zconf_endtoken($1, "menu")) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); - } -}; - -menu_stmt: menu_entry stmt_list menu_end -; - -menu_option_list: - /* empty */ - | menu_option_list visible - | menu_option_list depends -; - -source_stmt: T_SOURCE prompt T_EOL -{ - printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); - zconf_nextfile($2); - free($2); -}; - -/* comment entry */ - -comment: T_COMMENT prompt T_EOL -{ - menu_add_entry(NULL); - menu_add_prompt(P_COMMENT, $2, NULL); - printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); -}; - -comment_stmt: comment comment_option_list -; - -comment_option_list: - /* empty */ - | comment_option_list depends -; - -/* help option */ - -help_start: T_HELP T_EOL -{ - printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); - zconf_starthelp(); -}; - -help: help_start T_HELPTEXT -{ - if (current_entry->help) { - free(current_entry->help); - zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used", - current_entry->sym->name ?: ""); - } - - /* Is the help text empty or all whitespace? */ - if ($2[strspn($2, " \f\n\r\t\v")] == '\0') - zconfprint("warning: '%s' defined with blank help text", - current_entry->sym->name ?: ""); - - current_entry->help = $2; -}; - -/* depends option */ - -depends: T_DEPENDS T_ON expr T_EOL -{ - menu_add_dep($3); - printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); -}; - -/* visibility option */ -visible: T_VISIBLE if_expr T_EOL -{ - menu_add_visibility($2); -}; - -/* prompt statement */ - -prompt_stmt_opt: - /* empty */ - | prompt if_expr -{ - menu_add_prompt(P_PROMPT, $1, $2); -}; - -prompt: T_WORD - | T_WORD_QUOTE -; - -end: T_ENDMENU T_EOL { $$ = "menu"; } - | T_ENDCHOICE T_EOL { $$ = "choice"; } - | T_ENDIF T_EOL { $$ = "if"; } -; - -if_expr: /* empty */ { $$ = NULL; } - | T_IF expr { $$ = $2; } -; - -expr: symbol { $$ = expr_alloc_symbol($1); } - | symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); } - | symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); } - | symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); } - | symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); } - | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } - | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } - | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } - | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } - | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } - | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } -; - -/* For symbol definitions, selects, etc., where quotes are not accepted */ -nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }; - -symbol: nonconst_symbol - | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } -; - -word_opt: /* empty */ { $$ = NULL; } - | T_WORD - -/* assignment statement */ - -assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } - -assign_op: - T_EQUAL { $$ = VAR_RECURSIVE; } - | T_COLON_EQUAL { $$ = VAR_SIMPLE; } - | T_PLUS_EQUAL { $$ = VAR_APPEND; } -; - -assign_val: - /* empty */ { $$ = xstrdup(""); }; - | T_ASSIGN_VAL -; - -%% - -void conf_parse(const char *name) -{ - struct symbol *sym; - int i; - - zconf_initscan(name); - - _menu_init(); - - if (getenv("ZCONF_DEBUG")) - yydebug = 1; - yyparse(); - - /* Variables are expanded in the parse phase. We can free them here. */ - variable_all_del(); - - if (yynerrs) - exit(1); - if (!modules_sym) - modules_sym = sym_find( "n" ); - - if (!menu_has_prompt(&rootmenu)) { - current_entry = &rootmenu; - menu_add_prompt(P_MENU, "Main menu", NULL); - } - - menu_finalize(&rootmenu); - for_all_symbols(i, sym) { - if (sym_check_deps(sym)) - yynerrs++; - } - if (yynerrs) - exit(1); - sym_set_change_count(1); -} - -static bool zconf_endtoken(const char *tokenname, - const char *expected_tokenname) -{ - if (strcmp(tokenname, expected_tokenname)) { - zconf_error("unexpected '%s' within %s block", - tokenname, expected_tokenname); - yynerrs++; - return false; - } - if (current_menu->file != current_file) { - zconf_error("'%s' in different file than '%s'", - tokenname, expected_tokenname); - fprintf(stderr, "%s:%d: location of the '%s'\n", - current_menu->file->name, current_menu->lineno, - expected_tokenname); - yynerrs++; - return false; - } - return true; -} - -static void zconfprint(const char *err, ...) -{ - va_list ap; - - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void zconf_error(const char *err, ...) -{ - va_list ap; - - yynerrs++; - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void yyerror(const char *err) -{ - fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); -} - -static void print_quoted_string(FILE *out, const char *str) -{ - const char *p; - int len; - - putc('"', out); - while ((p = strchr(str, '"'))) { - len = p - str; - if (len) - fprintf(out, "%.*s", len, str); - fputs("\\\"", out); - str = p + 1; - } - fputs(str, out); - putc('"', out); -} - -static void print_symbol(FILE *out, struct menu *menu) -{ - struct symbol *sym = menu->sym; - struct property *prop; - - if (sym_is_choice(sym)) - fprintf(out, "\nchoice\n"); - else - fprintf(out, "\nconfig %s\n", sym->name); - switch (sym->type) { - case S_BOOLEAN: - fputs(" bool\n", out); - break; - case S_TRISTATE: - fputs(" tristate\n", out); - break; - case S_STRING: - fputs(" string\n", out); - break; - case S_INT: - fputs(" integer\n", out); - break; - case S_HEX: - fputs(" hex\n", out); - break; - default: - fputs(" ???\n", out); - break; - } - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu != menu) - continue; - switch (prop->type) { - case P_PROMPT: - fputs(" prompt ", out); - print_quoted_string(out, prop->text); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_DEFAULT: - fputs( " default ", out); - expr_fprint(prop->expr, out); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_CHOICE: - fputs(" #choice value\n", out); - break; - case P_SELECT: - fputs( " select ", out); - expr_fprint(prop->expr, out); - fputc('\n', out); - break; - case P_IMPLY: - fputs( " imply ", out); - expr_fprint(prop->expr, out); - fputc('\n', out); - break; - case P_RANGE: - fputs( " range ", out); - expr_fprint(prop->expr, out); - fputc('\n', out); - break; - case P_MENU: - fputs( " menu ", out); - print_quoted_string(out, prop->text); - fputc('\n', out); - break; - case P_SYMBOL: - fputs( " symbol ", out); - fprintf(out, "%s\n", prop->sym->name); - break; - default: - fprintf(out, " unknown prop %d!\n", prop->type); - break; - } - } - if (menu->help) { - int len = strlen(menu->help); - while (menu->help[--len] == '\n') - menu->help[len] = 0; - fprintf(out, " help\n%s\n", menu->help); - } -} - -void zconfdump(FILE *out) -{ - struct property *prop; - struct symbol *sym; - struct menu *menu; - - menu = rootmenu.list; - while (menu) { - if ((sym = menu->sym)) - print_symbol(out, menu); - else if ((prop = menu->prompt)) { - switch (prop->type) { - case P_COMMENT: - fputs("\ncomment ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - case P_MENU: - fputs("\nmenu ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - default: - ; - } - if (!expr_is_yes(prop->visible.expr)) { - fputs(" depends ", out); - expr_fprint(prop->visible.expr, out); - fputc('\n', out); - } - } - - if (menu->list) - menu = menu->list; - else if (menu->next) - menu = menu->next; - else while ((menu = menu->parent)) { - if (menu->prompt && menu->prompt->type == P_MENU) - fputs("\nendmenu\n", out); - if (menu->next) { - menu = menu->next; - break; - } - } - } -} - -#include "util.c" -#include "menu.c" -- cgit v1.2.3 From 141f88a5f640625f63f70dad6f216a81596c42fc Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Wed, 9 Dec 2020 22:27:48 +1300 Subject: kconfig: Sync with upstream v5.2 This commit introduces the following upstream changes: 8dde5715b280 kconfig: tests: fix recursive inclusion unit test ec8f24b7faaf treewide: Add SPDX license identifier - Makefile/Kconfig fc2694ec1ab7 kconfig: use 'else ifneq' for Makefile to improve readability aff11cd983ec kconfig: Terminate menu blocks with a comment in the generated config 9cc342f6c4a0 treewide: prefix header search paths with $(srctree)/ 9b9f5948afcd kconfig: make conf_get_autoconfig_name() static b9d1a8e9302e kconfig: use snprintf for formatting pathnames 4cb726121e2c kconfig: remove useless NULL pointer check in conf_write_dep() 580c5b3e1b8b kconfig: make parent directories for the saved .config as needed 67424f61f813 kconfig: do not write .config if the content is the same ceb7f3296ea1 kconfig: do not accept a directory for configuration output 65be755a5411 kconfig: remove trailing whitespaces b63e37bc9ec4 kconfig: Make nconf-cfg.sh executable Signed-off-by: Chris Packham --- kconfig/confdata.c | 134 +++++++++++++++++++++++++++------------ kconfig/lexer.l | 3 +- kconfig/lkc.h | 1 - kconfig/lxdialog/BIG.FAT.WARNING | 2 +- kconfig/mconf.c | 2 +- kconfig/nconf.c | 3 +- 6 files changed, 100 insertions(+), 45 deletions(-) (limited to 'kconfig/nconf.c') diff --git a/kconfig/confdata.c b/kconfig/confdata.c index 08ba146a..6006154d 100644 --- a/kconfig/confdata.c +++ b/kconfig/confdata.c @@ -3,6 +3,7 @@ * Copyright (C) 2002 Roman Zippel */ +#include #include #include #include @@ -36,6 +37,52 @@ static bool is_dir(const char *path) return S_ISDIR(st.st_mode); } +/* return true if the given two files are the same, false otherwise */ +static bool is_same(const char *file1, const char *file2) +{ + int fd1, fd2; + struct stat st1, st2; + void *map1, *map2; + bool ret = false; + + fd1 = open(file1, O_RDONLY); + if (fd1 < 0) + return ret; + + fd2 = open(file2, O_RDONLY); + if (fd2 < 0) + goto close1; + + ret = fstat(fd1, &st1); + if (ret) + goto close2; + ret = fstat(fd2, &st2); + if (ret) + goto close2; + + if (st1.st_size != st2.st_size) + goto close2; + + map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); + if (map1 == MAP_FAILED) + goto close2; + + map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); + if (map2 == MAP_FAILED) + goto close2; + + if (bcmp(map1, map2, st1.st_size)) + goto close2; + + ret = true; +close2: + close(fd2); +close1: + close(fd1); + + return ret; +} + /* * Create the parent directory of the given path. * @@ -179,7 +226,7 @@ const char *conf_get_configname(void) return name ? name : ".config"; } -const char *conf_get_autoconfig_name(void) +static const char *conf_get_autoconfig_name(void) { char *name = getenv("KCONFIG_AUTOCONFIG"); @@ -194,7 +241,7 @@ char *conf_get_default_confname(void) name = expand_string(conf_defname); env = getenv(SRCTREE); if (env) { - sprintf(fullname, "%s/%s", env, name); + snprintf(fullname, sizeof(fullname), "%s/%s", env, name); if (is_present(fullname)) return fullname; } @@ -817,40 +864,35 @@ int conf_write(const char *name) FILE *out; struct symbol *sym; struct menu *menu; - const char *basename; const char *str; - char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; + char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; char *env; + bool need_newline = false; + + if (!name) + name = conf_get_configname(); + + if (!*name) { + fprintf(stderr, "config name is empty\n"); + return -1; + } + + if (is_dir(name)) { + fprintf(stderr, "%s: Is a directory\n", name); + return -1; + } + + if (make_parent_dir(name)) + return -1; - dirname[0] = 0; - if (name && name[0]) { - char *slash; - - if (is_dir(name)) { - strcpy(dirname, name); - strcat(dirname, "/"); - basename = conf_get_configname(); - } else if ((slash = strrchr(name, '/'))) { - int size = slash - name + 1; - memcpy(dirname, name, size); - dirname[size] = 0; - if (slash[1]) - basename = slash + 1; - else - basename = conf_get_configname(); - } else - basename = name; - } else - basename = conf_get_configname(); - - sprintf(newname, "%s%s", dirname, basename); env = getenv("KCONFIG_OVERWRITECONFIG"); - if (!env || !*env) { - sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); - out = fopen(tmpname, "w"); - } else { + if (env && *env) { *tmpname = 0; - out = fopen(newname, "w"); + out = fopen(name, "w"); + } else { + snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", + name, (int)getpid()); + out = fopen(tmpname, "w"); } if (!out) return 1; @@ -871,12 +913,16 @@ int conf_write(const char *name) "#\n" "# %s\n" "#\n", str); + need_newline = false; } else if (!(sym->flags & SYMBOL_CHOICE)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) goto next; + if (need_newline) { + fprintf(out, "\n"); + need_newline = false; + } sym->flags &= ~SYMBOL_WRITE; - conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); } @@ -888,6 +934,12 @@ next: if (menu->next) menu = menu->next; else while ((menu = menu->parent)) { + if (!menu->sym && menu_is_visible(menu) && + menu != &rootmenu) { + str = menu_get_prompt(menu); + fprintf(out, "# end of %s\n", str); + need_newline = true; + } if (menu->next) { menu = menu->next; break; @@ -897,14 +949,20 @@ next: fclose(out); if (*tmpname) { - strcat(dirname, basename); - strcat(dirname, ".old"); - rename(newname, dirname); - if (rename(tmpname, newname)) + if (is_same(name, tmpname)) { + conf_message("No change to %s", name); + unlink(tmpname); + sym_set_change_count(0); + return 0; + } + + snprintf(oldname, sizeof(oldname), "%s.old", name); + rename(name, oldname); + if (rename(tmpname, name)) return 1; } - conf_message("configuration written to %s", newname); + conf_message("configuration written to %s", name); sym_set_change_count(0); @@ -917,8 +975,6 @@ static int conf_write_dep(const char *name) struct file *file; FILE *out; - if (!name) - name = ".kconfig.d"; out = fopen("..config.tmp", "w"); if (!out) return 1; diff --git a/kconfig/lexer.l b/kconfig/lexer.l index c9df1c8b..6354c905 100644 --- a/kconfig/lexer.l +++ b/kconfig/lexer.l @@ -378,7 +378,8 @@ FILE *zconf_fopen(const char *name) if (!f && name != NULL && name[0] != '/') { env = getenv(SRCTREE); if (env) { - sprintf(fullname, "%s/%s", env, name); + snprintf(fullname, sizeof(fullname), + "%s/%s", env, name); f = fopen(fullname, "r"); } } diff --git a/kconfig/lkc.h b/kconfig/lkc.h index d871539e..cbc7658e 100644 --- a/kconfig/lkc.h +++ b/kconfig/lkc.h @@ -49,7 +49,6 @@ const char *zconf_curname(void); /* confdata.c */ const char *conf_get_configname(void); -const char *conf_get_autoconfig_name(void); char *conf_get_default_confname(void); void sym_set_change_count(int count); void sym_add_change_count(int count); diff --git a/kconfig/lxdialog/BIG.FAT.WARNING b/kconfig/lxdialog/BIG.FAT.WARNING index a8999d82..7cb5a7ec 100644 --- a/kconfig/lxdialog/BIG.FAT.WARNING +++ b/kconfig/lxdialog/BIG.FAT.WARNING @@ -1,4 +1,4 @@ This is NOT the official version of dialog. This version has been significantly modified from the original. It is for use by the Linux -kernel configuration script. Please do not bother Savio Lam with +kernel configuration script. Please do not bother Savio Lam with questions about this program. diff --git a/kconfig/mconf.c b/kconfig/mconf.c index 3d4bd5ef..0d775ce7 100644 --- a/kconfig/mconf.c +++ b/kconfig/mconf.c @@ -936,7 +936,7 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); + show_textbox(NULL, "Can't create file!", 5, 60); break; case 1: show_helptext("Save Alternate Configuration", save_config_help); diff --git a/kconfig/nconf.c b/kconfig/nconf.c index 96a6bac0..fca2cea6 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -1441,8 +1441,7 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - btn_dialog(main_window, "Can't create file! " - "Probably a nonexistent directory.", + btn_dialog(main_window, "Can't create file!", 1, ""); break; case 1: -- cgit v1.2.3 From 31695dd2b00fc3daac109324992901fdcd6068e5 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Thu, 10 Dec 2020 19:46:43 +1300 Subject: kconfig: Sync with upstream v5.3 This commit introduces the following upstream changes: 0c5b6c28ed68 kconfig: Clear "written" flag to avoid data loss 8e2442a5f86e kconfig: fix missing choice values in auto.conf 3266c806dc86 kconfig: run olddefconfig instead of oldconfig after merging fragments e3cd5136a4ec kconfig: remove meaningless if-conditional in conf_read() baa23ec86092 kconfig: Fix spelling of sym_is_changable cd238effefa2 docs: kbuild: convert docs to ReST and rename to *.rst bd305f259cd3 kconfig: make arch/*/configs/defconfig the default of KBUILD_DEFCONFIG 5533397d1ec8 kconfig: add static qualifier to expand_string() b6f7e9f7050b kconfig: require the argument of --defconfig e0a2668665a5 kconfig: remove always false ifeq ($(KBUILD_DEFCONFIG,) conditional Signed-off-by: Chris Packham --- kconfig/conf.c | 10 ++++------ kconfig/confdata.c | 36 ++++++++++-------------------------- kconfig/expr.h | 1 + kconfig/lkc.h | 1 - kconfig/lkc_proto.h | 3 +-- kconfig/mconf.c | 10 +++++----- kconfig/nconf.c | 10 +++++----- kconfig/preprocess.c | 3 ++- kconfig/symbol.c | 4 ++-- 9 files changed, 30 insertions(+), 48 deletions(-) (limited to 'kconfig/nconf.c') diff --git a/kconfig/conf.c b/kconfig/conf.c index 67e32197..dd714b48 100644 --- a/kconfig/conf.c +++ b/kconfig/conf.c @@ -90,7 +90,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) line[0] = '\n'; line[1] = 0; - if (!sym_is_changable(sym)) { + if (!sym_is_changeable(sym)) { printf("%s\n", def); line[0] = '\n'; line[1] = 0; @@ -234,7 +234,7 @@ static int conf_choice(struct menu *menu) sym = menu->sym; is_new = !sym_has_value(sym); - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { conf_sym(menu); sym_calc_value(sym); switch (sym_get_tristate_value(sym)) { @@ -418,7 +418,7 @@ static void check_conf(struct menu *menu) sym = menu->sym; if (sym && !sym_has_value(sym)) { - if (sym_is_changable(sym) || + if (sym_is_changeable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { if (input_mode == listnewconfig) { if (sym->name) { @@ -451,7 +451,7 @@ static struct option long_opts[] = { {"oldaskconfig", no_argument, NULL, oldaskconfig}, {"oldconfig", no_argument, NULL, oldconfig}, {"syncconfig", no_argument, NULL, syncconfig}, - {"defconfig", optional_argument, NULL, defconfig}, + {"defconfig", required_argument, NULL, defconfig}, {"savedefconfig", required_argument, NULL, savedefconfig}, {"allnoconfig", no_argument, NULL, allnoconfig}, {"allyesconfig", no_argument, NULL, allyesconfig}, @@ -542,8 +542,6 @@ int main(int ac, char **av) switch (input_mode) { case defconfig: - if (!defconfig_file) - defconfig_file = conf_get_default_confname(); if (conf_read(defconfig_file)) { fprintf(stderr, "***\n" diff --git a/kconfig/confdata.c b/kconfig/confdata.c index 6006154d..3569d2de 100644 --- a/kconfig/confdata.c +++ b/kconfig/confdata.c @@ -177,8 +177,6 @@ static void conf_message(const char *fmt, ...) static const char *conf_filename; static int conf_lineno, conf_warnings; -const char conf_defname[] = "arch/$(ARCH)/defconfig"; - static void conf_warning(const char *fmt, ...) { va_list ap; @@ -233,21 +231,6 @@ static const char *conf_get_autoconfig_name(void) return name ? name : "include/config/auto.conf"; } -char *conf_get_default_confname(void) -{ - static char fullname[PATH_MAX+1]; - char *env, *name; - - name = expand_string(conf_defname); - env = getenv(SRCTREE); - if (env) { - snprintf(fullname, sizeof(fullname), "%s/%s", env, name); - if (is_present(fullname)) - return fullname; - } - return name; -} - static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) { char *p2; @@ -551,11 +534,9 @@ int conf_read(const char *name) switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) - break; - if (!sym_is_choice(sym)) + if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) continue; - /* fall through */ + break; default: if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) continue; @@ -813,7 +794,7 @@ int conf_write_defconfig(const char *filename) goto next_menu; sym->flags &= ~SYMBOL_WRITE; /* If we cannot change the symbol - skip */ - if (!sym_is_changable(sym)) + if (!sym_is_changeable(sym)) goto next_menu; /* If symbol equals to default value - skip */ if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) @@ -867,6 +848,7 @@ int conf_write(const char *name) const char *str; char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; char *env; + int i; bool need_newline = false; if (!name) @@ -914,7 +896,8 @@ int conf_write(const char *name) "# %s\n" "#\n", str); need_newline = false; - } else if (!(sym->flags & SYMBOL_CHOICE)) { + } else if (!(sym->flags & SYMBOL_CHOICE) && + !(sym->flags & SYMBOL_WRITTEN)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) goto next; @@ -922,7 +905,7 @@ int conf_write(const char *name) fprintf(out, "\n"); need_newline = false; } - sym->flags &= ~SYMBOL_WRITE; + sym->flags |= SYMBOL_WRITTEN; conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); } @@ -948,6 +931,9 @@ next: } fclose(out); + for_all_symbols(i, sym) + sym->flags &= ~SYMBOL_WRITTEN; + if (*tmpname) { if (is_same(name, tmpname)) { conf_message("No change to %s", name); @@ -1082,8 +1068,6 @@ int conf_write_autoconf(int overwrite) if (!overwrite && is_present(autoconf_name)) return 0; - sym_clear_all_valid(); - conf_write_dep("include/config/auto.conf.cmd"); if (conf_touch_deps()) diff --git a/kconfig/expr.h b/kconfig/expr.h index 8dde65bc..017843c9 100644 --- a/kconfig/expr.h +++ b/kconfig/expr.h @@ -141,6 +141,7 @@ struct symbol { #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_CHANGED 0x0400 /* ? */ +#define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */ #define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */ #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ #define SYMBOL_WARNED 0x8000 /* warning has been issued */ diff --git a/kconfig/lkc.h b/kconfig/lkc.h index cbc7658e..4fb16f31 100644 --- a/kconfig/lkc.h +++ b/kconfig/lkc.h @@ -49,7 +49,6 @@ const char *zconf_curname(void); /* confdata.c */ const char *conf_get_configname(void); -char *conf_get_default_confname(void); void sym_set_change_count(int count); void sym_add_change_count(int count); bool conf_set_all_new_symbols(enum conf_def_mode mode); diff --git a/kconfig/lkc_proto.h b/kconfig/lkc_proto.h index 86c26754..f9ab9823 100644 --- a/kconfig/lkc_proto.h +++ b/kconfig/lkc_proto.h @@ -42,7 +42,7 @@ tristate sym_toggle_tristate_value(struct symbol *sym); bool sym_string_valid(struct symbol *sym, const char *newval); bool sym_string_within_range(struct symbol *sym, const char *str); bool sym_set_string_value(struct symbol *sym, const char *newval); -bool sym_is_changable(struct symbol *sym); +bool sym_is_changeable(struct symbol *sym); struct property * sym_get_choice_prop(struct symbol *sym); const char * sym_get_string_value(struct symbol *sym); @@ -58,7 +58,6 @@ void env_write_dep(FILE *f, const char *auto_conf_name); void variable_add(const char *name, const char *value, enum variable_flavor flavor); void variable_all_del(void); -char *expand_string(const char *in); char *expand_dollar(const char **str); char *expand_one_token(const char **str); diff --git a/kconfig/mconf.c b/kconfig/mconf.c index 0d775ce7..e3cb6809 100644 --- a/kconfig/mconf.c +++ b/kconfig/mconf.c @@ -536,7 +536,7 @@ static void build_conf(struct menu *menu) } val = sym_get_tristate_value(sym); - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { switch (type) { case S_BOOLEAN: item_make("[%c]", val == no ? ' ' : '*'); @@ -587,7 +587,7 @@ static void build_conf(struct menu *menu) } else { switch (type) { case S_BOOLEAN: - if (sym_is_changable(sym)) + if (sym_is_changeable(sym)) item_make("[%c]", val == no ? ' ' : '*'); else item_make("-%c-", val == no ? ' ' : '*'); @@ -600,7 +600,7 @@ static void build_conf(struct menu *menu) case mod: ch = 'M'; break; default: ch = ' '; break; } - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { if (sym->rev_dep.tri == mod) item_make("{%c}", ch); else @@ -617,7 +617,7 @@ static void build_conf(struct menu *menu) if (tmp < 0) tmp = 0; item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? + (sym_has_value(sym) || !sym_is_changeable(sym)) ? "" : " (NEW)"); item_set_tag('s'); item_set_data(menu); @@ -625,7 +625,7 @@ static void build_conf(struct menu *menu) } } item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? + (sym_has_value(sym) || !sym_is_changeable(sym)) ? "" : " (NEW)"); if (menu->prompt->type == P_MENU) { item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); diff --git a/kconfig/nconf.c b/kconfig/nconf.c index fca2cea6..bee51359 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -806,7 +806,7 @@ static void build_conf(struct menu *menu) } val = sym_get_tristate_value(sym); - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { switch (type) { case S_BOOLEAN: item_make(menu, 't', "[%c]", @@ -860,7 +860,7 @@ static void build_conf(struct menu *menu) } else { switch (type) { case S_BOOLEAN: - if (sym_is_changable(sym)) + if (sym_is_changeable(sym)) item_make(menu, 't', "[%c]", val == no ? ' ' : '*'); else @@ -879,7 +879,7 @@ static void build_conf(struct menu *menu) ch = ' '; break; } - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { if (sym->rev_dep.tri == mod) item_make(menu, 't', "{%c}", ch); @@ -899,14 +899,14 @@ static void build_conf(struct menu *menu) item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), (sym_has_value(sym) || - !sym_is_changable(sym)) ? "" : + !sym_is_changeable(sym)) ? "" : " (NEW)"); goto conf_childs; } } item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? + (sym_has_value(sym) || !sym_is_changeable(sym)) ? "" : " (NEW)"); if (menu->prompt && menu->prompt->type == P_MENU) { item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); diff --git a/kconfig/preprocess.c b/kconfig/preprocess.c index 592dfbfa..0243086f 100644 --- a/kconfig/preprocess.c +++ b/kconfig/preprocess.c @@ -15,6 +15,7 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) static char *expand_string_with_args(const char *in, int argc, char *argv[]); +static char *expand_string(const char *in); static void __attribute__((noreturn)) pperror(const char *format, ...) { @@ -550,7 +551,7 @@ static char *expand_string_with_args(const char *in, int argc, char *argv[]) return __expand_string(&in, is_end_of_str, argc, argv); } -char *expand_string(const char *in) +static char *expand_string(const char *in) { return expand_string_with_args(in, 0, NULL); } diff --git a/kconfig/symbol.c b/kconfig/symbol.c index 1f9266da..f56eec5e 100644 --- a/kconfig/symbol.c +++ b/kconfig/symbol.c @@ -785,7 +785,7 @@ const char *sym_get_string_value(struct symbol *sym) return (const char *)sym->curr.val; } -bool sym_is_changable(struct symbol *sym) +bool sym_is_changeable(struct symbol *sym) { return sym->visible > sym->rev_dep.tri; } @@ -1114,7 +1114,7 @@ static void sym_check_print_recursive(struct symbol *last_sym) } fprintf(stderr, - "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n" + "For a resolution refer to Documentation/kbuild/kconfig-language.rst\n" "subsection \"Kconfig recursive dependency limitations\"\n" "\n"); -- cgit v1.2.3 From 3bf9edb36c5f1ea9715de1a2a556390540398077 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Thu, 10 Dec 2020 19:53:19 +1300 Subject: kconfig: Sync with upstream v5.6 This commit introduces the following upstream changes: 089b7d890f97 kconfig: Invalidate all symbols after changing to y or m. 5f2fb52fac15 kbuild: rename hostprogs-y/always to hostprogs/always-y c8fb7d7e48d1 kconfig: fix broken dependency in randconfig-generated .config ba82f52e2287 kconfig: fix an "implicit declaration of function" warning a9609686042b kconfig: fix nesting of symbol help text 3460d0bc256a kconfig: distinguish between dependencies and visibility in help text edda15f21974 kconfig: list all definitions of a symbol in help text 89b9060987d9 kconfig: Add yes2modconfig and mod2yesconfig targets. c8138a57bbd1 kconfig: use $(PERL) in Makefile 1d1352373ebc kconfig: fix too deep indentation in Makefile 68f0d62746bc kconfig: localmodconfig: fix indentation for closing brace 5edcef8454a4 kconfig: localmodconfig: remove unused $config adf7c5bd0674 kconfig: squash prop_alloc() into menu_add_prop() 6397d96ba5a5 kconfig: remove sym from struct property 2ffeef615b5e kconfig: remove 'prompt' argument from menu_add_prop() 024352ff8d69 kconfig: move prompt handling to menu_add_prompt() from menu_add_prop() 1be6e791383a kconfig: remove 'prompt' symbol 801b27db4638 kconfig: drop T_WORD from the RHS of 'prompt' symbol de026ca9152c kconfig: use parent->dep as the parentdep of 'menu' f64048a20b0c kconfig: remove the rootmenu check in menu_add_prop() 8b41fc4454e3 kbuild: create modules.builtin without Makefile.modbuiltin or tristate.conf Signed-off-by: Chris Packham --- kconfig/conf.c | 14 ++++ kconfig/confdata.c | 62 +++++------------ kconfig/expr.c | 3 +- kconfig/expr.h | 2 +- kconfig/lkc.h | 4 +- kconfig/mconf.c | 1 + kconfig/menu.c | 195 +++++++++++++++++++++++++++++++---------------------- kconfig/nconf.c | 1 + kconfig/parser.y | 21 +++--- kconfig/symbol.c | 22 ------ 10 files changed, 160 insertions(+), 165 deletions(-) (limited to 'kconfig/nconf.c') diff --git a/kconfig/conf.c b/kconfig/conf.c index 393e96e4..422165dc 100644 --- a/kconfig/conf.c +++ b/kconfig/conf.c @@ -34,6 +34,8 @@ enum input_mode { listnewconfig, helpnewconfig, olddefconfig, + yes2modconfig, + mod2yesconfig, }; static enum input_mode input_mode = oldaskconfig; @@ -467,6 +469,8 @@ static struct option long_opts[] = { {"listnewconfig", no_argument, NULL, listnewconfig}, {"helpnewconfig", no_argument, NULL, helpnewconfig}, {"olddefconfig", no_argument, NULL, olddefconfig}, + {"yes2modconfig", no_argument, NULL, yes2modconfig}, + {"mod2yesconfig", no_argument, NULL, mod2yesconfig}, {NULL, 0, NULL, 0} }; @@ -532,6 +536,8 @@ int main(int ac, char **av) case listnewconfig: case helpnewconfig: case olddefconfig: + case yes2modconfig: + case mod2yesconfig: break; case '?': fprintf(stderr, "See README for usage info\n"); @@ -566,6 +572,8 @@ int main(int ac, char **av) case listnewconfig: case helpnewconfig: case olddefconfig: + case yes2modconfig: + case mod2yesconfig: conf_read(NULL); break; case allnoconfig: @@ -639,6 +647,12 @@ int main(int ac, char **av) break; case savedefconfig: break; + case yes2modconfig: + conf_rewrite_mod_or_yes(def_y2m); + break; + case mod2yesconfig: + conf_rewrite_mod_or_yes(def_m2y); + break; case oldaskconfig: rootEntry = &rootmenu; conf(&rootmenu); diff --git a/kconfig/confdata.c b/kconfig/confdata.c index 3569d2de..a39d93e3 100644 --- a/kconfig/confdata.c +++ b/kconfig/confdata.c @@ -710,25 +710,6 @@ static struct conf_printer header_printer_cb = .print_comment = header_print_comment, }; -/* - * Tristate printer - * - * This printer is used when generating the `include/config/tristate.conf' file. - */ -static void -tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) -{ - - if (sym->type == S_TRISTATE && *value != 'n') - fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value)); -} - -static struct conf_printer tristate_printer_cb = -{ - .print_symbol = tristate_print_symbol, - .print_comment = kconfig_print_comment, -}; - static void conf_write_symbol(FILE *fp, struct symbol *sym, struct conf_printer *printer, void *printer_arg) { @@ -1062,7 +1043,7 @@ 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; + FILE *out, *out_h; int i; if (!overwrite && is_present(autoconf_name)) @@ -1077,23 +1058,13 @@ int conf_write_autoconf(int overwrite) if (!out) return 1; - tristate = fopen(".tmpconfig_tristate", "w"); - if (!tristate) { - fclose(out); - return 1; - } - out_h = fopen(".tmpconfig.h", "w"); if (!out_h) { fclose(out); - fclose(tristate); return 1; } conf_write_heading(out, &kconfig_printer_cb, NULL); - - conf_write_heading(tristate, &tristate_printer_cb, NULL); - conf_write_heading(out_h, &header_printer_cb, NULL); for_all_symbols(i, sym) { @@ -1101,15 +1072,11 @@ int conf_write_autoconf(int overwrite) if (!(sym->flags & SYMBOL_WRITE) || !sym->name) continue; - /* write symbol to auto.conf, tristate and header files */ + /* write symbols to auto.conf and autoconf.h */ conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); - - conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); - conf_write_symbol(out_h, sym, &header_printer_cb, NULL); } fclose(out); - fclose(tristate); fclose(out_h); name = getenv("KCONFIG_AUTOHEADER"); @@ -1120,14 +1087,6 @@ int conf_write_autoconf(int overwrite) if (rename(".tmpconfig.h", name)) return 1; - name = getenv("KCONFIG_TRISTATE"); - if (!name) - name = "include/config/tristate.conf"; - if (make_parent_dir(name)) - return 1; - if (rename(".tmpconfig_tristate", name)) - return 1; - if (make_parent_dir(autoconf_name)) return 1; /* @@ -1353,7 +1312,7 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode) sym_calc_value(csym); if (mode == def_random) - has_changed = randomize_choice_values(csym); + has_changed |= randomize_choice_values(csym); else { set_all_choice_values(csym); has_changed = true; @@ -1362,3 +1321,18 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode) return has_changed; } + +void conf_rewrite_mod_or_yes(enum conf_def_mode mode) +{ + struct symbol *sym; + int i; + tristate old_val = (mode == def_y2m) ? yes : mod; + tristate new_val = (mode == def_y2m) ? mod : yes; + + for_all_symbols(i, sym) { + if (sym_get_type(sym) == S_TRISTATE && + sym->def[S_DEF_USER].tri == old_val) + sym->def[S_DEF_USER].tri = new_val; + } + sym_clear_all_valid(); +} diff --git a/kconfig/expr.c b/kconfig/expr.c index 9f1de58e..81ebf810 100644 --- a/kconfig/expr.c +++ b/kconfig/expr.c @@ -13,7 +13,6 @@ #define DEBUG_EXPR 0 -static int expr_eq(struct expr *e1, struct expr *e2); static struct expr *expr_eliminate_yn(struct expr *e); struct expr *expr_alloc_symbol(struct symbol *sym) @@ -250,7 +249,7 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) * equals some operand in the other (operands do not need to appear in the same * order), recursively. */ -static int expr_eq(struct expr *e1, struct expr *e2) +int expr_eq(struct expr *e1, struct expr *e2) { int res, old_count; diff --git a/kconfig/expr.h b/kconfig/expr.h index 017843c9..5c344369 100644 --- a/kconfig/expr.h +++ b/kconfig/expr.h @@ -191,7 +191,6 @@ enum prop_type { struct property { struct property *next; /* next property - null if last */ - struct symbol *sym; /* the symbol for which the property is associated */ enum prop_type type; /* type of property */ const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ struct expr_value visible; @@ -301,6 +300,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); struct expr *expr_copy(const struct expr *org); void expr_free(struct expr *e); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); +int expr_eq(struct expr *e1, struct expr *e2); tristate expr_calc_value(struct expr *e); struct expr *expr_trans_bool(struct expr *e); struct expr *expr_eliminate_dups(struct expr *e); diff --git a/kconfig/lkc.h b/kconfig/lkc.h index 4fb16f31..d4ca8297 100644 --- a/kconfig/lkc.h +++ b/kconfig/lkc.h @@ -34,6 +34,8 @@ enum conf_def_mode { def_default, def_yes, def_mod, + def_y2m, + def_m2y, def_no, def_random }; @@ -52,6 +54,7 @@ const char *conf_get_configname(void); void sym_set_change_count(int count); void sym_add_change_count(int count); bool conf_set_all_new_symbols(enum conf_def_mode mode); +void conf_rewrite_mod_or_yes(enum conf_def_mode mode); void set_all_choice_values(struct symbol *csym); /* confdata.c and expr.c */ @@ -112,7 +115,6 @@ struct symbol *sym_choice_default(struct symbol *sym); struct property *sym_get_range_prop(struct symbol *sym); const char *sym_get_string_default(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); -struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct symbol *prop_get_symbol(struct property *prop); static inline tristate sym_get_tristate_value(struct symbol *sym) diff --git a/kconfig/mconf.c b/kconfig/mconf.c index e3cb6809..2435b2b6 100644 --- a/kconfig/mconf.c +++ b/kconfig/mconf.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/kconfig/menu.c b/kconfig/menu.c index 264ba298..bfd78001 100644 --- a/kconfig/menu.c +++ b/kconfig/menu.c @@ -124,67 +124,82 @@ void menu_set_type(int type) sym_type_name(sym->type), sym_type_name(type)); } -static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) +static struct property *menu_add_prop(enum prop_type type, struct expr *expr, + struct expr *dep) { - struct property *prop = prop_alloc(type, current_entry->sym); + struct property *prop; + prop = xmalloc(sizeof(*prop)); + memset(prop, 0, sizeof(*prop)); + prop->type = type; + prop->file = current_file; + prop->lineno = zconf_lineno(); prop->menu = current_entry; prop->expr = expr; prop->visible.expr = dep; - if (prompt) { - /* For crostool-NG, a leading pipe followed with spaces - * means that pipe shall be removed, and the spaces should - * not be trimmed. - */ - if (*prompt == '|') + /* append property to the prop list of symbol */ + if (current_entry->sym) { + struct property **propp; + + for (propp = ¤t_entry->sym->prop; + *propp; + propp = &(*propp)->next) + ; + *propp = prop; + } + + return prop; +} + +struct property *menu_add_prompt(enum prop_type type, char *prompt, + struct expr *dep) +{ + struct property *prop = menu_add_prop(type, NULL, dep); + + /* For crostool-NG, a leading pipe followed with spaces + * means that pipe shall be removed, and the spaces should + * not be trimmed. + */ + if (*prompt == '|') + prompt++; + else if (isspace(*prompt)) { + prop_warn(prop, "leading whitespace ignored"); + while (isspace(*prompt)) prompt++; - else if (isspace(*prompt)) { - prop_warn(prop, "leading whitespace ignored"); - while (isspace(*prompt)) - prompt++; - } - if (current_entry->prompt && current_entry != &rootmenu) - prop_warn(prop, "prompt redefined"); + } + if (current_entry->prompt) + prop_warn(prop, "prompt redefined"); - /* Apply all upper menus' visibilities to actual prompts. */ - if(type == P_PROMPT) { - struct menu *menu = current_entry; + /* Apply all upper menus' visibilities to actual prompts. */ + if (type == P_PROMPT) { + struct menu *menu = current_entry; - while ((menu = menu->parent) != NULL) { - struct expr *dup_expr; + while ((menu = menu->parent) != NULL) { + struct expr *dup_expr; - if (!menu->visibility) - continue; - /* - * Do not add a reference to the - * menu's visibility expression but - * use a copy of it. Otherwise the - * expression reduction functions - * will modify expressions that have - * multiple references which can - * cause unwanted side effects. - */ - dup_expr = expr_copy(menu->visibility); + if (!menu->visibility) + continue; + /* + * Do not add a reference to the menu's visibility + * expression but use a copy of it. Otherwise the + * expression reduction functions will modify + * expressions that have multiple references which + * can cause unwanted side effects. + */ + dup_expr = expr_copy(menu->visibility); - prop->visible.expr - = expr_alloc_and(prop->visible.expr, - dup_expr); - } + prop->visible.expr = expr_alloc_and(prop->visible.expr, + dup_expr); } - - current_entry->prompt = prop; } + + current_entry->prompt = prop; prop->text = prompt; return prop; } -struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) -{ - return menu_add_prop(type, prompt, NULL, dep); -} - void menu_add_visibility(struct expr *expr) { current_entry->visibility = expr_alloc_and(current_entry->visibility, @@ -193,12 +208,12 @@ void menu_add_visibility(struct expr *expr) void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) { - menu_add_prop(type, NULL, expr, dep); + menu_add_prop(type, expr, dep); } void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) { - menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); + menu_add_prop(type, expr_alloc_symbol(sym), dep); } void menu_add_option_modules(void) @@ -332,12 +347,10 @@ void menu_finalize(struct menu *parent) * choice value symbols. */ parentdep = expr_alloc_symbol(sym); - } else if (parent->prompt) - /* Menu node for 'menu' */ - parentdep = parent->prompt->visible.expr; - else - /* Menu node for 'if' */ + } else { + /* Menu node for 'menu', 'if' */ parentdep = parent->dep; + } /* For each child menu node... */ for (menu = parent->list; menu; menu = menu->next) { @@ -704,6 +717,21 @@ const char *menu_get_help(struct menu *menu) return ""; } +static void get_def_str(struct gstr *r, struct menu *menu) +{ + str_printf(r, "Defined at %s:%d\n", + menu->file->name, menu->lineno); +} + +static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix) +{ + if (!expr_is_yes(expr)) { + str_append(r, prefix); + expr_gstr_print(expr, r); + str_append(r, "\n"); + } +} + static void get_prompt_str(struct gstr *r, struct property *prop, struct list_head *head) { @@ -711,7 +739,20 @@ static void get_prompt_str(struct gstr *r, struct property *prop, struct menu *submenu[8], *menu, *location = NULL; struct jump_key *jump = NULL; - str_printf(r, "Prompt: %s\n", prop->text); + str_printf(r, " Prompt: %s\n", prop->text); + + get_dep_str(r, prop->menu->dep, " Depends on: "); + /* + * Most prompts in Linux have visibility that exactly matches their + * dependencies. For these, we print only the dependencies to improve + * readability. However, prompts with inline "if" expressions and + * prompts with a parent that has a "visible if" expression have + * differing dependencies and visibility. In these rare cases, we + * print both. + */ + if (!expr_eq(prop->menu->dep, prop->visible.expr)) + get_dep_str(r, prop->visible.expr, " Visible if: "); + menu = prop->menu->parent; for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { bool accessible = menu_is_visible(menu); @@ -761,18 +802,6 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } } -/* - * get property of type P_SYMBOL - */ -static struct property *get_symbol_prop(struct symbol *sym) -{ - struct property *prop = NULL; - - for_all_properties(sym, prop, P_SYMBOL) - break; - return prop; -} - static void get_symbol_props_str(struct gstr *r, struct symbol *sym, enum prop_type tok, const char *prefix) { @@ -812,32 +841,34 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym, } } } - for_all_prompts(sym, prop) - get_prompt_str(r, prop, head); - - prop = get_symbol_prop(sym); - if (prop) { - str_printf(r, " Defined at %s:%d\n", prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, " Depends on: "); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); + + /* Print the definitions with prompts before the ones without */ + for_all_properties(sym, prop, P_SYMBOL) { + if (prop->menu->prompt) { + get_def_str(r, prop->menu); + get_prompt_str(r, prop->menu->prompt, head); + } + } + + for_all_properties(sym, prop, P_SYMBOL) { + if (!prop->menu->prompt) { + get_def_str(r, prop->menu); + get_dep_str(r, prop->menu->dep, " Depends on: "); } } - get_symbol_props_str(r, sym, P_SELECT, " Selects: "); + get_symbol_props_str(r, sym, P_SELECT, "Selects: "); if (sym->rev_dep.expr) { - expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n"); - expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n"); - expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "Selected by [y]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "Selected by [m]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "Selected by [n]:\n"); } - get_symbol_props_str(r, sym, P_IMPLY, " Implies: "); + get_symbol_props_str(r, sym, P_IMPLY, "Implies: "); if (sym->implied.expr) { - expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n"); - expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n"); - expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, yes, "Implied by [y]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, mod, "Implied by [m]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, no, "Implied by [n]:\n"); } str_append(r, "\n\n"); diff --git a/kconfig/nconf.c b/kconfig/nconf.c index bee51359..49b405d8 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -8,6 +8,7 @@ #define _GNU_SOURCE #endif #include +#include #include #include "lkc.h" diff --git a/kconfig/parser.y b/kconfig/parser.y index b3eff961..708b6c4b 100644 --- a/kconfig/parser.y +++ b/kconfig/parser.y @@ -90,7 +90,6 @@ static struct menu *current_menu, *current_entry; %left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL %nonassoc T_NOT -%type prompt %type nonconst_symbol %type symbol %type type logic_type default @@ -113,7 +112,7 @@ input: mainmenu_stmt stmt_list | stmt_list; /* mainmenu entry */ -mainmenu_stmt: T_MAINMENU prompt T_EOL +mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL { menu_add_prompt(P_MENU, $2, NULL); }; @@ -181,7 +180,7 @@ config_option: type prompt_stmt_opt T_EOL $1); }; -config_option: T_PROMPT prompt if_expr T_EOL +config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL { menu_add_prompt(P_PROMPT, $2, $3); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); @@ -265,7 +264,7 @@ choice_option_list: | choice_option_list help ; -choice_option: T_PROMPT prompt if_expr T_EOL +choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL { menu_add_prompt(P_PROMPT, $2, $3); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); @@ -334,7 +333,7 @@ if_stmt: if_entry stmt_list if_end /* menu entry */ -menu: T_MENU prompt T_EOL +menu: T_MENU T_WORD_QUOTE T_EOL { menu_add_entry(NULL); menu_add_prompt(P_MENU, $2, NULL); @@ -363,7 +362,7 @@ menu_option_list: | menu_option_list depends ; -source_stmt: T_SOURCE prompt T_EOL +source_stmt: T_SOURCE T_WORD_QUOTE T_EOL { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); zconf_nextfile($2); @@ -372,7 +371,7 @@ source_stmt: T_SOURCE prompt T_EOL /* comment entry */ -comment: T_COMMENT prompt T_EOL +comment: T_COMMENT T_WORD_QUOTE T_EOL { menu_add_entry(NULL); menu_add_prompt(P_COMMENT, $2, NULL); @@ -429,15 +428,11 @@ visible: T_VISIBLE if_expr T_EOL prompt_stmt_opt: /* empty */ - | prompt if_expr + | T_WORD_QUOTE if_expr { menu_add_prompt(P_PROMPT, $1, $2); }; -prompt: T_WORD - | T_WORD_QUOTE -; - end: T_ENDMENU T_EOL { $$ = "menu"; } | T_ENDCHOICE T_EOL { $$ = "choice"; } | T_ENDIF T_EOL { $$ = "if"; } @@ -665,7 +660,7 @@ static void print_symbol(FILE *out, struct menu *menu) break; case P_SYMBOL: fputs( " symbol ", out); - fprintf(out, "%s\n", prop->sym->name); + fprintf(out, "%s\n", prop->menu->sym->name); break; default: fprintf(out, " unknown prop %d!\n", prop->type); diff --git a/kconfig/symbol.c b/kconfig/symbol.c index f56eec5e..8d38b700 100644 --- a/kconfig/symbol.c +++ b/kconfig/symbol.c @@ -1273,28 +1273,6 @@ struct symbol *sym_check_deps(struct symbol *sym) return sym2; } -struct property *prop_alloc(enum prop_type type, struct symbol *sym) -{ - struct property *prop; - struct property **propp; - - prop = xmalloc(sizeof(*prop)); - memset(prop, 0, sizeof(*prop)); - prop->type = type; - prop->sym = sym; - prop->file = current_file; - prop->lineno = zconf_lineno(); - - /* append property to the prop list of symbol */ - if (sym) { - for (propp = &sym->prop; *propp; propp = &(*propp)->next) - ; - *propp = prop; - } - - return prop; -} - struct symbol *prop_get_symbol(struct property *prop) { if (prop->expr && (prop->expr->type == E_SYMBOL || -- cgit v1.2.3 From d0e328c8ad357a705b6218e20f74ec1ec1869e8d Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Mon, 1 Feb 2021 20:14:11 +1300 Subject: kconfig: Sync with upstream v5.9 19b835a5db93 kconfig: qconf: fix incomplete type 'struct gstr' warning 163e0c27fead kconfig: remove redundant assignment prompt = prompt d41809ff7af9 kconfig: add 'static' to some file-local data f70f74d15ca8 kconfig: remove '---help---' support Signed-off-by: Chris Packham --- kconfig/lexer.l | 4 ++-- kconfig/lkc.h | 47 ++++++++++++++++++++++++++++++----------------- kconfig/lkc_proto.h | 14 -------------- kconfig/nconf.c | 1 - kconfig/symbol.c | 14 ++++++++++---- 5 files changed, 42 insertions(+), 38 deletions(-) (limited to 'kconfig/nconf.c') diff --git a/kconfig/lexer.l b/kconfig/lexer.l index 6354c905..240109f9 100644 --- a/kconfig/lexer.l +++ b/kconfig/lexer.l @@ -36,7 +36,7 @@ struct buffer { YY_BUFFER_STATE state; }; -struct buffer *current_buf; +static struct buffer *current_buf; static int last_ts, first_ts; @@ -105,7 +105,7 @@ n [A-Za-z0-9_-] "endchoice" return T_ENDCHOICE; "endif" return T_ENDIF; "endmenu" return T_ENDMENU; -"help"|"---help---" return T_HELP; +"help" return T_HELP; "hex" return T_HEX; "if" return T_IF; "imply" return T_IMPLY; diff --git a/kconfig/lkc.h b/kconfig/lkc.h index d4ca8297..8454649b 100644 --- a/kconfig/lkc.h +++ b/kconfig/lkc.h @@ -66,23 +66,6 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) fprintf(stderr, "Error in writing or end of file.\n"); } -/* menu.c */ -void _menu_init(void); -void menu_warn(struct menu *menu, const char *fmt, ...); -struct menu *menu_add_menu(void); -void menu_end_menu(void); -void menu_add_entry(struct symbol *sym); -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); -void menu_add_option_modules(void); -void menu_add_option_defconfig_list(void); -void menu_add_option_allnoconfig_y(void); -void menu_finalize(struct menu *parent); -void menu_set_type(int type); - /* util.c */ struct file *file_lookup(const char *name); void *xmalloc(size_t size); @@ -109,6 +92,36 @@ void str_append(struct gstr *gs, const char *s); void str_printf(struct gstr *gs, const char *fmt, ...); const char *str_get(struct gstr *gs); +/* menu.c */ +void _menu_init(void); +void menu_warn(struct menu *menu, const char *fmt, ...); +struct menu *menu_add_menu(void); +void menu_end_menu(void); +void menu_add_entry(struct symbol *sym); +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); +void menu_add_option_modules(void); +void menu_add_option_defconfig_list(void); +void menu_add_option_allnoconfig_y(void); +void menu_finalize(struct menu *parent); +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_root_menu(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); +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); +void menu_get_ext_help(struct menu *menu, struct gstr *help); + /* symbol.c */ void sym_clear_all_valid(void); struct symbol *sym_choice_default(struct symbol *sym); diff --git a/kconfig/lkc_proto.h b/kconfig/lkc_proto.h index f9ab9823..9e81be33 100644 --- a/kconfig/lkc_proto.h +++ b/kconfig/lkc_proto.h @@ -12,20 +12,6 @@ bool conf_get_changed(void); void conf_set_changed_callback(void (*fn)(void)); void conf_set_message_callback(void (*fn)(const char *s)); -/* menu.c */ -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_root_menu(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); -struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); -void menu_get_ext_help(struct menu *menu, struct gstr *help); - /* symbol.c */ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; diff --git a/kconfig/nconf.c b/kconfig/nconf.c index 49b405d8..c1df68e3 100644 --- a/kconfig/nconf.c +++ b/kconfig/nconf.c @@ -758,7 +758,6 @@ static void build_conf(struct menu *menu) switch (ptype) { case P_MENU: child_count++; - prompt = prompt; if (single_menu_mode) { item_make(menu, 'm', "%s%*c%s", diff --git a/kconfig/symbol.c b/kconfig/symbol.c index 9363e37b..ffa3ec65 100644 --- a/kconfig/symbol.c +++ b/kconfig/symbol.c @@ -15,15 +15,21 @@ struct symbol symbol_yes = { .name = "y", .curr = { "y", yes }, .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_mod = { +}; + +struct symbol symbol_mod = { .name = "m", .curr = { "m", mod }, .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_no = { +}; + +struct symbol symbol_no = { .name = "n", .curr = { "n", no }, .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_empty = { +}; + +static struct symbol symbol_empty = { .name = "", .curr = { "", no }, .flags = SYMBOL_VALID, @@ -31,7 +37,7 @@ struct symbol symbol_yes = { struct symbol *sym_defconfig_list; struct symbol *modules_sym; -tristate modules_val; +static tristate modules_val; enum symbol_type sym_get_type(struct symbol *sym) { -- cgit v1.2.3