| |
@@ -1,4982 +0,0 @@
|
| |
- From c164bf7f87f9081fee7e1a186dd7a87a9a020b9e Mon Sep 17 00:00:00 2001
|
| |
- From: Jason Self <j@jxself.org>
|
| |
- Date: Thu, 4 Jul 2019 15:12:33 -0700
|
| |
- Subject: [PATCH 1/8] Update carl9170 to latest upstream
|
| |
-
|
| |
- Based on commit 001384147050b9cd9daadb4d3115cc0f13f5b319
|
| |
- Dated May 5 2019.
|
| |
- ---
|
| |
- WHENCE | 4 +-
|
| |
- carl9170fw/carlfw/include/wl.h | 2 +-
|
| |
- carl9170fw/carlfw/src/hostif.c | 8 +-
|
| |
- carl9170fw/carlfw/src/printf.c | 0
|
| |
- carl9170fw/carlfw/src/wlantx.c | 5 +-
|
| |
- carl9170fw/config/CMakeLists.txt | 6 +-
|
| |
- carl9170fw/config/conf.c | 210 ++++++----
|
| |
- carl9170fw/config/confdata.c | 329 +++++++++------
|
| |
- carl9170fw/config/expr.c | 206 +++++++---
|
| |
- carl9170fw/config/expr.h | 105 ++++-
|
| |
- carl9170fw/config/kconf_id.c | 54 ---
|
| |
- carl9170fw/config/lkc.h | 50 +--
|
| |
- carl9170fw/config/lkc_proto.h | 19 +-
|
| |
- carl9170fw/config/menu.c | 259 +++++++++---
|
| |
- carl9170fw/config/preprocess.c | 573 +++++++++++++++++++++++++++
|
| |
- carl9170fw/config/symbol.c | 255 ++++--------
|
| |
- carl9170fw/config/util.c | 86 ++--
|
| |
- carl9170fw/config/zconf.l | 336 ++++++++++------
|
| |
- carl9170fw/config/zconf.y | 403 +++++++++----------
|
| |
- carl9170fw/include/linux/ieee80211.h | 24 +-
|
| |
- carl9170fw/include/shared/wlan.h | 2 +-
|
| |
- carl9170fw/toolchain/Makefile | 8 +-
|
| |
- carl9170fw/toolchain/SHA256SUMS | 18 +-
|
| |
- 23 files changed, 1942 insertions(+), 1020 deletions(-)
|
| |
- mode change 100755 => 100644 carl9170fw/carlfw/src/printf.c
|
| |
- delete mode 100644 carl9170fw/config/kconf_id.c
|
| |
- create mode 100644 carl9170fw/config/preprocess.c
|
| |
-
|
| |
- diff --git a/WHENCE b/WHENCE
|
| |
- index dd8ec20..2932155 100644
|
| |
- --- a/WHENCE
|
| |
- +++ b/WHENCE
|
| |
- @@ -142,8 +142,8 @@ From https://git.kernel.org/pub/scm/utils/cis-tools/cis-tools.git
|
| |
-
|
| |
- Driver: carl9170 -- Atheros AR9170 802.11 draft-n USB driver
|
| |
-
|
| |
- -Version: Based on commit 370b7919114a02149088c482c8709cafb9bf7478
|
| |
- -dated May 2 2018.
|
| |
- +Version: Based on commit 001384147050b9cd9daadb4d3115cc0f13f5b319
|
| |
- +dated May 5 2019.
|
| |
-
|
| |
- Licence: GPLv2 or later.
|
| |
-
|
| |
- diff --git a/carl9170fw/carlfw/include/wl.h b/carl9170fw/carlfw/include/wl.h
|
| |
- index 8499ca2..5566be4 100644
|
| |
- --- a/carl9170fw/carlfw/include/wl.h
|
| |
- +++ b/carl9170fw/carlfw/include/wl.h
|
| |
- @@ -237,7 +237,7 @@ static inline __inline void unhide_super(struct dma_desc *desc)
|
| |
- desc->totalLen += sizeof(struct carl9170_tx_superdesc);
|
| |
- }
|
| |
-
|
| |
- -static inline __inline __hot void read_tsf(uint32_t *tsf)
|
| |
- +static inline __inline __hot void read_tsf(uint32_t tsf[static 2])
|
| |
- {
|
| |
- /*
|
| |
- * "According to the [hardware] documentation:
|
| |
- diff --git a/carl9170fw/carlfw/src/hostif.c b/carl9170fw/carlfw/src/hostif.c
|
| |
- index 73e89c7..06726db 100644
|
| |
- --- a/carl9170fw/carlfw/src/hostif.c
|
| |
- +++ b/carl9170fw/carlfw/src/hostif.c
|
| |
- @@ -213,10 +213,14 @@ void handle_cmd(struct carl9170_rsp *resp)
|
| |
- fw.reboot = 1;
|
| |
- break;
|
| |
-
|
| |
- - case CARL9170_CMD_READ_TSF:
|
| |
- + case CARL9170_CMD_READ_TSF: {
|
| |
- + uint32_t tmptsf[2];
|
| |
- +
|
| |
- + read_tsf(tmptsf);
|
| |
- resp->hdr.len = 8;
|
| |
- - read_tsf((uint32_t *)resp->tsf.tsf);
|
| |
- + memcpy(resp->tsf.tsf, tmptsf, sizeof(tmptsf));
|
| |
- break;
|
| |
- + }
|
| |
-
|
| |
- case CARL9170_CMD_RX_FILTER:
|
| |
- resp->hdr.len = 0;
|
| |
- diff --git a/carl9170fw/carlfw/src/printf.c b/carl9170fw/carlfw/src/printf.c
|
| |
- old mode 100755
|
| |
- new mode 100644
|
| |
- diff --git a/carl9170fw/carlfw/src/wlantx.c b/carl9170fw/carlfw/src/wlantx.c
|
| |
- index 474c040..a8d0952 100644
|
| |
- --- a/carl9170fw/carlfw/src/wlantx.c
|
| |
- +++ b/carl9170fw/carlfw/src/wlantx.c
|
| |
- @@ -260,7 +260,7 @@ static void __wlan_tx(struct dma_desc *desc)
|
| |
-
|
| |
- if (unlikely(super->s.fill_in_tsf)) {
|
| |
- struct ieee80211_mgmt *mgmt = (void *) &super->f.data.i3e;
|
| |
- - uint32_t *tsf = (uint32_t *) &mgmt->u.probe_resp.timestamp;
|
| |
- + uint32_t tmptsf[2];
|
| |
-
|
| |
- /*
|
| |
- * Truth be told: this is a hack.
|
| |
- @@ -272,7 +272,8 @@ static void __wlan_tx(struct dma_desc *desc)
|
| |
- * (even, if it's got an accurate atomic clock source).
|
| |
- */
|
| |
-
|
| |
- - read_tsf(tsf);
|
| |
- + read_tsf(tmptsf);
|
| |
- + memcpy(&mgmt->u.probe_resp.timestamp, tmptsf, sizeof(tmptsf));
|
| |
- }
|
| |
-
|
| |
- wlan_tx_ampdu(super);
|
| |
- diff --git a/carl9170fw/config/CMakeLists.txt b/carl9170fw/config/CMakeLists.txt
|
| |
- index 0a96a82..23e7218 100644
|
| |
- --- a/carl9170fw/config/CMakeLists.txt
|
| |
- +++ b/carl9170fw/config/CMakeLists.txt
|
| |
- @@ -11,13 +11,13 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
| |
-
|
| |
- file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../include/generated")
|
| |
-
|
| |
- -BISON_TARGET(zconf zconf.y zconf.tab.c COMPILE_FLAGS "-l -b zconf -p zconf -t")
|
| |
- -FLEX_TARGET(zconfscan zconf.l zconf.lex.c COMPILE_FLAGS "-Pzconf -L")
|
| |
- +BISON_TARGET(zconf zconf.y zconf.tab.c COMPILE_FLAGS "-l -b zconf -p yy -t")
|
| |
- +FLEX_TARGET(zconfscan zconf.l zconf.lex.c COMPILE_FLAGS "-Pyy -L")
|
| |
-
|
| |
- SET(zconf_deps ${FLEX_zconfscan_OUTPUTS})
|
| |
- SET_SOURCE_FILES_PROPERTIES(${BISON_zconf_OUTPUTS}
|
| |
- PROPERTIES OBJECT_DEPENDS "${zconf_deps}")
|
| |
-
|
| |
- -set(conf_src conf.c ${BISON_zconf_OUTPUTS})
|
| |
- +set(conf_src conf.c symbol.c confdata.c expr.c preprocess.c ${BISON_zconf_OUTPUTS} ${FLEX_zconfscan_OUTPUTS})
|
| |
-
|
| |
- add_executable(conf ${conf_src})
|
| |
- diff --git a/carl9170fw/config/conf.c b/carl9170fw/config/conf.c
|
| |
- index 6be6143..2949b7d 100644
|
| |
- --- a/carl9170fw/config/conf.c
|
| |
- +++ b/carl9170fw/config/conf.c
|
| |
- @@ -1,9 +1,8 @@
|
| |
- +// SPDX-License-Identifier: GPL-2.0
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
-
|
| |
- -#include <locale.h>
|
| |
- #include <ctype.h>
|
| |
- #include <limits.h>
|
| |
- #include <stdio.h>
|
| |
- @@ -20,10 +19,10 @@
|
| |
-
|
| |
- static void conf(struct menu *menu);
|
| |
- static void check_conf(struct menu *menu);
|
| |
- -static void xfgets(char *str, int size, FILE *in);
|
| |
-
|
| |
- enum input_mode {
|
| |
- oldaskconfig,
|
| |
- + syncconfig,
|
| |
- oldconfig,
|
| |
- allnoconfig,
|
| |
- allyesconfig,
|
| |
- @@ -33,12 +32,13 @@ enum input_mode {
|
| |
- defconfig,
|
| |
- savedefconfig,
|
| |
- listnewconfig,
|
| |
- - oldnoconfig,
|
| |
- -} input_mode = oldaskconfig;
|
| |
- + olddefconfig,
|
| |
- +};
|
| |
- +static enum input_mode input_mode = oldaskconfig;
|
| |
-
|
| |
- static int indent = 1;
|
| |
- static int tty_stdio;
|
| |
- -static int valid_stdin = 1;
|
| |
- +static int sync_kconfig;
|
| |
- static int conf_cnt;
|
| |
- static char line[PATH_MAX];
|
| |
- static struct menu *rootEntry;
|
| |
- @@ -70,14 +70,14 @@ static void strip(char *str)
|
| |
- *p-- = 0;
|
| |
- }
|
| |
-
|
| |
- -static void check_stdin(void)
|
| |
- +/* Helper function to facilitate fgets() by Jean Sacren. */
|
| |
- +static void xfgets(char *str, int size, FILE *in)
|
| |
- {
|
| |
- - if (!valid_stdin) {
|
| |
- - printf(_("aborted!\n\n"));
|
| |
- - printf(_("Console input/output is redirected. "));
|
| |
- - printf(_("Run 'make config' to update configuration.\n\n"));
|
| |
- - exit(1);
|
| |
- - }
|
| |
- + if (!fgets(str, size, in))
|
| |
- + fprintf(stderr, "\nError in reading or end of file.\n");
|
| |
- +
|
| |
- + if (!tty_stdio)
|
| |
- + printf("%s", str);
|
| |
- }
|
| |
-
|
| |
- static int conf_askvalue(struct symbol *sym, const char *def)
|
| |
- @@ -85,7 +85,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
|
| |
- enum symbol_type type = sym_get_type(sym);
|
| |
-
|
| |
- if (!sym_has_value(sym))
|
| |
- - printf(_("(NEW) "));
|
| |
- + printf("(NEW) ");
|
| |
-
|
| |
- line[0] = '\n';
|
| |
- line[1] = 0;
|
| |
- @@ -99,17 +99,15 @@ static int conf_askvalue(struct symbol *sym, const char *def)
|
| |
-
|
| |
- switch (input_mode) {
|
| |
- case oldconfig:
|
| |
- + case syncconfig:
|
| |
- if (sym_has_value(sym)) {
|
| |
- printf("%s\n", def);
|
| |
- return 0;
|
| |
- }
|
| |
- - check_stdin();
|
| |
- /* fall through */
|
| |
- case oldaskconfig:
|
| |
- fflush(stdout);
|
| |
- xfgets(line, sizeof(line), stdin);
|
| |
- - if (!tty_stdio)
|
| |
- - printf("\n");
|
| |
- return 1;
|
| |
- default:
|
| |
- break;
|
| |
- @@ -134,7 +132,7 @@ static int conf_string(struct menu *menu)
|
| |
- const char *def;
|
| |
-
|
| |
- while (1) {
|
| |
- - printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
|
| |
- + printf("%*s%s ", indent - 1, "", menu->prompt->text);
|
| |
- printf("(%s) ", sym->name);
|
| |
- def = sym_get_string_value(sym);
|
| |
- if (sym_get_string_value(sym))
|
| |
- @@ -167,7 +165,7 @@ static int conf_sym(struct menu *menu)
|
| |
- tristate oldval, newval;
|
| |
-
|
| |
- while (1) {
|
| |
- - printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
|
| |
- + printf("%*s%s ", indent - 1, "", menu->prompt->text);
|
| |
- if (sym->name)
|
| |
- printf("(%s) ", sym->name);
|
| |
- putchar('[');
|
| |
- @@ -189,9 +187,7 @@ static int conf_sym(struct menu *menu)
|
| |
- printf("/m");
|
| |
- if (oldval != yes && sym_tristate_within_range(sym, yes))
|
| |
- printf("/y");
|
| |
- - if (menu_has_help(menu))
|
| |
- - printf("/?");
|
| |
- - printf("] ");
|
| |
- + printf("/?] ");
|
| |
- if (!conf_askvalue(sym, sym_get_string_value(sym)))
|
| |
- return 0;
|
| |
- strip(line);
|
| |
- @@ -254,7 +250,7 @@ static int conf_choice(struct menu *menu)
|
| |
- case no:
|
| |
- return 1;
|
| |
- case mod:
|
| |
- - printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
|
| |
- + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
|
| |
- return 0;
|
| |
- case yes:
|
| |
- break;
|
| |
- @@ -264,7 +260,7 @@ static int conf_choice(struct menu *menu)
|
| |
- while (1) {
|
| |
- int cnt, def;
|
| |
-
|
| |
- - printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
|
| |
- + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
|
| |
- def_sym = sym_get_choice_value(sym);
|
| |
- cnt = def = 0;
|
| |
- line[0] = 0;
|
| |
- @@ -272,7 +268,7 @@ static int conf_choice(struct menu *menu)
|
| |
- if (!menu_is_visible(child))
|
| |
- continue;
|
| |
- if (!child->sym) {
|
| |
- - printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
|
| |
- + printf("%*c %s\n", indent, '*', menu_get_prompt(child));
|
| |
- continue;
|
| |
- }
|
| |
- cnt++;
|
| |
- @@ -281,30 +277,27 @@ static int conf_choice(struct menu *menu)
|
| |
- printf("%*c", indent, '>');
|
| |
- } else
|
| |
- printf("%*c", indent, ' ');
|
| |
- - printf(" %d. %s", cnt, _(menu_get_prompt(child)));
|
| |
- + printf(" %d. %s", cnt, menu_get_prompt(child));
|
| |
- if (child->sym->name)
|
| |
- printf(" (%s)", child->sym->name);
|
| |
- if (!sym_has_value(child->sym))
|
| |
- - printf(_(" (NEW)"));
|
| |
- + printf(" (NEW)");
|
| |
- printf("\n");
|
| |
- }
|
| |
- - printf(_("%*schoice"), indent - 1, "");
|
| |
- + printf("%*schoice", indent - 1, "");
|
| |
- if (cnt == 1) {
|
| |
- printf("[1]: 1\n");
|
| |
- goto conf_childs;
|
| |
- }
|
| |
- - printf("[1-%d", cnt);
|
| |
- - if (menu_has_help(menu))
|
| |
- - printf("?");
|
| |
- - printf("]: ");
|
| |
- + printf("[1-%d?]: ", cnt);
|
| |
- switch (input_mode) {
|
| |
- case oldconfig:
|
| |
- + case syncconfig:
|
| |
- if (!is_new) {
|
| |
- cnt = def;
|
| |
- printf("%d\n", cnt);
|
| |
- break;
|
| |
- }
|
| |
- - check_stdin();
|
| |
- /* fall through */
|
| |
- case oldaskconfig:
|
| |
- fflush(stdout);
|
| |
- @@ -364,9 +357,11 @@ static void conf(struct menu *menu)
|
| |
-
|
| |
- switch (prop->type) {
|
| |
- case P_MENU:
|
| |
- - if ((input_mode == listnewconfig ||
|
| |
- - input_mode == oldnoconfig) &&
|
| |
- - rootEntry != menu) {
|
| |
- + /*
|
| |
- + * Except in oldaskconfig mode, we show only menus that
|
| |
- + * contain new symbols.
|
| |
- + */
|
| |
- + if (input_mode != oldaskconfig && rootEntry != menu) {
|
| |
- check_conf(menu);
|
| |
- return;
|
| |
- }
|
| |
- @@ -376,7 +371,7 @@ static void conf(struct menu *menu)
|
| |
- if (prompt)
|
| |
- printf("%*c\n%*c %s\n%*c\n",
|
| |
- indent, '*',
|
| |
- - indent, '*', _(prompt),
|
| |
- + indent, '*', prompt,
|
| |
- indent, '*');
|
| |
- default:
|
| |
- ;
|
| |
- @@ -426,12 +421,22 @@ static void check_conf(struct menu *menu)
|
| |
- if (sym_is_changable(sym) ||
|
| |
- (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
|
| |
- if (input_mode == listnewconfig) {
|
| |
- - if (sym->name && !sym_is_choice_value(sym)) {
|
| |
- - printf("%s%s\n", CONFIG_, sym->name);
|
| |
- + if (sym->name) {
|
| |
- + const char *str;
|
| |
- +
|
| |
- + if (sym->type == S_STRING) {
|
| |
- + str = sym_get_string_value(sym);
|
| |
- + str = sym_escape_string_value(str);
|
| |
- + printf("%s%s=%s\n", CONFIG_, sym->name, str);
|
| |
- + free((void *)str);
|
| |
- + } else {
|
| |
- + str = sym_get_string_value(sym);
|
| |
- + printf("%s%s=%s\n", CONFIG_, sym->name, str);
|
| |
- + }
|
| |
- }
|
| |
- - } else if (input_mode != oldnoconfig) {
|
| |
- + } else {
|
| |
- if (!conf_cnt++)
|
| |
- - printf(_("*\n* Restart config...\n*\n"));
|
| |
- + printf("*\n* Restart config...\n*\n");
|
| |
- rootEntry = menu_get_parent_menu(menu);
|
| |
- conf(rootEntry);
|
| |
- }
|
| |
- @@ -443,8 +448,9 @@ static void check_conf(struct menu *menu)
|
| |
- }
|
| |
-
|
| |
- static struct option long_opts[] = {
|
| |
- - {"askconfig", no_argument, NULL, oldaskconfig},
|
| |
- - {"config", no_argument, NULL, oldconfig},
|
| |
- + {"oldaskconfig", no_argument, NULL, oldaskconfig},
|
| |
- + {"oldconfig", no_argument, NULL, oldconfig},
|
| |
- + {"syncconfig", no_argument, NULL, syncconfig},
|
| |
- {"defconfig", optional_argument, NULL, defconfig},
|
| |
- {"savedefconfig", required_argument, NULL, savedefconfig},
|
| |
- {"allnoconfig", no_argument, NULL, allnoconfig},
|
| |
- @@ -453,7 +459,7 @@ static struct option long_opts[] = {
|
| |
- {"alldefconfig", no_argument, NULL, alldefconfig},
|
| |
- {"randconfig", no_argument, NULL, randconfig},
|
| |
- {"listnewconfig", no_argument, NULL, listnewconfig},
|
| |
- - {"noconfig", no_argument, NULL, oldnoconfig},
|
| |
- + {"olddefconfig", no_argument, NULL, olddefconfig},
|
| |
- {NULL, 0, NULL, 0}
|
| |
- };
|
| |
-
|
| |
- @@ -463,10 +469,11 @@ static void conf_usage(const char *progname)
|
| |
- printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
|
| |
- printf("[option] is _one_ of the following:\n");
|
| |
- printf(" --listnewconfig List new options\n");
|
| |
- - printf(" --askconfig Start a new configuration using a line-oriented program\n");
|
| |
- - printf(" --config Update a configuration using a provided .config as base\n");
|
| |
- - printf(" --silentconfig Same as config, but quietly, additionally update deps\n");
|
| |
- - printf(" --noconfig Same as silentconfig but set new symbols to no\n");
|
| |
- + printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
|
| |
- + printf(" --oldconfig Update a configuration using a provided .config as base\n");
|
| |
- + printf(" --syncconfig Similar to oldconfig but generates configuration in\n"
|
| |
- + " include/{generated/,config/}\n");
|
| |
- + printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n");
|
| |
- printf(" --defconfig <file> New config with default defined in <file>\n");
|
| |
- printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
|
| |
- printf(" --allnoconfig New config where all options are answered with no\n");
|
| |
- @@ -482,12 +489,9 @@ int main(int ac, char **av)
|
| |
- int opt;
|
| |
- const char *name, *defconfig_file = NULL /* gcc uninit */;
|
| |
- struct stat tmpstat;
|
| |
- + int no_conf_write = 0;
|
| |
-
|
| |
- - setlocale(LC_ALL, "");
|
| |
- - bindtextdomain(PACKAGE, LOCALEDIR);
|
| |
- - textdomain(PACKAGE);
|
| |
- -
|
| |
- - tty_stdio = isatty(0) && isatty(1) && isatty(2);
|
| |
- + tty_stdio = isatty(0) && isatty(1);
|
| |
-
|
| |
- while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
|
| |
- if (opt == 's') {
|
| |
- @@ -496,6 +500,14 @@ 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:
|
| |
- case savedefconfig:
|
| |
- defconfig_file = optarg;
|
| |
- @@ -532,7 +544,7 @@ int main(int ac, char **av)
|
| |
- case allmodconfig:
|
| |
- case alldefconfig:
|
| |
- case listnewconfig:
|
| |
- - case oldnoconfig:
|
| |
- + case olddefconfig:
|
| |
- break;
|
| |
- case '?':
|
| |
- conf_usage(progname);
|
| |
- @@ -541,30 +553,45 @@ int main(int ac, char **av)
|
| |
- }
|
| |
- }
|
| |
- if (ac == optind) {
|
| |
- - printf(_("%s: Kconfig file missing\n"), av[0]);
|
| |
- + fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
|
| |
- conf_usage(progname);
|
| |
- exit(1);
|
| |
- }
|
| |
- 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 run some configurator (e.g. \"make oldconfig\" or\n"
|
| |
- + "*** \"make menuconfig\" or \"make xconfig\").\n"
|
| |
- + "***\n", name);
|
| |
- + exit(1);
|
| |
- + }
|
| |
- + }
|
| |
-
|
| |
- switch (input_mode) {
|
| |
- case defconfig:
|
| |
- if (!defconfig_file)
|
| |
- defconfig_file = conf_get_default_confname();
|
| |
- if (conf_read(defconfig_file)) {
|
| |
- - printf(_("***\n"
|
| |
- - "*** Can't find default configuration \"%s\"!\n"
|
| |
- - "***\n"), defconfig_file);
|
| |
- + fprintf(stderr,
|
| |
- + "***\n"
|
| |
- + "*** Can't find default configuration \"%s\"!\n"
|
| |
- + "***\n",
|
| |
- + defconfig_file);
|
| |
- exit(1);
|
| |
- }
|
| |
- break;
|
| |
- case savedefconfig:
|
| |
- + case syncconfig:
|
| |
- case oldaskconfig:
|
| |
- case oldconfig:
|
| |
- case listnewconfig:
|
| |
- - case oldnoconfig:
|
| |
- + case olddefconfig:
|
| |
- conf_read(NULL);
|
| |
- break;
|
| |
- case allnoconfig:
|
| |
- @@ -578,7 +605,7 @@ int main(int ac, char **av)
|
| |
- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
|
| |
- if (conf_read_simple(name, S_DEF_USER)) {
|
| |
- fprintf(stderr,
|
| |
- - _("*** Can't read seed configuration \"%s\"!\n"),
|
| |
- + "*** Can't read seed configuration \"%s\"!\n",
|
| |
- name);
|
| |
- exit(1);
|
| |
- }
|
| |
- @@ -595,7 +622,7 @@ int main(int ac, char **av)
|
| |
- if (conf_read_simple(name, S_DEF_USER) &&
|
| |
- conf_read_simple("all.config", S_DEF_USER)) {
|
| |
- fprintf(stderr,
|
| |
- - _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
|
| |
- + "*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
|
| |
- name);
|
| |
- exit(1);
|
| |
- }
|
| |
- @@ -604,7 +631,17 @@ int main(int ac, char **av)
|
| |
- break;
|
| |
- }
|
| |
-
|
| |
- - valid_stdin = tty_stdio;
|
| |
- + if (sync_kconfig) {
|
| |
- + 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;
|
| |
- + }
|
| |
- + }
|
| |
-
|
| |
- switch (input_mode) {
|
| |
- case allnoconfig:
|
| |
- @@ -635,44 +672,51 @@ int main(int ac, char **av)
|
| |
- /* fall through */
|
| |
- case oldconfig:
|
| |
- case listnewconfig:
|
| |
- - case oldnoconfig:
|
| |
- + case syncconfig:
|
| |
- /* Update until a loop caused no more changes */
|
| |
- do {
|
| |
- conf_cnt = 0;
|
| |
- check_conf(&rootmenu);
|
| |
- - } while (conf_cnt &&
|
| |
- - (input_mode != listnewconfig &&
|
| |
- - input_mode != oldnoconfig));
|
| |
- + } while (conf_cnt);
|
| |
- + break;
|
| |
- + case olddefconfig:
|
| |
- + default:
|
| |
- break;
|
| |
- }
|
| |
-
|
| |
- if (input_mode == savedefconfig) {
|
| |
- if (conf_write_defconfig(defconfig_file)) {
|
| |
- - fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
|
| |
- + fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
|
| |
- defconfig_file);
|
| |
- return 1;
|
| |
- }
|
| |
- } else if (input_mode != listnewconfig) {
|
| |
- - /*
|
| |
- - * build so we shall update autoconf.
|
| |
- - */
|
| |
- - if (conf_write(NULL)) {
|
| |
- - fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
|
| |
- + if (!no_conf_write && conf_write(NULL)) {
|
| |
- + fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
|
| |
- exit(1);
|
| |
- }
|
| |
- - if (conf_write_autoconf()) {
|
| |
- - fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
|
| |
- +
|
| |
- + /*
|
| |
- + * Create auto.conf if it does not exist.
|
| |
- + * This prevents GNU Make 4.1 or older from emitting
|
| |
- + * "include/generated/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 our cmake case, we always want to update the autogenerated
|
| |
- + * files.
|
| |
- + */
|
| |
- + sync_kconfig = 1;
|
| |
- +
|
| |
- + if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
|
| |
- + fprintf(stderr,
|
| |
- + "\n*** Error during sync of the configuration.\n\n");
|
| |
- return 1;
|
| |
- }
|
| |
- }
|
| |
- return 0;
|
| |
- }
|
| |
- -
|
| |
- -/*
|
| |
- - * Helper function to facilitate fgets() by Jean Sacren.
|
| |
- - */
|
| |
- -void xfgets(char *str, int size, FILE *in)
|
| |
- -{
|
| |
- - if (fgets(str, size, in) == NULL)
|
| |
- - fprintf(stderr, "\nError in reading or end of file.\n");
|
| |
- -}
|
| |
- diff --git a/carl9170fw/config/confdata.c b/carl9170fw/config/confdata.c
|
| |
- index e606f06..d67695d 100644
|
| |
- --- a/carl9170fw/config/confdata.c
|
| |
- +++ b/carl9170fw/config/confdata.c
|
| |
- @@ -1,12 +1,13 @@
|
| |
- +// SPDX-License-Identifier: GPL-2.0
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
-
|
| |
- #include <sys/stat.h>
|
| |
- #include <ctype.h>
|
| |
- #include <errno.h>
|
| |
- #include <fcntl.h>
|
| |
- +#include <limits.h>
|
| |
- #include <stdarg.h>
|
| |
- #include <stdio.h>
|
| |
- #include <stdlib.h>
|
| |
- @@ -16,6 +17,105 @@
|
| |
-
|
| |
- #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;
|
| |
- +}
|
| |
- +
|
| |
- +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 *);
|
| |
- @@ -28,7 +128,7 @@ static void conf_message(const char *fmt, ...)
|
| |
- __attribute__ ((format (printf, 1, 2)));
|
| |
-
|
| |
- static const char *conf_filename;
|
| |
- -static int conf_lineno, conf_warnings, conf_unsaved;
|
| |
- +static int conf_lineno, conf_warnings;
|
| |
-
|
| |
- const char conf_defname[] = "include/generated/defconfig";
|
| |
-
|
| |
- @@ -43,16 +143,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 +160,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);
|
| |
- }
|
| |
-
|
| |
- @@ -81,43 +186,16 @@ const char *conf_get_autoconfig_name(void)
|
| |
- return name ? name : "include/generated/auto.conf";
|
| |
- }
|
| |
-
|
| |
- -static char *conf_expand_value(const char *in)
|
| |
- -{
|
| |
- - struct symbol *sym;
|
| |
- - const char *src;
|
| |
- - static char res_value[SYMBOL_MAXLENGTH];
|
| |
- - char *dst, name[SYMBOL_MAXLENGTH];
|
| |
- -
|
| |
- - res_value[0] = 0;
|
| |
- - dst = name;
|
| |
- - while ((src = strchr(in, '$'))) {
|
| |
- - strncat(res_value, in, src - in);
|
| |
- - src++;
|
| |
- - dst = name;
|
| |
- - while (isalnum(*src) || *src == '_')
|
| |
- - *dst++ = *src++;
|
| |
- - *dst = 0;
|
| |
- - sym = sym_lookup(name, 0);
|
| |
- - sym_calc_value(sym);
|
| |
- - strcat(res_value, sym_get_string_value(sym));
|
| |
- - in = src;
|
| |
- - }
|
| |
- - strcat(res_value, in);
|
| |
- -
|
| |
- - return res_value;
|
| |
- -}
|
| |
- -
|
| |
- char *conf_get_default_confname(void)
|
| |
- {
|
| |
- - struct stat buf;
|
| |
- static char fullname[PATH_MAX+1];
|
| |
- char *env, *name;
|
| |
-
|
| |
- - name = conf_expand_value(conf_defname);
|
| |
- + name = expand_string(conf_defname);
|
| |
- env = getenv(SRCTREE);
|
| |
- if (env) {
|
| |
- sprintf(fullname, "%s/%s", env, name);
|
| |
- - if (!stat(fullname, &buf))
|
| |
- + if (is_present(fullname))
|
| |
- return fullname;
|
| |
- }
|
| |
- return name;
|
| |
- @@ -150,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;
|
| |
- @@ -176,9 +246,8 @@ 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 = strdup(p);
|
| |
- + sym->def[def].val = xstrdup(p);
|
| |
- sym->flags |= def_flags;
|
| |
- } else {
|
| |
- if (def != S_DEF_AUTO)
|
| |
- @@ -201,7 +270,7 @@ static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
|
| |
- if (new_size > *n) {
|
| |
- new_size += LINE_GROWTH - 1;
|
| |
- new_size *= 2;
|
| |
- - nline = realloc(*lineptr, new_size);
|
| |
- + nline = xrealloc(*lineptr, new_size);
|
| |
- if (!nline)
|
| |
- return -1;
|
| |
-
|
| |
- @@ -274,10 +343,11 @@ int conf_read_simple(const char *name, int def)
|
| |
- if (expr_calc_value(prop->visible.expr) == no ||
|
| |
- prop->expr->type != E_SYMBOL)
|
| |
- continue;
|
| |
- - name = conf_expand_value(prop->expr->left.sym->name);
|
| |
- + sym_calc_value(prop->expr->left.sym);
|
| |
- + name = sym_get_string_value(prop->expr->left.sym);
|
| |
- in = zconf_fopen(name);
|
| |
- if (in) {
|
| |
- - conf_message(_("using defaults found in %s"),
|
| |
- + conf_message("using defaults found in %s",
|
| |
- name);
|
| |
- goto load;
|
| |
- }
|
| |
- @@ -290,7 +360,6 @@ load:
|
| |
- conf_filename = name;
|
| |
- conf_lineno = 0;
|
| |
- conf_warnings = 0;
|
| |
- - conf_unsaved = 0;
|
| |
-
|
| |
- def_flags = SYMBOL_DEF << def;
|
| |
- for_all_symbols(i, sym) {
|
| |
- @@ -327,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);
|
| |
- @@ -357,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);
|
| |
- }
|
| |
- @@ -380,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) {
|
| |
- @@ -409,6 +483,7 @@ setsym:
|
| |
- int conf_read(const char *name)
|
| |
- {
|
| |
- struct symbol *sym;
|
| |
- + int conf_unsaved = 0;
|
| |
- int i;
|
| |
-
|
| |
- sym_set_change_count(0);
|
| |
- @@ -422,7 +497,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 */
|
| |
- @@ -678,7 +753,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:
|
| |
- @@ -791,15 +865,14 @@ int conf_write(const char *name)
|
| |
- struct menu *menu;
|
| |
- const char *basename;
|
| |
- const char *str;
|
| |
- - char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
|
| |
- + char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];
|
| |
- char *env;
|
| |
-
|
| |
- 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();
|
| |
- @@ -877,33 +950,61 @@ next:
|
| |
- return 1;
|
| |
- }
|
| |
-
|
| |
- - conf_message(_("configuration written to %s"), newname);
|
| |
- + conf_message("configuration written to %s", newname);
|
| |
-
|
| |
- sym_set_change_count(0);
|
| |
-
|
| |
- return 0;
|
| |
- }
|
| |
-
|
| |
- -static int conf_split_config(void)
|
| |
- +/* 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_touch_deps(void)
|
| |
- {
|
| |
- const char *name;
|
| |
- - char path[PATH_MAX+1];
|
| |
- - char *s, *d, c;
|
| |
- struct symbol *sym;
|
| |
- - struct stat sb;
|
| |
- - int res, i, fd;
|
| |
- + int res, i;
|
| |
- +
|
| |
- + strcpy(depfile_path, "include/generated/");
|
| |
- + depfile_prefix_len = strlen(depfile_path);
|
| |
-
|
| |
- name = conf_get_autoconfig_name();
|
| |
- conf_read_simple(name, S_DEF_AUTO);
|
| |
- sym_calc_value(modules_sym);
|
| |
-
|
| |
- - if (chdir("include/generated"))
|
| |
- - 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) {
|
| |
- @@ -952,63 +1053,30 @@ 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;
|
| |
- - }
|
| |
- - /*
|
| |
- - * 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++ = '/';
|
| |
- - }
|
| |
- - /* 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(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, *out_c;
|
| |
- int i;
|
| |
-
|
| |
- + if (!overwrite && is_present(autoconf_name))
|
| |
- + return 0;
|
| |
- +
|
| |
- sym_clear_all_valid();
|
| |
-
|
| |
- - file_write_dep("include/generated/auto.conf.cmd");
|
| |
- + conf_write_dep("include/generated/auto.conf.cmd");
|
| |
-
|
| |
- - if (conf_split_config())
|
| |
- + if (conf_touch_deps())
|
| |
- return 1;
|
| |
-
|
| |
- out = fopen(".tmpconfig", "w");
|
| |
- @@ -1065,24 +1133,35 @@ 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/generated/tristate.conf";
|
| |
- + if (make_parent_dir(name))
|
| |
- + return 1;
|
| |
- if (rename(".tmpconfig_tristate", name))
|
| |
- return 1;
|
| |
- +
|
| |
- + if (make_parent_dir(autoconf_name))
|
| |
- + return 1;
|
| |
- +
|
| |
- name = getenv("KCONFIG_CMAKE");
|
| |
- if (!name)
|
| |
- name = "config.cmake";
|
| |
- + if (make_parent_dir(name))
|
| |
- + return 1;
|
| |
- if (rename(".tmpconfig.cmake", name))
|
| |
- return 1;
|
| |
- - name = conf_get_autoconfig_name();
|
| |
- +
|
| |
- /*
|
| |
- * 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;
|
| |
- @@ -1186,7 +1265,7 @@ void set_all_choice_values(struct symbol *csym)
|
| |
- bool conf_set_all_new_symbols(enum conf_def_mode mode)
|
| |
- {
|
| |
- struct symbol *sym, *csym;
|
| |
- - int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
|
| |
- + int i, cnt, pby, pty, ptm; /* pby: probability of bool = y
|
| |
- * pty: probability of tristate = y
|
| |
- * ptm: probability of tristate = m
|
| |
- */
|
| |
- diff --git a/carl9170fw/config/expr.c b/carl9170fw/config/expr.c
|
| |
- index 8cee597..77ffff3 100644
|
| |
- --- a/carl9170fw/config/expr.c
|
| |
- +++ b/carl9170fw/config/expr.c
|
| |
- @@ -1,8 +1,10 @@
|
| |
- +// SPDX-License-Identifier: GPL-2.0
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
-
|
| |
- +#include <ctype.h>
|
| |
- +#include <errno.h>
|
| |
- #include <stdio.h>
|
| |
- #include <stdlib.h>
|
| |
- #include <string.h>
|
| |
- @@ -94,7 +96,7 @@ struct expr *expr_copy(const struct expr *org)
|
| |
- e->right.expr = expr_copy(org->right.expr);
|
| |
- break;
|
| |
- default:
|
| |
- - printf("can't copy type %d\n", e->type);
|
| |
- + fprintf(stderr, "can't copy type %d\n", e->type);
|
| |
- free(e);
|
| |
- e = NULL;
|
| |
- break;
|
| |
- @@ -113,7 +115,7 @@ void expr_free(struct expr *e)
|
| |
- break;
|
| |
- case E_NOT:
|
| |
- expr_free(e->left.expr);
|
| |
- - return;
|
| |
- + break;
|
| |
- case E_EQUAL:
|
| |
- case E_GEQ:
|
| |
- case E_GTH:
|
| |
- @@ -127,7 +129,7 @@ void expr_free(struct expr *e)
|
| |
- expr_free(e->right.expr);
|
| |
- break;
|
| |
- default:
|
| |
- - printf("how to free type %d?\n", e->type);
|
| |
- + fprintf(stderr, "how to free type %d?\n", e->type);
|
| |
- break;
|
| |
- }
|
| |
- free(e);
|
| |
- @@ -138,8 +140,18 @@ static int trans_count;
|
| |
- #define e1 (*ep1)
|
| |
- #define e2 (*ep2)
|
| |
-
|
| |
- +/*
|
| |
- + * expr_eliminate_eq() helper.
|
| |
- + *
|
| |
- + * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
|
| |
- + * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
|
| |
- + * against all other leaves. Two equal leaves are both replaced with either 'y'
|
| |
- + * or 'n' as appropriate for 'type', to be eliminated later.
|
| |
- + */
|
| |
- static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
|
| |
- {
|
| |
- + /* Recurse down to leaves */
|
| |
- +
|
| |
- if (e1->type == type) {
|
| |
- __expr_eliminate_eq(type, &e1->left.expr, &e2);
|
| |
- __expr_eliminate_eq(type, &e1->right.expr, &e2);
|
| |
- @@ -150,12 +162,18 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
|
| |
- __expr_eliminate_eq(type, &e1, &e2->right.expr);
|
| |
- return;
|
| |
- }
|
| |
- +
|
| |
- + /* e1 and e2 are leaves. Compare them. */
|
| |
- +
|
| |
- if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
|
| |
- e1->left.sym == e2->left.sym &&
|
| |
- (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
|
| |
- return;
|
| |
- if (!expr_eq(e1, e2))
|
| |
- return;
|
| |
- +
|
| |
- + /* e1 and e2 are equal leaves. Prepare them for elimination. */
|
| |
- +
|
| |
- trans_count++;
|
| |
- expr_free(e1); expr_free(e2);
|
| |
- switch (type) {
|
| |
- @@ -172,6 +190,35 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
|
| |
- }
|
| |
- }
|
| |
-
|
| |
- +/*
|
| |
- + * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
|
| |
- + * Example reductions:
|
| |
- + *
|
| |
- + * ep1: A && B -> ep1: y
|
| |
- + * ep2: A && B && C -> ep2: C
|
| |
- + *
|
| |
- + * ep1: A || B -> ep1: n
|
| |
- + * ep2: A || B || C -> ep2: C
|
| |
- + *
|
| |
- + * ep1: A && (B && FOO) -> ep1: FOO
|
| |
- + * ep2: (BAR && B) && A -> ep2: BAR
|
| |
- + *
|
| |
- + * ep1: A && (B || C) -> ep1: y
|
| |
- + * ep2: (C || B) && A -> ep2: y
|
| |
- + *
|
| |
- + * Comparisons are done between all operands at the same "level" of && or ||.
|
| |
- + * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
|
| |
- + * following operands will be compared:
|
| |
- + *
|
| |
- + * - 'e1', 'e2 || e3', and 'e4 || e5', against each other
|
| |
- + * - e2 against e3
|
| |
- + * - e4 against e5
|
| |
- + *
|
| |
- + * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
|
| |
- + * '(e1 && e2) && e3' are both a single level.
|
| |
- + *
|
| |
- + * See __expr_eliminate_eq() as well.
|
| |
- + */
|
| |
- void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
|
| |
- {
|
| |
- if (!e1 || !e2)
|
| |
- @@ -197,6 +244,12 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
|
| |
- #undef e1
|
| |
- #undef e2
|
| |
-
|
| |
- +/*
|
| |
- + * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
|
| |
- + * &&/|| expressions are considered equal if every operand in one expression
|
| |
- + * 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 res, old_count;
|
| |
- @@ -243,6 +296,17 @@ static int expr_eq(struct expr *e1, struct expr *e2)
|
| |
- return 0;
|
| |
- }
|
| |
-
|
| |
- +/*
|
| |
- + * Recursively performs the following simplifications in-place (as well as the
|
| |
- + * corresponding simplifications with swapped operands):
|
| |
- + *
|
| |
- + * expr && n -> n
|
| |
- + * expr && y -> expr
|
| |
- + * expr || n -> expr
|
| |
- + * expr || y -> y
|
| |
- + *
|
| |
- + * Returns the optimized expression.
|
| |
- + */
|
| |
- static struct expr *expr_eliminate_yn(struct expr *e)
|
| |
- {
|
| |
- struct expr *tmp;
|
| |
- @@ -516,12 +580,21 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
|
| |
- return NULL;
|
| |
- }
|
| |
-
|
| |
- +/*
|
| |
- + * expr_eliminate_dups() helper.
|
| |
- + *
|
| |
- + * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
|
| |
- + * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
|
| |
- + * against all other leaves to look for simplifications.
|
| |
- + */
|
| |
- static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
|
| |
- {
|
| |
- #define e1 (*ep1)
|
| |
- #define e2 (*ep2)
|
| |
- struct expr *tmp;
|
| |
-
|
| |
- + /* Recurse down to leaves */
|
| |
- +
|
| |
- if (e1->type == type) {
|
| |
- expr_eliminate_dups1(type, &e1->left.expr, &e2);
|
| |
- expr_eliminate_dups1(type, &e1->right.expr, &e2);
|
| |
- @@ -532,6 +605,9 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
|
| |
- expr_eliminate_dups1(type, &e1, &e2->right.expr);
|
| |
- return;
|
| |
- }
|
| |
- +
|
| |
- + /* e1 and e2 are leaves. Compare and process them. */
|
| |
- +
|
| |
- if (e1 == e2)
|
| |
- return;
|
| |
-
|
| |
- @@ -568,6 +644,17 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
|
| |
- #undef e2
|
| |
- }
|
| |
-
|
| |
- +/*
|
| |
- + * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
|
| |
- + * operands.
|
| |
- + *
|
| |
- + * Example simplifications:
|
| |
- + *
|
| |
- + * A || B || A -> A || B
|
| |
- + * A && B && A=y -> A=y && B
|
| |
- + *
|
| |
- + * Returns the deduplicated expression.
|
| |
- + */
|
| |
- struct expr *expr_eliminate_dups(struct expr *e)
|
| |
- {
|
| |
- int oldcount;
|
| |
- @@ -584,6 +671,7 @@ struct expr *expr_eliminate_dups(struct expr *e)
|
| |
- ;
|
| |
- }
|
| |
- if (!trans_count)
|
| |
- + /* No simplifications done in this pass. We're done */
|
| |
- break;
|
| |
- e = expr_eliminate_yn(e);
|
| |
- }
|
| |
- @@ -591,6 +679,12 @@ struct expr *expr_eliminate_dups(struct expr *e)
|
| |
- return e;
|
| |
- }
|
| |
-
|
| |
- +/*
|
| |
- + * Performs various simplifications involving logical operators and
|
| |
- + * comparisons.
|
| |
- + *
|
| |
- + * Allocates and returns a new expression.
|
| |
- + */
|
| |
- struct expr *expr_transform(struct expr *e)
|
| |
- {
|
| |
- struct expr *tmp;
|
| |
- @@ -805,6 +899,20 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
|
| |
- return false;
|
| |
- }
|
| |
-
|
| |
- +/*
|
| |
- + * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
|
| |
- + * expression 'e'.
|
| |
- + *
|
| |
- + * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
|
| |
- + *
|
| |
- + * A -> A!=n
|
| |
- + * !A -> A=n
|
| |
- + * A && B -> !(A=n || B=n)
|
| |
- + * A || B -> !(A=n && B=n)
|
| |
- + * A && (B || C) -> !(A=n || (B=n && C=n))
|
| |
- + *
|
| |
- + * Allocates and returns a new expression.
|
| |
- + */
|
| |
- struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
|
| |
- {
|
| |
- struct expr *e1, *e2;
|
| |
- @@ -874,7 +982,6 @@ enum string_value_kind {
|
| |
- k_string,
|
| |
- k_signed,
|
| |
- k_unsigned,
|
| |
- - k_invalid
|
| |
- };
|
| |
-
|
| |
- union string_value {
|
| |
- @@ -905,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;
|
| |
- @@ -967,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);
|
| |
- @@ -1031,49 +1129,9 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
|
| |
- return 0;
|
| |
- }
|
| |
-
|
| |
- -static inline struct expr *
|
| |
- -expr_get_leftmost_symbol(const struct expr *e)
|
| |
- -{
|
| |
- -
|
| |
- - if (e == NULL)
|
| |
- - return NULL;
|
| |
- -
|
| |
- - while (e->type != E_SYMBOL)
|
| |
- - e = e->left.expr;
|
| |
- -
|
| |
- - return expr_copy(e);
|
| |
- -}
|
| |
- -
|
| |
- -/*
|
| |
- - * Given expression `e1' and `e2', returns the leaf of the longest
|
| |
- - * sub-expression of `e1' not containing 'e2.
|
| |
- - */
|
| |
- -struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
|
| |
- -{
|
| |
- - struct expr *ret;
|
| |
- -
|
| |
- - switch (e1->type) {
|
| |
- - case E_OR:
|
| |
- - return expr_alloc_and(
|
| |
- - expr_simplify_unmet_dep(e1->left.expr, e2),
|
| |
- - expr_simplify_unmet_dep(e1->right.expr, e2));
|
| |
- - case E_AND: {
|
| |
- - struct expr *e;
|
| |
- - e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
|
| |
- - e = expr_eliminate_dups(e);
|
| |
- - ret = (!expr_eq(e, e1)) ? e1 : NULL;
|
| |
- - expr_free(e);
|
| |
- - break;
|
| |
- - }
|
| |
- - default:
|
| |
- - ret = e1;
|
| |
- - break;
|
| |
- - }
|
| |
- -
|
| |
- - return expr_get_leftmost_symbol(ret);
|
| |
- -}
|
| |
- -
|
| |
- -void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
|
| |
- +void expr_print(struct expr *e,
|
| |
- + void (*fn)(void *, struct symbol *, const char *),
|
| |
- + void *data, int prevtoken)
|
| |
- {
|
| |
- if (!e) {
|
| |
- fn(data, NULL, "y");
|
| |
- @@ -1207,3 +1265,33 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
|
| |
- {
|
| |
- expr_print(e, expr_print_gstr_helper, gs, E_NONE);
|
| |
- }
|
| |
- +
|
| |
- +/*
|
| |
- + * Transform the top level "||" tokens into newlines and prepend each
|
| |
- + * line with a minus. This makes expressions much easier to read.
|
| |
- + * Suitable for reverse dependency expressions.
|
| |
- + */
|
| |
- +static void expr_print_revdep(struct expr *e,
|
| |
- + void (*fn)(void *, struct symbol *, const char *),
|
| |
- + void *data, tristate pr_type, const char **title)
|
| |
- +{
|
| |
- + if (e->type == E_OR) {
|
| |
- + expr_print_revdep(e->left.expr, fn, data, pr_type, title);
|
| |
- + expr_print_revdep(e->right.expr, fn, data, pr_type, title);
|
| |
- + } else if (expr_calc_value(e) == pr_type) {
|
| |
- + if (*title) {
|
| |
- + fn(data, NULL, *title);
|
| |
- + *title = NULL;
|
| |
- + }
|
| |
- +
|
| |
- + fn(data, NULL, " - ");
|
| |
- + expr_print(e, fn, data, E_NONE);
|
| |
- + fn(data, NULL, "\n");
|
| |
- + }
|
| |
- +}
|
| |
- +
|
| |
- +void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
|
| |
- + tristate pr_type, const char *title)
|
| |
- +{
|
| |
- + expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
|
| |
- +}
|
| |
- diff --git a/carl9170fw/config/expr.h b/carl9170fw/config/expr.h
|
| |
- index a73f762..999edb6 100644
|
| |
- --- a/carl9170fw/config/expr.h
|
| |
- +++ b/carl9170fw/config/expr.h
|
| |
- @@ -1,6 +1,6 @@
|
| |
- +/* SPDX-License-Identifier: GPL-2.0 */
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * 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[] */
|
| |
- @@ -74,21 +74,64 @@ enum {
|
| |
- S_DEF_COUNT
|
| |
- };
|
| |
-
|
| |
- +/*
|
| |
- + * Represents a configuration symbol.
|
| |
- + *
|
| |
- + * Choices are represented as a special kind of symbol and have the
|
| |
- + * SYMBOL_CHOICE bit set in 'flags'.
|
| |
- + */
|
| |
- struct symbol {
|
| |
- + /* The next symbol in the same bucket in the symbol hash table */
|
| |
- struct symbol *next;
|
| |
- +
|
| |
- + /* The name of the symbol, e.g. "FOO" for 'config FOO' */
|
| |
- char *name;
|
| |
- +
|
| |
- + /* S_BOOLEAN, S_TRISTATE, ... */
|
| |
- enum symbol_type type;
|
| |
- +
|
| |
- + /*
|
| |
- + * The calculated value of the symbol. The SYMBOL_VALID bit is set in
|
| |
- + * 'flags' when this is up to date. Note that this value might differ
|
| |
- + * from the user value set in e.g. a .config file, due to visibility.
|
| |
- + */
|
| |
- struct symbol_value curr;
|
| |
- +
|
| |
- + /*
|
| |
- + * Values for the symbol provided from outside. def[S_DEF_USER] holds
|
| |
- + * the .config value.
|
| |
- + */
|
| |
- struct symbol_value def[S_DEF_COUNT];
|
| |
- +
|
| |
- + /*
|
| |
- + * An upper bound on the tristate value the user can set for the symbol
|
| |
- + * if it is a boolean or tristate. Calculated from prompt dependencies,
|
| |
- + * which also inherit dependencies from enclosing menus, choices, and
|
| |
- + * ifs. If 'n', the user value will be ignored.
|
| |
- + *
|
| |
- + * Symbols lacking prompts always have visibility 'n'.
|
| |
- + */
|
| |
- tristate visible;
|
| |
- +
|
| |
- + /* SYMBOL_* flags */
|
| |
- int flags;
|
| |
- +
|
| |
- + /* List of properties. See prop_type. */
|
| |
- struct property *prop;
|
| |
- +
|
| |
- + /* Dependencies from enclosing menus, choices, and ifs */
|
| |
- struct expr_value dir_dep;
|
| |
- +
|
| |
- + /* Reverse dependencies through being selected by other symbols */
|
| |
- struct expr_value rev_dep;
|
| |
- +
|
| |
- + /*
|
| |
- + * "Weak" reverse dependencies through being implied by other symbols
|
| |
- + */
|
| |
- 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 */
|
| |
- @@ -98,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 */
|
| |
-
|
| |
- @@ -128,18 +171,20 @@ struct symbol {
|
| |
- * config BAZ
|
| |
- * int "BAZ Value"
|
| |
- * range 1..255
|
| |
- + *
|
| |
- + * Please, also check zconf.y:print_symbol() when modifying the
|
| |
- + * list of property types!
|
| |
- */
|
| |
- enum prop_type {
|
| |
- P_UNKNOWN,
|
| |
- P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */
|
| |
- P_COMMENT, /* text associated with a comment */
|
| |
- - P_MENU, /* prompt associated with a menuconfig option */
|
| |
- + P_MENU, /* prompt associated with a menu or menuconfig symbol */
|
| |
- P_DEFAULT, /* default y */
|
| |
- P_CHOICE, /* choice value */
|
| |
- 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 */
|
| |
- };
|
| |
-
|
| |
- @@ -166,22 +211,67 @@ struct property {
|
| |
- for (st = sym->prop; st; st = st->next) \
|
| |
- if (st->text)
|
| |
-
|
| |
- +/*
|
| |
- + * Represents a node in the menu tree, as seen in e.g. menuconfig (though used
|
| |
- + * for all front ends). Each symbol, menu, etc. defined in the Kconfig files
|
| |
- + * gets a node. A symbol defined in multiple locations gets one node at each
|
| |
- + * location.
|
| |
- + */
|
| |
- struct menu {
|
| |
- + /* The next menu node at the same level */
|
| |
- struct menu *next;
|
| |
- +
|
| |
- + /* The parent menu node, corresponding to e.g. a menu or choice */
|
| |
- struct menu *parent;
|
| |
- +
|
| |
- + /* The first child menu node, for e.g. menus and choices */
|
| |
- struct menu *list;
|
| |
- +
|
| |
- + /*
|
| |
- + * The symbol associated with the menu node. Choices are implemented as
|
| |
- + * a special kind of symbol. NULL for menus, comments, and ifs.
|
| |
- + */
|
| |
- struct symbol *sym;
|
| |
- +
|
| |
- + /*
|
| |
- + * The prompt associated with the node. This holds the prompt for a
|
| |
- + * symbol as well as the text for a menu or comment, along with the
|
| |
- + * type (P_PROMPT, P_MENU, etc.)
|
| |
- + */
|
| |
- struct property *prompt;
|
| |
- +
|
| |
- + /*
|
| |
- + * 'visible if' dependencies. If more than one is given, they will be
|
| |
- + * ANDed together.
|
| |
- + */
|
| |
- struct expr *visibility;
|
| |
- +
|
| |
- + /*
|
| |
- + * Ordinary dependencies from e.g. 'depends on' and 'if', ANDed
|
| |
- + * together
|
| |
- + */
|
| |
- struct expr *dep;
|
| |
- +
|
| |
- + /* MENU_* flags */
|
| |
- unsigned int flags;
|
| |
- +
|
| |
- + /* Any help text associated with the node */
|
| |
- char *help;
|
| |
- +
|
| |
- + /* The location where the menu node appears in the Kconfig files */
|
| |
- struct file *file;
|
| |
- int lineno;
|
| |
- +
|
| |
- + /* For use by front ends that need to store auxiliary data */
|
| |
- void *data;
|
| |
- };
|
| |
-
|
| |
- +/*
|
| |
- + * Set on a menu node when the corresponding symbol changes state in some way.
|
| |
- + * Can be checked by front ends.
|
| |
- + */
|
| |
- #define MENU_CHANGED 0x0001
|
| |
- +
|
| |
- #define MENU_ROOT 0x0002
|
| |
-
|
| |
- struct jump_key {
|
| |
- @@ -217,11 +307,12 @@ struct expr *expr_transform(struct expr *e);
|
| |
- int expr_contains_symbol(struct expr *dep, struct symbol *sym);
|
| |
- bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
|
| |
- struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
|
| |
- -struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
|
| |
-
|
| |
- void expr_fprint(struct expr *e, FILE *out);
|
| |
- struct gstr; /* forward */
|
| |
- void expr_gstr_print(struct expr *e, struct gstr *gs);
|
| |
- +void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
|
| |
- + tristate pr_type, const char *title);
|
| |
-
|
| |
- static inline int expr_is_yes(struct expr *e)
|
| |
- {
|
| |
- diff --git a/carl9170fw/config/kconf_id.c b/carl9170fw/config/kconf_id.c
|
| |
- deleted file mode 100644
|
| |
- index 5abbc72..0000000
|
| |
- --- a/carl9170fw/config/kconf_id.c
|
| |
- +++ /dev/null
|
| |
- @@ -1,54 +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 },
|
| |
- - { "boolean", 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 },
|
| |
- - { "env", T_OPT_ENV, 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/carl9170fw/config/lkc.h b/carl9170fw/config/lkc.h
|
| |
- index cdcbe43..531ff7c 100644
|
| |
- --- a/carl9170fw/config/lkc.h
|
| |
- +++ b/carl9170fw/config/lkc.h
|
| |
- @@ -1,6 +1,6 @@
|
| |
- +/* SPDX-License-Identifier: GPL-2.0 */
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
-
|
| |
- #ifndef LKC_H
|
| |
- @@ -8,15 +8,6 @@
|
| |
-
|
| |
- #include "expr.h"
|
| |
-
|
| |
- -#ifndef KBUILD_NO_NLS
|
| |
- -# include <libintl.h>
|
| |
- -#else
|
| |
- -static inline const char *gettext(const char *txt) { return txt; }
|
| |
- -static inline void textdomain(const char *domainname) {}
|
| |
- -static inline void bindtextdomain(const char *name, const char *dir) {}
|
| |
- -static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
|
| |
- -#endif
|
| |
- -
|
| |
- #ifdef __cplusplus
|
| |
- extern "C" {
|
| |
- #endif
|
| |
- @@ -29,11 +20,6 @@ extern "C" {
|
| |
- #define PACKAGE "linux"
|
| |
- #endif
|
| |
-
|
| |
- -#define LOCALEDIR "/usr/share/locale"
|
| |
- -
|
| |
- -#define _(text) gettext(text)
|
| |
- -#define N_(text) (text)
|
| |
- -
|
| |
- #ifndef CONFIG_
|
| |
- #define CONFIG_ "CONFIG_"
|
| |
- #endif
|
| |
- @@ -44,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,
|
| |
- @@ -56,18 +38,7 @@ enum conf_def_mode {
|
| |
- def_random
|
| |
- };
|
| |
-
|
| |
- -#define T_OPT_MODULES 1
|
| |
- -#define T_OPT_DEFCONFIG_LIST 2
|
| |
- -#define T_OPT_ENV 3
|
| |
- -#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);
|
| |
- FILE *zconf_fopen(const char *name);
|
| |
- @@ -100,21 +71,27 @@ 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_end_entry(void);
|
| |
- 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(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);
|
| |
-
|
| |
- /* 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);
|
| |
- +char *xstrdup(const char *s);
|
| |
- +char *xstrndup(const char *s, size_t n);
|
| |
- +
|
| |
- +/* zconf.l */
|
| |
- +int yylex(void);
|
| |
-
|
| |
- struct gstr {
|
| |
- size_t len;
|
| |
- @@ -132,16 +109,13 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
|
| |
- const char *str_get(struct gstr *gs);
|
| |
-
|
| |
- /* symbol.c */
|
| |
- -extern struct expr *sym_env_list;
|
| |
- -
|
| |
- -void sym_init(void);
|
| |
- 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);
|
| |
- 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/carl9170fw/config/lkc_proto.h b/carl9170fw/config/lkc_proto.h
|
| |
- index 5d86e2d..86c2675 100644
|
| |
- --- a/carl9170fw/config/lkc_proto.h
|
| |
- +++ b/carl9170fw/config/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;
|
| |
- @@ -31,7 +31,6 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
|
| |
-
|
| |
- struct symbol * sym_lookup(const char *name, int flags);
|
| |
- struct symbol * sym_find(const char *name);
|
| |
- -const char * sym_expand_string_value(const char *in);
|
| |
- const char * sym_escape_string_value(const char *in);
|
| |
- struct symbol ** sym_re_search(const char *pattern);
|
| |
- const char * sym_type_name(enum symbol_type type);
|
| |
- @@ -49,5 +48,19 @@ const char * sym_get_string_value(struct symbol *sym);
|
| |
-
|
| |
- const char * prop_get_type_name(enum prop_type type);
|
| |
-
|
| |
- +/* preprocess.c */
|
| |
- +enum variable_flavor {
|
| |
- + VAR_SIMPLE,
|
| |
- + VAR_RECURSIVE,
|
| |
- + VAR_APPEND,
|
| |
- +};
|
| |
- +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);
|
| |
- +
|
| |
- /* expr.c */
|
| |
- void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
|
| |
- diff --git a/carl9170fw/config/menu.c b/carl9170fw/config/menu.c
|
| |
- index e935793..d9d1646 100644
|
| |
- --- a/carl9170fw/config/menu.c
|
| |
- +++ b/carl9170fw/config/menu.c
|
| |
- @@ -1,6 +1,6 @@
|
| |
- +// SPDX-License-Identifier: GPL-2.0
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
-
|
| |
- #include <ctype.h>
|
| |
- @@ -62,13 +62,8 @@ void menu_add_entry(struct symbol *sym)
|
| |
- menu_add_symbol(P_SYMBOL, sym, NULL);
|
| |
- }
|
| |
-
|
| |
- -void menu_end_entry(void)
|
| |
- -{
|
| |
- -}
|
| |
- -
|
| |
- struct menu *menu_add_menu(void)
|
| |
- {
|
| |
- - menu_end_entry();
|
| |
- last_entry_ptr = ¤t_entry->list;
|
| |
- return current_menu = current_entry;
|
| |
- }
|
| |
- @@ -79,19 +74,23 @@ void menu_end_menu(void)
|
| |
- current_menu = current_menu->parent;
|
| |
- }
|
| |
-
|
| |
- -static struct expr *menu_check_dep(struct expr *e)
|
| |
- +/*
|
| |
- + * Rewrites 'm' to 'm' && MODULES, so that it evaluates to 'n' when running
|
| |
- + * without modules
|
| |
- + */
|
| |
- +static struct expr *rewrite_m(struct expr *e)
|
| |
- {
|
| |
- if (!e)
|
| |
- return e;
|
| |
-
|
| |
- switch (e->type) {
|
| |
- case E_NOT:
|
| |
- - e->left.expr = menu_check_dep(e->left.expr);
|
| |
- + e->left.expr = rewrite_m(e->left.expr);
|
| |
- break;
|
| |
- case E_OR:
|
| |
- case E_AND:
|
| |
- - e->left.expr = menu_check_dep(e->left.expr);
|
| |
- - e->right.expr = menu_check_dep(e->right.expr);
|
| |
- + e->left.expr = rewrite_m(e->left.expr);
|
| |
- + e->right.expr = rewrite_m(e->right.expr);
|
| |
- break;
|
| |
- case E_SYMBOL:
|
| |
- /* change 'm' into 'm' && MODULES */
|
| |
- @@ -106,7 +105,7 @@ static struct expr *menu_check_dep(struct expr *e)
|
| |
-
|
| |
- void menu_add_dep(struct expr *dep)
|
| |
- {
|
| |
- - current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
|
| |
- + current_entry->dep = expr_alloc_and(current_entry->dep, dep);
|
| |
- }
|
| |
-
|
| |
- void menu_set_type(int type)
|
| |
- @@ -131,7 +130,7 @@ static struct property *menu_add_prop(enum prop_type type, char *prompt, struct
|
| |
-
|
| |
- prop->menu = current_entry;
|
| |
- prop->expr = expr;
|
| |
- - prop->visible.expr = menu_check_dep(dep);
|
| |
- + prop->visible.expr = dep;
|
| |
-
|
| |
- if (prompt) {
|
| |
- if (isspace(*prompt)) {
|
| |
- @@ -196,31 +195,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");
|
| |
- - break;
|
| |
- - case T_OPT_ENV:
|
| |
- - prop_add_env(arg);
|
| |
- - 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)
|
| |
- @@ -252,6 +246,16 @@ static void sym_check_prop(struct symbol *sym)
|
| |
- "'%s': number is invalid",
|
| |
- sym->name);
|
| |
- }
|
| |
- + if (sym_is_choice(sym)) {
|
| |
- + struct property *choice_prop =
|
| |
- + sym_get_choice_prop(sym2);
|
| |
- +
|
| |
- + if (!choice_prop ||
|
| |
- + prop_get_symbol(choice_prop) != sym)
|
| |
- + prop_warn(prop,
|
| |
- + "choice default symbol '%s' is not contained in the choice",
|
| |
- + sym2->name);
|
| |
- + }
|
| |
- break;
|
| |
- case P_SELECT:
|
| |
- case P_IMPLY:
|
| |
- @@ -260,13 +264,13 @@ static void sym_check_prop(struct symbol *sym)
|
| |
- if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
|
| |
- prop_warn(prop,
|
| |
- "config symbol '%s' uses %s, but is "
|
| |
- - "not boolean or tristate", sym->name, use);
|
| |
- + "not bool or tristate", sym->name, use);
|
| |
- else if (sym2->type != S_UNKNOWN &&
|
| |
- sym2->type != S_BOOLEAN &&
|
| |
- sym2->type != S_TRISTATE)
|
| |
- prop_warn(prop,
|
| |
- "'%s' has wrong type. '%s' only "
|
| |
- - "accept arguments of boolean and "
|
| |
- + "accept arguments of bool and "
|
| |
- "tristate type", sym2->name, use);
|
| |
- break;
|
| |
- case P_RANGE:
|
| |
- @@ -292,6 +296,11 @@ void menu_finalize(struct menu *parent)
|
| |
-
|
| |
- sym = parent->sym;
|
| |
- if (parent->list) {
|
| |
- + /*
|
| |
- + * This menu node has children. We (recursively) process them
|
| |
- + * and propagate parent dependencies before moving on.
|
| |
- + */
|
| |
- +
|
| |
- if (sym && sym_is_choice(sym)) {
|
| |
- if (sym->type == S_UNKNOWN) {
|
| |
- /* find the first choice value to find out choice type */
|
| |
- @@ -309,30 +318,83 @@ void menu_finalize(struct menu *parent)
|
| |
- if (menu->sym && menu->sym->type == S_UNKNOWN)
|
| |
- menu_set_type(sym->type);
|
| |
- }
|
| |
- +
|
| |
- + /*
|
| |
- + * Use the choice itself as the parent dependency of
|
| |
- + * the contained items. This turns the mode of the
|
| |
- + * choice into an upper bound on the visibility of the
|
| |
- + * 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' */
|
| |
- parentdep = parent->dep;
|
| |
-
|
| |
- + /* For each child menu node... */
|
| |
- for (menu = parent->list; menu; menu = menu->next) {
|
| |
- - basedep = expr_transform(menu->dep);
|
| |
- + /*
|
| |
- + * Propagate parent dependencies to the child menu
|
| |
- + * node, also rewriting and simplifying expressions
|
| |
- + */
|
| |
- + basedep = rewrite_m(menu->dep);
|
| |
- + basedep = expr_transform(basedep);
|
| |
- basedep = expr_alloc_and(expr_copy(parentdep), basedep);
|
| |
- basedep = expr_eliminate_dups(basedep);
|
| |
- menu->dep = basedep;
|
| |
- +
|
| |
- if (menu->sym)
|
| |
- + /*
|
| |
- + * Note: For symbols, all prompts are included
|
| |
- + * too in the symbol's own property list
|
| |
- + */
|
| |
- prop = menu->sym->prop;
|
| |
- else
|
| |
- + /*
|
| |
- + * For non-symbol menu nodes, we just need to
|
| |
- + * handle the prompt
|
| |
- + */
|
| |
- prop = menu->prompt;
|
| |
- +
|
| |
- + /* For each property... */
|
| |
- for (; prop; prop = prop->next) {
|
| |
- if (prop->menu != menu)
|
| |
- + /*
|
| |
- + * Two possibilities:
|
| |
- + *
|
| |
- + * 1. The property lacks dependencies
|
| |
- + * and so isn't location-specific,
|
| |
- + * e.g. an 'option'
|
| |
- + *
|
| |
- + * 2. The property belongs to a symbol
|
| |
- + * defined in multiple locations and
|
| |
- + * is from some other location. It
|
| |
- + * will be handled there in that
|
| |
- + * case.
|
| |
- + *
|
| |
- + * Skip the property.
|
| |
- + */
|
| |
- continue;
|
| |
- - dep = expr_transform(prop->visible.expr);
|
| |
- +
|
| |
- + /*
|
| |
- + * Propagate parent dependencies to the
|
| |
- + * property's condition, rewriting and
|
| |
- + * simplifying expressions at the same time
|
| |
- + */
|
| |
- + dep = rewrite_m(prop->visible.expr);
|
| |
- + dep = expr_transform(dep);
|
| |
- dep = expr_alloc_and(expr_copy(basedep), dep);
|
| |
- dep = expr_eliminate_dups(dep);
|
| |
- if (menu->sym && menu->sym->type != S_TRISTATE)
|
| |
- dep = expr_trans_bool(dep);
|
| |
- prop->visible.expr = dep;
|
| |
- +
|
| |
- + /*
|
| |
- + * Handle selects and implies, which modify the
|
| |
- + * dependencies of the selected/implied symbol
|
| |
- + */
|
| |
- if (prop->type == P_SELECT) {
|
| |
- struct symbol *es = prop_get_symbol(prop);
|
| |
- es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
|
| |
- @@ -344,34 +406,81 @@ void menu_finalize(struct menu *parent)
|
| |
- }
|
| |
- }
|
| |
- }
|
| |
- +
|
| |
- + if (sym && sym_is_choice(sym))
|
| |
- + expr_free(parentdep);
|
| |
- +
|
| |
- + /*
|
| |
- + * Recursively process children in the same fashion before
|
| |
- + * moving on
|
| |
- + */
|
| |
- for (menu = parent->list; menu; menu = menu->next)
|
| |
- menu_finalize(menu);
|
| |
- } else if (sym) {
|
| |
- + /*
|
| |
- + * Automatic submenu creation. If sym is a symbol and A, B, C,
|
| |
- + * ... are consecutive items (symbols, menus, ifs, etc.) that
|
| |
- + * all depend on sym, then the following menu structure is
|
| |
- + * created:
|
| |
- + *
|
| |
- + * sym
|
| |
- + * +-A
|
| |
- + * +-B
|
| |
- + * +-C
|
| |
- + * ...
|
| |
- + *
|
| |
- + * This also works recursively, giving the following structure
|
| |
- + * if A is a symbol and B depends on A:
|
| |
- + *
|
| |
- + * sym
|
| |
- + * +-A
|
| |
- + * | +-B
|
| |
- + * +-C
|
| |
- + * ...
|
| |
- + */
|
| |
- +
|
| |
- basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
|
| |
- basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
|
| |
- basedep = expr_eliminate_dups(expr_transform(basedep));
|
| |
- +
|
| |
- + /* Examine consecutive elements after sym */
|
| |
- last_menu = NULL;
|
| |
- for (menu = parent->next; menu; menu = menu->next) {
|
| |
- dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
|
| |
- if (!expr_contains_symbol(dep, sym))
|
| |
- + /* No dependency, quit */
|
| |
- break;
|
| |
- if (expr_depends_symbol(dep, sym))
|
| |
- + /* Absolute dependency, put in submenu */
|
| |
- goto next;
|
| |
- +
|
| |
- + /*
|
| |
- + * Also consider it a dependency on sym if our
|
| |
- + * dependencies contain sym and are a "superset" of
|
| |
- + * sym's dependencies, e.g. '(sym || Q) && R' when sym
|
| |
- + * depends on R.
|
| |
- + *
|
| |
- + * Note that 'R' might be from an enclosing menu or if,
|
| |
- + * making this a more common case than it might seem.
|
| |
- + */
|
| |
- dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
|
| |
- dep = expr_eliminate_dups(expr_transform(dep));
|
| |
- dep2 = expr_copy(basedep);
|
| |
- expr_eliminate_eq(&dep, &dep2);
|
| |
- expr_free(dep);
|
| |
- if (!expr_is_yes(dep2)) {
|
| |
- + /* Not superset, quit */
|
| |
- expr_free(dep2);
|
| |
- break;
|
| |
- }
|
| |
- + /* Superset, put in submenu */
|
| |
- expr_free(dep2);
|
| |
- next:
|
| |
- menu_finalize(menu);
|
| |
- menu->parent = parent;
|
| |
- last_menu = menu;
|
| |
- }
|
| |
- + expr_free(basedep);
|
| |
- if (last_menu) {
|
| |
- parent->list = parent->next;
|
| |
- parent->next = last_menu->next;
|
| |
- @@ -420,6 +529,35 @@ void menu_finalize(struct menu *parent)
|
| |
- *ep = expr_alloc_one(E_LIST, NULL);
|
| |
- (*ep)->right.sym = menu->sym;
|
| |
- }
|
| |
- +
|
| |
- + /*
|
| |
- + * This code serves two purposes:
|
| |
- + *
|
| |
- + * (1) Flattening 'if' blocks, which do not specify a submenu
|
| |
- + * and only add dependencies.
|
| |
- + *
|
| |
- + * (Automatic submenu creation might still create a submenu
|
| |
- + * from an 'if' before this code runs.)
|
| |
- + *
|
| |
- + * (2) "Undoing" any automatic submenus created earlier below
|
| |
- + * promptless symbols.
|
| |
- + *
|
| |
- + * Before:
|
| |
- + *
|
| |
- + * A
|
| |
- + * if ... (or promptless symbol)
|
| |
- + * +-B
|
| |
- + * +-C
|
| |
- + * D
|
| |
- + *
|
| |
- + * After:
|
| |
- + *
|
| |
- + * A
|
| |
- + * if ... (or promptless symbol)
|
| |
- + * B
|
| |
- + * C
|
| |
- + * D
|
| |
- + */
|
| |
- if (menu->list && (!menu->prompt || !menu->prompt->text)) {
|
| |
- for (last_menu = menu->list; ; last_menu = last_menu->next) {
|
| |
- last_menu->parent = parent;
|
| |
- @@ -444,6 +582,15 @@ void menu_finalize(struct menu *parent)
|
| |
- sym->flags |= SYMBOL_WARNED;
|
| |
- }
|
| |
-
|
| |
- + /*
|
| |
- + * For non-optional choices, add a reverse dependency (corresponding to
|
| |
- + * a select) of '<visibility> && m'. This prevents the user from
|
| |
- + * setting the choice mode to 'n' when the choice is visible.
|
| |
- + *
|
| |
- + * This would also work for non-choice symbols, but only non-optional
|
| |
- + * choices clear SYMBOL_OPTIONAL as of writing. Choices are implemented
|
| |
- + * as a type of symbol.
|
| |
- + */
|
| |
- if (sym && !sym_is_optional(sym) && parent->prompt) {
|
| |
- sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
|
| |
- expr_alloc_and(parent->prompt->visible.expr,
|
| |
- @@ -558,7 +705,7 @@ 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);
|
| |
- menu = prop->menu->parent;
|
| |
- for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
|
| |
- bool accessible = menu_is_visible(menu);
|
| |
- @@ -591,16 +738,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
|
| |
- }
|
| |
-
|
| |
- if (i > 0) {
|
| |
- - str_printf(r, _(" Location:\n"));
|
| |
- + str_printf(r, " Location:\n");
|
| |
- for (j = 4; --i >= 0; j += 2) {
|
| |
- menu = submenu[i];
|
| |
- if (jump && menu == location)
|
| |
- jump->offset = strlen(r->s);
|
| |
- str_printf(r, "%*c-> %s", j, ' ',
|
| |
- - _(menu_get_prompt(menu)));
|
| |
- + menu_get_prompt(menu));
|
| |
- if (menu->sym) {
|
| |
- str_printf(r, " (%s [=%s])", menu->sym->name ?
|
| |
- - menu->sym->name : _("<choice>"),
|
| |
- + menu->sym->name : "<choice>",
|
| |
- sym_get_string_value(menu->sym));
|
| |
- }
|
| |
- str_append(r, "\n");
|
| |
- @@ -664,27 +811,27 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
| |
-
|
| |
- prop = get_symbol_prop(sym);
|
| |
- if (prop) {
|
| |
- - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
|
| |
- + 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: "));
|
| |
- + str_append(r, " Depends on: ");
|
| |
- expr_gstr_print(prop->visible.expr, r);
|
| |
- str_append(r, "\n");
|
| |
- }
|
| |
- }
|
| |
-
|
| |
- - get_symbol_props_str(r, sym, P_SELECT, _(" Selects: "));
|
| |
- + get_symbol_props_str(r, sym, P_SELECT, " Selects: ");
|
| |
- if (sym->rev_dep.expr) {
|
| |
- - str_append(r, _(" Selected by: "));
|
| |
- - expr_gstr_print(sym->rev_dep.expr, r);
|
| |
- - str_append(r, "\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) {
|
| |
- - str_append(r, _(" Implied by: "));
|
| |
- - expr_gstr_print(sym->implied.expr, r);
|
| |
- - str_append(r, "\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");
|
| |
- @@ -699,7 +846,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)
|
| |
- for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
|
| |
- get_symbol_str(&res, sym, head);
|
| |
- if (!i)
|
| |
- - str_append(&res, _("No matches found.\n"));
|
| |
- + str_append(&res, "No matches found.\n");
|
| |
- return res;
|
| |
- }
|
| |
-
|
| |
- @@ -714,7 +861,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
|
| |
- str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
|
| |
- help_text = menu_get_help(menu);
|
| |
- }
|
| |
- - str_printf(help, "%s\n", _(help_text));
|
| |
- + str_printf(help, "%s\n", help_text);
|
| |
- if (sym)
|
| |
- get_symbol_str(help, sym, NULL);
|
| |
- }
|
| |
- diff --git a/carl9170fw/config/preprocess.c b/carl9170fw/config/preprocess.c
|
| |
- new file mode 100644
|
| |
- index 0000000..592dfbf
|
| |
- --- /dev/null
|
| |
- +++ b/carl9170fw/config/preprocess.c
|
| |
- @@ -0,0 +1,573 @@
|
| |
- +// SPDX-License-Identifier: GPL-2.0
|
| |
- +//
|
| |
- +// Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
|
| |
- +
|
| |
- +#include <ctype.h>
|
| |
- +#include <stdarg.h>
|
| |
- +#include <stdbool.h>
|
| |
- +#include <stdio.h>
|
| |
- +#include <stdlib.h>
|
| |
- +#include <string.h>
|
| |
- +
|
| |
- +#include "list.h"
|
| |
- +#include "lkc.h"
|
| |
- +
|
| |
- +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
| |
- +
|
| |
- +static char *expand_string_with_args(const char *in, int argc, char *argv[]);
|
| |
- +
|
| |
- +static void __attribute__((noreturn)) pperror(const char *format, ...)
|
| |
- +{
|
| |
- + va_list ap;
|
| |
- +
|
| |
- + fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
|
| |
- + va_start(ap, format);
|
| |
- + vfprintf(stderr, format, ap);
|
| |
- + va_end(ap);
|
| |
- + fprintf(stderr, "\n");
|
| |
- +
|
| |
- + exit(1);
|
| |
- +}
|
| |
- +
|
| |
- +/*
|
| |
- + * Environment variables
|
| |
- + */
|
| |
- +static LIST_HEAD(env_list);
|
| |
- +
|
| |
- +struct env {
|
| |
- + char *name;
|
| |
- + char *value;
|
| |
- + struct list_head node;
|
| |
- +};
|
| |
- +
|
| |
- +static void env_add(const char *name, const char *value)
|
| |
- +{
|
| |
- + struct env *e;
|
| |
- +
|
| |
- + e = xmalloc(sizeof(*e));
|
| |
- + e->name = xstrdup(name);
|
| |
- + e->value = xstrdup(value);
|
| |
- +
|
| |
- + list_add_tail(&e->node, &env_list);
|
| |
- +}
|
| |
- +
|
| |
- +static void env_del(struct env *e)
|
| |
- +{
|
| |
- + list_del(&e->node);
|
| |
- + free(e->name);
|
| |
- + free(e->value);
|
| |
- + free(e);
|
| |
- +}
|
| |
- +
|
| |
- +/* The returned pointer must be freed when done */
|
| |
- +static char *env_expand(const char *name)
|
| |
- +{
|
| |
- + struct env *e;
|
| |
- + const char *value;
|
| |
- +
|
| |
- + if (!*name)
|
| |
- + return NULL;
|
| |
- +
|
| |
- + list_for_each_entry(e, &env_list, node) {
|
| |
- + if (!strcmp(name, e->name))
|
| |
- + return xstrdup(e->value);
|
| |
- + }
|
| |
- +
|
| |
- + value = getenv(name);
|
| |
- + if (!value)
|
| |
- + return NULL;
|
| |
- +
|
| |
- + /*
|
| |
- + * We need to remember all referenced environment variables.
|
| |
- + * They will be written out to include/config/auto.conf.cmd
|
| |
- + */
|
| |
- + env_add(name, value);
|
| |
- +
|
| |
- + return xstrdup(value);
|
| |
- +}
|
| |
- +
|
| |
- +void env_write_dep(FILE *f, const char *autoconfig_name)
|
| |
- +{
|
| |
- + struct env *e, *tmp;
|
| |
- +
|
| |
- + list_for_each_entry_safe(e, tmp, &env_list, node) {
|
| |
- + fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
|
| |
- + fprintf(f, "%s: FORCE\n", autoconfig_name);
|
| |
- + fprintf(f, "endif\n");
|
| |
- + env_del(e);
|
| |
- + }
|
| |
- +}
|
| |
- +
|
| |
- +/*
|
| |
- + * Built-in functions
|
| |
- + */
|
| |
- +struct function {
|
| |
- + const char *name;
|
| |
- + unsigned int min_args;
|
| |
- + unsigned int max_args;
|
| |
- + char *(*func)(int argc, char *argv[]);
|
| |
- +};
|
| |
- +
|
| |
- +static char *do_error_if(int argc, char *argv[])
|
| |
- +{
|
| |
- + if (!strcmp(argv[0], "y"))
|
| |
- + pperror("%s", argv[1]);
|
| |
- +
|
| |
- + return NULL;
|
| |
- +}
|
| |
- +
|
| |
- +static char *do_filename(int argc, char *argv[])
|
| |
- +{
|
| |
- + return xstrdup(current_file->name);
|
| |
- +}
|
| |
- +
|
| |
- +static char *do_info(int argc, char *argv[])
|
| |
- +{
|
| |
- + printf("%s\n", argv[0]);
|
| |
- +
|
| |
- + return xstrdup("");
|
| |
- +}
|
| |
- +
|
| |
- +static char *do_lineno(int argc, char *argv[])
|
| |
- +{
|
| |
- + char buf[16];
|
| |
- +
|
| |
- + sprintf(buf, "%d", yylineno);
|
| |
- +
|
| |
- + return xstrdup(buf);
|
| |
- +}
|
| |
- +
|
| |
- +static char *do_shell(int argc, char *argv[])
|
| |
- +{
|
| |
- + FILE *p;
|
| |
- + char buf[256];
|
| |
- + char *cmd;
|
| |
- + size_t nread;
|
| |
- + int i;
|
| |
- +
|
| |
- + cmd = argv[0];
|
| |
- +
|
| |
- + p = popen(cmd, "r");
|
| |
- + if (!p) {
|
| |
- + perror(cmd);
|
| |
- + exit(1);
|
| |
- + }
|
| |
- +
|
| |
- + nread = fread(buf, 1, sizeof(buf), p);
|
| |
- + if (nread == sizeof(buf))
|
| |
- + nread--;
|
| |
- +
|
| |
- + /* remove trailing new lines */
|
| |
- + while (nread > 0 && buf[nread - 1] == '\n')
|
| |
- + nread--;
|
| |
- +
|
| |
- + buf[nread] = 0;
|
| |
- +
|
| |
- + /* replace a new line with a space */
|
| |
- + for (i = 0; i < nread; i++) {
|
| |
- + if (buf[i] == '\n')
|
| |
- + buf[i] = ' ';
|
| |
- + }
|
| |
- +
|
| |
- + if (pclose(p) == -1) {
|
| |
- + perror(cmd);
|
| |
- + exit(1);
|
| |
- + }
|
| |
- +
|
| |
- + return xstrdup(buf);
|
| |
- +}
|
| |
- +
|
| |
- +static char *do_warning_if(int argc, char *argv[])
|
| |
- +{
|
| |
- + if (!strcmp(argv[0], "y"))
|
| |
- + fprintf(stderr, "%s:%d: %s\n",
|
| |
- + current_file->name, yylineno, argv[1]);
|
| |
- +
|
| |
- + return xstrdup("");
|
| |
- +}
|
| |
- +
|
| |
- +static const struct function function_table[] = {
|
| |
- + /* Name MIN MAX Function */
|
| |
- + { "error-if", 2, 2, do_error_if },
|
| |
- + { "filename", 0, 0, do_filename },
|
| |
- + { "info", 1, 1, do_info },
|
| |
- + { "lineno", 0, 0, do_lineno },
|
| |
- + { "shell", 1, 1, do_shell },
|
| |
- + { "warning-if", 2, 2, do_warning_if },
|
| |
- +};
|
| |
- +
|
| |
- +#define FUNCTION_MAX_ARGS 16
|
| |
- +
|
| |
- +static char *function_expand(const char *name, int argc, char *argv[])
|
| |
- +{
|
| |
- + const struct function *f;
|
| |
- + int i;
|
| |
- +
|
| |
- + for (i = 0; i < ARRAY_SIZE(function_table); i++) {
|
| |
- + f = &function_table[i];
|
| |
- + if (strcmp(f->name, name))
|
| |
- + continue;
|
| |
- +
|
| |
- + if (argc < f->min_args)
|
| |
- + pperror("too few function arguments passed to '%s'",
|
| |
- + name);
|
| |
- +
|
| |
- + if (argc > f->max_args)
|
| |
- + pperror("too many function arguments passed to '%s'",
|
| |
- + name);
|
| |
- +
|
| |
- + return f->func(argc, argv);
|
| |
- + }
|
| |
- +
|
| |
- + return NULL;
|
| |
- +}
|
| |
- +
|
| |
- +/*
|
| |
- + * Variables (and user-defined functions)
|
| |
- + */
|
| |
- +static LIST_HEAD(variable_list);
|
| |
- +
|
| |
- +struct variable {
|
| |
- + char *name;
|
| |
- + char *value;
|
| |
- + enum variable_flavor flavor;
|
| |
- + int exp_count;
|
| |
- + struct list_head node;
|
| |
- +};
|
| |
- +
|
| |
- +static struct variable *variable_lookup(const char *name)
|
| |
- +{
|
| |
- + struct variable *v;
|
| |
- +
|
| |
- + list_for_each_entry(v, &variable_list, node) {
|
| |
- + if (!strcmp(name, v->name))
|
| |
- + return v;
|
| |
- + }
|
| |
- +
|
| |
- + return NULL;
|
| |
- +}
|
| |
- +
|
| |
- +static char *variable_expand(const char *name, int argc, char *argv[])
|
| |
- +{
|
| |
- + struct variable *v;
|
| |
- + char *res;
|
| |
- +
|
| |
- + v = variable_lookup(name);
|
| |
- + if (!v)
|
| |
- + return NULL;
|
| |
- +
|
| |
- + if (argc == 0 && v->exp_count)
|
| |
- + pperror("Recursive variable '%s' references itself (eventually)",
|
| |
- + name);
|
| |
- +
|
| |
- + if (v->exp_count > 1000)
|
| |
- + pperror("Too deep recursive expansion");
|
| |
- +
|
| |
- + v->exp_count++;
|
| |
- +
|
| |
- + if (v->flavor == VAR_RECURSIVE)
|
| |
- + res = expand_string_with_args(v->value, argc, argv);
|
| |
- + else
|
| |
- + res = xstrdup(v->value);
|
| |
- +
|
| |
- + v->exp_count--;
|
| |
- +
|
| |
- + return res;
|
| |
- +}
|
| |
- +
|
| |
- +void variable_add(const char *name, const char *value,
|
| |
- + enum variable_flavor flavor)
|
| |
- +{
|
| |
- + struct variable *v;
|
| |
- + char *new_value;
|
| |
- + bool append = false;
|
| |
- +
|
| |
- + v = variable_lookup(name);
|
| |
- + if (v) {
|
| |
- + /* For defined variables, += inherits the existing flavor */
|
| |
- + if (flavor == VAR_APPEND) {
|
| |
- + flavor = v->flavor;
|
| |
- + append = true;
|
| |
- + } else {
|
| |
- + free(v->value);
|
| |
- + }
|
| |
- + } else {
|
| |
- + /* For undefined variables, += assumes the recursive flavor */
|
| |
- + if (flavor == VAR_APPEND)
|
| |
- + flavor = VAR_RECURSIVE;
|
| |
- +
|
| |
- + v = xmalloc(sizeof(*v));
|
| |
- + v->name = xstrdup(name);
|
| |
- + v->exp_count = 0;
|
| |
- + list_add_tail(&v->node, &variable_list);
|
| |
- + }
|
| |
- +
|
| |
- + v->flavor = flavor;
|
| |
- +
|
| |
- + if (flavor == VAR_SIMPLE)
|
| |
- + new_value = expand_string(value);
|
| |
- + else
|
| |
- + new_value = xstrdup(value);
|
| |
- +
|
| |
- + if (append) {
|
| |
- + v->value = xrealloc(v->value,
|
| |
- + strlen(v->value) + strlen(new_value) + 2);
|
| |
- + strcat(v->value, " ");
|
| |
- + strcat(v->value, new_value);
|
| |
- + free(new_value);
|
| |
- + } else {
|
| |
- + v->value = new_value;
|
| |
- + }
|
| |
- +}
|
| |
- +
|
| |
- +static void variable_del(struct variable *v)
|
| |
- +{
|
| |
- + list_del(&v->node);
|
| |
- + free(v->name);
|
| |
- + free(v->value);
|
| |
- + free(v);
|
| |
- +}
|
| |
- +
|
| |
- +void variable_all_del(void)
|
| |
- +{
|
| |
- + struct variable *v, *tmp;
|
| |
- +
|
| |
- + list_for_each_entry_safe(v, tmp, &variable_list, node)
|
| |
- + variable_del(v);
|
| |
- +}
|
| |
- +
|
| |
- +/*
|
| |
- + * Evaluate a clause with arguments. argc/argv are arguments from the upper
|
| |
- + * function call.
|
| |
- + *
|
| |
- + * Returned string must be freed when done
|
| |
- + */
|
| |
- +static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
|
| |
- +{
|
| |
- + char *tmp, *name, *res, *endptr, *prev, *p;
|
| |
- + int new_argc = 0;
|
| |
- + char *new_argv[FUNCTION_MAX_ARGS];
|
| |
- + int nest = 0;
|
| |
- + int i;
|
| |
- + unsigned long n;
|
| |
- +
|
| |
- + tmp = xstrndup(str, len);
|
| |
- +
|
| |
- + /*
|
| |
- + * If variable name is '1', '2', etc. It is generally an argument
|
| |
- + * from a user-function call (i.e. local-scope variable). If not
|
| |
- + * available, then look-up global-scope variables.
|
| |
- + */
|
| |
- + n = strtoul(tmp, &endptr, 10);
|
| |
- + if (!*endptr && n > 0 && n <= argc) {
|
| |
- + res = xstrdup(argv[n - 1]);
|
| |
- + goto free_tmp;
|
| |
- + }
|
| |
- +
|
| |
- + prev = p = tmp;
|
| |
- +
|
| |
- + /*
|
| |
- + * Split into tokens
|
| |
- + * The function name and arguments are separated by a comma.
|
| |
- + * For example, if the function call is like this:
|
| |
- + * $(foo,$(x),$(y))
|
| |
- + *
|
| |
- + * The input string for this helper should be:
|
| |
- + * foo,$(x),$(y)
|
| |
- + *
|
| |
- + * and split into:
|
| |
- + * new_argv[0] = 'foo'
|
| |
- + * new_argv[1] = '$(x)'
|
| |
- + * new_argv[2] = '$(y)'
|
| |
- + */
|
| |
- + while (*p) {
|
| |
- + if (nest == 0 && *p == ',') {
|
| |
- + *p = 0;
|
| |
- + if (new_argc >= FUNCTION_MAX_ARGS)
|
| |
- + pperror("too many function arguments");
|
| |
- + new_argv[new_argc++] = prev;
|
| |
- + prev = p + 1;
|
| |
- + } else if (*p == '(') {
|
| |
- + nest++;
|
| |
- + } else if (*p == ')') {
|
| |
- + nest--;
|
| |
- + }
|
| |
- +
|
| |
- + p++;
|
| |
- + }
|
| |
- + new_argv[new_argc++] = prev;
|
| |
- +
|
| |
- + /*
|
| |
- + * Shift arguments
|
| |
- + * new_argv[0] represents a function name or a variable name. Put it
|
| |
- + * into 'name', then shift the rest of the arguments. This simplifies
|
| |
- + * 'const' handling.
|
| |
- + */
|
| |
- + name = expand_string_with_args(new_argv[0], argc, argv);
|
| |
- + new_argc--;
|
| |
- + for (i = 0; i < new_argc; i++)
|
| |
- + new_argv[i] = expand_string_with_args(new_argv[i + 1],
|
| |
- + argc, argv);
|
| |
- +
|
| |
- + /* Search for variables */
|
| |
- + res = variable_expand(name, new_argc, new_argv);
|
| |
- + if (res)
|
| |
- + goto free;
|
| |
- +
|
| |
- + /* Look for built-in functions */
|
| |
- + res = function_expand(name, new_argc, new_argv);
|
| |
- + if (res)
|
| |
- + goto free;
|
| |
- +
|
| |
- + /* Last, try environment variable */
|
| |
- + if (new_argc == 0) {
|
| |
- + res = env_expand(name);
|
| |
- + if (res)
|
| |
- + goto free;
|
| |
- + }
|
| |
- +
|
| |
- + res = xstrdup("");
|
| |
- +free:
|
| |
- + for (i = 0; i < new_argc; i++)
|
| |
- + free(new_argv[i]);
|
| |
- + free(name);
|
| |
- +free_tmp:
|
| |
- + free(tmp);
|
| |
- +
|
| |
- + return res;
|
| |
- +}
|
| |
- +
|
| |
- +/*
|
| |
- + * Expand a string that follows '$'
|
| |
- + *
|
| |
- + * For example, if the input string is
|
| |
- + * ($(FOO)$($(BAR)))$(BAZ)
|
| |
- + * this helper evaluates
|
| |
- + * $($(FOO)$($(BAR)))
|
| |
- + * and returns a new string containing the expansion (note that the string is
|
| |
- + * recursively expanded), also advancing 'str' to point to the next character
|
| |
- + * after the corresponding closing parenthesis, in this case, *str will be
|
| |
- + * $(BAR)
|
| |
- + */
|
| |
- +static char *expand_dollar_with_args(const char **str, int argc, char *argv[])
|
| |
- +{
|
| |
- + const char *p = *str;
|
| |
- + const char *q;
|
| |
- + int nest = 0;
|
| |
- +
|
| |
- + /*
|
| |
- + * In Kconfig, variable/function references always start with "$(".
|
| |
- + * Neither single-letter variables as in $A nor curly braces as in ${CC}
|
| |
- + * are supported. '$' not followed by '(' loses its special meaning.
|
| |
- + */
|
| |
- + if (*p != '(') {
|
| |
- + *str = p;
|
| |
- + return xstrdup("$");
|
| |
- + }
|
| |
- +
|
| |
- + p++;
|
| |
- + q = p;
|
| |
- + while (*q) {
|
| |
- + if (*q == '(') {
|
| |
- + nest++;
|
| |
- + } else if (*q == ')') {
|
| |
- + if (nest-- == 0)
|
| |
- + break;
|
| |
- + }
|
| |
- + q++;
|
| |
- + }
|
| |
- +
|
| |
- + if (!*q)
|
| |
- + pperror("unterminated reference to '%s': missing ')'", p);
|
| |
- +
|
| |
- + /* Advance 'str' to after the expanded initial portion of the string */
|
| |
- + *str = q + 1;
|
| |
- +
|
| |
- + return eval_clause(p, q - p, argc, argv);
|
| |
- +}
|
| |
- +
|
| |
- +char *expand_dollar(const char **str)
|
| |
- +{
|
| |
- + return expand_dollar_with_args(str, 0, NULL);
|
| |
- +}
|
| |
- +
|
| |
- +static char *__expand_string(const char **str, bool (*is_end)(char c),
|
| |
- + int argc, char *argv[])
|
| |
- +{
|
| |
- + const char *in, *p;
|
| |
- + char *expansion, *out;
|
| |
- + size_t in_len, out_len;
|
| |
- +
|
| |
- + out = xmalloc(1);
|
| |
- + *out = 0;
|
| |
- + out_len = 1;
|
| |
- +
|
| |
- + p = in = *str;
|
| |
- +
|
| |
- + while (1) {
|
| |
- + if (*p == '$') {
|
| |
- + in_len = p - in;
|
| |
- + p++;
|
| |
- + expansion = expand_dollar_with_args(&p, argc, argv);
|
| |
- + out_len += in_len + strlen(expansion);
|
| |
- + out = xrealloc(out, out_len);
|
| |
- + strncat(out, in, in_len);
|
| |
- + strcat(out, expansion);
|
| |
- + free(expansion);
|
| |
- + in = p;
|
| |
- + continue;
|
| |
- + }
|
| |
- +
|
| |
- + if (is_end(*p))
|
| |
- + break;
|
| |
- +
|
| |
- + p++;
|
| |
- + }
|
| |
- +
|
| |
- + in_len = p - in;
|
| |
- + out_len += in_len;
|
| |
- + out = xrealloc(out, out_len);
|
| |
- + strncat(out, in, in_len);
|
| |
- +
|
| |
- + /* Advance 'str' to the end character */
|
| |
- + *str = p;
|
| |
- +
|
| |
- + return out;
|
| |
- +}
|
| |
- +
|
| |
- +static bool is_end_of_str(char c)
|
| |
- +{
|
| |
- + return !c;
|
| |
- +}
|
| |
- +
|
| |
- +/*
|
| |
- + * Expand variables and functions in the given string. Undefined variables
|
| |
- + * expand to an empty string.
|
| |
- + * The returned string must be freed when done.
|
| |
- + */
|
| |
- +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)
|
| |
- +{
|
| |
- + return expand_string_with_args(in, 0, NULL);
|
| |
- +}
|
| |
- +
|
| |
- +static bool is_end_of_token(char c)
|
| |
- +{
|
| |
- + return !(isalnum(c) || c == '_' || c == '-');
|
| |
- +}
|
| |
- +
|
| |
- +/*
|
| |
- + * Expand variables in a token. The parsing stops when a token separater
|
| |
- + * (in most cases, it is a whitespace) is encountered. 'str' is updated to
|
| |
- + * point to the next character.
|
| |
- + *
|
| |
- + * The returned string must be freed when done.
|
| |
- + */
|
| |
- +char *expand_one_token(const char **str)
|
| |
- +{
|
| |
- + return __expand_string(str, is_end_of_token, 0, NULL);
|
| |
- +}
|
| |
- diff --git a/carl9170fw/config/symbol.c b/carl9170fw/config/symbol.c
|
| |
- index 3c8bd9b..1f9266d 100644
|
| |
- --- a/carl9170fw/config/symbol.c
|
| |
- +++ b/carl9170fw/config/symbol.c
|
| |
- @@ -1,6 +1,6 @@
|
| |
- +// SPDX-License-Identifier: GPL-2.0
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
-
|
| |
- #include <ctype.h>
|
| |
- @@ -33,33 +33,6 @@ struct symbol *sym_defconfig_list;
|
| |
- struct symbol *modules_sym;
|
| |
- tristate modules_val;
|
| |
-
|
| |
- -struct expr *sym_env_list;
|
| |
- -
|
| |
- -static void sym_add_default(struct symbol *sym, const char *def)
|
| |
- -{
|
| |
- - struct property *prop = prop_alloc(P_DEFAULT, sym);
|
| |
- -
|
| |
- - prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
|
| |
- -}
|
| |
- -
|
| |
- -void sym_init(void)
|
| |
- -{
|
| |
- - struct symbol *sym;
|
| |
- - struct utsname uts;
|
| |
- - static bool inited = false;
|
| |
- -
|
| |
- - if (inited)
|
| |
- - return;
|
| |
- - inited = true;
|
| |
- -
|
| |
- - uname(&uts);
|
| |
- -
|
| |
- - sym = sym_lookup("UNAME_RELEASE", 0);
|
| |
- - sym->type = S_STRING;
|
| |
- - sym->flags |= SYMBOL_AUTO;
|
| |
- - sym_add_default(sym, uts.release);
|
| |
- -}
|
| |
- -
|
| |
- enum symbol_type sym_get_type(struct symbol *sym)
|
| |
- {
|
| |
- enum symbol_type type = sym->type;
|
| |
- @@ -77,7 +50,7 @@ const char *sym_type_name(enum symbol_type type)
|
| |
- {
|
| |
- switch (type) {
|
| |
- case S_BOOLEAN:
|
| |
- - return "boolean";
|
| |
- + return "bool";
|
| |
- case S_TRISTATE:
|
| |
- return "tristate";
|
| |
- case S_INT:
|
| |
- @@ -88,8 +61,6 @@ const char *sym_type_name(enum symbol_type type)
|
| |
- return "string";
|
| |
- case S_UNKNOWN:
|
| |
- return "unknown";
|
| |
- - case S_OTHER:
|
| |
- - break;
|
| |
- }
|
| |
- return "???";
|
| |
- }
|
| |
- @@ -103,15 +74,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;
|
| |
- @@ -124,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;
|
| |
-
|
| |
- @@ -183,7 +145,7 @@ static void sym_validate_range(struct symbol *sym)
|
| |
- sprintf(str, "%lld", val2);
|
| |
- else
|
| |
- sprintf(str, "0x%llx", val2);
|
| |
- - sym->curr.val = strdup(str);
|
| |
- + sym->curr.val = xstrdup(str);
|
| |
- }
|
| |
-
|
| |
- static void sym_set_changed(struct symbol *sym)
|
| |
- @@ -243,7 +205,7 @@ static void sym_calc_visibility(struct symbol *sym)
|
| |
- tri = yes;
|
| |
- if (sym->dir_dep.expr)
|
| |
- tri = expr_calc_value(sym->dir_dep.expr);
|
| |
- - if (tri == mod)
|
| |
- + if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
|
| |
- tri = yes;
|
| |
- if (sym->dir_dep.tri != tri) {
|
| |
- sym->dir_dep.tri = tri;
|
| |
- @@ -333,6 +295,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
|
| |
- return def_sym;
|
| |
- }
|
| |
-
|
| |
- +static void sym_warn_unmet_dep(struct symbol *sym)
|
| |
- +{
|
| |
- + struct gstr gs = str_new();
|
| |
- +
|
| |
- + str_printf(&gs,
|
| |
- + "\nWARNING: unmet direct dependencies detected for %s\n",
|
| |
- + sym->name);
|
| |
- + str_printf(&gs,
|
| |
- + " Depends on [%c]: ",
|
| |
- + sym->dir_dep.tri == mod ? 'm' : 'n');
|
| |
- + expr_gstr_print(sym->dir_dep.expr, &gs);
|
| |
- + str_printf(&gs, "\n");
|
| |
- +
|
| |
- + expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
|
| |
- + " Selected by [y]:\n");
|
| |
- + expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
|
| |
- + " Selected by [m]:\n");
|
| |
- +
|
| |
- + fputs(str_get(&gs), stderr);
|
| |
- +}
|
| |
- +
|
| |
- void sym_calc_value(struct symbol *sym)
|
| |
- {
|
| |
- struct symbol_value newval, oldval;
|
| |
- @@ -371,11 +354,13 @@ void sym_calc_value(struct symbol *sym)
|
| |
- sym->curr.tri = no;
|
| |
- return;
|
| |
- }
|
| |
- - if (!sym_is_choice_value(sym))
|
| |
- - sym->flags &= ~SYMBOL_WRITE;
|
| |
- + sym->flags &= ~SYMBOL_WRITE;
|
| |
-
|
| |
- sym_calc_visibility(sym);
|
| |
-
|
| |
- + if (sym->visible != no)
|
| |
- + sym->flags |= SYMBOL_WRITE;
|
| |
- +
|
| |
- /* set default if recursively called */
|
| |
- sym->curr = newval;
|
| |
-
|
| |
- @@ -390,7 +375,6 @@ void sym_calc_value(struct symbol *sym)
|
| |
- /* if the symbol is visible use the user value
|
| |
- * if available, otherwise try the default value
|
| |
- */
|
| |
- - sym->flags |= SYMBOL_WRITE;
|
| |
- if (sym_has_value(sym)) {
|
| |
- newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
|
| |
- sym->visible);
|
| |
- @@ -402,9 +386,10 @@ void sym_calc_value(struct symbol *sym)
|
| |
- if (!sym_is_choice(sym)) {
|
| |
- prop = sym_get_default_prop(sym);
|
| |
- if (prop) {
|
| |
- - sym->flags |= SYMBOL_WRITE;
|
| |
- newval.tri = EXPR_AND(expr_calc_value(prop->expr),
|
| |
- prop->visible.tri);
|
| |
- + if (newval.tri != no)
|
| |
- + sym->flags |= SYMBOL_WRITE;
|
| |
- }
|
| |
- if (sym->implied.tri != no) {
|
| |
- sym->flags |= SYMBOL_WRITE;
|
| |
- @@ -412,18 +397,8 @@ void sym_calc_value(struct symbol *sym)
|
| |
- }
|
| |
- }
|
| |
- calc_newval:
|
| |
- - if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
|
| |
- - struct expr *e;
|
| |
- - e = expr_simplify_unmet_dep(sym->rev_dep.expr,
|
| |
- - sym->dir_dep.expr);
|
| |
- - fprintf(stderr, "warning: (");
|
| |
- - expr_fprint(e, stderr);
|
| |
- - fprintf(stderr, ") selects %s which has unmet direct dependencies (",
|
| |
- - sym->name);
|
| |
- - expr_fprint(sym->dir_dep.expr, stderr);
|
| |
- - fprintf(stderr, ")\n");
|
| |
- - expr_free(e);
|
| |
- - }
|
| |
- + if (sym->dir_dep.tri < sym->rev_dep.tri)
|
| |
- + sym_warn_unmet_dep(sym);
|
| |
- newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
|
| |
- }
|
| |
- if (newval.tri == mod &&
|
| |
- @@ -433,12 +408,9 @@ void sym_calc_value(struct symbol *sym)
|
| |
- case S_STRING:
|
| |
- case S_HEX:
|
| |
- case S_INT:
|
| |
- - if (sym->visible != no) {
|
| |
- - sym->flags |= SYMBOL_WRITE;
|
| |
- - if (sym_has_value(sym)) {
|
| |
- - newval.val = sym->def[S_DEF_USER].val;
|
| |
- - break;
|
| |
- - }
|
| |
- + if (sym->visible != no && sym_has_value(sym)) {
|
| |
- + newval.val = sym->def[S_DEF_USER].val;
|
| |
- + break;
|
| |
- }
|
| |
- prop = sym_get_default_prop(sym);
|
| |
- if (prop) {
|
| |
- @@ -480,7 +452,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)
|
| |
- @@ -783,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;
|
| |
- }
|
| |
- @@ -851,7 +822,7 @@ struct symbol *sym_lookup(const char *name, int flags)
|
| |
- : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
|
| |
- return symbol;
|
| |
- }
|
| |
- - new_name = strdup(name);
|
| |
- + new_name = xstrdup(name);
|
| |
- } else {
|
| |
- new_name = NULL;
|
| |
- hash = 0;
|
| |
- @@ -896,55 +867,6 @@ struct symbol *sym_find(const char *name)
|
| |
- return symbol;
|
| |
- }
|
| |
-
|
| |
- -/*
|
| |
- - * Expand symbol's names embedded in the string given in argument. Symbols'
|
| |
- - * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
|
| |
- - * the empty string.
|
| |
- - */
|
| |
- -const char *sym_expand_string_value(const char *in)
|
| |
- -{
|
| |
- - const char *src;
|
| |
- - char *res;
|
| |
- - size_t reslen;
|
| |
- -
|
| |
- - reslen = strlen(in) + 1;
|
| |
- - res = xmalloc(reslen);
|
| |
- - res[0] = '\0';
|
| |
- -
|
| |
- - while ((src = strchr(in, '$'))) {
|
| |
- - char *p, name[SYMBOL_MAXLENGTH];
|
| |
- - const char *symval = "";
|
| |
- - struct symbol *sym;
|
| |
- - size_t newlen;
|
| |
- -
|
| |
- - strncat(res, in, src - in);
|
| |
- - src++;
|
| |
- -
|
| |
- - p = name;
|
| |
- - while (isalnum(*src) || *src == '_')
|
| |
- - *p++ = *src++;
|
| |
- - *p = '\0';
|
| |
- -
|
| |
- - sym = sym_find(name);
|
| |
- - if (sym != NULL) {
|
| |
- - sym_calc_value(sym);
|
| |
- - symval = sym_get_string_value(sym);
|
| |
- - }
|
| |
- -
|
| |
- - newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
|
| |
- - if (newlen > reslen) {
|
| |
- - reslen = newlen;
|
| |
- - res = realloc(res, reslen);
|
| |
- - }
|
| |
- -
|
| |
- - strcat(res, symval);
|
| |
- - in = src;
|
| |
- - }
|
| |
- - strcat(res, in);
|
| |
- -
|
| |
- - return res;
|
| |
- -}
|
| |
- -
|
| |
- const char *sym_escape_string_value(const char *in)
|
| |
- {
|
| |
- const char *p;
|
| |
- @@ -1086,7 +1008,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)
|
| |
- @@ -1150,37 +1072,52 @@ static void sym_check_print_recursive(struct symbol *last_sym)
|
| |
- if (stack->sym == last_sym)
|
| |
- fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
|
| |
- prop->file->name, prop->lineno);
|
| |
- - fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n");
|
| |
- - fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n");
|
| |
- - 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 : "<choice>",
|
| |
- - prop_get_type_name(prop->type),
|
| |
- next_sym->name ? next_sym->name : "<choice>");
|
| |
- - } else if (stack->prop) {
|
| |
- + } 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 : "<choice>",
|
| |
- + next_sym->name ? next_sym->name : "<choice>");
|
| |
- + } 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 : "<choice>",
|
| |
- next_sym->name ? next_sym->name : "<choice>");
|
| |
- - } 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 : "<choice>",
|
| |
- next_sym->name ? next_sym->name : "<choice>");
|
| |
- - } 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 : "<choice>",
|
| |
- + next_sym->name ? next_sym->name : "<choice>");
|
| |
- + } else if (stack->expr) {
|
| |
- + fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
|
| |
- + prop->file->name, prop->lineno,
|
| |
- sym->name ? sym->name : "<choice>",
|
| |
- + prop_get_type_name(prop->type),
|
| |
- next_sym->name ? next_sym->name : "<choice>");
|
| |
- } 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 : "<choice>",
|
| |
- + prop_get_type_name(prop->type),
|
| |
- next_sym->name ? next_sym->name : "<choice>");
|
| |
- }
|
| |
- }
|
| |
-
|
| |
- + fprintf(stderr,
|
| |
- + "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n"
|
| |
- + "subsection \"Kconfig recursive dependency limitations\"\n"
|
| |
- + "\n");
|
| |
- +
|
| |
- if (check_top == &cv_stack)
|
| |
- dep_stack_remove();
|
| |
- }
|
| |
- @@ -1215,7 +1152,7 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
|
| |
- default:
|
| |
- break;
|
| |
- }
|
| |
- - printf("Oops! How to check %d?\n", e->type);
|
| |
- + fprintf(stderr, "Oops! How to check %d?\n", e->type);
|
| |
- return NULL;
|
| |
- }
|
| |
-
|
| |
- @@ -1228,12 +1165,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);
|
| |
- @@ -1241,7 +1192,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;
|
| |
- @@ -1319,9 +1270,6 @@ struct symbol *sym_check_deps(struct symbol *sym)
|
| |
- sym->flags &= ~SYMBOL_CHECK;
|
| |
- }
|
| |
-
|
| |
- - if (sym2 && sym2 == sym)
|
| |
- - sym2 = NULL;
|
| |
- -
|
| |
- return sym2;
|
| |
- }
|
| |
-
|
| |
- @@ -1360,8 +1308,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:
|
| |
- @@ -1383,32 +1329,3 @@ const char *prop_get_type_name(enum prop_type type)
|
| |
- }
|
| |
- return "unknown";
|
| |
- }
|
| |
- -
|
| |
- -static void prop_add_env(const char *env)
|
| |
- -{
|
| |
- - struct symbol *sym, *sym2;
|
| |
- - struct property *prop;
|
| |
- - char *p;
|
| |
- -
|
| |
- - sym = current_entry->sym;
|
| |
- - sym->flags |= SYMBOL_AUTO;
|
| |
- - for_all_properties(sym, prop, P_ENV) {
|
| |
- - sym2 = prop_get_symbol(prop);
|
| |
- - if (strcmp(sym2->name, env))
|
| |
- - menu_warn(current_entry, "redefining environment symbol from %s",
|
| |
- - sym2->name);
|
| |
- - return;
|
| |
- - }
|
| |
- -
|
| |
- - prop = prop_alloc(P_ENV, sym);
|
| |
- - prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
|
| |
- -
|
| |
- - sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
|
| |
- - sym_env_list->right.sym = sym;
|
| |
- -
|
| |
- - p = getenv(env);
|
| |
- - if (p)
|
| |
- - sym_add_default(sym, p);
|
| |
- - else
|
| |
- - menu_warn(current_entry, "environment variable %s undefined", env);
|
| |
- -}
|
| |
- diff --git a/carl9170fw/config/util.c b/carl9170fw/config/util.c
|
| |
- index 0e76042..2958539 100644
|
| |
- --- a/carl9170fw/config/util.c
|
| |
- +++ b/carl9170fw/config/util.c
|
| |
- @@ -1,8 +1,7 @@
|
| |
- +// SPDX-License-Identifier: GPL-2.0
|
| |
- /*
|
| |
- * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
|
| |
- * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
|
| |
- - *
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
-
|
| |
- #include <stdarg.h>
|
| |
- @@ -14,69 +13,21 @@
|
| |
- struct file *file_lookup(const char *name)
|
| |
- {
|
| |
- struct file *file;
|
| |
- - const char *file_name = sym_expand_string_value(name);
|
| |
-
|
| |
- for (file = file_list; file; file = file->next) {
|
| |
- if (!strcmp(name, file->name)) {
|
| |
- - free((void *)file_name);
|
| |
- return file;
|
| |
- }
|
| |
- }
|
| |
-
|
| |
- file = xmalloc(sizeof(*file));
|
| |
- memset(file, 0, sizeof(*file));
|
| |
- - file->name = file_name;
|
| |
- + file->name = xstrdup(name);
|
| |
- file->next = file_list;
|
| |
- file_list = file;
|
| |
- return file;
|
| |
- }
|
| |
-
|
| |
- -/* write a dependency file as used by kbuild to track dependencies */
|
| |
- -int file_write_dep(const char *name)
|
| |
- -{
|
| |
- - struct symbol *sym, *env_sym;
|
| |
- - struct expr *e;
|
| |
- - 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());
|
| |
- -
|
| |
- - expr_list_for_each_sym(sym_env_list, e, sym) {
|
| |
- - struct property *prop;
|
| |
- - const char *value;
|
| |
- -
|
| |
- - prop = sym_get_env_prop(sym);
|
| |
- - env_sym = prop_get_symbol(prop);
|
| |
- - if (!env_sym)
|
| |
- - continue;
|
| |
- - value = getenv(env_sym->name);
|
| |
- - if (!value)
|
| |
- - value = "";
|
| |
- - fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
|
| |
- - fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name());
|
| |
- - fprintf(out, "endif\n");
|
| |
- - }
|
| |
- -
|
| |
- - fprintf(out, "\n$(deps_config): ;\n");
|
| |
- - fclose(out);
|
| |
- - rename("..config.tmp", name);
|
| |
- - return 0;
|
| |
- -}
|
| |
- -
|
| |
- -
|
| |
- /* Allocate initial growable string */
|
| |
- struct gstr str_new(void)
|
| |
- {
|
| |
- @@ -104,7 +55,7 @@ void str_append(struct gstr *gs, const char *s)
|
| |
- if (s) {
|
| |
- l = strlen(gs->s) + strlen(s) + 1;
|
| |
- if (l > gs->len) {
|
| |
- - gs->s = realloc(gs->s, l);
|
| |
- + gs->s = xrealloc(gs->s, l);
|
| |
- gs->len = l;
|
| |
- }
|
| |
- strcat(gs->s, s);
|
| |
- @@ -145,3 +96,34 @@ void *xcalloc(size_t nmemb, size_t size)
|
| |
- fprintf(stderr, "Out of memory.\n");
|
| |
- exit(1);
|
| |
- }
|
| |
- +
|
| |
- +void *xrealloc(void *p, size_t size)
|
| |
- +{
|
| |
- + p = realloc(p, size);
|
| |
- + if (p)
|
| |
- + return p;
|
| |
- + fprintf(stderr, "Out of memory.\n");
|
| |
- + exit(1);
|
| |
- +}
|
| |
- +
|
| |
- +char *xstrdup(const char *s)
|
| |
- +{
|
| |
- + char *p;
|
| |
- +
|
| |
- + p = strdup(s);
|
| |
- + if (p)
|
| |
- + return p;
|
| |
- + fprintf(stderr, "Out of memory.\n");
|
| |
- + exit(1);
|
| |
- +}
|
| |
- +
|
| |
- +char *xstrndup(const char *s, size_t n)
|
| |
- +{
|
| |
- + char *p;
|
| |
- +
|
| |
- + p = strndup(s, n);
|
| |
- + if (p)
|
| |
- + return p;
|
| |
- + fprintf(stderr, "Out of memory.\n");
|
| |
- + exit(1);
|
| |
- +}
|
| |
- diff --git a/carl9170fw/config/zconf.l b/carl9170fw/config/zconf.l
|
| |
- index 9720530..c52cce8 100644
|
| |
- --- a/carl9170fw/config/zconf.l
|
| |
- +++ b/carl9170fw/config/zconf.l
|
| |
- @@ -1,13 +1,13 @@
|
| |
- -%option nostdinit noyywrap never-interactive full ecs
|
| |
- -%option 8bit nodefault perf-report perf-report
|
| |
- -%option noinput
|
| |
- -%x COMMAND HELP STRING PARAM
|
| |
- -%{
|
| |
- +/* SPDX-License-Identifier: GPL-2.0 */
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * 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 <assert.h>
|
| |
- #include <limits.h>
|
| |
- #include <stdio.h>
|
| |
- #include <stdlib.h>
|
| |
- @@ -15,6 +15,9 @@
|
| |
- #include <unistd.h>
|
| |
-
|
| |
- #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;
|
| |
-
|
| |
- @@ -35,6 +40,8 @@ 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);
|
| |
-
|
| |
- @@ -52,7 +59,7 @@ static void append_string(const char *str, int size)
|
| |
- if (new_size > text_asize) {
|
| |
- new_size += START_STRSIZE - 1;
|
| |
- new_size &= -START_STRSIZE;
|
| |
- - text = realloc(text, new_size);
|
| |
- + text = xrealloc(text, new_size);
|
| |
- text_asize = new_size;
|
| |
- }
|
| |
- memcpy(text + text_size, str, size);
|
| |
- @@ -71,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);
|
| |
- }
|
| |
- %}
|
| |
-
|
| |
- @@ -81,116 +88,113 @@ n [A-Za-z0-9_-]
|
| |
- int str = 0;
|
| |
- int ts, i;
|
| |
-
|
| |
- -[ \t]*#.*\n |
|
| |
- -[ \t]*\n {
|
| |
- - current_file->lineno++;
|
| |
- - return T_EOL;
|
| |
- -}
|
| |
- -[ \t]*#.*
|
| |
- -
|
| |
- -
|
| |
- -[ \t]+ {
|
| |
- - BEGIN(COMMAND);
|
| |
- -}
|
| |
- -
|
| |
- -. {
|
| |
- - unput(yytext[0]);
|
| |
- - BEGIN(COMMAND);
|
| |
- -}
|
| |
- -
|
| |
- -
|
| |
- -<COMMAND>{
|
| |
- - {n}+ {
|
| |
- - const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
| |
- - BEGIN(PARAM);
|
| |
- - current_pos.file = current_file;
|
| |
- - current_pos.lineno = current_file->lineno;
|
| |
- - if (id && id->flags & TF_COMMAND) {
|
| |
- - zconflval.id = id;
|
| |
- - return id->token;
|
| |
- - }
|
| |
- - alloc_string(yytext, yyleng);
|
| |
- - zconflval.string = text;
|
| |
- - return T_WORD;
|
| |
- - }
|
| |
- - . warn_ignored_character(*yytext);
|
| |
- - \n {
|
| |
- - BEGIN(INITIAL);
|
| |
- - current_file->lineno++;
|
| |
- - 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);
|
| |
-
|
| |
- -<PARAM>{
|
| |
- - "&&" 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); current_file->lineno++; return T_EOL;
|
| |
- - ({n}|[/.])+ {
|
| |
- - const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
| |
- - if (id && id->flags & TF_PARAM) {
|
| |
- - zconflval.id = id;
|
| |
- - return id->token;
|
| |
- - }
|
| |
- +<ASSIGN_VAL>{
|
| |
- + [^[:blank:]\n]+.* {
|
| |
- alloc_string(yytext, yyleng);
|
| |
- - zconflval.string = text;
|
| |
- - return T_WORD;
|
| |
- - }
|
| |
- - #.* /* comment */
|
| |
- - \\\n current_file->lineno++;
|
| |
- - [[:blank:]]+
|
| |
- - . warn_ignored_character(*yytext);
|
| |
- - <<EOF>> {
|
| |
- - BEGIN(INITIAL);
|
| |
- + yylval.string = text;
|
| |
- + return T_ASSIGN_VAL;
|
| |
- }
|
| |
- + \n { BEGIN(INITIAL); return T_EOL; }
|
| |
- + .
|
| |
- }
|
| |
-
|
| |
- <STRING>{
|
| |
- - [^'"\\\n]+/\n {
|
| |
- - append_string(yytext, yyleng);
|
| |
- - zconflval.string = text;
|
| |
- - return T_WORD_QUOTE;
|
| |
- - }
|
| |
- - [^'"\\\n]+ {
|
| |
- + "$".* append_expanded_string(yytext);
|
| |
- + [^$'"\\\n]+ {
|
| |
- append_string(yytext, yyleng);
|
| |
- }
|
| |
- - \\.?/\n {
|
| |
- - append_string(yytext + 1, yyleng - 1);
|
| |
- - zconflval.string = text;
|
| |
- - return T_WORD_QUOTE;
|
| |
- - }
|
| |
- \\.? {
|
| |
- append_string(yytext + 1, yyleng - 1);
|
| |
- }
|
| |
- \'|\" {
|
| |
- if (str == yytext[0]) {
|
| |
- - BEGIN(PARAM);
|
| |
- - zconflval.string = text;
|
| |
- + BEGIN(INITIAL);
|
| |
- + yylval.string = text;
|
| |
- return T_WORD_QUOTE;
|
| |
- } else
|
| |
- append_string(yytext, 1);
|
| |
- }
|
| |
- \n {
|
| |
- - printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
|
| |
- - current_file->lineno++;
|
| |
- + 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;
|
| |
- }
|
| |
- <<EOF>> {
|
| |
- BEGIN(INITIAL);
|
| |
- + yylval.string = text;
|
| |
- + return T_WORD_QUOTE;
|
| |
- }
|
| |
- }
|
| |
-
|
| |
- @@ -218,12 +222,10 @@ n [A-Za-z0-9_-]
|
| |
- }
|
| |
- }
|
| |
- [ \t]*\n/[^ \t\n] {
|
| |
- - current_file->lineno++;
|
| |
- zconf_endhelp();
|
| |
- return T_HELPTEXT;
|
| |
- }
|
| |
- [ \t]*\n {
|
| |
- - current_file->lineno++;
|
| |
- append_string("\n", 1);
|
| |
- }
|
| |
- [^ \t\n].* {
|
| |
- @@ -243,6 +245,12 @@ n [A-Za-z0-9_-]
|
| |
- }
|
| |
-
|
| |
- <<EOF>> {
|
| |
- + 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;
|
| |
- @@ -252,6 +260,93 @@ 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;
|
| |
- + 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();
|
| |
- @@ -261,7 +356,7 @@ void zconf_starthelp(void)
|
| |
-
|
| |
- static void zconf_endhelp(void)
|
| |
- {
|
| |
- - zconflval.string = text;
|
| |
- + yylval.string = text;
|
| |
- BEGIN(INITIAL);
|
| |
- }
|
| |
-
|
| |
- @@ -294,7 +389,7 @@ void zconf_initscan(const char *name)
|
| |
- {
|
| |
- yyin = zconf_fopen(name);
|
| |
- if (!yyin) {
|
| |
- - printf("can't find file %s\n", name);
|
| |
- + fprintf(stderr, "can't find file %s\n", name);
|
| |
- exit(1);
|
| |
- }
|
| |
-
|
| |
- @@ -302,7 +397,7 @@ void zconf_initscan(const char *name)
|
| |
- memset(current_buf, 0, sizeof(*current_buf));
|
| |
-
|
| |
- current_file = file_lookup(name);
|
| |
- - current_file->lineno = 1;
|
| |
- + yylineno = 1;
|
| |
- }
|
| |
-
|
| |
- void zconf_nextfile(const char *name)
|
| |
- @@ -315,35 +410,34 @@ void zconf_nextfile(const char *name)
|
| |
- current_buf->state = YY_CURRENT_BUFFER;
|
| |
- yyin = zconf_fopen(file->name);
|
| |
- if (!yyin) {
|
| |
- - printf("%s:%d: can't open file \"%s\"\n",
|
| |
- - zconf_curname(), zconf_lineno(), file->name);
|
| |
- + 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;
|
| |
-
|
| |
- - for (iter = current_file->parent; iter; iter = iter->parent ) {
|
| |
- - if (!strcmp(current_file->name,iter->name) ) {
|
| |
- - printf("%s:%d: recursive inclusion detected. "
|
| |
- - "Inclusion path:\n current file : '%s'\n",
|
| |
- - zconf_curname(), zconf_lineno(),
|
| |
- - zconf_curname());
|
| |
- - iter = current_file->parent;
|
| |
- - while (iter && \
|
| |
- - strcmp(iter->name,current_file->name)) {
|
| |
- - printf(" included from: '%s:%d'\n",
|
| |
- - iter->name, iter->lineno-1);
|
| |
- + 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;
|
| |
- - }
|
| |
- - if (iter)
|
| |
- - printf(" included from: '%s:%d'\n",
|
| |
- - iter->name, iter->lineno+1);
|
| |
- + fprintf(stderr, " included from: %s:%d\n",
|
| |
- + iter->name, iter->lineno - 1);
|
| |
- + } while (strcmp(iter->name, file->name));
|
| |
- exit(1);
|
| |
- }
|
| |
- }
|
| |
- - file->lineno = 1;
|
| |
- - file->parent = current_file;
|
| |
- +
|
| |
- + yylineno = 1;
|
| |
- current_file = file;
|
| |
- }
|
| |
-
|
| |
- @@ -352,6 +446,8 @@ 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) {
|
| |
- diff --git a/carl9170fw/config/zconf.y b/carl9170fw/config/zconf.y
|
| |
- index 79c4f04..60936c7 100644
|
| |
- --- a/carl9170fw/config/zconf.y
|
| |
- +++ b/carl9170fw/config/zconf.y
|
| |
- @@ -1,8 +1,8 @@
|
| |
- -%{
|
| |
- +/* SPDX-License-Identifier: GPL-2.0 */
|
| |
- /*
|
| |
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
| |
- - * Released under the terms of the GNU GPL v2.0.
|
| |
- */
|
| |
- +%{
|
| |
-
|
| |
- #include <ctype.h>
|
| |
- #include <stdarg.h>
|
| |
- @@ -20,63 +20,69 @@
|
| |
-
|
| |
- int cdebug = PRINTD;
|
| |
-
|
| |
- -extern int zconflex(void);
|
| |
- +static void yyerror(const char *err);
|
| |
- static void zconfprint(const char *err, ...);
|
| |
- static void zconf_error(const char *err, ...);
|
| |
- -static void zconferror(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 32
|
| |
-
|
| |
- %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 <id>T_MAINMENU
|
| |
- -%token <id>T_MENU
|
| |
- -%token <id>T_ENDMENU
|
| |
- -%token <id>T_SOURCE
|
| |
- -%token <id>T_CHOICE
|
| |
- -%token <id>T_ENDCHOICE
|
| |
- -%token <id>T_COMMENT
|
| |
- -%token <id>T_CONFIG
|
| |
- -%token <id>T_MENUCONFIG
|
| |
- -%token <id>T_HELP
|
| |
- %token <string> T_HELPTEXT
|
| |
- -%token <id>T_IF
|
| |
- -%token <id>T_ENDIF
|
| |
- -%token <id>T_DEPENDS
|
| |
- -%token <id>T_OPTIONAL
|
| |
- -%token <id>T_PROMPT
|
| |
- -%token <id>T_TYPE
|
| |
- -%token <id>T_DEFAULT
|
| |
- -%token <id>T_SELECT
|
| |
- -%token <id>T_IMPLY
|
| |
- -%token <id>T_RANGE
|
| |
- -%token <id>T_VISIBLE
|
| |
- -%token <id>T_OPTION
|
| |
- -%token <id>T_ON
|
| |
- %token <string> T_WORD
|
| |
- %token <string> 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 <string> T_ASSIGN_VAL
|
| |
-
|
| |
- %left T_OR
|
| |
- %left T_AND
|
| |
- @@ -85,13 +91,15 @@ static struct menu *current_menu, *current_entry;
|
| |
- %nonassoc T_NOT
|
| |
-
|
| |
- %type <string> prompt
|
| |
- +%type <symbol> nonconst_symbol
|
| |
- %type <symbol> symbol
|
| |
- +%type <type> type logic_type default
|
| |
- %type <expr> expr
|
| |
- %type <expr> if_expr
|
| |
- -%type <id> end
|
| |
- -%type <id> option_name
|
| |
- +%type <string> end
|
| |
- %type <menu> if_entry menu_entry choice_entry
|
| |
- -%type <string> symbol_option_arg word_opt
|
| |
- +%type <string> word_opt assign_val
|
| |
- +%type <flavor> assign_op
|
| |
-
|
| |
- %destructor {
|
| |
- fprintf(stderr, "%s:%d: missing end statement for this entry\n",
|
| |
- @@ -100,71 +108,53 @@ static struct menu *current_menu, *current_entry;
|
| |
- menu_end_menu();
|
| |
- } if_entry menu_entry choice_entry
|
| |
-
|
| |
- -%{
|
| |
- -/* Include zconf_id.c here so it can see the token constants. */
|
| |
- -#include "kconf_id.c"
|
| |
- -%}
|
| |
- -
|
| |
- %%
|
| |
- -input: nl start | start;
|
| |
- +input: mainmenu_stmt stmt_list | stmt_list;
|
| |
-
|
| |
- -start: 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 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
|
| |
- | source_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 T_WORD T_EOL
|
| |
- +config_entry_start: T_CONFIG nonconst_symbol T_EOL
|
| |
- {
|
| |
- - struct symbol *sym = sym_lookup($2, 0);
|
| |
- - sym->flags |= SYMBOL_OPTIONAL;
|
| |
- - menu_add_entry(sym);
|
| |
- - printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
|
| |
- + $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
|
| |
- {
|
| |
- - menu_end_entry();
|
| |
- printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
|
| |
- };
|
| |
-
|
| |
- -menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
|
| |
- +menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
|
| |
- {
|
| |
- - struct symbol *sym = sym_lookup($2, 0);
|
| |
- - sym->flags |= SYMBOL_OPTIONAL;
|
| |
- - menu_add_entry(sym);
|
| |
- - printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
|
| |
- + $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
|
| |
- @@ -173,26 +163,22 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
|
| |
- current_entry->prompt->type = P_MENU;
|
| |
- else
|
| |
- zconfprint("warning: menuconfig statement without prompt");
|
| |
- - menu_end_entry();
|
| |
- printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
|
| |
- };
|
| |
-
|
| |
- 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
|
| |
- @@ -201,25 +187,25 @@ 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 T_WORD if_expr T_EOL
|
| |
- +config_option: T_SELECT nonconst_symbol if_expr T_EOL
|
| |
- {
|
| |
- - menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
|
| |
- + menu_add_symbol(P_SELECT, $2, $3);
|
| |
- printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
|
| |
- };
|
| |
-
|
| |
- -config_option: T_IMPLY T_WORD if_expr T_EOL
|
| |
- +config_option: T_IMPLY nonconst_symbol if_expr T_EOL
|
| |
- {
|
| |
- - menu_add_symbol(P_IMPLY, sym_lookup($2, 0), $3);
|
| |
- + menu_add_symbol(P_IMPLY, $2, $3);
|
| |
- printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
|
| |
- };
|
| |
-
|
| |
- @@ -229,34 +215,30 @@ 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);
|
| |
- - 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 */
|
| |
-
|
| |
- 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);
|
| |
- printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
|
| |
- };
|
| |
-
|
| |
- @@ -267,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());
|
| |
- }
|
| |
- @@ -281,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
|
| |
- @@ -291,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
|
| |
- @@ -308,16 +284,28 @@ choice_option: T_OPTIONAL T_EOL
|
| |
- printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
|
| |
- };
|
| |
-
|
| |
- -choice_option: T_DEFAULT T_WORD if_expr T_EOL
|
| |
- +choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
|
| |
- {
|
| |
- - if ($1->stype == S_UNKNOWN) {
|
| |
- - menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $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
|
| |
- @@ -325,7 +313,7 @@ choice_block:
|
| |
-
|
| |
- /* if entry */
|
| |
-
|
| |
- -if_entry: T_IF expr nl
|
| |
- +if_entry: T_IF expr T_EOL
|
| |
- {
|
| |
- printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
|
| |
- menu_add_entry(NULL);
|
| |
- @@ -335,29 +323,15 @@ if_entry: T_IF expr nl
|
| |
-
|
| |
- 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_stmt: if_entry stmt_list if_end
|
| |
- ;
|
| |
-
|
| |
- -if_block:
|
| |
- - /* empty */
|
| |
- - | if_block common_stmt
|
| |
- - | if_block menu_stmt
|
| |
- - | if_block choice_stmt
|
| |
- -;
|
| |
- -
|
| |
- -/* mainmenu entry */
|
| |
- -
|
| |
- -mainmenu_stmt: T_MAINMENU prompt nl
|
| |
- -{
|
| |
- - menu_add_prompt(P_MENU, $2, NULL);
|
| |
- -};
|
| |
- -
|
| |
- /* menu entry */
|
| |
-
|
| |
- menu: T_MENU prompt T_EOL
|
| |
- @@ -367,33 +341,33 @@ 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
|
| |
- {
|
| |
- printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
|
| |
- zconf_nextfile($2);
|
| |
- + free($2);
|
| |
- };
|
| |
-
|
| |
- /* comment entry */
|
| |
- @@ -405,10 +379,13 @@ comment: T_COMMENT prompt T_EOL
|
| |
- printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
|
| |
- };
|
| |
-
|
| |
- -comment_stmt: comment depends_list
|
| |
- -{
|
| |
- - menu_end_entry();
|
| |
- -};
|
| |
- +comment_stmt: comment comment_option_list
|
| |
- +;
|
| |
- +
|
| |
- +comment_option_list:
|
| |
- + /* empty */
|
| |
- + | comment_option_list depends
|
| |
- +;
|
| |
-
|
| |
- /* help option */
|
| |
-
|
| |
- @@ -420,18 +397,22 @@ help_start: T_HELP T_EOL
|
| |
-
|
| |
- 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 ?: "<choice>");
|
| |
- + }
|
| |
- +
|
| |
- + /* 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 ?: "<choice>");
|
| |
- +
|
| |
- current_entry->help = $2;
|
| |
- };
|
| |
-
|
| |
- /* 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);
|
| |
- @@ -439,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);
|
| |
- };
|
| |
- @@ -464,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; }
|
| |
- @@ -491,13 +460,31 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
|
| |
- | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
|
| |
- ;
|
| |
-
|
| |
- -symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
|
| |
- +/* 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)
|
| |
- @@ -507,61 +494,51 @@ void conf_parse(const char *name)
|
| |
-
|
| |
- zconf_initscan(name);
|
| |
-
|
| |
- - sym_init();
|
| |
- _menu_init();
|
| |
- - rootmenu.prompt = menu_add_prompt(P_MENU, "CARL9170 Firmware Configuration", NULL);
|
| |
-
|
| |
- if (getenv("ZCONF_DEBUG"))
|
| |
- - zconfdebug = 1;
|
| |
- - zconfparse();
|
| |
- - if (zconfnerrs)
|
| |
- + 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" );
|
| |
-
|
| |
- - rootmenu.prompt->text = _(rootmenu.prompt->text);
|
| |
- - rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
|
| |
- + 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))
|
| |
- - zconfnerrs++;
|
| |
- + yynerrs++;
|
| |
- }
|
| |
- - if (zconfnerrs)
|
| |
- + if (yynerrs)
|
| |
- exit(1);
|
| |
- 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 "<token>";
|
| |
- -}
|
| |
- -
|
| |
- -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));
|
| |
- - zconfnerrs++;
|
| |
- + 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));
|
| |
- - zconfnerrs++;
|
| |
- + expected_tokenname);
|
| |
- + yynerrs++;
|
| |
- return false;
|
| |
- }
|
| |
- return true;
|
| |
- @@ -582,7 +559,7 @@ static void zconf_error(const char *err, ...)
|
| |
- {
|
| |
- va_list ap;
|
| |
-
|
| |
- - zconfnerrs++;
|
| |
- + yynerrs++;
|
| |
- fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
|
| |
- va_start(ap, err);
|
| |
- vfprintf(stderr, err, ap);
|
| |
- @@ -590,7 +567,7 @@ static void zconf_error(const char *err, ...)
|
| |
- fprintf(stderr, "\n");
|
| |
- }
|
| |
-
|
| |
- -static void zconferror(const char *err)
|
| |
- +static void yyerror(const char *err)
|
| |
- {
|
| |
- fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
|
| |
- }
|
| |
- @@ -623,7 +600,7 @@ static void print_symbol(FILE *out, struct menu *menu)
|
| |
- fprintf(out, "\nconfig %s\n", sym->name);
|
| |
- switch (sym->type) {
|
| |
- case S_BOOLEAN:
|
| |
- - fputs(" boolean\n", out);
|
| |
- + fputs(" bool\n", out);
|
| |
- break;
|
| |
- case S_TRISTATE:
|
| |
- fputs(" tristate\n", out);
|
| |
- @@ -686,6 +663,10 @@ static void print_symbol(FILE *out, struct menu *menu)
|
| |
- 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;
|
| |
- @@ -746,9 +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"
|
| |
- diff --git a/carl9170fw/include/linux/ieee80211.h b/carl9170fw/include/linux/ieee80211.h
|
| |
- index 31c59ea..46ce6cf 100644
|
| |
- --- a/carl9170fw/include/linux/ieee80211.h
|
| |
- +++ b/carl9170fw/include/linux/ieee80211.h
|
| |
- @@ -897,33 +897,33 @@ struct ieee80211_mgmt {
|
| |
- __le16 status_code;
|
| |
- /* possibly followed by Challenge text */
|
| |
- u8 variable[0];
|
| |
- - } __packed auth;
|
| |
- + } __packed __aligned(4) auth;
|
| |
- struct {
|
| |
- __le16 reason_code;
|
| |
- - } __packed deauth;
|
| |
- + } __packed __aligned(4) deauth;
|
| |
- struct {
|
| |
- __le16 capab_info;
|
| |
- __le16 listen_interval;
|
| |
- /* followed by SSID and Supported rates */
|
| |
- u8 variable[0];
|
| |
- - } __packed assoc_req;
|
| |
- + } __packed __aligned(4) assoc_req;
|
| |
- struct {
|
| |
- __le16 capab_info;
|
| |
- __le16 status_code;
|
| |
- __le16 aid;
|
| |
- /* followed by Supported rates */
|
| |
- u8 variable[0];
|
| |
- - } __packed assoc_resp, reassoc_resp;
|
| |
- + } __packed __aligned(4) assoc_resp, reassoc_resp;
|
| |
- struct {
|
| |
- __le16 capab_info;
|
| |
- __le16 listen_interval;
|
| |
- u8 current_ap[6];
|
| |
- /* followed by SSID and Supported rates */
|
| |
- u8 variable[0];
|
| |
- - } __packed reassoc_req;
|
| |
- + } __packed __aligned(4) reassoc_req;
|
| |
- struct {
|
| |
- __le16 reason_code;
|
| |
- - } __packed disassoc;
|
| |
- + } __packed __aligned(4) disassoc;
|
| |
- struct {
|
| |
- __le64 timestamp;
|
| |
- __le16 beacon_int;
|
| |
- @@ -931,11 +931,11 @@ struct ieee80211_mgmt {
|
| |
- /* followed by some of SSID, Supported rates,
|
| |
- * FH Params, DS Params, CF Params, IBSS Params, TIM */
|
| |
- u8 variable[0];
|
| |
- - } __packed beacon;
|
| |
- + } __packed __aligned(4) beacon;
|
| |
- struct {
|
| |
- /* only variable items: SSID, Supported rates */
|
| |
- u8 variable[0];
|
| |
- - } __packed probe_req;
|
| |
- + } __packed __aligned(4) probe_req;
|
| |
- struct {
|
| |
- __le64 timestamp;
|
| |
- __le16 beacon_int;
|
| |
- @@ -943,7 +943,7 @@ struct ieee80211_mgmt {
|
| |
- /* followed by some of SSID, Supported rates,
|
| |
- * FH Params, DS Params, CF Params, IBSS Params */
|
| |
- u8 variable[0];
|
| |
- - } __packed probe_resp;
|
| |
- + } __packed __aligned(4) probe_resp;
|
| |
- struct {
|
| |
- u8 category;
|
| |
- union {
|
| |
- @@ -1041,8 +1041,8 @@ struct ieee80211_mgmt {
|
| |
- u8 variable[0];
|
| |
- } __packed ftm;
|
| |
- } u;
|
| |
- - } __packed action;
|
| |
- - } u;
|
| |
- + } __packed __aligned(4) action;
|
| |
- + } u __aligned(2);
|
| |
- } __packed __aligned(2);
|
| |
-
|
| |
- /* Supported rates membership selectors */
|
| |
- @@ -1245,7 +1245,7 @@ struct ieee80211_bar {
|
| |
- __u8 ta[6];
|
| |
- __le16 control;
|
| |
- __le16 start_seq_num;
|
| |
- -} __packed __aligned(4);
|
| |
- +} __packed __aligned(2);
|
| |
-
|
| |
- /* 802.11 BA(R) control masks */
|
| |
- #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000
|
| |
- diff --git a/carl9170fw/include/shared/wlan.h b/carl9170fw/include/shared/wlan.h
|
| |
- index 9c6b7ff..117f005 100644
|
| |
- --- a/carl9170fw/include/shared/wlan.h
|
| |
- +++ b/carl9170fw/include/shared/wlan.h
|
| |
- @@ -273,7 +273,7 @@ struct ar9170_tx_frame {
|
| |
- struct ieee80211_hdr i3e;
|
| |
- u8 payload[0];
|
| |
- } data;
|
| |
- -} __packed;
|
| |
- +} __packed __aligned(4);
|
| |
-
|
| |
- struct carl9170_tx_superframe {
|
| |
- struct carl9170_tx_superdesc s;
|
| |
- diff --git a/carl9170fw/toolchain/Makefile b/carl9170fw/toolchain/Makefile
|
| |
- index 11db906..43e546d 100644
|
| |
- --- a/carl9170fw/toolchain/Makefile
|
| |
- +++ b/carl9170fw/toolchain/Makefile
|
| |
- @@ -1,16 +1,16 @@
|
| |
- -BINUTILS_VER=2.31.1
|
| |
- +BINUTILS_VER=2.32
|
| |
- BINUTILS_TAR=binutils-$(BINUTILS_VER).tar.xz
|
| |
- BINUTILS_URL="https://ftp.gnu.org/gnu/binutils/$(BINUTILS_TAR)"
|
| |
-
|
| |
- -NEWLIB_VER=3.0.0
|
| |
- +NEWLIB_VER=3.1.0
|
| |
- NEWLIB_TAR=newlib-$(NEWLIB_VER).tar.gz
|
| |
- NEWLIB_URL="ftp://sourceware.org/pub/newlib/$(NEWLIB_TAR)"
|
| |
-
|
| |
- -GCC_VER=8.2.0
|
| |
- +GCC_VER=9.1.0
|
| |
- GCC_TAR=gcc-$(GCC_VER).tar.xz
|
| |
- GCC_URL="https://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VER)/$(GCC_TAR)"
|
| |
-
|
| |
- -MPFR_VER=4.0.1
|
| |
- +MPFR_VER=4.0.2
|
| |
- MPFR_TAR=mpfr-$(MPFR_VER).tar.xz
|
| |
- MPFR_URL="https://ftp.gnu.org/gnu/mpfr/$(MPFR_TAR)"
|
| |
-
|
| |
- diff --git a/carl9170fw/toolchain/SHA256SUMS b/carl9170fw/toolchain/SHA256SUMS
|
| |
- index 1b65040..3a53959 100644
|
| |
- --- a/carl9170fw/toolchain/SHA256SUMS
|
| |
- +++ b/carl9170fw/toolchain/SHA256SUMS
|
| |
- @@ -1,16 +1,6 @@
|
| |
- -1cf7adf8ff4b5aa49041c8734bbcf1ad18cc4c94d0029aae0f4e48841088479a src/gcc-7.2.0.tar.xz
|
| |
- -5b76a9b97c9464209772ed25ce55181a7bb144a66e5669aaec945aa64da3189b src/newlib-2.5.0.tar.gz
|
| |
- -0b871e271c4c620444f8264f72143b4d224aa305306d85dd77ab8dce785b1e85 src/binutils-2.29.tar.xz
|
| |
- 87b565e89a9a684fe4ebeeddb8399dce2599f9c9049854ca8c0dfbdea0e21912 src/gmp-6.1.2.tar.xz
|
| |
- -617decc6ea09889fb08ede330917a00b16809b8db88c29c31bfbb49cbf88ecc3 src/mpc-1.0.3.tar.gz
|
| |
- -7a62ac1a04408614fccdc506e4844b10cf0ad2c2b1677097f8f35d3a1344a950 src/mpfr-3.1.6.tar.xz
|
| |
- 6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e src/mpc-1.1.0.tar.gz
|
| |
- -fbe2cd1418b321f5c899ce4f0f0f4e73f5ecc7d02145b0e1fd096f5c3afb8a1d src/mpfr-4.0.0.tar.xz
|
| |
- -c8566335ee74e5fcaeb8595b4ebd0400c4b043d6acb3263ecb1314f8f5501332 src/newlib-3.0.0.tar.gz
|
| |
- -832ca6ae04636adbb430e865a1451adf6979ab44ca1c8374f61fba65645ce15c src/gcc-7.3.0.tar.xz
|
| |
- -e7010a46969f9d3e53b650a518663f98a5dde3c3ae21b7d71e5e6803bc36b577 src/binutils-2.29.1.tar.xz
|
| |
- -67874a60826303ee2fb6affc6dc0ddd3e749e9bfcb4c8655e3953d0458a6e16e src/mpfr-4.0.1.tar.xz
|
| |
- -6e46b8aeae2f727a36f0bd9505e405768a72218f1796f0d09757d45209871ae6 src/binutils-2.30.tar.xz
|
| |
- -1d1866f992626e61349a1ccd0b8d5253816222cdc13390dcfaa74b093aa2b153 src/gcc-8.1.0.tar.xz
|
| |
- -5d20086ecf5752cc7d9134246e9588fa201740d540f7eb84d795b1f7a93bca86 src/binutils-2.31.1.tar.xz
|
| |
- -196c3c04ba2613f893283977e6011b2345d1cd1af9abeac58e916b1aab3e0080 src/gcc-8.2.0.tar.xz
|
| |
- \ No newline at end of file
|
| |
- +fb4fa1cc21e9060719208300a61420e4089d6de6ef59cf533b57fe74801d102a src/newlib-3.1.0.tar.gz
|
| |
- +1d3be708604eae0e42d578ba93b390c2a145f17743a744d8f3f8c2ad5855a38a src/mpfr-4.0.2.tar.xz
|
| |
- +0ab6c55dd86a92ed561972ba15b9b70a8b9f75557f896446c82e8b36e473ee04 src/binutils-2.32.tar.xz
|
| |
- +79a66834e96a6050d8fe78db2c3b32fb285b230b855d0a66288235bc04b327a0 src/gcc-9.1.0.tar.xz
|
| |
- --
|
| |
- 2.26.0
|
| |
-
|
| |
⚠ Depends on https://pagure.io/iceweasel/pull-request/7
Only the most recent commit is relevant.
Built for x86_64.
i686 build failed, please find the logs:
iceweasel-1:95.0-1.parabola1-i686-prepare.log: https://termbin.com/o7fx
iceweasel-1:95.0-1.parabola1-i686-build_truncated_before_error.log: https://termbin.com/e3uk
Also tried to build armv7h and waited until it started "Compiling..." steps, then canceled the build. Didn't want to wait so much time for it to complete, sorry.