From e8440b5c2722b2740b7fd444edcd7cbd531ccddb Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 6 Apr 2014 14:46:57 +0200 Subject: use lowercase directory name --- toolchain/uclibc/patches/uclibc-git-20140313.patch | 116105 ++++++++++++++++++ toolchain/uclibc/patches/xxx-origin.patch | 177 + toolchain/uclibc/patches/xxx-sparc-wait4.patch | 12 + 3 files changed, 116294 insertions(+) create mode 100644 toolchain/uclibc/patches/uclibc-git-20140313.patch create mode 100644 toolchain/uclibc/patches/xxx-origin.patch create mode 100644 toolchain/uclibc/patches/xxx-sparc-wait4.patch (limited to 'toolchain/uclibc/patches') diff --git a/toolchain/uclibc/patches/uclibc-git-20140313.patch b/toolchain/uclibc/patches/uclibc-git-20140313.patch new file mode 100644 index 000000000..561c08007 --- /dev/null +++ b/toolchain/uclibc/patches/uclibc-git-20140313.patch @@ -0,0 +1,116105 @@ +diff -Nur uClibc-0.9.33.2/docs/man/arc4random.3 uClibc-git/docs/man/arc4random.3 +--- uClibc-0.9.33.2/docs/man/arc4random.3 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-git/docs/man/arc4random.3 2014-02-03 12:32:56.000000000 +0100 +@@ -0,0 +1,110 @@ ++.\" $OpenBSD: arc4random.3,v 1.19 2005/07/17 08:50:55 jaredy Exp $ ++.\" ++.\" Copyright 1997 Niels Provos ++.\" All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. All advertising materials mentioning features or use of this software ++.\" must display the following acknowledgement: ++.\" This product includes software developed by Niels Provos. ++.\" 4. The name of the author may not be used to endorse or promote products ++.\" derived from this software without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++.\" ++.\" Manual page, using -mandoc macros ++.\" ++.Dd April 15, 1997 ++.Dt ARC4RANDOM 3 ++.Os ++.Sh NAME ++.Nm arc4random , ++.Nm arc4random_stir , ++.Nm arc4random_addrandom ++.Nd arc4 random number generator ++.Sh SYNOPSIS ++.Fd #include ++.Ft uint32_t ++.Fn arc4random "void" ++.Ft void ++.Fn arc4random_stir "void" ++.Ft void ++.Fn arc4random_addrandom "u_char *dat" "int datlen" ++.Sh DESCRIPTION ++The ++.Fn arc4random ++function provides a high quality 32-bit pseudo-random ++number very quickly. ++.Fn arc4random ++seeds itself on a regular basis from the kernel strong random number ++subsystem described in ++.Xr random 4 . ++On each call, an ARC4 generator is used to generate a new result. ++The ++.Fn arc4random ++function uses the ARC4 cipher key stream generator, ++which uses 8*8 8-bit S-Boxes. ++The S-Boxes can be in about (2**1700) states. ++.Pp ++.Fn arc4random ++fits into a middle ground not covered by other subsystems such as ++the strong, slow, and resource expensive random ++devices described in ++.Xr random 4 ++versus the fast but poor quality interfaces described in ++.Xr rand 3 , ++.Xr random 3 , ++and ++.Xr drand48 3 . ++.Pp ++The ++.Fn arc4random_stir ++function reads data from a pseudo-random device, usually ++.Pa /dev/urandom, ++and uses it to permute the S-Boxes via ++.Fn arc4random_addrandom . ++.Pp ++There is no need to call ++.Fn arc4random_stir ++before using ++.Fn arc4random , ++since ++.Fn arc4random ++automatically initializes itself. ++.Sh SEE ALSO ++.Xr rand 3 , ++.Xr rand48 3 , ++.Xr random 3 ++.Sh HISTORY ++An algorithm called ++.Pa RC4 ++was designed by RSA Data Security, Inc. ++It was considered a trade secret. ++Because it was a trade secret, it obviously could not be patented. ++A clone of this was posted anonymously to USENET and confirmed to ++be equivalent by several sources who had access to the original cipher. ++Because of the trade secret situation, RSA Data Security, Inc. can do ++nothing about the release of the ARC4 algorithm. ++Since ++.Pa RC4 ++used to be a trade secret, the cipher is now referred to as ++.Pa ARC4 . ++.Pp ++These functions first appeared in ++.Ox 2.1 . +diff -Nur uClibc-0.9.33.2/docs/PORTING uClibc-git/docs/PORTING +--- uClibc-0.9.33.2/docs/PORTING 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/docs/PORTING 2014-02-03 12:32:56.000000000 +0100 +@@ -130,9 +130,6 @@ + ==================== + === Misc Cruft === + ==================== +-- utils/readelf.c - not really needed generally speaking, but might as well +- add your arch to the giant EM_* list (describe_elf_hdr) +- + - MAINTAINERS - presumably you're going to submit this code back to mainline + and since you're the only one who cares about this arch (right now), you + should add yourself to the toplevel MAINTAINERS file. do it. +diff -Nur uClibc-0.9.33.2/extra/config/check.sh uClibc-git/extra/config/check.sh +--- uClibc-0.9.33.2/extra/config/check.sh 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/check.sh 2014-02-03 12:32:56.000000000 +0100 +@@ -1,6 +1,6 @@ + #!/bin/sh + # Needed for systems without gettext +-$* -xc -o /dev/null - > /dev/null 2>&1 << EOF ++$* -x c -o /dev/null - > /dev/null 2>&1 << EOF + #include + int main() + { +diff -Nur uClibc-0.9.33.2/extra/config/conf.c uClibc-git/extra/config/conf.c +--- uClibc-0.9.33.2/extra/config/conf.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/conf.c 2014-02-03 12:32:56.000000000 +0100 +@@ -10,42 +10,48 @@ + #include + #include + #include ++#include + #include + #include ++#include + +-#define LKC_DIRECT_LINK + #include "lkc.h" + + static void conf(struct menu *menu); + static void check_conf(struct menu *menu); ++static void xfgets(char *str, int size, FILE *in); + +-enum { +- ask_all, +- ask_new, +- ask_silent, +- set_default, +- set_yes, +- set_mod, +- set_no, +- set_random +-} input_mode = ask_all; +-char *defconfig_file; ++enum input_mode { ++ oldaskconfig, ++ silentoldconfig, ++ oldconfig, ++ allnoconfig, ++ allyesconfig, ++ allmodconfig, ++ alldefconfig, ++ randconfig, ++ defconfig, ++ savedefconfig, ++ listnewconfig, ++ olddefconfig, ++} 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[128]; + static struct menu *rootEntry; + +-static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); +- +-static const char *get_help(struct menu *menu) ++static void print_help(struct menu *menu) + { +- if (menu_has_help(menu)) +- return _(menu_get_help(menu)); +- else +- return nohelp_text; ++ struct gstr help = str_new(); ++ ++ menu_get_ext_help(menu, &help); ++ ++ printf("\n%s\n", str_get(&help)); ++ str_free(&help); + } + + static void strip(char *str) +@@ -93,16 +99,19 @@ + } + + switch (input_mode) { +- case ask_new: +- case ask_silent: ++ case oldconfig: ++ case silentoldconfig: + if (sym_has_value(sym)) { + printf("%s\n", def); + return 0; + } + check_stdin(); +- case ask_all: ++ /* fall through */ ++ case oldaskconfig: + fflush(stdout); +- fgets(line, 128, stdin); ++ xfgets(line, 128, stdin); ++ if (!tty_stdio) ++ printf("\n"); + return 1; + default: + break; +@@ -121,7 +130,7 @@ + return 1; + } + +-int conf_string(struct menu *menu) ++static int conf_string(struct menu *menu) + { + struct symbol *sym = menu->sym; + const char *def; +@@ -140,10 +149,11 @@ + case '?': + /* print help */ + if (line[1] == '\n') { +- printf("\n%s\n", get_help(menu)); ++ print_help(menu); + def = NULL; + break; + } ++ /* fall through */ + default: + line[strlen(line)-1] = 0; + def = line; +@@ -156,14 +166,12 @@ + static int conf_sym(struct menu *menu) + { + struct symbol *sym = menu->sym; +- int type; + tristate oldval, newval; + + while (1) { + printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); + if (sym->name) + printf("(%s) ", sym->name); +- type = sym_get_type(sym); + putchar('['); + oldval = sym_get_tristate_value(sym); + switch (oldval) { +@@ -220,7 +228,7 @@ + if (sym_set_tristate_value(sym, newval)) + return 0; + help: +- printf("\n%s\n", get_help(menu)); ++ print_help(menu); + } + } + +@@ -228,11 +236,9 @@ + { + struct symbol *sym, *def_sym; + struct menu *child; +- int type; + bool is_new; + + sym = menu->sym; +- type = sym_get_type(sym); + is_new = !sym_has_value(sym); + if (sym_is_changable(sym)) { + conf_sym(menu); +@@ -294,20 +300,21 @@ + printf("?"); + printf("]: "); + switch (input_mode) { +- case ask_new: +- case ask_silent: ++ case oldconfig: ++ case silentoldconfig: + if (!is_new) { + cnt = def; + printf("%d\n", cnt); + break; + } + check_stdin(); +- case ask_all: ++ /* fall through */ ++ case oldaskconfig: + fflush(stdout); +- fgets(line, 128, stdin); ++ xfgets(line, 128, stdin); + strip(line); + if (line[0] == '?') { +- printf("\n%s\n", get_help(menu)); ++ print_help(menu); + continue; + } + if (!line[0]) +@@ -330,8 +337,8 @@ + } + if (!child) + continue; +- if (line[strlen(line) - 1] == '?') { +- printf("\n%s\n", get_help(child)); ++ if (line[0] && line[strlen(line) - 1] == '?') { ++ print_help(child); + continue; + } + sym_set_choice_value(sym, child->sym); +@@ -360,10 +367,14 @@ + + switch (prop->type) { + case P_MENU: +- if (input_mode == ask_silent && rootEntry != menu) { ++ if ((input_mode == silentoldconfig || ++ input_mode == listnewconfig || ++ input_mode == olddefconfig) && ++ rootEntry != menu) { + check_conf(menu); + return; + } ++ /* fall through */ + case P_COMMENT: + prompt = menu_get_prompt(menu); + if (prompt) +@@ -418,10 +429,16 @@ + if (sym && !sym_has_value(sym)) { + if (sym_is_changable(sym) || + (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { +- if (!conf_cnt++) +- printf(_("*\n* Restart config...\n*\n")); +- rootEntry = menu_get_parent_menu(menu); +- conf(rootEntry); ++ if (input_mode == listnewconfig) { ++ if (sym->name && !sym_is_choice_value(sym)) { ++ printf("%s%s\n", CONFIG_, sym->name); ++ } ++ } else if (input_mode != olddefconfig) { ++ if (!conf_cnt++) ++ printf(_("*\n* Restart config...\n*\n")); ++ rootEntry = menu_get_parent_menu(menu); ++ conf(rootEntry); ++ } + } + } + +@@ -429,90 +446,170 @@ + check_conf(child); + } + ++#if 00 // || !defined __UCLIBC__ || \ ++ (defined UCLIBC_HAS_GETOPT_LONG || defined UCLIBC_HAS_GNU_GETOPT) ++static struct option long_opts[] = { ++ {"oldaskconfig", no_argument, NULL, oldaskconfig}, ++ {"oldconfig", no_argument, NULL, oldconfig}, ++ {"silentoldconfig", no_argument, NULL, silentoldconfig}, ++ {"defconfig", optional_argument, NULL, defconfig}, ++ {"savedefconfig", required_argument, NULL, savedefconfig}, ++ {"allnoconfig", no_argument, NULL, allnoconfig}, ++ {"allyesconfig", no_argument, NULL, allyesconfig}, ++ {"allmodconfig", no_argument, NULL, allmodconfig}, ++ {"alldefconfig", no_argument, NULL, alldefconfig}, ++ {"randconfig", no_argument, NULL, randconfig}, ++ {"listnewconfig", no_argument, NULL, listnewconfig}, ++ {"olddefconfig", no_argument, NULL, olddefconfig}, ++ /* ++ * oldnoconfig is an alias of olddefconfig, because people already ++ * are dependent on its behavior(sets new symbols to their default ++ * value but not 'n') with the counter-intuitive name. ++ */ ++ {"oldnoconfig", no_argument, NULL, olddefconfig}, ++ {NULL, 0, NULL, 0} ++}; ++ ++static void conf_usage(const char *progname) ++{ ++ ++ printf("Usage: %s [option] \n", progname); ++ printf("[option] is _one_ of the following:\n"); ++ printf(" --listnewconfig List new options\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(" --silentoldconfig Same as oldconfig, but quietly, additionally update deps\n"); ++ printf(" --olddefconfig Same as silentoldconfig but sets new symbols to their default value\n"); ++ printf(" --oldnoconfig An alias of olddefconfig\n"); ++ printf(" --defconfig New config with default defined in \n"); ++ printf(" --savedefconfig Save the minimal current configuration to \n"); ++ printf(" --allnoconfig New config where all options are answered with no\n"); ++ printf(" --allyesconfig New config where all options are answered with yes\n"); ++ printf(" --allmodconfig New config where all options are answered with mod\n"); ++ printf(" --alldefconfig New config with all symbols set to default\n"); ++ printf(" --randconfig New config with random answer to all options\n"); ++} ++#else ++static void conf_usage(const char *progname) ++{ ++ ++ printf("Usage: %s [option] \n", progname); ++ printf("[option] is _one_ of the following:\n"); ++ printf(" -a, --oldaskconfig Start a new configuration using a line-oriented program\n"); ++ printf(" -s, --silentoldconfig Same as oldconfig, but quietly, additionally update deps\n"); ++ printf(" -o, --oldconfig Update a configuration using a provided .config as base\n"); ++ printf(" -n, --allnoconfig New config where all options are answered with no\n"); ++ printf(" -y, --allyesconfig New config where all options are answered with yes\n"); ++ printf(" -m, --allmodconfig New config where all options are answered with mod\n"); ++ printf(" -A, --alldefconfig New config with all symbols set to default\n"); ++ printf(" -r, --randconfig New config with random answer to all options\n"); ++ printf(" -D, --defconfig New config with default defined in \n"); ++ printf(" -S, --savedefconfig Save the minimal current configuration to \n"); ++ printf(" -l, --listnewconfig List new options\n"); ++ printf(" -d, --olddefconfig Same as silentoldconfig but sets new symbols to their default value\n"); ++ printf(" --oldnoconfig An alias of olddefconfig\n"); ++ ++} ++#endif ++ + int main(int ac, char **av) + { ++ const char *progname = av[0]; + int opt; +- const char *name; +- const char *configname = conf_get_configname(); ++ const char *name, *defconfig_file = NULL /* gcc uninit */; + struct stat tmpstat; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + +- while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { ++ tty_stdio = isatty(0) && isatty(1) && isatty(2); ++ ++#if 00// !defined __UCLIBC__ || \ ++ (defined UCLIBC_HAS_GETOPT_LONG || defined UCLIBC_HAS_GNU_GETOPT) ++ while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) ++#else ++ char *gch = "asonymArDSld"; ++ while ((opt = getopt(ac, av, "asonymArD:S:ldh")) != -1) ++#endif ++ { ++ char *x = memchr(gch, opt, strlen(gch)); ++ if (x == NULL) ++ opt = '?'; ++ else ++ opt = x - gch; ++ input_mode = (enum input_mode)opt; + switch (opt) { +- case 'o': +- input_mode = ask_silent; +- break; +- case 's': +- input_mode = ask_silent; ++ case silentoldconfig: + sync_kconfig = 1; + break; +- case 'd': +- input_mode = set_default; +- break; +- case 'D': +- input_mode = set_default; ++ case defconfig: ++ case savedefconfig: + defconfig_file = optarg; + break; +- case 'n': +- input_mode = set_no; +- break; +- case 'm': +- input_mode = set_mod; +- break; +- case 'y': +- input_mode = set_yes; +- break; +- case 'r': ++ case randconfig: + { + struct timeval now; + unsigned int seed; ++ char *seed_env; + + /* + * Use microseconds derived seed, + * compensate for systems where it may be zero + */ + gettimeofday(&now, NULL); +- + seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); +- srand(seed); + +- input_mode = set_random; ++ seed_env = getenv("KCONFIG_SEED"); ++ if( seed_env && *seed_env ) { ++ char *endp; ++ int tmp = (int)strtol(seed_env, &endp, 0); ++ if (*endp == '\0') { ++ seed = tmp; ++ } ++ } ++ fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed ); ++ srand(seed); + break; + } +- case 'h': +- printf(_("See README for usage info\n")); +- exit(0); ++ case oldaskconfig: ++ case oldconfig: ++ case allnoconfig: ++ case allyesconfig: ++ case allmodconfig: ++ case alldefconfig: ++ case listnewconfig: ++ case olddefconfig: + break; +- default: +- fprintf(stderr, _("See README for usage info\n")); ++ case '?': ++ conf_usage(progname); + exit(1); ++ break; + } + } + if (ac == optind) { + printf(_("%s: Kconfig file missing\n"), av[0]); ++ conf_usage(progname); + exit(1); + } + name = av[optind]; + conf_parse(name); + //zconfdump(stdout); + if (sync_kconfig) { +- if (stat(configname, &tmpstat)) { ++ name = conf_get_configname(); ++ if (stat(name, &tmpstat)) { + fprintf(stderr, _("***\n" +- "*** You have not yet configured!\n" +- "*** (missing .config file)\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")); ++ "***\n"), name); + exit(1); + } + } + + switch (input_mode) { +- case set_default: ++ case defconfig: + if (!defconfig_file) + defconfig_file = conf_get_default_confname(); + if (conf_read(defconfig_file)) { +@@ -522,31 +619,46 @@ + exit(1); + } + break; +- case ask_silent: +- case ask_all: +- case ask_new: ++ case savedefconfig: ++ case silentoldconfig: ++ case oldaskconfig: ++ case oldconfig: ++ case listnewconfig: ++ case olddefconfig: + conf_read(NULL); + break; +- case set_no: +- case set_mod: +- case set_yes: +- case set_random: ++ case allnoconfig: ++ case allyesconfig: ++ case allmodconfig: ++ case alldefconfig: ++ case randconfig: + name = getenv("KCONFIG_ALLCONFIG"); +- if (name && !stat(name, &tmpstat)) { +- conf_read_simple(name, S_DEF_USER); ++ if (!name) ++ break; ++ 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"), ++ name); ++ exit(1); ++ } + break; + } + switch (input_mode) { +- case set_no: name = "allno.config"; break; +- case set_mod: name = "allmod.config"; break; +- case set_yes: name = "allyes.config"; break; +- case set_random: name = "allrandom.config"; break; ++ case allnoconfig: name = "allno.config"; break; ++ case allyesconfig: name = "allyes.config"; break; ++ case allmodconfig: name = "allmod.config"; break; ++ case alldefconfig: name = "alldef.config"; break; ++ case randconfig: name = "allrandom.config"; break; + default: break; + } +- if (!stat(name, &tmpstat)) +- conf_read_simple(name, S_DEF_USER); +- else if (!stat("all.config", &tmpstat)) +- conf_read_simple("all.config", S_DEF_USER); ++ 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"), ++ name); ++ exit(1); ++ } + break; + default: + break; +@@ -557,41 +669,51 @@ + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + fprintf(stderr, +- _("\n*** configuration requires explicit update.\n\n")); ++ _("\n*** The configuration requires explicit update.\n\n")); + return 1; + } + } +- valid_stdin = isatty(0) && isatty(1) && isatty(2); ++ valid_stdin = tty_stdio; + } + + switch (input_mode) { +- case set_no: ++ case allnoconfig: + conf_set_all_new_symbols(def_no); + break; +- case set_yes: ++ case allyesconfig: + conf_set_all_new_symbols(def_yes); + break; +- case set_mod: ++ case allmodconfig: + conf_set_all_new_symbols(def_mod); + break; +- case set_random: +- conf_set_all_new_symbols(def_random); ++ case alldefconfig: ++ conf_set_all_new_symbols(def_default); ++ break; ++ case randconfig: ++ /* Really nothing to do in this loop */ ++ while (conf_set_all_new_symbols(def_random)) ; + break; +- case set_default: ++ case defconfig: + conf_set_all_new_symbols(def_default); + break; +- case ask_new: +- case ask_all: ++ case savedefconfig: ++ break; ++ case oldaskconfig: + rootEntry = &rootmenu; + conf(&rootmenu); +- input_mode = ask_silent; ++ input_mode = silentoldconfig; + /* fall through */ +- case ask_silent: ++ case oldconfig: ++ case listnewconfig: ++ case olddefconfig: ++ case silentoldconfig: + /* Update until a loop caused no more changes */ + do { + conf_cnt = 0; + check_conf(&rootmenu); +- } while (conf_cnt); ++ } while (conf_cnt && ++ (input_mode != listnewconfig && ++ input_mode != olddefconfig)); + break; + } + +@@ -607,7 +729,13 @@ + fprintf(stderr, _("\n*** Error during update of the configuration.\n\n")); + return 1; + } +- } else { ++ } else if (input_mode == savedefconfig) { ++ if (conf_write_defconfig(defconfig_file)) { ++ fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), ++ defconfig_file); ++ return 1; ++ } ++ } else if (input_mode != listnewconfig) { + if (conf_write(NULL)) { + fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); + exit(1); +@@ -615,3 +743,12 @@ + } + 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 -Nur uClibc-0.9.33.2/extra/config/confdata.c uClibc-git/extra/config/confdata.c +--- uClibc-0.9.33.2/extra/config/confdata.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/confdata.c 2014-02-03 12:32:56.000000000 +0100 +@@ -5,24 +5,27 @@ + + #include + #include ++#include + #include ++#include + #include + #include + #include + #include + #include +-#include + +-#define LKC_DIRECT_LINK + #include "lkc.h" + + static void conf_warning(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); + ++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; + +-const char conf_defname[] = "extra/Configs/defconfigs/$ARCH"; ++const char conf_defname[] = "arch/$ARCH/defconfig"; + + static void conf_warning(const char *fmt, ...) + { +@@ -35,6 +38,29 @@ + conf_warnings++; + } + ++static void conf_default_message_callback(const char *fmt, va_list ap) ++{ ++ printf("#\n# "); ++ vprintf(fmt, ap); ++ printf("\n#\n"); ++} ++ ++static void (*conf_message_callback) (const char *fmt, va_list ap) = ++ conf_default_message_callback; ++void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) ++{ ++ conf_message_callback = fn; ++} ++ ++static void conf_message(const char *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ if (conf_message_callback) ++ conf_message_callback(fmt, ap); ++} ++ + const char *conf_get_configname(void) + { + char *name = getenv("KCONFIG_CONFIG"); +@@ -42,6 +68,13 @@ + return name ? name : ".config"; + } + ++const char *conf_get_autoconfig_name(void) ++{ ++ char *name = getenv("KCONFIG_AUTOCONFIG"); ++ ++ return name ? name : "include/config/auto.conf"; ++} ++ + static char *conf_expand_value(const char *in) + { + struct symbol *sym; +@@ -95,6 +128,7 @@ + sym->flags |= def_flags; + break; + } ++ /* fall through */ + case S_BOOLEAN: + if (p[0] == 'y') { + sym->def[def].tri = yes; +@@ -107,7 +141,7 @@ + break; + } + conf_warning("symbol value '%s' invalid for %s", p, sym->name); +- break; ++ return 1; + case S_OTHER: + if (*p != '"') { + for (p2 = p; *p2 && !isspace(*p2); p2++) +@@ -115,6 +149,7 @@ + sym->type = S_STRING; + goto done; + } ++ /* fall through */ + case S_STRING: + if (*p++ != '"') + break; +@@ -129,6 +164,7 @@ + conf_warning("invalid string found"); + return 1; + } ++ /* fall through */ + case S_INT: + case S_HEX: + done: +@@ -146,10 +182,66 @@ + return 0; + } + ++#define LINE_GROWTH 16 ++static int add_byte(int c, char **lineptr, size_t slen, size_t *n) ++{ ++ char *nline; ++ size_t new_size = slen + 1; ++ if (new_size > *n) { ++ new_size += LINE_GROWTH - 1; ++ new_size *= 2; ++ nline = realloc(*lineptr, new_size); ++ if (!nline) ++ return -1; ++ ++ *lineptr = nline; ++ *n = new_size; ++ } ++ ++ (*lineptr)[slen] = c; ++ ++ return 0; ++} ++ ++static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream) ++{ ++ char *line = *lineptr; ++ size_t slen = 0; ++ ++ for (;;) { ++ int c = getc(stream); ++ ++ switch (c) { ++ case '\n': ++ if (add_byte(c, &line, slen, n) < 0) ++ goto e_out; ++ slen++; ++ /* fall through */ ++ case EOF: ++ if (add_byte('\0', &line, slen, n) < 0) ++ goto e_out; ++ *lineptr = line; ++ if (slen == 0) ++ return -1; ++ return slen; ++ default: ++ if (add_byte(c, &line, slen, n) < 0) ++ goto e_out; ++ slen++; ++ } ++ } ++ ++e_out: ++ line[slen-1] = '\0'; ++ *lineptr = line; ++ return -1; ++} ++ + int conf_read_simple(const char *name, int def) + { + FILE *in = NULL; +- char line[1024]; ++ char *line = NULL; ++ size_t line_asize = 0; + char *p, *p2; + struct symbol *sym; + int i, def_flags; +@@ -164,8 +256,11 @@ + if (in) + goto load; + sym_add_change_count(1); +- if (!sym_defconfig_list) ++ if (!sym_defconfig_list) { ++ if (modules_sym) ++ sym_calc_value(modules_sym); + return 1; ++ } + + for_all_defaults(sym_defconfig_list, prop) { + if (expr_calc_value(prop->visible.expr) == no || +@@ -174,9 +269,8 @@ + name = conf_expand_value(prop->expr->left.sym->name); + in = zconf_fopen(name); + if (in) { +- printf(_("#\n" +- "# using defaults found in %s\n" +- "#\n"), name); ++ conf_message(_("using defaults found in %s"), ++ name); + goto load; + } + } +@@ -202,33 +296,33 @@ + case S_STRING: + if (sym->def[def].val) + free(sym->def[def].val); ++ /* fall through */ + default: + sym->def[def].val = NULL; + sym->def[def].tri = no; + } + } + +- while (fgets(line, sizeof(line), in)) { ++ while (compat_getline(&line, &line_asize, in) != -1) { + conf_lineno++; + sym = NULL; +- switch (line[0]) { +- case '#': +- if (line[1] != ' ') ++ if (line[0] == '#') { ++ if (memcmp(line + 2, CONFIG_, strlen(CONFIG_))) + continue; +- p = strchr(line + 2, ' '); ++ p = strchr(line + 2 + strlen(CONFIG_), ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; + if (def == S_DEF_USER) { +- sym = sym_find(line + 2); ++ sym = sym_find(line + 2 + strlen(CONFIG_)); + if (!sym) { + sym_add_change_count(1); +- break; ++ goto setsym; + } + } else { +- sym = sym_lookup(line + 2, 0); ++ sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); + if (sym->type == S_UNKNOWN) + sym->type = S_BOOLEAN; + } +@@ -244,13 +338,10 @@ + default: + ; + } +- break; +- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': +- p = strchr(line, '='); +- if (!p) { +- conf_warning("unexpected data '%s'", line); ++ } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) { ++ p = strchr(line + strlen(CONFIG_), '='); ++ if (!p) + continue; +- } + *p++ = 0; + p2 = strchr(p, '\n'); + if (p2) { +@@ -259,13 +350,13 @@ + *p2 = 0; + } + if (def == S_DEF_USER) { +- sym = sym_find(line); ++ sym = sym_find(line + strlen(CONFIG_)); + if (!sym) { + sym_add_change_count(1); +- break; ++ goto setsym; + } + } else { +- sym = sym_lookup(line, 0); ++ sym = sym_lookup(line + strlen(CONFIG_), 0); + if (sym->type == S_UNKNOWN) + sym->type = S_OTHER; + } +@@ -274,14 +365,12 @@ + } + if (conf_set_sym_val(sym, def, def_flags, p)) + continue; +- break; +- case '\r': +- case '\n': +- break; +- default: +- conf_warning("unexpected data"); ++ } else { ++ if (line[0] != '\r' && line[0] != '\n') ++ conf_warning("unexpected data"); + 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) { +@@ -302,6 +391,7 @@ + cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); + } + } ++ free(line); + fclose(in); + + if (modules_sym) +@@ -311,10 +401,8 @@ + + int conf_read(const char *name) + { +- struct symbol *sym, *choice_sym; +- struct property *prop; +- struct expr *e; +- int i, flags; ++ struct symbol *sym; ++ int i; + + sym_set_change_count(0); + +@@ -324,7 +412,7 @@ + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) +- goto sym_ok; ++ continue; + if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { + /* check that calculated value agrees with saved value */ + switch (sym->type) { +@@ -333,29 +421,18 @@ + if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) + break; + if (!sym_is_choice(sym)) +- goto sym_ok; ++ continue; ++ /* fall through */ + default: + if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) +- goto sym_ok; ++ continue; + break; + } + } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) + /* no previous value and not saved */ +- goto sym_ok; ++ continue; + conf_unsaved++; + /* maybe print value in verbose mode... */ +- sym_ok: +- if (!sym_is_choice(sym)) +- continue; +- /* The choice symbol only has a set value (and thus is not new) +- * if all its visible childs have values. +- */ +- prop = sym_get_choice_prop(sym); +- flags = sym->flags; +- expr_list_for_each_sym(prop->expr, e, choice_sym) +- if (choice_sym->visible != no) +- flags &= choice_sym->flags; +- sym->flags &= flags | ~SYMBOL_DEF_USER; + } + + for_all_symbols(i, sym) { +@@ -388,43 +465,300 @@ + return 0; + } + ++/* ++ * Kconfig configuration printer ++ * ++ * This printer is used when generating the resulting configuration after ++ * kconfig invocation and `defconfig' files. Unset symbol might be omitted by ++ * passing a non-NULL argument to the printer. ++ * ++ */ ++static void ++kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) ++{ ++ ++ switch (sym->type) { ++ case S_BOOLEAN: ++ case S_TRISTATE: ++ if (*value == 'n') { ++ bool skip_unset = (arg != NULL); ++ ++ if (!skip_unset) ++ fprintf(fp, "# %s%s is not set\n", ++ CONFIG_, sym->name); ++ return; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value); ++} ++ ++static void ++kconfig_print_comment(FILE *fp, const char *value, void *arg) ++{ ++ const char *p = value; ++ size_t l; ++ ++ for (;;) { ++ l = strcspn(p, "\n"); ++ fprintf(fp, "#"); ++ if (l) { ++ fprintf(fp, " "); ++ xfwrite(p, l, 1, fp); ++ p += l; ++ } ++ fprintf(fp, "\n"); ++ if (*p++ == '\0') ++ break; ++ } ++} ++ ++static struct conf_printer kconfig_printer_cb = ++{ ++ .print_symbol = kconfig_print_symbol, ++ .print_comment = kconfig_print_comment, ++}; ++ ++/* ++ * Header printer ++ * ++ * This printer is used when generating the `include/generated/autoconf.h' file. ++ */ ++static void ++header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) ++{ ++ ++ switch (sym->type) { ++ case S_BOOLEAN: ++ case S_TRISTATE: { ++ const char *suffix = ""; ++ ++ switch (*value) { ++ case 'n': ++ break; ++ case 'm': ++ suffix = "_MODULE"; ++ /* fall through */ ++ default: ++ fprintf(fp, "#define %s%s%s 1\n", ++ CONFIG_, sym->name, suffix); ++ } ++ break; ++ } ++ case S_HEX: { ++ const char *prefix = ""; ++ ++ if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) ++ prefix = "0x"; ++ fprintf(fp, "#define %s%s %s%s\n", ++ CONFIG_, sym->name, prefix, value); ++ break; ++ } ++ case S_STRING: ++ case S_INT: ++ fprintf(fp, "#define %s%s %s\n", ++ CONFIG_, sym->name, value); ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++static void ++header_print_comment(FILE *fp, const char *value, void *arg) ++{ ++ const char *p = value; ++ size_t l; ++ ++ fprintf(fp, "/*\n"); ++ for (;;) { ++ l = strcspn(p, "\n"); ++ fprintf(fp, " *"); ++ if (l) { ++ fprintf(fp, " "); ++ xfwrite(p, l, 1, fp); ++ p += l; ++ } ++ fprintf(fp, "\n"); ++ if (*p++ == '\0') ++ break; ++ } ++ fprintf(fp, " */\n"); ++} ++ ++static struct conf_printer header_printer_cb = ++{ ++ .print_symbol = header_print_symbol, ++ .print_comment = header_print_comment, ++}; ++ ++/* ++ * Tristate printer ++ * ++ * This printer is used when generating the `include/config/tristate.conf' file. ++ */ ++static void ++tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) ++{ ++ ++ if (sym->type == S_TRISTATE && *value != 'n') ++ fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value)); ++} ++ ++static struct conf_printer tristate_printer_cb = ++{ ++ .print_symbol = tristate_print_symbol, ++ .print_comment = kconfig_print_comment, ++}; ++ ++static void conf_write_symbol(FILE *fp, struct symbol *sym, ++ struct conf_printer *printer, void *printer_arg) ++{ ++ const char *str; ++ ++ switch (sym->type) { ++ case S_OTHER: ++ case S_UNKNOWN: ++ break; ++ case S_STRING: ++ str = sym_get_string_value(sym); ++ str = sym_escape_string_value(str); ++ printer->print_symbol(fp, sym, str, printer_arg); ++ free((void *)str); ++ break; ++ default: ++ str = sym_get_string_value(sym); ++ printer->print_symbol(fp, sym, str, printer_arg); ++ } ++} ++ ++static void ++conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg) ++{ ++ char buf[256]; ++ ++ snprintf(buf, sizeof(buf), ++ "\n" ++ "Automatically generated file; DO NOT EDIT.\n" ++ "%s\n", ++ rootmenu.prompt->text); ++ ++ printer->print_comment(fp, buf, printer_arg); ++} ++ ++/* ++ * Write out a minimal config. ++ * All values that has default values are skipped as this is redundant. ++ */ ++int conf_write_defconfig(const char *filename) ++{ ++ struct symbol *sym; ++ struct menu *menu; ++ FILE *out; ++ ++ out = fopen(filename, "w"); ++ if (!out) ++ return 1; ++ ++ sym_clear_all_valid(); ++ ++ /* Traverse all menus to find all relevant symbols */ ++ menu = rootmenu.list; ++ ++ while (menu != NULL) ++ { ++ sym = menu->sym; ++ if (sym == NULL) { ++ if (!menu_is_visible(menu)) ++ goto next_menu; ++ } else if (!sym_is_choice(sym)) { ++ sym_calc_value(sym); ++ if (!(sym->flags & SYMBOL_WRITE)) ++ goto next_menu; ++ sym->flags &= ~SYMBOL_WRITE; ++ /* If we cannot change the symbol - skip */ ++ if (!sym_is_changable(sym)) ++ goto next_menu; ++ /* If symbol equals to default value - skip */ ++ if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) ++ goto next_menu; ++ ++ /* ++ * If symbol is a choice value and equals to the ++ * default for a choice - skip. ++ * But only if value is bool and equal to "y" and ++ * choice is not "optional". ++ * (If choice is "optional" then all values can be "n") ++ */ ++ if (sym_is_choice_value(sym)) { ++ struct symbol *cs; ++ struct symbol *ds; ++ ++ cs = prop_get_symbol(sym_get_choice_prop(sym)); ++ ds = sym_choice_default(cs); ++ if (!sym_is_optional(cs) && sym == ds) { ++ if ((sym->type == S_BOOLEAN) && ++ sym_get_tristate_value(sym) == yes) ++ goto next_menu; ++ } ++ } ++ conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); ++ } ++next_menu: ++ if (menu->list != NULL) { ++ menu = menu->list; ++ } ++ else if (menu->next != NULL) { ++ menu = menu->next; ++ } else { ++ while ((menu = menu->parent)) { ++ if (menu->next != NULL) { ++ menu = menu->next; ++ break; ++ } ++ } ++ } ++ } ++ fclose(out); ++ return 0; ++} ++ + int conf_write(const char *name) + { + FILE *out; + struct symbol *sym; + struct menu *menu; + const char *basename; +- char dirname[128], tmpname[128], newname[128]; +- int type, l; + const char *str; +- time_t now; +- int use_timestamp = 1; +- char *env; ++ char tmpname[PATH_MAX+1], newname[PATH_MAX+1]; ++ char *env, *dirname = NULL; + +- dirname[0] = 0; +- if (name == NULL) +- name = conf_get_configname(); + if (name && name[0]) { + struct stat st; + char *slash; + + if (!stat(name, &st) && S_ISDIR(st.st_mode)) { +- strcpy(dirname, name); ++ dirname = strndup(name, strlen(name) + 1); + strcat(dirname, "/"); + basename = conf_get_configname(); + } else if ((slash = strrchr(name, '/'))) { + int size = slash - name + 1; +- memcpy(dirname, name, size); +- dirname[size] = 0; ++ dirname = strndup(name, size); + if (slash[1]) + basename = slash + 1; + else + basename = conf_get_configname(); + } else + basename = name; +- } else +- basename = conf_get_configname(); +- ++ } else { ++ dirname = strdup(conf_get_configname()); ++ basename = strdup(base_name(dirname)); ++ dirname = dir_name(dirname); ++ } + sprintf(newname, "%s%s", dirname, basename); + env = getenv("KCONFIG_OVERWRITECONFIG"); + if (!env || !*env) { +@@ -434,24 +768,11 @@ + *tmpname = 0; + out = fopen(newname, "w"); + } ++ free(dirname); + if (!out) + return 1; + +- sym = sym_lookup("VERSION", 0); +- sym_calc_value(sym); +- time(&now); +- env = getenv("KCONFIG_NOTIMESTAMP"); +- if (env && *env) +- use_timestamp = 0; +- +- fprintf(out, _("#\n" +- "# Automatically generated make config: don't edit\n" +- "# Version: %s\n" +- "%s%s" +- "#\n"), +- sym_get_string_value(sym), +- use_timestamp ? "# " : "", +- use_timestamp ? ctime(&now) : ""); ++ conf_write_heading(out, &kconfig_printer_cb, NULL); + + if (!conf_get_changed()) + sym_clear_all_valid(); +@@ -472,56 +793,11 @@ + if (!(sym->flags & SYMBOL_WRITE)) + goto next; + sym->flags &= ~SYMBOL_WRITE; +- type = sym->type; +- if (type == S_TRISTATE) { +- sym_calc_value(modules_sym); +- if (modules_sym->curr.tri == no) +- type = S_BOOLEAN; +- } +- switch (type) { +- case S_BOOLEAN: +- case S_TRISTATE: +- switch (sym_get_tristate_value(sym)) { +- case no: +- fprintf(out, "# %s is not set\n", sym->name); +- break; +- case mod: +- fprintf(out, "%s=m\n", sym->name); +- break; +- case yes: +- fprintf(out, "%s=y\n", sym->name); +- break; +- } +- break; +- case S_STRING: +- str = sym_get_string_value(sym); +- fprintf(out, "%s=\"", sym->name); +- while (1) { +- l = strcspn(str, "\"\\"); +- if (l) { +- fwrite(str, l, 1, out); +- str += l; +- } +- if (!*str) +- break; +- fprintf(out, "\\%c", *str++); +- } +- fputs("\"\n", out); +- break; +- case S_HEX: +- str = sym_get_string_value(sym); +- if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { +- fprintf(out, "%s=%s\n", sym->name, str); +- break; +- } +- case S_INT: +- str = sym_get_string_value(sym); +- fprintf(out, "%s=%s\n", sym->name, str); +- break; +- } ++ ++ conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); + } + +- next: ++next: + if (menu->list) { + menu = menu->list; + continue; +@@ -538,38 +814,39 @@ + fclose(out); + + if (*tmpname) { +- strcat(dirname, basename); ++ dirname = strndup(basename, strlen(basename) + 4); + strcat(dirname, ".old"); + rename(newname, dirname); ++ free(dirname); + if (rename(tmpname, newname)) + return 1; + } + +- printf(_("#\n" +- "# configuration written to %s\n" +- "#\n"), newname); ++ conf_message(_("configuration written to %s"), newname); + + sym_set_change_count(0); + + return 0; + } + +-int conf_split_config(void) ++static int conf_split_config(void) + { +- char *name, path[128], opwd[512]; ++ const char *name; ++ char path[PATH_MAX+1], opwd[PATH_MAX+1]; + char *s, *d, c; + struct symbol *sym; + struct stat sb; + int res, i, fd; + +- name = getenv("KCONFIG_AUTOCONFIG"); +- if (!name) +- name = "include/config/auto.conf"; +- conf_read_simple(name, S_DEF_AUTO); +- + if (getcwd(opwd, sizeof(opwd)) == NULL) + return 1; +- if (chdir(dirname(strdup(name)))) ++ name = conf_get_autoconfig_name(); ++ conf_read_simple(name, S_DEF_AUTO); ++ ++ strcpy(path, name); ++ dir_name(path); ++ ++ if (chdir(path)) + return 1; + + res = 0; +@@ -671,126 +948,85 @@ + + int conf_write_autoconf(void) + { +- char opwd[512]; + struct symbol *sym; +- const char *str; +- char *name; +- FILE *out, *out_h; +- time_t now; +- int i, l; ++ const char *name; ++ char cfg_fname[PATH_MAX+1], tristate_fname[PATH_MAX+1], ++ cfgh_fname[PATH_MAX+1]; ++ char *dirname; ++ FILE *out, *tristate, *out_h; ++ int i; + +- if (getcwd(opwd, sizeof(opwd)) == NULL) +- return 1; +- if (chdir(dirname(strdup(conf_get_configname())))) +- return 1; + sym_clear_all_valid(); + +- file_write_dep("include/config/auto.conf.cmd"); ++ sprintf(cfg_fname, "%s.cmd", conf_get_autoconfig_name()); ++ file_write_dep(cfg_fname); + + if (conf_split_config()) + return 1; + +- out = fopen(".tmpconfig", "w"); ++ dirname = dir_name(strdup(conf_get_configname())); ++ sprintf(cfg_fname, "%s.tmpconfig", dirname); ++ sprintf(tristate_fname, "%s.tmpconfig_tristate", dirname); ++ sprintf(cfgh_fname, "%s.tmpconfig.h", dirname); ++ free(dirname); ++ ++ out = fopen(cfg_fname, "w"); + if (!out) + return 1; + +- out_h = fopen(".tmpconfig.h", "w"); ++ tristate = fopen(tristate_fname, "w"); ++ if (!tristate) { ++ fclose(out); ++ return 1; ++ } ++ ++ out_h = fopen(cfgh_fname, "w"); + if (!out_h) { + fclose(out); ++ fclose(tristate); + return 1; + } + +- sym = sym_lookup("VERSION", 0); +- sym_calc_value(sym); +- time(&now); +- fprintf(out, "#\n" +- "# Automatically generated make config: don't edit\n" +- "# Version: %s\n" +- "# %s" +- "#\n", +- sym_get_string_value(sym), ctime(&now)); +- fprintf(out_h, "/*\n" +- " * Automatically generated C config: don't edit\n" +- " * Version: %s\n" +- " * %s" +- " */\n" +- "#define AUTOCONF_INCLUDED\n", +- sym_get_string_value(sym), ctime(&now)); ++ conf_write_heading(out, &kconfig_printer_cb, NULL); ++ ++ conf_write_heading(tristate, &tristate_printer_cb, NULL); ++ ++ conf_write_heading(out_h, &header_printer_cb, NULL); + + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE) || !sym->name) + continue; +- switch (sym->type) { +- case S_BOOLEAN: +- case S_TRISTATE: +- switch (sym_get_tristate_value(sym)) { +- case no: +- break; +- case mod: +- fprintf(out, "CONFIG_%s=m\n", sym->name); +- fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); +- break; +- case yes: +- fprintf(out, "%s=y\n", sym->name); +- fprintf(out_h, "#define %s 1\n", sym->name); +- break; +- } +- break; +- case S_STRING: +- str = sym_get_string_value(sym); +- fprintf(out, "%s=\"", sym->name); +- fprintf(out_h, "#define %s \"", sym->name); +- while (1) { +- l = strcspn(str, "\"\\"); +- if (l) { +- fwrite(str, l, 1, out); +- fwrite(str, l, 1, out_h); +- str += l; +- } +- if (!*str) +- break; +- fprintf(out, "\\%c", *str); +- fprintf(out_h, "\\%c", *str); +- str++; +- } +- fputs("\"\n", out); +- fputs("\"\n", out_h); +- break; +- case S_HEX: +- str = sym_get_string_value(sym); +- if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { +- fprintf(out, "%s=%s\n", sym->name, str); +- fprintf(out_h, "#define %s 0x%s\n", sym->name, str); +- break; +- } +- case S_INT: +- str = sym_get_string_value(sym); +- fprintf(out, "%s=%s\n", sym->name, str); +- fprintf(out_h, "#define %s %s\n", sym->name, str); +- break; +- default: +- break; +- } ++ ++ /* write symbol to auto.conf, tristate and header files */ ++ conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); ++ ++ conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); ++ ++ conf_write_symbol(out_h, sym, &header_printer_cb, NULL); + } + fclose(out); ++ fclose(tristate); + fclose(out_h); + + name = getenv("KCONFIG_AUTOHEADER"); + if (!name) +- name = "include/config/autoconf.h"; +- if (rename(".tmpconfig.h", name)) ++ name = "include/generated/autoconf.h"; ++ if (rename(cfgh_fname, name)) + return 1; +- name = getenv("KCONFIG_AUTOCONFIG"); ++ name = getenv("KCONFIG_TRISTATE"); + if (!name) +- name = "include/config/auto.conf"; ++ name = "include/config/tristate.conf"; ++ if (rename(tristate_fname, 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(cfg_fname, name)) + return 1; +- chdir(opwd); ++ + return 0; + } + +@@ -821,20 +1057,131 @@ + conf_changed_callback = fn; + } + ++static bool randomize_choice_values(struct symbol *csym) ++{ ++ struct property *prop; ++ struct symbol *sym; ++ struct expr *e; ++ int cnt, def; + +-void conf_set_all_new_symbols(enum conf_def_mode mode) ++ /* ++ * If choice is mod then we may have more items selected ++ * and if no then no-one. ++ * In both cases stop. ++ */ ++ if (csym->curr.tri != yes) ++ return false; ++ ++ prop = sym_get_choice_prop(csym); ++ ++ /* count entries in choice block */ ++ cnt = 0; ++ expr_list_for_each_sym(prop->expr, e, sym) ++ cnt++; ++ ++ /* ++ * find a random value and set it to yes, ++ * set the rest to no so we have only one set ++ */ ++ def = (rand() % cnt); ++ ++ cnt = 0; ++ expr_list_for_each_sym(prop->expr, e, sym) { ++ if (def == cnt++) { ++ sym->def[S_DEF_USER].tri = yes; ++ csym->def[S_DEF_USER].val = sym; ++ } ++ else { ++ sym->def[S_DEF_USER].tri = no; ++ } ++ sym->flags |= SYMBOL_DEF_USER; ++ /* clear VALID to get value calculated */ ++ sym->flags &= ~SYMBOL_VALID; ++ } ++ csym->flags |= SYMBOL_DEF_USER; ++ /* clear VALID to get value calculated */ ++ csym->flags &= ~(SYMBOL_VALID); ++ ++ return true; ++} ++ ++void set_all_choice_values(struct symbol *csym) + { +- struct symbol *sym, *csym; + struct property *prop; ++ struct symbol *sym; + struct expr *e; +- int i, cnt, def; ++ ++ prop = sym_get_choice_prop(csym); ++ ++ /* ++ * Set all non-assinged choice values to no ++ */ ++ expr_list_for_each_sym(prop->expr, e, sym) { ++ if (!sym_has_value(sym)) ++ sym->def[S_DEF_USER].tri = no; ++ } ++ csym->flags |= SYMBOL_DEF_USER; ++ /* clear VALID to get value calculated */ ++ csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); ++} ++ ++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 ++ * pty: probability of tristate = y ++ * ptm: probability of tristate = m ++ */ ++ ++ pby = 50; pty = ptm = 33; /* can't go as the default in switch-case ++ * below, otherwise gcc whines about ++ * -Wmaybe-uninitialized */ ++ if (mode == def_random) { ++ int n, p[3]; ++ char *env = getenv("KCONFIG_PROBABILITY"); ++ n = 0; ++ while( env && *env ) { ++ char *endp; ++ int tmp = strtol( env, &endp, 10 ); ++ if( tmp >= 0 && tmp <= 100 ) { ++ p[n++] = tmp; ++ } else { ++ errno = ERANGE; ++ perror( "KCONFIG_PROBABILITY" ); ++ exit( 1 ); ++ } ++ env = (*endp == ':') ? endp+1 : endp; ++ if( n >=3 ) { ++ break; ++ } ++ } ++ switch( n ) { ++ case 1: ++ pby = p[0]; ptm = pby/2; pty = pby-ptm; ++ break; ++ case 2: ++ pty = p[0]; ptm = p[1]; pby = pty + ptm; ++ break; ++ case 3: ++ pby = p[0]; pty = p[1]; ptm = p[2]; ++ break; ++ } ++ ++ if( pty+ptm > 100 ) { ++ errno = ERANGE; ++ perror( "KCONFIG_PROBABILITY" ); ++ exit( 1 ); ++ } ++ } ++ bool has_changed = false; + + for_all_symbols(i, sym) { +- if (sym_has_value(sym)) ++ if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) + continue; + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: ++ has_changed = true; + switch (mode) { + case def_yes: + sym->def[S_DEF_USER].tri = yes; +@@ -846,7 +1193,15 @@ + sym->def[S_DEF_USER].tri = no; + break; + case def_random: +- sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); ++ sym->def[S_DEF_USER].tri = no; ++ cnt = rand() % 100; ++ if (sym->type == S_TRISTATE) { ++ if (cnt < pty) ++ sym->def[S_DEF_USER].tri = yes; ++ else if (cnt < (pty+ptm)) ++ sym->def[S_DEF_USER].tri = mod; ++ } else if (cnt < pby) ++ sym->def[S_DEF_USER].tri = yes; + break; + default: + continue; +@@ -862,51 +1217,35 @@ + + sym_clear_all_valid(); + +- if (mode != def_random) +- return; + /* + * We have different type of choice blocks. +- * If curr.tri equal to mod then we can select several ++ * If curr.tri equals to mod then we can select several + * choice symbols in one block. + * In this case we do nothing. +- * If curr.tri equal yes then only one symbol can be ++ * If curr.tri equals yes then only one symbol can be + * selected in a choice block and we set it to yes, + * and the rest to no. + */ ++ if (mode != def_random) { ++ for_all_symbols(i, csym) { ++ if ((sym_is_choice(csym) && !sym_has_value(csym)) || ++ sym_is_choice_value(csym)) ++ csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; ++ } ++ } ++ + for_all_symbols(i, csym) { + if (sym_has_value(csym) || !sym_is_choice(csym)) + continue; + + sym_calc_value(csym); +- +- if (csym->curr.tri != yes) +- continue; +- +- prop = sym_get_choice_prop(csym); +- +- /* count entries in choice block */ +- cnt = 0; +- expr_list_for_each_sym(prop->expr, e, sym) +- cnt++; +- +- /* +- * find a random value and set it to yes, +- * set the rest to no so we have only one set +- */ +- def = (rand() % cnt); +- +- cnt = 0; +- expr_list_for_each_sym(prop->expr, e, sym) { +- if (def == cnt++) { +- sym->def[S_DEF_USER].tri = yes; +- csym->def[S_DEF_USER].val = sym; +- } +- else { +- sym->def[S_DEF_USER].tri = no; +- } ++ if (mode == def_random) ++ has_changed = randomize_choice_values(csym); ++ else { ++ set_all_choice_values(csym); ++ has_changed = true; + } +- csym->flags |= SYMBOL_DEF_USER; +- /* clear VALID to get value calculated */ +- csym->flags &= ~(SYMBOL_VALID); + } ++ ++ return has_changed; + } +diff -Nur uClibc-0.9.33.2/extra/config/expr.c uClibc-git/extra/config/expr.c +--- uClibc-0.9.33.2/extra/config/expr.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/expr.c 2014-02-03 12:32:56.000000000 +0100 +@@ -7,15 +7,13 @@ + #include + #include + +-#define LKC_DIRECT_LINK + #include "lkc.h" + + #define DEBUG_EXPR 0 + + struct expr *expr_alloc_symbol(struct symbol *sym) + { +- struct expr *e = malloc(sizeof(*e)); +- memset(e, 0, sizeof(*e)); ++ struct expr *e = xcalloc(1, sizeof(*e)); + e->type = E_SYMBOL; + e->left.sym = sym; + return e; +@@ -23,8 +21,7 @@ + + struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) + { +- struct expr *e = malloc(sizeof(*e)); +- memset(e, 0, sizeof(*e)); ++ struct expr *e = xcalloc(1, sizeof(*e)); + e->type = type; + e->left.expr = ce; + return e; +@@ -32,8 +29,7 @@ + + struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) + { +- struct expr *e = malloc(sizeof(*e)); +- memset(e, 0, sizeof(*e)); ++ struct expr *e = xcalloc(1, sizeof(*e)); + e->type = type; + e->left.expr = e1; + e->right.expr = e2; +@@ -42,8 +38,7 @@ + + struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) + { +- struct expr *e = malloc(sizeof(*e)); +- memset(e, 0, sizeof(*e)); ++ struct expr *e = xcalloc(1, sizeof(*e)); + e->type = type; + e->left.sym = s1; + e->right.sym = s2; +@@ -64,14 +59,14 @@ + return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; + } + +-struct expr *expr_copy(struct expr *org) ++struct expr *expr_copy(const struct expr *org) + { + struct expr *e; + + if (!org) + return NULL; + +- e = malloc(sizeof(*org)); ++ e = xmalloc(sizeof(*org)); + memcpy(e, org, sizeof(*org)); + switch (org->type) { + case E_SYMBOL: +@@ -348,7 +343,7 @@ + /* + * e1 || e2 -> ? + */ +-struct expr *expr_join_or(struct expr *e1, struct expr *e2) ++static struct expr *expr_join_or(struct expr *e1, struct expr *e2) + { + struct expr *tmp; + struct symbol *sym1, *sym2; +@@ -412,7 +407,7 @@ + return NULL; + } + +-struct expr *expr_join_and(struct expr *e1, struct expr *e2) ++static struct expr *expr_join_and(struct expr *e1, struct expr *e2) + { + struct expr *tmp; + struct symbol *sym1, *sym2; +@@ -1013,6 +1008,48 @@ + #endif + } + ++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) + { + if (!e) { +@@ -1087,7 +1124,7 @@ + + static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) + { +- fwrite(str, strlen(str), 1, data); ++ xfwrite(str, strlen(str), 1, data); + } + + void expr_fprint(struct expr *e, FILE *out) +@@ -1097,7 +1134,32 @@ + + static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) + { +- str_append((struct gstr*)data, str); ++ struct gstr *gs = (struct gstr*)data; ++ const char *sym_str = NULL; ++ ++ if (sym) ++ sym_str = sym_get_string_value(sym); ++ ++ if (gs->max_width) { ++ unsigned extra_length = strlen(str); ++ const char *last_cr = strrchr(gs->s, '\n'); ++ unsigned last_line_length; ++ ++ if (sym_str) ++ extra_length += 4 + strlen(sym_str); ++ ++ if (!last_cr) ++ last_cr = gs->s; ++ ++ last_line_length = strlen(gs->s) - (last_cr - gs->s); ++ ++ if ((last_line_length + extra_length) > gs->max_width) ++ str_append(gs, "\\\n"); ++ } ++ ++ str_append(gs, str); ++ if (sym && sym->type != S_UNKNOWN) ++ str_printf(gs, " [=%s]", sym_str); + } + + void expr_gstr_print(struct expr *e, struct gstr *gs) +diff -Nur uClibc-0.9.33.2/extra/config/expr.h uClibc-git/extra/config/expr.h +--- uClibc-0.9.33.2/extra/config/expr.h 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/expr.h 2014-02-03 12:32:56.000000000 +0100 +@@ -10,7 +10,9 @@ + extern "C" { + #endif + ++#include + #include ++#include "list.h" + #ifndef __cplusplus + #include + #endif +@@ -18,14 +20,10 @@ + struct file { + struct file *next; + struct file *parent; +- char *name; ++ const char *name; + int lineno; +- int flags; + }; + +-#define FILE_BUSY 0x0001 +-#define FILE_SCANNED 0x0002 +- + typedef enum tristate { + no, mod, yes + } tristate; +@@ -83,10 +81,11 @@ + tristate visible; + int flags; + struct property *prop; ++ struct expr_value dir_dep; + struct expr_value rev_dep; + }; + +-#define for_all_symbols(i, sym) for (i = 0; i < 257; 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) if (sym->type != S_OTHER) + + #define SYMBOL_CONST 0x0001 /* symbol is const */ + #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ +@@ -107,9 +106,11 @@ + #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ + #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ + ++/* choice values need to be set before calculating this symbol value */ ++#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000 ++ + #define SYMBOL_MAXLENGTH 256 +-#define SYMBOL_HASHSIZE 257 +-#define SYMBOL_HASHMASK 0xff ++#define SYMBOL_HASHSIZE 9973 + + /* A property represent the config options that can be associated + * with a config "symbol". +@@ -132,6 +133,7 @@ + P_SELECT, /* select BAR */ + P_RANGE, /* range 7..100 (for a symbol) */ + P_ENV, /* value from environment variable */ ++ P_SYMBOL, /* where a symbol is defined */ + }; + + struct property { +@@ -163,6 +165,7 @@ + struct menu *list; + struct symbol *sym; + struct property *prompt; ++ struct expr *visibility; + struct expr *dep; + unsigned int flags; + char *help; +@@ -174,7 +177,14 @@ + #define MENU_CHANGED 0x0001 + #define MENU_ROOT 0x0002 + +-#ifndef SWIG ++struct jump_key { ++ struct list_head entries; ++ size_t offset; ++ struct menu *target; ++ int index; ++}; ++ ++#define JUMP_NB 9 + + extern struct file *file_list; + extern struct file *current_file; +@@ -190,7 +200,7 @@ + struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); + struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); + struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); +-struct expr *expr_copy(struct expr *org); ++struct expr *expr_copy(const struct expr *org); + void expr_free(struct expr *e); + int expr_eq(struct expr *e1, struct expr *e2); + void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); +@@ -205,6 +215,7 @@ + struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); + void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); + 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 */ +@@ -219,7 +230,6 @@ + { + return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); + } +-#endif + + #ifdef __cplusplus + } +diff -Nur uClibc-0.9.33.2/extra/config/gconf.c uClibc-git/extra/config/gconf.c +--- uClibc-0.9.33.2/extra/config/gconf.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/gconf.c 2014-02-03 12:32:56.000000000 +0100 +@@ -10,6 +10,7 @@ + # include + #endif + ++#include + #include "lkc.h" + #include "images.c" + +@@ -22,7 +23,6 @@ + #include + #include + #include +-#include + + //#define DEBUG + +@@ -30,13 +30,16 @@ + SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW + }; + ++enum { ++ OPT_NORMAL, OPT_ALL, OPT_PROMPT ++}; ++ + static gint view_mode = FULL_VIEW; + static gboolean show_name = TRUE; + static gboolean show_range = TRUE; + static gboolean show_value = TRUE; +-static gboolean show_all = FALSE; +-static gboolean show_debug = FALSE; + static gboolean resizeable = FALSE; ++static int opt_mode = OPT_NORMAL; + + GtkWidget *main_wnd = NULL; + GtkWidget *tree1_w = NULL; // left frame +@@ -76,36 +79,7 @@ + + /* Helping/Debugging Functions */ + +- +-const char *dbg_print_stype(int val) +-{ +- static char buf[256]; +- +- bzero(buf, 256); +- +- if (val == S_UNKNOWN) +- strcpy(buf, "unknown"); +- if (val == S_BOOLEAN) +- strcpy(buf, "boolean"); +- if (val == S_TRISTATE) +- strcpy(buf, "tristate"); +- if (val == S_INT) +- strcpy(buf, "int"); +- if (val == S_HEX) +- strcpy(buf, "hex"); +- if (val == S_STRING) +- strcpy(buf, "string"); +- if (val == S_OTHER) +- strcpy(buf, "other"); +- +-#ifdef DEBUG +- printf("%s", buf); +-#endif +- +- return buf; +-} +- +-const char *dbg_print_flags(int val) ++const char *dbg_sym_flags(int val) + { + static char buf[256]; + +@@ -131,40 +105,10 @@ + strcat(buf, "auto/"); + + buf[strlen(buf) - 1] = '\0'; +-#ifdef DEBUG +- printf("%s", buf); +-#endif + + return buf; + } + +-const char *dbg_print_ptype(int val) +-{ +- static char buf[256]; +- +- bzero(buf, 256); +- +- if (val == P_UNKNOWN) +- strcpy(buf, "unknown"); +- if (val == P_PROMPT) +- strcpy(buf, "prompt"); +- if (val == P_COMMENT) +- strcpy(buf, "comment"); +- if (val == P_MENU) +- strcpy(buf, "menu"); +- if (val == P_DEFAULT) +- strcpy(buf, "default"); +- if (val == P_CHOICE) +- strcpy(buf, "choice"); +- +-#ifdef DEBUG +- printf("%s", buf); +-#endif +- +- return buf; +-} +- +- + void replace_button_icon(GladeXML * xml, GdkDrawable * window, + GtkStyle * style, gchar * btn_name, gchar ** xpm) + { +@@ -189,7 +133,6 @@ + GladeXML *xml; + GtkWidget *widget; + GtkTextBuffer *txtbuf; +- char title[256]; + GtkStyle *style; + + xml = glade_xml_new(glade_file, "window1", NULL); +@@ -266,9 +209,7 @@ + /*"style", PANGO_STYLE_OBLIQUE, */ + NULL); + +- sprintf(title, _("uClibc v%s Configuration"), +- getenv("VERSION")); +- gtk_window_set_title(GTK_WINDOW(main_wnd), title); ++ gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text); + + gtk_widget_show(main_wnd); + } +@@ -312,7 +253,7 @@ + + gtk_tree_view_set_model(view, model1); + gtk_tree_view_set_headers_visible(view, TRUE); +- gtk_tree_view_set_rules_hint(view, FALSE); ++ gtk_tree_view_set_rules_hint(view, TRUE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); +@@ -344,8 +285,6 @@ + static void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data); +-static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle, +- gchar * arg1, gpointer user_data); + + void init_right_tree(void) + { +@@ -357,7 +296,7 @@ + + gtk_tree_view_set_model(view, model2); + gtk_tree_view_set_headers_visible(view, TRUE); +- gtk_tree_view_set_rules_hint(view, FALSE); ++ gtk_tree_view_set_rules_hint(view, TRUE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); +@@ -379,8 +318,6 @@ + "inconsistent", COL_BTNINC, + "visible", COL_BTNVIS, + "radio", COL_BTNRAD, NULL); +- /*g_signal_connect(G_OBJECT(renderer), "toggled", +- G_CALLBACK(renderer_toggled), NULL); */ + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); +@@ -456,19 +393,9 @@ + GtkTextBuffer *buffer; + GtkTextIter start, end; + const char *prompt = _(menu_get_prompt(menu)); +- gchar *name; +- const char *help; +- +- help = menu_get_help(menu); +- +- /* Gettextize if the help text not empty */ +- if ((help != 0) && (help[0] != 0)) +- help = _(help); ++ struct gstr help = str_new(); + +- if (menu->sym && menu->sym->name) +- name = g_strdup_printf(menu->sym->name); +- else +- name = g_strdup(""); ++ menu_get_ext_help(menu, &help); + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + gtk_text_buffer_get_bounds(buffer, &start, &end); +@@ -478,14 +405,11 @@ + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, + NULL); +- gtk_text_buffer_insert_at_cursor(buffer, " ", 1); +- gtk_text_buffer_get_end_iter(buffer, &end); +- gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1, +- NULL); + gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); + gtk_text_buffer_get_end_iter(buffer, &end); +- gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2, ++ gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2, + NULL); ++ str_free(&help); + } + + +@@ -710,20 +634,29 @@ + + + void +-on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) ++on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data) + { +- show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; ++ opt_mode = OPT_NORMAL; ++ gtk_tree_store_clear(tree2); ++ display_tree(&rootmenu); /* instead of update_tree to speed-up */ ++} + ++ ++void ++on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data) ++{ ++ opt_mode = OPT_ALL; + gtk_tree_store_clear(tree2); +- display_tree(&rootmenu); // instead of update_tree to speed-up ++ display_tree(&rootmenu); /* instead of update_tree to speed-up */ + } + + + void +-on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) ++on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) + { +- show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; +- update_tree(&rootmenu, NULL); ++ opt_mode = OPT_PROMPT; ++ gtk_tree_store_clear(tree2); ++ display_tree(&rootmenu); /* instead of update_tree to speed-up */ + } + + +@@ -732,7 +665,6 @@ + GtkWidget *dialog; + const gchar *intro_text = _( + "Welcome to gkc, the GTK+ graphical configuration tool\n" +- "for uClibc.\n" + "For each option, a blank box indicates the feature is disabled, a\n" + "check indicates it is enabled, and a dot indicates that it is to\n" + "be compiled as a module. Clicking on the box will cycle through the three states.\n" +@@ -751,7 +683,7 @@ + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, +- GTK_BUTTONS_CLOSE, intro_text); ++ GTK_BUTTONS_CLOSE, "%s", intro_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); +@@ -769,7 +701,7 @@ + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, +- GTK_BUTTONS_CLOSE, about_text); ++ GTK_BUTTONS_CLOSE, "%s", about_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); +@@ -788,7 +720,7 @@ + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, +- GTK_BUTTONS_CLOSE, license_text); ++ GTK_BUTTONS_CLOSE, "%s", license_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); +@@ -820,7 +752,6 @@ + void on_single_clicked(GtkButton * button, gpointer user_data) + { + view_mode = SINGLE_VIEW; +- gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + current = &rootmenu; + display_tree_part(); +@@ -846,7 +777,6 @@ + void on_full_clicked(GtkButton * button, gpointer user_data) + { + view_mode = FULL_VIEW; +- gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + if (tree2) + gtk_tree_store_clear(tree2); +@@ -900,7 +830,7 @@ + static void change_sym_value(struct menu *menu, gint col) + { + struct symbol *sym = menu->sym; +- tristate oldval, newval; ++ tristate newval; + + if (!sym) + return; +@@ -917,7 +847,6 @@ + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: +- oldval = sym_get_tristate_value(sym); + if (!sym_tristate_within_range(sym, newval)) + newval = yes; + sym_set_tristate_value(sym, newval); +@@ -954,35 +883,6 @@ + display_tree_part(); //fixme: keep exp/coll + } + +-static void renderer_toggled(GtkCellRendererToggle * cell, +- gchar * path_string, gpointer user_data) +-{ +- GtkTreePath *path, *sel_path = NULL; +- GtkTreeIter iter, sel_iter; +- GtkTreeSelection *sel; +- struct menu *menu; +- +- path = gtk_tree_path_new_from_string(path_string); +- if (!gtk_tree_model_get_iter(model2, &iter, path)) +- return; +- +- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w)); +- if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter)) +- sel_path = gtk_tree_model_get_path(model2, &sel_iter); +- if (!sel_path) +- goto out1; +- if (gtk_tree_path_compare(path, sel_path)) +- goto out2; +- +- gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); +- toggle_sym_value(menu); +- +- out2: +- gtk_tree_path_free(sel_path); +- out1: +- gtk_tree_path_free(path); +-} +- + static gint column2index(GtkTreeViewColumn * column) + { + gint i; +@@ -1174,9 +1074,12 @@ + + row[COL_OPTION] = + g_strdup_printf("%s %s", _(menu_get_prompt(menu)), +- sym && sym_has_value(sym) ? "(NEW)" : ""); ++ sym && !sym_has_value(sym) ? "(NEW)" : ""); + +- if (show_all && !menu_is_visible(menu)) ++ if (opt_mode == OPT_ALL && !menu_is_visible(menu)) ++ row[COL_COLOR] = g_strdup("DarkGray"); ++ else if (opt_mode == OPT_PROMPT && ++ menu_has_prompt(menu) && !menu_is_visible(menu)) + row[COL_COLOR] = g_strdup("DarkGray"); + else + row[COL_COLOR] = g_strdup("Black"); +@@ -1235,6 +1138,7 @@ + row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); + if (sym_is_choice(sym)) + break; ++ /* fall through */ + case S_TRISTATE: + val = sym_get_tristate_value(sym); + switch (val) { +@@ -1373,7 +1277,6 @@ + gboolean valid; + GtkTreeIter *sibling; + struct symbol *sym; +- struct property *prop; + struct menu *menu1, *menu2; + + if (src == &rootmenu) +@@ -1382,7 +1285,6 @@ + valid = gtk_tree_model_iter_children(model2, child2, dst); + for (child1 = src->list; child1; child1 = child1->next) { + +- prop = child1->prompt; + sym = child1->sym; + + reparse: +@@ -1399,16 +1301,20 @@ + menu2 ? menu_get_prompt(menu2) : "nil"); + #endif + +- if (!menu_is_visible(child1) && !show_all) { // remove node ++ if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || ++ (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) || ++ (opt_mode == OPT_ALL && !menu_get_prompt(child1))) { ++ ++ /* remove node */ + if (gtktree_iter_find_node(dst, menu1) != NULL) { + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree2, &tmp); + if (!valid) +- return; // next parent ++ return; /* next parent */ + else +- goto reparse; // next child ++ goto reparse; /* next child */ + } else + continue; + } +@@ -1477,17 +1383,19 @@ + && (tree == tree2)) + continue; + +- if (menu_is_visible(child) || show_all) ++ if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) || ++ (opt_mode == OPT_PROMPT && menu_has_prompt(child)) || ++ (opt_mode == OPT_ALL && menu_get_prompt(child))) + place_node(child, fill_row(child)); + #ifdef DEBUG + printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); + printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); +- dbg_print_ptype(ptype); ++ printf("%s", prop_get_type_name(ptype)); + printf(" | "); + if (sym) { +- dbg_print_stype(sym->type); ++ printf("%s", sym_type_name(sym->type)); + printf(" | "); +- dbg_print_flags(sym->flags); ++ printf("%s", dbg_sym_flags(sym->flags)); + printf("\n"); + } else + printf("\n"); +@@ -1499,6 +1407,12 @@ + if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW))*/ ++ ++ /* Change paned position if the view is not in 'split mode' */ ++ if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) { ++ gtk_paned_set_position(GTK_PANED(hpaned), 0); ++ } ++ + if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW)) { +@@ -1557,10 +1471,6 @@ + char *env; + gchar *glade_file; + +-#ifndef LKC_DIRECT_LINK +- kconfig_load(); +-#endif +- + bindtextdomain(PACKAGE, LOCALEDIR); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + textdomain(PACKAGE); +@@ -1582,12 +1492,6 @@ + else + glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL); + +- /* Load the interface and connect signals */ +- init_main_window(glade_file); +- init_tree_model(); +- init_left_tree(); +- init_right_tree(); +- + /* Conf stuffs */ + if (ac > 1 && av[1][0] == '-') { + switch (av[1][1]) { +@@ -1607,6 +1511,12 @@ + fixup_rootmenu(&rootmenu); + conf_read(NULL); + ++ /* Load the interface and connect signals */ ++ init_main_window(glade_file); ++ init_tree_model(); ++ init_left_tree(); ++ init_right_tree(); ++ + switch (view_mode) { + case SINGLE_VIEW: + display_tree_part(); +diff -Nur uClibc-0.9.33.2/extra/config/gconf.glade uClibc-git/extra/config/gconf.glade +--- uClibc-0.9.33.2/extra/config/gconf.glade 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/gconf.glade 2014-02-03 12:32:56.000000000 +0100 +@@ -1,11 +1,10 @@ + +- + + + + + True +- Gtk uClibc Configurator ++ Gtk uCLibc Configurator + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False +@@ -190,26 +189,40 @@ + + + +- ++ ++ True ++ Show normal options ++ Show normal options ++ True ++ True ++ ++ ++ ++ ++ ++ + True + Show all options + Show all _options + True + False +- ++ set_option_mode1 ++ + + + + +- ++ + True +- Show masked options +- Show _debug info ++ Show all options with prompts ++ Show all prompt options + True + False +- ++ set_option_mode1 ++ + + ++ + + + +@@ -547,7 +560,7 @@ + True + False + False +- True ++ False + + + +@@ -582,7 +595,7 @@ + True + False + False +- True ++ False + + + +diff -Nur uClibc-0.9.33.2/extra/config/.gitignore uClibc-git/extra/config/.gitignore +--- uClibc-0.9.33.2/extra/config/.gitignore 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/.gitignore 2014-02-03 12:32:56.000000000 +0100 +@@ -2,18 +2,21 @@ + # Generated files + # + config* +-lex.*.c ++*.lex.c + *.tab.c + *.tab.h + zconf.hash.c + *.moc +-lkc_defs.h ++gconf.glade.h ++*.pot ++*.mo + + # + # configuration programs + # + conf + mconf ++nconf + qconf + gconf + kxgettext +diff -Nur uClibc-0.9.33.2/extra/config/kconfig-language.txt uClibc-git/extra/config/kconfig-language.txt +--- uClibc-0.9.33.2/extra/config/kconfig-language.txt 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/kconfig-language.txt 2014-02-03 12:32:56.000000000 +0100 +@@ -112,7 +112,13 @@ + (no prompts anywhere) and for symbols with no dependencies. + That will limit the usefulness but on the other hand avoid + the illegal configurations all over. +- kconfig should one day warn about such things. ++ ++- limiting menu display: "visible if" ++ This attribute is only applicable to menu blocks, if the condition is ++ false, the menu block is not displayed to the user (the symbols ++ contained there can still be selected by other symbols, though). It is ++ similar to a conditional "prompt" attribute for individual menu ++ entries. Default value of "visible" is true. + + - numerical ranges: "range" ["if" ] + This allows to limit the range of possible input values for int +@@ -181,7 +187,7 @@ + (7) Returns the result of max(/expr/, /expr/). + + An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 +-respectively for calculations). A menu entry becomes visible when it's ++respectively for calculations). A menu entry becomes visible when its + expression evaluates to 'm' or 'y'. + + There are two types of symbols: constant and non-constant symbols. +@@ -268,7 +274,7 @@ + + choices: + +- "choice" ++ "choice" [symbol] + + + "endchoice" +@@ -282,6 +288,10 @@ + can be compiled as modules. + A choice accepts another option "optional", which allows to set the + choice to 'n' and no entry needs to be selected. ++If no [symbol] is associated with a choice, then you can not have multiple ++definitions of that choice. If a [symbol] is associated to the choice, ++then you may define the same choice (ie. with the same entries) in another ++place. + + comment: + +@@ -300,7 +310,8 @@ + "endmenu" + + This defines a menu block, see "Menu structure" above for more +-information. The only possible options are dependencies. ++information. The only possible options are dependencies and "visible" ++attributes. + + if: + +@@ -322,7 +333,8 @@ + "mainmenu" + + This sets the config program's title bar if the config program chooses +-to use it. ++to use it. It should be placed at the top of the configuration, before any ++other statement. + + + Kconfig hints +@@ -376,4 +388,3 @@ + depends on BAR && m + + limits FOO to module (=m) or disabled (=n). +- +diff -Nur uClibc-0.9.33.2/extra/config/kconfig_load.c uClibc-git/extra/config/kconfig_load.c +--- uClibc-0.9.33.2/extra/config/kconfig_load.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/kconfig_load.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,35 +0,0 @@ +-#include +-#include +-#include +- +-#include "lkc.h" +- +-#define P(name,type,arg) type (*name ## _p) arg +-#include "lkc_proto.h" +-#undef P +- +-void kconfig_load(void) +-{ +- void *handle; +- char *error; +- +- handle = dlopen("./libkconfig.so", RTLD_LAZY); +- if (!handle) { +- handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY); +- if (!handle) { +- fprintf(stderr, "%s\n", dlerror()); +- exit(1); +- } +- } +- +-#define P(name,type,arg) \ +-{ \ +- name ## _p = dlsym(handle, #name); \ +- if ((error = dlerror())) { \ +- fprintf(stderr, "%s\n", error); \ +- exit(1); \ +- } \ +-} +-#include "lkc_proto.h" +-#undef P +-} +Binary files uClibc-0.9.33.2/extra/config/kconfig-to-uclibc.patch.gz and uClibc-git/extra/config/kconfig-to-uclibc.patch.gz differ +Binary files uClibc-0.9.33.2/extra/config/kconfig-to-uclibc.tar.gz and uClibc-git/extra/config/kconfig-to-uclibc.tar.gz differ +diff -Nur uClibc-0.9.33.2/extra/config/kxgettext.c uClibc-git/extra/config/kxgettext.c +--- uClibc-0.9.33.2/extra/config/kxgettext.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/kxgettext.c 2014-02-03 12:32:56.000000000 +0100 +@@ -7,7 +7,6 @@ + #include + #include + +-#define LKC_DIRECT_LINK + #include "lkc.h" + + static char *escape(const char* text, char *bf, int len) +@@ -43,6 +42,10 @@ + ++text; + goto next; + } ++ else if (*text == '\\') { ++ *bfp++ = '\\'; ++ len--; ++ } + *bfp++ = *text++; + next: + --len; +@@ -59,11 +62,11 @@ + + struct file_line { + struct file_line *next; +- char* file; +- int lineno; ++ const char *file; ++ int lineno; + }; + +-static struct file_line *file_line__new(char *file, int lineno) ++static struct file_line *file_line__new(const char *file, int lineno) + { + struct file_line *self = malloc(sizeof(*self)); + +@@ -86,7 +89,8 @@ + + static struct message *message__list; + +-static struct message *message__new(const char *msg, char *option, char *file, int lineno) ++static struct message *message__new(const char *msg, char *option, ++ const char *file, int lineno) + { + struct message *self = malloc(sizeof(*self)); + +@@ -126,7 +130,8 @@ + return m; + } + +-static int message__add_file_line(struct message *self, char *file, int lineno) ++static int message__add_file_line(struct message *self, const char *file, ++ int lineno) + { + int rc = -1; + struct file_line *fl = file_line__new(file, lineno); +@@ -141,7 +146,8 @@ + return rc; + } + +-static int message__add(const char *msg, char *option, char *file, int lineno) ++static int message__add(const char *msg, char *option, const char *file, ++ int lineno) + { + int rc = 0; + char bf[16384]; +@@ -162,7 +168,7 @@ + return rc; + } + +-void menu_build_message_list(struct menu *menu) ++static void menu_build_message_list(struct menu *menu) + { + struct menu *child; + +@@ -207,7 +213,7 @@ + "msgstr \"\"\n", self->msg); + } + +-void menu__xgettext(void) ++static void menu__xgettext(void) + { + struct message *m = message__list; + +diff -Nur uClibc-0.9.33.2/extra/config/lex.zconf.c_shipped uClibc-git/extra/config/lex.zconf.c_shipped +--- uClibc-0.9.33.2/extra/config/lex.zconf.c_shipped 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lex.zconf.c_shipped 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2416 +0,0 @@ +- +-#line 3 "scripts/kconfig/lex.zconf.c" +- +-#define YY_INT_ALIGNED short int +- +-/* A lexical scanner generated by flex */ +- +-#define yy_create_buffer zconf_create_buffer +-#define yy_delete_buffer zconf_delete_buffer +-#define yy_flex_debug zconf_flex_debug +-#define yy_init_buffer zconf_init_buffer +-#define yy_flush_buffer zconf_flush_buffer +-#define yy_load_buffer_state zconf_load_buffer_state +-#define yy_switch_to_buffer zconf_switch_to_buffer +-#define yyin zconfin +-#define yyleng zconfleng +-#define yylex zconflex +-#define yylineno zconflineno +-#define yyout zconfout +-#define yyrestart zconfrestart +-#define yytext zconftext +-#define yywrap zconfwrap +-#define yyalloc zconfalloc +-#define yyrealloc zconfrealloc +-#define yyfree zconffree +- +-#define FLEX_SCANNER +-#define YY_FLEX_MAJOR_VERSION 2 +-#define YY_FLEX_MINOR_VERSION 5 +-#define YY_FLEX_SUBMINOR_VERSION 35 +-#if YY_FLEX_SUBMINOR_VERSION > 0 +-#define FLEX_BETA +-#endif +- +-/* First, we deal with platform-specific or compiler-specific issues. */ +- +-/* begin standard C headers. */ +-#include +-#include +-#include +-#include +- +-/* end standard C headers. */ +- +-/* flex integer type definitions */ +- +-#ifndef FLEXINT_H +-#define FLEXINT_H +- +-/* C99 systems have . Non-C99 systems may or may not. */ +- +-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +- +-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, +- * if you want the limit (max/min) macros for int types. +- */ +-#ifndef __STDC_LIMIT_MACROS +-#define __STDC_LIMIT_MACROS 1 +-#endif +- +-#include +-typedef int8_t flex_int8_t; +-typedef uint8_t flex_uint8_t; +-typedef int16_t flex_int16_t; +-typedef uint16_t flex_uint16_t; +-typedef int32_t flex_int32_t; +-typedef uint32_t flex_uint32_t; +-#else +-typedef signed char flex_int8_t; +-typedef short int flex_int16_t; +-typedef int flex_int32_t; +-typedef unsigned char flex_uint8_t; +-typedef unsigned short int flex_uint16_t; +-typedef unsigned int flex_uint32_t; +- +-/* Limits of integral types. */ +-#ifndef INT8_MIN +-#define INT8_MIN (-128) +-#endif +-#ifndef INT16_MIN +-#define INT16_MIN (-32767-1) +-#endif +-#ifndef INT32_MIN +-#define INT32_MIN (-2147483647-1) +-#endif +-#ifndef INT8_MAX +-#define INT8_MAX (127) +-#endif +-#ifndef INT16_MAX +-#define INT16_MAX (32767) +-#endif +-#ifndef INT32_MAX +-#define INT32_MAX (2147483647) +-#endif +-#ifndef UINT8_MAX +-#define UINT8_MAX (255U) +-#endif +-#ifndef UINT16_MAX +-#define UINT16_MAX (65535U) +-#endif +-#ifndef UINT32_MAX +-#define UINT32_MAX (4294967295U) +-#endif +- +-#endif /* ! C99 */ +- +-#endif /* ! FLEXINT_H */ +- +-#ifdef __cplusplus +- +-/* The "const" storage-class-modifier is valid. */ +-#define YY_USE_CONST +- +-#else /* ! __cplusplus */ +- +-/* C99 requires __STDC__ to be defined as 1. */ +-#if defined (__STDC__) +- +-#define YY_USE_CONST +- +-#endif /* defined (__STDC__) */ +-#endif /* ! __cplusplus */ +- +-#ifdef YY_USE_CONST +-#define yyconst const +-#else +-#define yyconst +-#endif +- +-/* Returned upon end-of-file. */ +-#define YY_NULL 0 +- +-/* Promotes a possibly negative, possibly signed char to an unsigned +- * integer for use as an array index. If the signed char is negative, +- * we want to instead treat it as an 8-bit unsigned char, hence the +- * double cast. +- */ +-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +- +-/* Enter a start condition. This macro really ought to take a parameter, +- * but we do it the disgusting crufty way forced on us by the ()-less +- * definition of BEGIN. +- */ +-#define BEGIN (yy_start) = 1 + 2 * +- +-/* Translate the current start state into a value that can be later handed +- * to BEGIN to return to the state. The YYSTATE alias is for lex +- * compatibility. +- */ +-#define YY_START (((yy_start) - 1) / 2) +-#define YYSTATE YY_START +- +-/* Action number for EOF rule of a given start state. */ +-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +- +-/* Special action meaning "start processing a new file". */ +-#define YY_NEW_FILE zconfrestart(zconfin ) +- +-#define YY_END_OF_BUFFER_CHAR 0 +- +-/* Size of default input buffer. */ +-#ifndef YY_BUF_SIZE +-#define YY_BUF_SIZE 16384 +-#endif +- +-/* The state buf must be large enough to hold one state per character in the main buffer. +- */ +-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) +- +-#ifndef YY_TYPEDEF_YY_BUFFER_STATE +-#define YY_TYPEDEF_YY_BUFFER_STATE +-typedef struct yy_buffer_state *YY_BUFFER_STATE; +-#endif +- +-extern int zconfleng; +- +-extern FILE *zconfin, *zconfout; +- +-#define EOB_ACT_CONTINUE_SCAN 0 +-#define EOB_ACT_END_OF_FILE 1 +-#define EOB_ACT_LAST_MATCH 2 +- +- #define YY_LESS_LINENO(n) +- +-/* Return all but the first "n" matched characters back to the input stream. */ +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up zconftext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- *yy_cp = (yy_hold_char); \ +- YY_RESTORE_YY_MORE_OFFSET \ +- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ +- YY_DO_BEFORE_ACTION; /* set up zconftext again */ \ +- } \ +- while ( 0 ) +- +-#define unput(c) yyunput( c, (yytext_ptr) ) +- +-#ifndef YY_TYPEDEF_YY_SIZE_T +-#define YY_TYPEDEF_YY_SIZE_T +-typedef size_t yy_size_t; +-#endif +- +-#ifndef YY_STRUCT_YY_BUFFER_STATE +-#define YY_STRUCT_YY_BUFFER_STATE +-struct yy_buffer_state +- { +- FILE *yy_input_file; +- +- char *yy_ch_buf; /* input buffer */ +- char *yy_buf_pos; /* current position in input buffer */ +- +- /* Size of input buffer in bytes, not including room for EOB +- * characters. +- */ +- yy_size_t yy_buf_size; +- +- /* Number of characters read into yy_ch_buf, not including EOB +- * characters. +- */ +- int yy_n_chars; +- +- /* Whether we "own" the buffer - i.e., we know we created it, +- * and can realloc() it to grow it, and should free() it to +- * delete it. +- */ +- int yy_is_our_buffer; +- +- /* Whether this is an "interactive" input source; if so, and +- * if we're using stdio for input, then we want to use getc() +- * instead of fread(), to make sure we stop fetching input after +- * each newline. +- */ +- int yy_is_interactive; +- +- /* Whether we're considered to be at the beginning of a line. +- * If so, '^' rules will be active on the next match, otherwise +- * not. +- */ +- int yy_at_bol; +- +- int yy_bs_lineno; /**< The line count. */ +- int yy_bs_column; /**< The column count. */ +- +- /* Whether to try to fill the input buffer when we reach the +- * end of it. +- */ +- int yy_fill_buffer; +- +- int yy_buffer_status; +- +-#define YY_BUFFER_NEW 0 +-#define YY_BUFFER_NORMAL 1 +- /* When an EOF's been seen but there's still some text to process +- * then we mark the buffer as YY_EOF_PENDING, to indicate that we +- * shouldn't try reading from the input source any more. We might +- * still have a bunch of tokens to match, though, because of +- * possible backing-up. +- * +- * When we actually see the EOF, we change the status to "new" +- * (via zconfrestart()), so that the user can continue scanning by +- * just pointing zconfin at a new input file. +- */ +-#define YY_BUFFER_EOF_PENDING 2 +- +- }; +-#endif /* !YY_STRUCT_YY_BUFFER_STATE */ +- +-/* Stack of input buffers. */ +-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ +- +-/* We provide macros for accessing buffer states in case in the +- * future we want to put the buffer states in a more general +- * "scanner state". +- * +- * Returns the top of the stack, or NULL. +- */ +-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ +- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ +- : NULL) +- +-/* Same as previous macro, but useful when we know that the buffer stack is not +- * NULL or when we need an lvalue. For internal use only. +- */ +-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] +- +-/* yy_hold_char holds the character lost when zconftext is formed. */ +-static char yy_hold_char; +-static int yy_n_chars; /* number of characters read into yy_ch_buf */ +-int zconfleng; +- +-/* Points to current character in buffer. */ +-static char *yy_c_buf_p = (char *) 0; +-static int yy_init = 0; /* whether we need to initialize */ +-static int yy_start = 0; /* start state number */ +- +-/* Flag which is used to allow zconfwrap()'s to do buffer switches +- * instead of setting up a fresh zconfin. A bit of a hack ... +- */ +-static int yy_did_buffer_switch_on_eof; +- +-void zconfrestart (FILE *input_file ); +-void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +-YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size ); +-void zconf_delete_buffer (YY_BUFFER_STATE b ); +-void zconf_flush_buffer (YY_BUFFER_STATE b ); +-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ); +-void zconfpop_buffer_state (void ); +- +-static void zconfensure_buffer_stack (void ); +-static void zconf_load_buffer_state (void ); +-static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file ); +- +-#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER ) +- +-YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size ); +-YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len ); +- +-void *zconfalloc (yy_size_t ); +-void *zconfrealloc (void *,yy_size_t ); +-void zconffree (void * ); +- +-#define yy_new_buffer zconf_create_buffer +- +-#define yy_set_interactive(is_interactive) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){ \ +- zconfensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ +- } +- +-#define yy_set_bol(at_bol) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){\ +- zconfensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ +- } +- +-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) +- +-/* Begin user sect3 */ +- +-#define zconfwrap(n) 1 +-#define YY_SKIP_YYWRAP +- +-typedef unsigned char YY_CHAR; +- +-FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0; +- +-typedef int yy_state_type; +- +-extern int zconflineno; +- +-int zconflineno = 1; +- +-extern char *zconftext; +-#define yytext_ptr zconftext +-static yyconst flex_int16_t yy_nxt[][17] = +- { +- { +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0 +- }, +- +- { +- 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, +- 12, 12, 12, 12, 12, 12, 12 +- }, +- +- { +- 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, +- 12, 12, 12, 12, 12, 12, 12 +- }, +- +- { +- 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 18, 16, 16, 16 +- }, +- +- { +- 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 18, 16, 16, 16 +- +- }, +- +- { +- 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, +- 19, 19, 19, 19, 19, 19, 19 +- }, +- +- { +- 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, +- 19, 19, 19, 19, 19, 19, 19 +- }, +- +- { +- 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, +- 22, 22, 22, 22, 22, 25, 22 +- }, +- +- { +- 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, +- 22, 22, 22, 22, 22, 25, 22 +- }, +- +- { +- 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, +- 33, 34, 35, 35, 36, 37, 38 +- +- }, +- +- { +- 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, +- 33, 34, 35, 35, 36, 37, 38 +- }, +- +- { +- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, +- -11, -11, -11, -11, -11, -11, -11 +- }, +- +- { +- 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, +- -12, -12, -12, -12, -12, -12, -12 +- }, +- +- { +- 11, -13, 39, 40, -13, -13, 41, -13, -13, -13, +- -13, -13, -13, -13, -13, -13, -13 +- }, +- +- { +- 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, +- -14, -14, -14, -14, -14, -14, -14 +- +- }, +- +- { +- 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, +- 42, 42, 42, 42, 42, 42, 42 +- }, +- +- { +- 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, +- -16, -16, -16, -16, -16, -16, -16 +- }, +- +- { +- 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, +- -17, -17, -17, -17, -17, -17, -17 +- }, +- +- { +- 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, +- -18, -18, -18, 44, -18, -18, -18 +- }, +- +- { +- 11, 45, 45, -19, 45, 45, 45, 45, 45, 45, +- 45, 45, 45, 45, 45, 45, 45 +- +- }, +- +- { +- 11, -20, 46, 47, -20, -20, -20, -20, -20, -20, +- -20, -20, -20, -20, -20, -20, -20 +- }, +- +- { +- 11, 48, -21, -21, 48, 48, 48, 48, 48, 48, +- 48, 48, 48, 48, 48, 48, 48 +- }, +- +- { +- 11, 49, 49, 50, 49, -22, 49, 49, -22, 49, +- 49, 49, 49, 49, 49, -22, 49 +- }, +- +- { +- 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, +- -23, -23, -23, -23, -23, -23, -23 +- }, +- +- { +- 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, +- -24, -24, -24, -24, -24, -24, -24 +- +- }, +- +- { +- 11, 51, 51, 52, 51, 51, 51, 51, 51, 51, +- 51, 51, 51, 51, 51, 51, 51 +- }, +- +- { +- 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, +- -26, -26, -26, -26, -26, -26, -26 +- }, +- +- { +- 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, +- -27, -27, -27, -27, -27, -27, -27 +- }, +- +- { +- 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, +- -28, -28, -28, -28, 53, -28, -28 +- }, +- +- { +- 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, +- -29, -29, -29, -29, -29, -29, -29 +- +- }, +- +- { +- 11, 54, 54, -30, 54, 54, 54, 54, 54, 54, +- 54, 54, 54, 54, 54, 54, 54 +- }, +- +- { +- 11, -31, -31, -31, -31, -31, -31, 55, -31, -31, +- -31, -31, -31, -31, -31, -31, -31 +- }, +- +- { +- 11, -32, -32, -32, -32, -32, -32, -32, -32, -32, +- -32, -32, -32, -32, -32, -32, -32 +- }, +- +- { +- 11, -33, -33, -33, -33, -33, -33, -33, -33, -33, +- -33, -33, -33, -33, -33, -33, -33 +- }, +- +- { +- 11, -34, -34, -34, -34, -34, -34, -34, -34, -34, +- -34, 56, 57, 57, -34, -34, -34 +- +- }, +- +- { +- 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, +- -35, 57, 57, 57, -35, -35, -35 +- }, +- +- { +- 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, +- -36, -36, -36, -36, -36, -36, -36 +- }, +- +- { +- 11, -37, -37, 58, -37, -37, -37, -37, -37, -37, +- -37, -37, -37, -37, -37, -37, -37 +- }, +- +- { +- 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, +- -38, -38, -38, -38, -38, -38, 59 +- }, +- +- { +- 11, -39, 39, 40, -39, -39, 41, -39, -39, -39, +- -39, -39, -39, -39, -39, -39, -39 +- +- }, +- +- { +- 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, +- -40, -40, -40, -40, -40, -40, -40 +- }, +- +- { +- 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, +- 42, 42, 42, 42, 42, 42, 42 +- }, +- +- { +- 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, +- 42, 42, 42, 42, 42, 42, 42 +- }, +- +- { +- 11, -43, -43, -43, -43, -43, -43, -43, -43, -43, +- -43, -43, -43, -43, -43, -43, -43 +- }, +- +- { +- 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, +- -44, -44, -44, 44, -44, -44, -44 +- +- }, +- +- { +- 11, 45, 45, -45, 45, 45, 45, 45, 45, 45, +- 45, 45, 45, 45, 45, 45, 45 +- }, +- +- { +- 11, -46, 46, 47, -46, -46, -46, -46, -46, -46, +- -46, -46, -46, -46, -46, -46, -46 +- }, +- +- { +- 11, 48, -47, -47, 48, 48, 48, 48, 48, 48, +- 48, 48, 48, 48, 48, 48, 48 +- }, +- +- { +- 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, +- -48, -48, -48, -48, -48, -48, -48 +- }, +- +- { +- 11, 49, 49, 50, 49, -49, 49, 49, -49, 49, +- 49, 49, 49, 49, 49, -49, 49 +- +- }, +- +- { +- 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, +- -50, -50, -50, -50, -50, -50, -50 +- }, +- +- { +- 11, -51, -51, 52, -51, -51, -51, -51, -51, -51, +- -51, -51, -51, -51, -51, -51, -51 +- }, +- +- { +- 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, +- -52, -52, -52, -52, -52, -52, -52 +- }, +- +- { +- 11, -53, -53, -53, -53, -53, -53, -53, -53, -53, +- -53, -53, -53, -53, -53, -53, -53 +- }, +- +- { +- 11, 54, 54, -54, 54, 54, 54, 54, 54, 54, +- 54, 54, 54, 54, 54, 54, 54 +- +- }, +- +- { +- 11, -55, -55, -55, -55, -55, -55, -55, -55, -55, +- -55, -55, -55, -55, -55, -55, -55 +- }, +- +- { +- 11, -56, -56, -56, -56, -56, -56, -56, -56, -56, +- -56, 60, 57, 57, -56, -56, -56 +- }, +- +- { +- 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, +- -57, 57, 57, 57, -57, -57, -57 +- }, +- +- { +- 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, +- -58, -58, -58, -58, -58, -58, -58 +- }, +- +- { +- 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, +- -59, -59, -59, -59, -59, -59, -59 +- +- }, +- +- { +- 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, +- -60, 57, 57, 57, -60, -60, -60 +- }, +- +- } ; +- +-static yy_state_type yy_get_previous_state (void ); +-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +-static int yy_get_next_buffer (void ); +-static void yy_fatal_error (yyconst char msg[] ); +- +-/* Done after the current pattern has been matched and before the +- * corresponding action - sets up zconftext. +- */ +-#define YY_DO_BEFORE_ACTION \ +- (yytext_ptr) = yy_bp; \ +- zconfleng = (size_t) (yy_cp - yy_bp); \ +- (yy_hold_char) = *yy_cp; \ +- *yy_cp = '\0'; \ +- (yy_c_buf_p) = yy_cp; +- +-#define YY_NUM_RULES 33 +-#define YY_END_OF_BUFFER 34 +-/* This struct is not used in this scanner, +- but its presence is necessary. */ +-struct yy_trans_info +- { +- flex_int32_t yy_verify; +- flex_int32_t yy_nxt; +- }; +-static yyconst flex_int16_t yy_accept[61] = +- { 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 34, 5, 4, 2, 3, 7, 8, 6, 32, 29, +- 31, 24, 28, 27, 26, 22, 17, 13, 16, 20, +- 22, 11, 12, 19, 19, 14, 22, 22, 4, 2, +- 3, 3, 1, 6, 32, 29, 31, 30, 24, 23, +- 26, 25, 15, 20, 9, 19, 19, 21, 10, 18 +- } ; +- +-static yyconst flex_int32_t yy_ec[256] = +- { 0, +- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 2, 4, 5, 6, 1, 1, 7, 8, 9, +- 10, 1, 1, 1, 11, 12, 12, 13, 13, 13, +- 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, +- 14, 1, 1, 1, 13, 13, 13, 13, 13, 13, +- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +- 1, 15, 1, 1, 13, 1, 13, 13, 13, 13, +- +- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +- 13, 13, 1, 16, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1 +- } ; +- +-extern int zconf_flex_debug; +-int zconf_flex_debug = 0; +- +-/* The intent behind this definition is that it'll catch +- * any uses of REJECT which flex missed. +- */ +-#define REJECT reject_used_but_not_detected +-#define yymore() yymore_used_but_not_detected +-#define YY_MORE_ADJ 0 +-#define YY_RESTORE_YY_MORE_OFFSET +-char *zconftext; +-#define YY_NO_INPUT 1 +- +-/* +- * Copyright (C) 2002 Roman Zippel +- * Released under the terms of the GNU GPL v2.0. +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#define LKC_DIRECT_LINK +-#include "lkc.h" +- +-#define START_STRSIZE 16 +- +-static struct { +- struct file *file; +- int lineno; +-} current_pos; +- +-static char *text; +-static int text_size, text_asize; +- +-struct buffer { +- struct buffer *parent; +- YY_BUFFER_STATE state; +-}; +- +-struct buffer *current_buf; +- +-static int last_ts, first_ts; +- +-static void zconf_endhelp(void); +-static void zconf_endfile(void); +- +-void new_string(void) +-{ +- text = malloc(START_STRSIZE); +- text_asize = START_STRSIZE; +- text_size = 0; +- *text = 0; +-} +- +-void append_string(const char *str, int size) +-{ +- int new_size = text_size + size + 1; +- if (new_size > text_asize) { +- new_size += START_STRSIZE - 1; +- new_size &= -START_STRSIZE; +- text = realloc(text, new_size); +- text_asize = new_size; +- } +- memcpy(text + text_size, str, size); +- text_size += size; +- text[text_size] = 0; +-} +- +-void alloc_string(const char *str, int size) +-{ +- text = malloc(size + 1); +- memcpy(text, str, size); +- text[size] = 0; +-} +- +-#define INITIAL 0 +-#define COMMAND 1 +-#define HELP 2 +-#define STRING 3 +-#define PARAM 4 +- +-#ifndef YY_NO_UNISTD_H +-/* Special case for "unistd.h", since it is non-ANSI. We include it way +- * down here because we want the user's section 1 to have been scanned first. +- * The user has a chance to override it with an option. +- */ +-#include +-#endif +- +-#ifndef YY_EXTRA_TYPE +-#define YY_EXTRA_TYPE void * +-#endif +- +-static int yy_init_globals (void ); +- +-/* Accessor methods to globals. +- These are made visible to non-reentrant scanners for convenience. */ +- +-int zconflex_destroy (void ); +- +-int zconfget_debug (void ); +- +-void zconfset_debug (int debug_flag ); +- +-YY_EXTRA_TYPE zconfget_extra (void ); +- +-void zconfset_extra (YY_EXTRA_TYPE user_defined ); +- +-FILE *zconfget_in (void ); +- +-void zconfset_in (FILE * in_str ); +- +-FILE *zconfget_out (void ); +- +-void zconfset_out (FILE * out_str ); +- +-int zconfget_leng (void ); +- +-char *zconfget_text (void ); +- +-int zconfget_lineno (void ); +- +-void zconfset_lineno (int line_number ); +- +-/* Macros after this point can all be overridden by user definitions in +- * section 1. +- */ +- +-#ifndef YY_SKIP_YYWRAP +-#ifdef __cplusplus +-extern "C" int zconfwrap (void ); +-#else +-extern int zconfwrap (void ); +-#endif +-#endif +- +- static void yyunput (int c,char *buf_ptr ); +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char *,yyconst char *,int ); +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * ); +-#endif +- +-#ifndef YY_NO_INPUT +- +-#ifdef __cplusplus +-static int yyinput (void ); +-#else +-static int input (void ); +-#endif +- +-#endif +- +-/* Amount of stuff to slurp up with each read. */ +-#ifndef YY_READ_BUF_SIZE +-#define YY_READ_BUF_SIZE 8192 +-#endif +- +-/* Copy whatever the last rule matched to the standard output. */ +-#ifndef ECHO +-/* This used to be an fputs(), but since the string might contain NUL's, +- * we now use fwrite(). +- */ +-#define ECHO fwrite( zconftext, zconfleng, 1, zconfout ) +-#endif +- +-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, +- * is returned in "result". +- */ +-#ifndef YY_INPUT +-#define YY_INPUT(buf,result,max_size) \ +- errno=0; \ +- while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \ +- { \ +- if( errno != EINTR) \ +- { \ +- YY_FATAL_ERROR( "input in flex scanner failed" ); \ +- break; \ +- } \ +- errno=0; \ +- clearerr(zconfin); \ +- }\ +-\ +- +-#endif +- +-/* No semi-colon after return; correct usage is to write "yyterminate();" - +- * we don't want an extra ';' after the "return" because that will cause +- * some compilers to complain about unreachable statements. +- */ +-#ifndef yyterminate +-#define yyterminate() return YY_NULL +-#endif +- +-/* Number of entries by which start-condition stack grows. */ +-#ifndef YY_START_STACK_INCR +-#define YY_START_STACK_INCR 25 +-#endif +- +-/* Report a fatal error. */ +-#ifndef YY_FATAL_ERROR +-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +-#endif +- +-/* end tables serialization structures and prototypes */ +- +-/* Default declaration of generated scanner - a define so the user can +- * easily add parameters. +- */ +-#ifndef YY_DECL +-#define YY_DECL_IS_OURS 1 +- +-extern int zconflex (void); +- +-#define YY_DECL int zconflex (void) +-#endif /* !YY_DECL */ +- +-/* Code executed at the beginning of each rule, after zconftext and zconfleng +- * have been set up. +- */ +-#ifndef YY_USER_ACTION +-#define YY_USER_ACTION +-#endif +- +-/* Code executed at the end of each rule. */ +-#ifndef YY_BREAK +-#define YY_BREAK break; +-#endif +- +-#define YY_RULE_SETUP \ +- YY_USER_ACTION +- +-/** The main scanner function which does all the work. +- */ +-YY_DECL +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp, *yy_bp; +- register int yy_act; +- +- int str = 0; +- int ts, i; +- +- if ( !(yy_init) ) +- { +- (yy_init) = 1; +- +-#ifdef YY_USER_INIT +- YY_USER_INIT; +-#endif +- +- if ( ! (yy_start) ) +- (yy_start) = 1; /* first start state */ +- +- if ( ! zconfin ) +- zconfin = stdin; +- +- if ( ! zconfout ) +- zconfout = stdout; +- +- if ( ! YY_CURRENT_BUFFER ) { +- zconfensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- zconf_create_buffer(zconfin,YY_BUF_SIZE ); +- } +- +- zconf_load_buffer_state( ); +- } +- +- while ( 1 ) /* loops until end-of-file is reached */ +- { +- yy_cp = (yy_c_buf_p); +- +- /* Support of zconftext. */ +- *yy_cp = (yy_hold_char); +- +- /* yy_bp points to the position in yy_ch_buf of the start of +- * the current run. +- */ +- yy_bp = yy_cp; +- +- yy_current_state = (yy_start); +-yy_match: +- while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 ) +- ++yy_cp; +- +- yy_current_state = -yy_current_state; +- +-yy_find_action: +- yy_act = yy_accept[yy_current_state]; +- +- YY_DO_BEFORE_ACTION; +- +-do_action: /* This label is used only to access EOF actions. */ +- +- switch ( yy_act ) +- { /* beginning of action switch */ +-case 1: +-/* rule 1 can match eol */ +-case 2: +-/* rule 2 can match eol */ +-YY_RULE_SETUP +-{ +- current_file->lineno++; +- return T_EOL; +-} +- YY_BREAK +-case 3: +-YY_RULE_SETUP +- +- YY_BREAK +-case 4: +-YY_RULE_SETUP +-{ +- BEGIN(COMMAND); +-} +- YY_BREAK +-case 5: +-YY_RULE_SETUP +-{ +- unput(zconftext[0]); +- BEGIN(COMMAND); +-} +- YY_BREAK +- +-case 6: +-YY_RULE_SETUP +-{ +- struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); +- 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(zconftext, zconfleng); +- zconflval.string = text; +- return T_WORD; +- } +- YY_BREAK +-case 7: +-YY_RULE_SETUP +- +- YY_BREAK +-case 8: +-/* rule 8 can match eol */ +-YY_RULE_SETUP +-{ +- BEGIN(INITIAL); +- current_file->lineno++; +- return T_EOL; +- } +- YY_BREAK +- +-case 9: +-YY_RULE_SETUP +-return T_AND; +- YY_BREAK +-case 10: +-YY_RULE_SETUP +-return T_OR; +- YY_BREAK +-case 11: +-YY_RULE_SETUP +-return T_OPEN_PAREN; +- YY_BREAK +-case 12: +-YY_RULE_SETUP +-return T_CLOSE_PAREN; +- YY_BREAK +-case 13: +-YY_RULE_SETUP +-return T_NOT; +- YY_BREAK +-case 14: +-YY_RULE_SETUP +-return T_EQUAL; +- YY_BREAK +-case 15: +-YY_RULE_SETUP +-return T_UNEQUAL; +- YY_BREAK +-case 16: +-YY_RULE_SETUP +-{ +- str = zconftext[0]; +- new_string(); +- BEGIN(STRING); +- } +- YY_BREAK +-case 17: +-/* rule 17 can match eol */ +-YY_RULE_SETUP +-BEGIN(INITIAL); current_file->lineno++; return T_EOL; +- YY_BREAK +-case 18: +-YY_RULE_SETUP +-/* ignore */ +- YY_BREAK +-case 19: +-YY_RULE_SETUP +-{ +- struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); +- if (id && id->flags & TF_PARAM) { +- zconflval.id = id; +- return id->token; +- } +- alloc_string(zconftext, zconfleng); +- zconflval.string = text; +- return T_WORD; +- } +- YY_BREAK +-case 20: +-YY_RULE_SETUP +-/* comment */ +- YY_BREAK +-case 21: +-/* rule 21 can match eol */ +-YY_RULE_SETUP +-current_file->lineno++; +- YY_BREAK +-case 22: +-YY_RULE_SETUP +- +- YY_BREAK +-case YY_STATE_EOF(PARAM): +-{ +- BEGIN(INITIAL); +- } +- YY_BREAK +- +-case 23: +-/* rule 23 can match eol */ +-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +-(yy_c_buf_p) = yy_cp -= 1; +-YY_DO_BEFORE_ACTION; /* set up zconftext again */ +-YY_RULE_SETUP +-{ +- append_string(zconftext, zconfleng); +- zconflval.string = text; +- return T_WORD_QUOTE; +- } +- YY_BREAK +-case 24: +-YY_RULE_SETUP +-{ +- append_string(zconftext, zconfleng); +- } +- YY_BREAK +-case 25: +-/* rule 25 can match eol */ +-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +-(yy_c_buf_p) = yy_cp -= 1; +-YY_DO_BEFORE_ACTION; /* set up zconftext again */ +-YY_RULE_SETUP +-{ +- append_string(zconftext + 1, zconfleng - 1); +- zconflval.string = text; +- return T_WORD_QUOTE; +- } +- YY_BREAK +-case 26: +-YY_RULE_SETUP +-{ +- append_string(zconftext + 1, zconfleng - 1); +- } +- YY_BREAK +-case 27: +-YY_RULE_SETUP +-{ +- if (str == zconftext[0]) { +- BEGIN(PARAM); +- zconflval.string = text; +- return T_WORD_QUOTE; +- } else +- append_string(zconftext, 1); +- } +- YY_BREAK +-case 28: +-/* rule 28 can match eol */ +-YY_RULE_SETUP +-{ +- printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); +- current_file->lineno++; +- BEGIN(INITIAL); +- return T_EOL; +- } +- YY_BREAK +-case YY_STATE_EOF(STRING): +-{ +- BEGIN(INITIAL); +- } +- YY_BREAK +- +-case 29: +-YY_RULE_SETUP +-{ +- ts = 0; +- for (i = 0; i < zconfleng; i++) { +- if (zconftext[i] == '\t') +- ts = (ts & ~7) + 8; +- else +- ts++; +- } +- last_ts = ts; +- if (first_ts) { +- if (ts < first_ts) { +- zconf_endhelp(); +- return T_HELPTEXT; +- } +- ts -= first_ts; +- while (ts > 8) { +- append_string(" ", 8); +- ts -= 8; +- } +- append_string(" ", ts); +- } +- } +- YY_BREAK +-case 30: +-/* rule 30 can match eol */ +-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +-(yy_c_buf_p) = yy_cp -= 1; +-YY_DO_BEFORE_ACTION; /* set up zconftext again */ +-YY_RULE_SETUP +-{ +- current_file->lineno++; +- zconf_endhelp(); +- return T_HELPTEXT; +- } +- YY_BREAK +-case 31: +-/* rule 31 can match eol */ +-YY_RULE_SETUP +-{ +- current_file->lineno++; +- append_string("\n", 1); +- } +- YY_BREAK +-case 32: +-YY_RULE_SETUP +-{ +- while (zconfleng) { +- if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t')) +- break; +- zconfleng--; +- } +- append_string(zconftext, zconfleng); +- if (!first_ts) +- first_ts = last_ts; +- } +- YY_BREAK +-case YY_STATE_EOF(HELP): +-{ +- zconf_endhelp(); +- return T_HELPTEXT; +- } +- YY_BREAK +- +-case YY_STATE_EOF(INITIAL): +-case YY_STATE_EOF(COMMAND): +-{ +- if (current_file) { +- zconf_endfile(); +- return T_EOL; +- } +- fclose(zconfin); +- yyterminate(); +-} +- YY_BREAK +-case 33: +-YY_RULE_SETUP +-YY_FATAL_ERROR( "flex scanner jammed" ); +- YY_BREAK +- +- case YY_END_OF_BUFFER: +- { +- /* Amount of text matched not including the EOB char. */ +- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; +- +- /* Undo the effects of YY_DO_BEFORE_ACTION. */ +- *yy_cp = (yy_hold_char); +- YY_RESTORE_YY_MORE_OFFSET +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) +- { +- /* We're scanning a new file or input source. It's +- * possible that this happened because the user +- * just pointed zconfin at a new source and called +- * zconflex(). If so, then we have to assure +- * consistency between YY_CURRENT_BUFFER and our +- * globals. Here is the right place to do so, because +- * this is the first action (other than possibly a +- * back-up) that will match for the new input source. +- */ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; +- } +- +- /* Note that here we test for yy_c_buf_p "<=" to the position +- * of the first EOB in the buffer, since yy_c_buf_p will +- * already have been incremented past the NUL character +- * (since all states make transitions on EOB to the +- * end-of-buffer state). Contrast this with the test +- * in input(). +- */ +- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- { /* This was really a NUL. */ +- yy_state_type yy_next_state; +- +- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- /* Okay, we're now positioned to make the NUL +- * transition. We couldn't have +- * yy_get_previous_state() go ahead and do it +- * for us because it doesn't know how to deal +- * with the possibility of jamming (and we don't +- * want to build jamming into it because then it +- * will run more slowly). +- */ +- +- yy_next_state = yy_try_NUL_trans( yy_current_state ); +- +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- +- if ( yy_next_state ) +- { +- /* Consume the NUL. */ +- yy_cp = ++(yy_c_buf_p); +- yy_current_state = yy_next_state; +- goto yy_match; +- } +- +- else +- { +- yy_cp = (yy_c_buf_p); +- goto yy_find_action; +- } +- } +- +- else switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_END_OF_FILE: +- { +- (yy_did_buffer_switch_on_eof) = 0; +- +- if ( zconfwrap( ) ) +- { +- /* Note: because we've taken care in +- * yy_get_next_buffer() to have set up +- * zconftext, we can now set up +- * yy_c_buf_p so that if some total +- * hoser (like flex itself) wants to +- * call the scanner after we return the +- * YY_NULL, it'll still work - another +- * YY_NULL will get returned. +- */ +- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; +- +- yy_act = YY_STATE_EOF(YY_START); +- goto do_action; +- } +- +- else +- { +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +- } +- break; +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = +- (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_match; +- +- case EOB_ACT_LAST_MATCH: +- (yy_c_buf_p) = +- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_find_action; +- } +- break; +- } +- +- default: +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--no action found" ); +- } /* end of action switch */ +- } /* end of scanning one token */ +-} /* end of zconflex */ +- +-/* yy_get_next_buffer - try to read in a new buffer +- * +- * Returns a code representing an action: +- * EOB_ACT_LAST_MATCH - +- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position +- * EOB_ACT_END_OF_FILE - end of file +- */ +-static int yy_get_next_buffer (void) +-{ +- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; +- register char *source = (yytext_ptr); +- register int number_to_move, i; +- int ret_val; +- +- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--end of buffer missed" ); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) +- { /* Don't try to fill the buffer, so this is an EOF. */ +- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) +- { +- /* We matched a single character, the EOB, so +- * treat this as a final EOF. +- */ +- return EOB_ACT_END_OF_FILE; +- } +- +- else +- { +- /* We matched some text prior to the EOB, first +- * process it. +- */ +- return EOB_ACT_LAST_MATCH; +- } +- } +- +- /* Try to read more data. */ +- +- /* First move last chars to start of buffer. */ +- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; +- +- for ( i = 0; i < number_to_move; ++i ) +- *(dest++) = *(source++); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) +- /* don't do the read, it's not guaranteed to return an EOF, +- * just force an EOF +- */ +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; +- +- else +- { +- int num_to_read = +- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; +- +- while ( num_to_read <= 0 ) +- { /* Not enough room in the buffer - grow it. */ +- +- /* just a shorter name for the current buffer */ +- YY_BUFFER_STATE b = YY_CURRENT_BUFFER; +- +- int yy_c_buf_p_offset = +- (int) ((yy_c_buf_p) - b->yy_ch_buf); +- +- if ( b->yy_is_our_buffer ) +- { +- int new_size = b->yy_buf_size * 2; +- +- if ( new_size <= 0 ) +- b->yy_buf_size += b->yy_buf_size / 8; +- else +- b->yy_buf_size *= 2; +- +- b->yy_ch_buf = (char *) +- /* Include room in for 2 EOB chars. */ +- zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); +- } +- else +- /* Can't grow it, we don't own it. */ +- b->yy_ch_buf = 0; +- +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( +- "fatal error - scanner input buffer overflow" ); +- +- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; +- +- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - +- number_to_move - 1; +- +- } +- +- if ( num_to_read > YY_READ_BUF_SIZE ) +- num_to_read = YY_READ_BUF_SIZE; +- +- /* Read in more data. */ +- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- (yy_n_chars), (size_t) num_to_read ); +- +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- if ( (yy_n_chars) == 0 ) +- { +- if ( number_to_move == YY_MORE_ADJ ) +- { +- ret_val = EOB_ACT_END_OF_FILE; +- zconfrestart(zconfin ); +- } +- +- else +- { +- ret_val = EOB_ACT_LAST_MATCH; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = +- YY_BUFFER_EOF_PENDING; +- } +- } +- +- else +- ret_val = EOB_ACT_CONTINUE_SCAN; +- +- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { +- /* Extend the array by 50%, plus the number we really need. */ +- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) zconfrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); +- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); +- } +- +- (yy_n_chars) += number_to_move; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; +- +- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; +- +- return ret_val; +-} +- +-/* yy_get_previous_state - get the state just before the EOB char was reached */ +- +- static yy_state_type yy_get_previous_state (void) +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp; +- +- yy_current_state = (yy_start); +- +- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) +- { +- yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)]; +- } +- +- return yy_current_state; +-} +- +-/* yy_try_NUL_trans - try to make a transition on the NUL character +- * +- * synopsis +- * next_state = yy_try_NUL_trans( current_state ); +- */ +- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +-{ +- register int yy_is_jam; +- +- yy_current_state = yy_nxt[yy_current_state][1]; +- yy_is_jam = (yy_current_state <= 0); +- +- return yy_is_jam ? 0 : yy_current_state; +-} +- +- static void yyunput (int c, register char * yy_bp ) +-{ +- register char *yy_cp; +- +- yy_cp = (yy_c_buf_p); +- +- /* undo effects of setting up zconftext */ +- *yy_cp = (yy_hold_char); +- +- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) +- { /* need to shift things up to make room */ +- /* +2 for EOB chars. */ +- register int number_to_move = (yy_n_chars) + 2; +- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ +- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; +- register char *source = +- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; +- +- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) +- *--dest = *--source; +- +- yy_cp += (int) (dest - source); +- yy_bp += (int) (dest - source); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; +- +- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) +- YY_FATAL_ERROR( "flex scanner push-back overflow" ); +- } +- +- *--yy_cp = (char) c; +- +- (yytext_ptr) = yy_bp; +- (yy_hold_char) = *yy_cp; +- (yy_c_buf_p) = yy_cp; +-} +- +-#ifndef YY_NO_INPUT +-#ifdef __cplusplus +- static int yyinput (void) +-#else +- static int input (void) +-#endif +- +-{ +- int c; +- +- *(yy_c_buf_p) = (yy_hold_char); +- +- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) +- { +- /* yy_c_buf_p now points to the character we want to return. +- * If this occurs *before* the EOB characters, then it's a +- * valid NUL; if not, then we've hit the end of the buffer. +- */ +- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- /* This was really a NUL. */ +- *(yy_c_buf_p) = '\0'; +- +- else +- { /* need more input */ +- int offset = (yy_c_buf_p) - (yytext_ptr); +- ++(yy_c_buf_p); +- +- switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_LAST_MATCH: +- /* This happens because yy_g_n_b() +- * sees that we've accumulated a +- * token and flags that we need to +- * try matching the token before +- * proceeding. But for input(), +- * there's no matching to consider. +- * So convert the EOB_ACT_LAST_MATCH +- * to EOB_ACT_END_OF_FILE. +- */ +- +- /* Reset buffer status. */ +- zconfrestart(zconfin ); +- +- /*FALLTHROUGH*/ +- +- case EOB_ACT_END_OF_FILE: +- { +- if ( zconfwrap( ) ) +- return EOF; +- +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +-#ifdef __cplusplus +- return yyinput(); +-#else +- return input(); +-#endif +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = (yytext_ptr) + offset; +- break; +- } +- } +- } +- +- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ +- *(yy_c_buf_p) = '\0'; /* preserve zconftext */ +- (yy_hold_char) = *++(yy_c_buf_p); +- +- return c; +-} +-#endif /* ifndef YY_NO_INPUT */ +- +-/** Immediately switch to a different input stream. +- * @param input_file A readable stream. +- * +- * @note This function does not reset the start condition to @c INITIAL . +- */ +- void zconfrestart (FILE * input_file ) +-{ +- +- if ( ! YY_CURRENT_BUFFER ){ +- zconfensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- zconf_create_buffer(zconfin,YY_BUF_SIZE ); +- } +- +- zconf_init_buffer(YY_CURRENT_BUFFER,input_file ); +- zconf_load_buffer_state( ); +-} +- +-/** Switch to a different input buffer. +- * @param new_buffer The new input buffer. +- * +- */ +- void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +-{ +- +- /* TODO. We should be able to replace this entire function body +- * with +- * zconfpop_buffer_state(); +- * zconfpush_buffer_state(new_buffer); +- */ +- zconfensure_buffer_stack (); +- if ( YY_CURRENT_BUFFER == new_buffer ) +- return; +- +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- zconf_load_buffer_state( ); +- +- /* We don't actually know whether we did this switch during +- * EOF (zconfwrap()) processing, but the only time this flag +- * is looked at is after zconfwrap() is called, so it's safe +- * to go ahead and always set it. +- */ +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-static void zconf_load_buffer_state (void) +-{ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; +- zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; +- (yy_hold_char) = *(yy_c_buf_p); +-} +- +-/** Allocate and initialize an input buffer state. +- * @param file A readable stream. +- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. +- * +- * @return the allocated buffer state. +- */ +- YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size ) +-{ +- YY_BUFFER_STATE b; +- +- b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); +- +- b->yy_buf_size = size; +- +- /* yy_ch_buf has to be 2 characters longer than the size given because +- * we need to put in 2 end-of-buffer characters. +- */ +- b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 ); +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); +- +- b->yy_is_our_buffer = 1; +- +- zconf_init_buffer(b,file ); +- +- return b; +-} +- +-/** Destroy the buffer. +- * @param b a buffer created with zconf_create_buffer() +- * +- */ +- void zconf_delete_buffer (YY_BUFFER_STATE b ) +-{ +- +- if ( ! b ) +- return; +- +- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ +- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; +- +- if ( b->yy_is_our_buffer ) +- zconffree((void *) b->yy_ch_buf ); +- +- zconffree((void *) b ); +-} +- +-/* Initializes or reinitializes a buffer. +- * This function is sometimes called more than once on the same buffer, +- * such as during a zconfrestart() or at EOF. +- */ +- static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file ) +- +-{ +- int oerrno = errno; +- +- zconf_flush_buffer(b ); +- +- b->yy_input_file = file; +- b->yy_fill_buffer = 1; +- +- /* If b is the current buffer, then zconf_init_buffer was _probably_ +- * called from zconfrestart() or through yy_get_next_buffer. +- * In that case, we don't want to reset the lineno or column. +- */ +- if (b != YY_CURRENT_BUFFER){ +- b->yy_bs_lineno = 1; +- b->yy_bs_column = 0; +- } +- +- b->yy_is_interactive = 0; +- +- errno = oerrno; +-} +- +-/** Discard all buffered characters. On the next scan, YY_INPUT will be called. +- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. +- * +- */ +- void zconf_flush_buffer (YY_BUFFER_STATE b ) +-{ +- if ( ! b ) +- return; +- +- b->yy_n_chars = 0; +- +- /* We always need two end-of-buffer characters. The first causes +- * a transition to the end-of-buffer state. The second causes +- * a jam in that state. +- */ +- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; +- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; +- +- b->yy_buf_pos = &b->yy_ch_buf[0]; +- +- b->yy_at_bol = 1; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- if ( b == YY_CURRENT_BUFFER ) +- zconf_load_buffer_state( ); +-} +- +-/** Pushes the new state onto the stack. The new state becomes +- * the current state. This function will allocate the stack +- * if necessary. +- * @param new_buffer The new state. +- * +- */ +-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ) +-{ +- if (new_buffer == NULL) +- return; +- +- zconfensure_buffer_stack(); +- +- /* This block is copied from zconf_switch_to_buffer. */ +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- /* Only push if top exists. Otherwise, replace top. */ +- if (YY_CURRENT_BUFFER) +- (yy_buffer_stack_top)++; +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- +- /* copied from zconf_switch_to_buffer. */ +- zconf_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-/** Removes and deletes the top of the stack, if present. +- * The next element becomes the new top. +- * +- */ +-void zconfpop_buffer_state (void) +-{ +- if (!YY_CURRENT_BUFFER) +- return; +- +- zconf_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- if ((yy_buffer_stack_top) > 0) +- --(yy_buffer_stack_top); +- +- if (YY_CURRENT_BUFFER) { +- zconf_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +- } +-} +- +-/* Allocates the stack if it does not exist. +- * Guarantees space for at least one push. +- */ +-static void zconfensure_buffer_stack (void) +-{ +- int num_to_alloc; +- +- if (!(yy_buffer_stack)) { +- +- /* First allocation is just for 2 elements, since we don't know if this +- * scanner will even need a stack. We use 2 instead of 1 to avoid an +- * immediate realloc on the next call. +- */ +- num_to_alloc = 1; +- (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc +- (num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" ); +- +- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); +- +- (yy_buffer_stack_max) = num_to_alloc; +- (yy_buffer_stack_top) = 0; +- return; +- } +- +- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ +- +- /* Increase the buffer to prepare for a possible push. */ +- int grow_size = 8 /* arbitrary grow size */; +- +- num_to_alloc = (yy_buffer_stack_max) + grow_size; +- (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc +- ((yy_buffer_stack), +- num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" ); +- +- /* zero only the new slots.*/ +- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); +- (yy_buffer_stack_max) = num_to_alloc; +- } +-} +- +-/** Setup the input buffer state to scan directly from a user-specified character buffer. +- * @param base the character buffer +- * @param size the size in bytes of the character buffer +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size ) +-{ +- YY_BUFFER_STATE b; +- +- if ( size < 2 || +- base[size-2] != YY_END_OF_BUFFER_CHAR || +- base[size-1] != YY_END_OF_BUFFER_CHAR ) +- /* They forgot to leave room for the EOB's. */ +- return 0; +- +- b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" ); +- +- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ +- b->yy_buf_pos = b->yy_ch_buf = base; +- b->yy_is_our_buffer = 0; +- b->yy_input_file = 0; +- b->yy_n_chars = b->yy_buf_size; +- b->yy_is_interactive = 0; +- b->yy_at_bol = 1; +- b->yy_fill_buffer = 0; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- zconf_switch_to_buffer(b ); +- +- return b; +-} +- +-/** Setup the input buffer state to scan a string. The next call to zconflex() will +- * scan from a @e copy of @a str. +- * @param yystr a NUL-terminated string to scan +- * +- * @return the newly allocated buffer state object. +- * @note If you want to scan bytes that may contain NUL values, then use +- * zconf_scan_bytes() instead. +- */ +-YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr ) +-{ +- +- return zconf_scan_bytes(yystr,strlen(yystr) ); +-} +- +-/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will +- * scan from a @e copy of @a bytes. +- * @param bytes the byte buffer to scan +- * @param len the number of bytes in the buffer pointed to by @a bytes. +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE zconf_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +-{ +- YY_BUFFER_STATE b; +- char *buf; +- yy_size_t n; +- int i; +- +- /* Get memory for full buffer, including space for trailing EOB's. */ +- n = _yybytes_len + 2; +- buf = (char *) zconfalloc(n ); +- if ( ! buf ) +- YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); +- +- for ( i = 0; i < _yybytes_len; ++i ) +- buf[i] = yybytes[i]; +- +- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; +- +- b = zconf_scan_buffer(buf,n ); +- if ( ! b ) +- YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" ); +- +- /* It's okay to grow etc. this buffer, and we should throw it +- * away when we're done. +- */ +- b->yy_is_our_buffer = 1; +- +- return b; +-} +- +-#ifndef YY_EXIT_FAILURE +-#define YY_EXIT_FAILURE 2 +-#endif +- +-static void yy_fatal_error (yyconst char* msg ) +-{ +- (void) fprintf( stderr, "%s\n", msg ); +- exit( YY_EXIT_FAILURE ); +-} +- +-/* Redefine yyless() so it works in section 3 code. */ +- +-#undef yyless +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up zconftext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- zconftext[zconfleng] = (yy_hold_char); \ +- (yy_c_buf_p) = zconftext + yyless_macro_arg; \ +- (yy_hold_char) = *(yy_c_buf_p); \ +- *(yy_c_buf_p) = '\0'; \ +- zconfleng = yyless_macro_arg; \ +- } \ +- while ( 0 ) +- +-/* Accessor methods (get/set functions) to struct members. */ +- +-/** Get the current line number. +- * +- */ +-int zconfget_lineno (void) +-{ +- +- return zconflineno; +-} +- +-/** Get the input stream. +- * +- */ +-FILE *zconfget_in (void) +-{ +- return zconfin; +-} +- +-/** Get the output stream. +- * +- */ +-FILE *zconfget_out (void) +-{ +- return zconfout; +-} +- +-/** Get the length of the current token. +- * +- */ +-int zconfget_leng (void) +-{ +- return zconfleng; +-} +- +-/** Get the current token. +- * +- */ +- +-char *zconfget_text (void) +-{ +- return zconftext; +-} +- +-/** Set the current line number. +- * @param line_number +- * +- */ +-void zconfset_lineno (int line_number ) +-{ +- +- zconflineno = line_number; +-} +- +-/** Set the input stream. This does not discard the current +- * input buffer. +- * @param in_str A readable stream. +- * +- * @see zconf_switch_to_buffer +- */ +-void zconfset_in (FILE * in_str ) +-{ +- zconfin = in_str ; +-} +- +-void zconfset_out (FILE * out_str ) +-{ +- zconfout = out_str ; +-} +- +-int zconfget_debug (void) +-{ +- return zconf_flex_debug; +-} +- +-void zconfset_debug (int bdebug ) +-{ +- zconf_flex_debug = bdebug ; +-} +- +-static int yy_init_globals (void) +-{ +- /* Initialization is the same as for the non-reentrant scanner. +- * This function is called from zconflex_destroy(), so don't allocate here. +- */ +- +- (yy_buffer_stack) = 0; +- (yy_buffer_stack_top) = 0; +- (yy_buffer_stack_max) = 0; +- (yy_c_buf_p) = (char *) 0; +- (yy_init) = 0; +- (yy_start) = 0; +- +-/* Defined in main.c */ +-#ifdef YY_STDINIT +- zconfin = stdin; +- zconfout = stdout; +-#else +- zconfin = (FILE *) 0; +- zconfout = (FILE *) 0; +-#endif +- +- /* For future reference: Set errno on error, since we are called by +- * zconflex_init() +- */ +- return 0; +-} +- +-/* zconflex_destroy is for both reentrant and non-reentrant scanners. */ +-int zconflex_destroy (void) +-{ +- +- /* Pop the buffer stack, destroying each element. */ +- while(YY_CURRENT_BUFFER){ +- zconf_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- zconfpop_buffer_state(); +- } +- +- /* Destroy the stack itself. */ +- zconffree((yy_buffer_stack) ); +- (yy_buffer_stack) = NULL; +- +- /* Reset the globals. This is important in a non-reentrant scanner so the next time +- * zconflex() is called, initialization will occur. */ +- yy_init_globals( ); +- +- return 0; +-} +- +-/* +- * Internal utility routines. +- */ +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +-{ +- register int i; +- for ( i = 0; i < n; ++i ) +- s1[i] = s2[i]; +-} +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * s ) +-{ +- register int n; +- for ( n = 0; s[n]; ++n ) +- ; +- +- return n; +-} +-#endif +- +-void *zconfalloc (yy_size_t size ) +-{ +- return (void *) malloc( size ); +-} +- +-void *zconfrealloc (void * ptr, yy_size_t size ) +-{ +- /* The cast to (char *) in the following accommodates both +- * implementations that use char* generic pointers, and those +- * that use void* generic pointers. It works with the latter +- * because both ANSI C and C++ allow castless assignment from +- * any pointer type to void*, and deal with argument conversions +- * as though doing an assignment. +- */ +- return (void *) realloc( (char *) ptr, size ); +-} +- +-void zconffree (void * ptr ) +-{ +- free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */ +-} +- +-#define YYTABLES_NAME "yytables" +- +-void zconf_starthelp(void) +-{ +- new_string(); +- last_ts = first_ts = 0; +- BEGIN(HELP); +-} +- +-static void zconf_endhelp(void) +-{ +- zconflval.string = text; +- BEGIN(INITIAL); +-} +- +-/* +- * Try to open specified file with following names: +- * ./name +- * $(srctree)/name +- * The latter is used when srctree is separate from objtree +- * when compiling the kernel. +- * Return NULL if file is not found. +- */ +-FILE *zconf_fopen(const char *name) +-{ +- char *env, fullname[PATH_MAX+1]; +- FILE *f; +- +- f = fopen(name, "r"); +- if (!f && name != NULL && name[0] != '/') { +- env = getenv(SRCTREE); +- if (env) { +- sprintf(fullname, "%s/%s", env, name); +- f = fopen(fullname, "r"); +- } +- } +- return f; +-} +- +-void zconf_initscan(const char *name) +-{ +- zconfin = zconf_fopen(name); +- if (!zconfin) { +- printf("can't find file %s\n", name); +- exit(1); +- } +- +- current_buf = malloc(sizeof(*current_buf)); +- memset(current_buf, 0, sizeof(*current_buf)); +- +- current_file = file_lookup(name); +- current_file->lineno = 1; +- current_file->flags = FILE_BUSY; +-} +- +-void zconf_nextfile(const char *name) +-{ +- struct file *file = file_lookup(name); +- struct buffer *buf = malloc(sizeof(*buf)); +- memset(buf, 0, sizeof(*buf)); +- +- current_buf->state = YY_CURRENT_BUFFER; +- zconfin = zconf_fopen(name); +- if (!zconfin) { +- printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); +- exit(1); +- } +- zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); +- buf->parent = current_buf; +- current_buf = buf; +- +- if (file->flags & FILE_BUSY) { +- printf("%s:%d: do not source '%s' from itself\n", +- zconf_curname(), zconf_lineno(), name); +- exit(1); +- } +- if (file->flags & FILE_SCANNED) { +- printf("%s:%d: file '%s' is already sourced from '%s'\n", +- zconf_curname(), zconf_lineno(), name, +- file->parent->name); +- exit(1); +- } +- file->flags |= FILE_BUSY; +- file->lineno = 1; +- file->parent = current_file; +- current_file = file; +-} +- +-static void zconf_endfile(void) +-{ +- struct buffer *parent; +- +- current_file->flags |= FILE_SCANNED; +- current_file->flags &= ~FILE_BUSY; +- current_file = current_file->parent; +- +- parent = current_buf->parent; +- if (parent) { +- fclose(zconfin); +- zconf_delete_buffer(YY_CURRENT_BUFFER); +- zconf_switch_to_buffer(parent->state); +- } +- free(current_buf); +- current_buf = parent; +-} +- +-int zconf_lineno(void) +-{ +- return current_pos.lineno; +-} +- +-char *zconf_curname(void) +-{ +- return current_pos.file ? current_pos.file->name : ""; +-} +- +diff -Nur uClibc-0.9.33.2/extra/config/list.h uClibc-git/extra/config/list.h +--- uClibc-0.9.33.2/extra/config/list.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-git/extra/config/list.h 2014-02-03 12:32:56.000000000 +0100 +@@ -0,0 +1,131 @@ ++#ifndef LIST_H ++#define LIST_H ++ ++/* ++ * Copied from include/linux/... ++ */ ++ ++#undef offsetof ++#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) ++ ++/** ++ * container_of - cast a member of a structure out to the containing structure ++ * @ptr: the pointer to the member. ++ * @type: the type of the container struct this is embedded in. ++ * @member: the name of the member within the struct. ++ * ++ */ ++#define container_of(ptr, type, member) ({ \ ++ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ++ (type *)( (char *)__mptr - offsetof(type,member) );}) ++ ++ ++struct list_head { ++ struct list_head *next, *prev; ++}; ++ ++ ++#define LIST_HEAD_INIT(name) { &(name), &(name) } ++ ++#define LIST_HEAD(name) \ ++ struct list_head name = LIST_HEAD_INIT(name) ++ ++/** ++ * list_entry - get the struct for this entry ++ * @ptr: the &struct list_head pointer. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_entry(ptr, type, member) \ ++ container_of(ptr, type, member) ++ ++/** ++ * list_for_each_entry - iterate over list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry(pos, head, member) \ ++ for (pos = list_entry((head)->next, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = list_entry(pos->member.next, typeof(*pos), member)) ++ ++/** ++ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry ++ * @pos: the type * to use as a loop cursor. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry_safe(pos, n, head, member) \ ++ for (pos = list_entry((head)->next, typeof(*pos), member), \ ++ n = list_entry(pos->member.next, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_entry(n->member.next, typeof(*n), member)) ++ ++/** ++ * list_empty - tests whether a list is empty ++ * @head: the list to test. ++ */ ++static inline int list_empty(const struct list_head *head) ++{ ++ return head->next == head; ++} ++ ++/* ++ * Insert a new entry between two known consecutive entries. ++ * ++ * This is only for internal list manipulation where we know ++ * the prev/next entries already! ++ */ ++static inline void __list_add(struct list_head *_new, ++ struct list_head *prev, ++ struct list_head *next) ++{ ++ next->prev = _new; ++ _new->next = next; ++ _new->prev = prev; ++ prev->next = _new; ++} ++ ++/** ++ * list_add_tail - add a new entry ++ * @new: new entry to be added ++ * @head: list head to add it before ++ * ++ * Insert a new entry before the specified head. ++ * This is useful for implementing queues. ++ */ ++static inline void list_add_tail(struct list_head *_new, struct list_head *head) ++{ ++ __list_add(_new, head->prev, head); ++} ++ ++/* ++ * Delete a list entry by making the prev/next entries ++ * point to each other. ++ * ++ * This is only for internal list manipulation where we know ++ * the prev/next entries already! ++ */ ++static inline void __list_del(struct list_head *prev, struct list_head *next) ++{ ++ next->prev = prev; ++ prev->next = next; ++} ++ ++#define LIST_POISON1 ((void *) 0x00100100) ++#define LIST_POISON2 ((void *) 0x00200200) ++/** ++ * list_del - deletes entry from list. ++ * @entry: the element to delete from the list. ++ * Note: list_empty() on entry does not return true after this, the entry is ++ * in an undefined state. ++ */ ++static inline void list_del(struct list_head *entry) ++{ ++ __list_del(entry->prev, entry->next); ++ entry->next = (struct list_head*)LIST_POISON1; ++ entry->prev = (struct list_head*)LIST_POISON2; ++} ++#endif +diff -Nur uClibc-0.9.33.2/extra/config/lkc.h uClibc-git/extra/config/lkc.h +--- uClibc-0.9.33.2/extra/config/lkc.h 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lkc.h 2014-02-03 12:32:56.000000000 +0100 +@@ -14,29 +14,37 @@ + 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 + +-#ifdef LKC_DIRECT_LINK + #define P(name,type,arg) extern type name arg +-#else +-#include "lkc_defs.h" +-#define P(name,type,arg) extern type (*name ## _p) arg +-#endif + #include "lkc_proto.h" + #undef P + + #define SRCTREE "srctree" + ++#ifndef PACKAGE + #define PACKAGE "linux" ++#endif ++ + #define LOCALEDIR "/usr/share/locale" + + #define _(text) gettext(text) + #define N_(text) (text) + ++#ifndef CONFIG_ ++#define CONFIG_ "CONFIG_" ++#endif ++static inline const char *CONFIG_prefix(void) ++{ ++ return getenv( "CONFIG_" ) ?: CONFIG_; ++} ++#undef CONFIG_ ++#define CONFIG_ CONFIG_prefix() + + #define TF_COMMAND 0x0001 + #define TF_PARAM 0x0002 +@@ -61,35 +69,49 @@ + enum symbol_type stype; + }; + ++extern int zconfdebug; ++ + int zconfparse(void); + void zconfdump(FILE *out); +- +-extern int zconfdebug; + void zconf_starthelp(void); + FILE *zconf_fopen(const char *name); + void zconf_initscan(const char *name); + void zconf_nextfile(const char *name); + int zconf_lineno(void); +-char *zconf_curname(void); ++const char *zconf_curname(void); + + /* confdata.c */ + const char *conf_get_configname(void); ++const char *conf_get_autoconfig_name(void); + char *conf_get_default_confname(void); + void sym_set_change_count(int count); + void sym_add_change_count(int count); +-void conf_set_all_new_symbols(enum conf_def_mode mode); ++bool conf_set_all_new_symbols(enum conf_def_mode mode); ++void set_all_choice_values(struct symbol *csym); ++ ++struct conf_printer { ++ void (*print_symbol)(FILE *, struct symbol *, const char *, void *); ++ void (*print_comment)(FILE *, const char *, void *); ++}; + +-/* kconfig_load.c */ +-void kconfig_load(void); ++/* confdata.c and expr.c */ ++static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) ++{ ++ assert(len != 0); ++ ++ if (fwrite(str, len, count, out) != count) ++ fprintf(stderr, "Error in writing or end of file.\n"); ++} + + /* menu.c */ +-void menu_init(void); ++void _menu_init(void); + void menu_warn(struct menu *menu, const char *fmt, ...); + struct menu *menu_add_menu(void); + void menu_end_menu(void); + void menu_add_entry(struct symbol *sym); + void menu_end_entry(void); + void menu_add_dep(struct expr *dep); ++void menu_add_visibility(struct expr *dep); + struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, 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); +@@ -101,10 +123,19 @@ + /* 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); ++char *dir_name(char *path); ++char *base_name(char *path); + + struct gstr { + size_t len; + char *s; ++ /* ++ * when max_width is not zero long lines in string s (if any) get ++ * wrapped not to exceed the max_width value ++ */ ++ int max_width; + }; + struct gstr str_new(void); + struct gstr str_assign(const char *s); +@@ -120,6 +151,8 @@ + void sym_clear_all_valid(void); + void sym_set_all_changed(void); + void sym_set_changed(struct symbol *sym); ++struct symbol *sym_choice_default(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); +diff -Nur uClibc-0.9.33.2/extra/config/lkc_proto.h uClibc-git/extra/config/lkc_proto.h +--- uClibc-0.9.33.2/extra/config/lkc_proto.h 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lkc_proto.h 2014-02-03 12:32:56.000000000 +0100 +@@ -1,28 +1,40 @@ ++#include + + /* confdata.c */ + P(conf_parse,void,(const char *name)); + P(conf_read,int,(const char *name)); + P(conf_read_simple,int,(const char *name, int)); ++P(conf_write_defconfig,int,(const char *name)); + P(conf_write,int,(const char *name)); + P(conf_write_autoconf,int,(void)); + P(conf_get_changed,bool,(void)); + P(conf_set_changed_callback, void,(void (*fn)(void))); ++P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); + + /* menu.c */ + P(rootmenu,struct menu,); + +-P(menu_is_visible,bool,(struct menu *menu)); ++P(menu_is_empty, bool, (struct menu *menu)); ++P(menu_is_visible, bool, (struct menu *menu)); ++P(menu_has_prompt, bool, (struct menu *menu)); + P(menu_get_prompt,const char *,(struct menu *menu)); + P(menu_get_root_menu,struct menu *,(struct menu *menu)); + P(menu_get_parent_menu,struct menu *,(struct menu *menu)); + P(menu_has_help,bool,(struct menu *menu)); + P(menu_get_help,const char *,(struct menu *menu)); ++P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head ++ *head)); ++P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head ++ *head)); ++P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); + + /* symbol.c */ + P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); + + P(sym_lookup,struct symbol *,(const char *name, int flags)); + P(sym_find,struct symbol *,(const char *name)); ++P(sym_expand_string_value,const char *,(const char *in)); ++P(sym_escape_string_value, const char *,(const char *in)); + P(sym_re_search,struct symbol **,(const char *pattern)); + P(sym_type_name,const char *,(enum symbol_type type)); + P(sym_calc_value,void,(struct symbol *sym)); +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/checklist.c uClibc-git/extra/config/lxdialog/checklist.c +--- uClibc-0.9.33.2/extra/config/lxdialog/checklist.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/checklist.c 2014-02-03 12:32:56.000000000 +0100 +@@ -31,6 +31,10 @@ + static void print_item(WINDOW * win, int choice, int selected) + { + int i; ++ char *list_item = malloc(list_width + 1); ++ ++ strncpy(list_item, item_str(), list_width - item_x); ++ list_item[list_width - item_x] = '\0'; + + /* Clear 'residue' of last item */ + wattrset(win, dlg.menubox.atr); +@@ -41,16 +45,18 @@ + wmove(win, choice, check_x); + wattrset(win, selected ? dlg.check_selected.atr + : dlg.check.atr); +- wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); ++ if (!item_is_tag(':')) ++ wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); + + wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); +- mvwaddch(win, choice, item_x, item_str()[0]); ++ mvwaddch(win, choice, item_x, list_item[0]); + wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); +- waddstr(win, (char *)item_str() + 1); ++ waddstr(win, list_item + 1); + if (selected) { + wmove(win, choice, check_x + 1); + wrefresh(win); + } ++ free(list_item); + } + + /* +@@ -126,16 +132,16 @@ + } + + do_resize: +- if (getmaxy(stdscr) < (height + 6)) ++ if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN)) + return -ERRDISPLAYTOOSMALL; +- if (getmaxx(stdscr) < (width + 6)) ++ if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN)) + return -ERRDISPLAYTOOSMALL; + + max_choice = MIN(list_height, item_count()); + + /* center dialog box on screen */ +- x = (COLS - width) / 2; +- y = (LINES - height) / 2; ++ x = (getmaxx(stdscr) - width) / 2; ++ y = (getmaxy(stdscr) - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + +@@ -174,6 +180,7 @@ + check_x = 0; + item_foreach() + check_x = MAX(check_x, strlen(item_str()) + 4); ++ check_x = MIN(check_x, list_width); + + check_x = (list_width - check_x) / 2; + item_x = check_x + 4; +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/check-lxdialog.sh uClibc-git/extra/config/lxdialog/check-lxdialog.sh +--- uClibc-0.9.33.2/extra/config/lxdialog/check-lxdialog.sh 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/check-lxdialog.sh 2014-02-03 12:32:56.000000000 +0100 +@@ -4,7 +4,9 @@ + # What library to link + ldflags() + { +- for ext in so a dylib ; do ++ pkg-config --libs ncursesw 2>/dev/null && exit ++ pkg-config --libs ncurses 2>/dev/null && exit ++ for ext in so a dll.a dylib ; do + for lib in ncursesw ncurses curses ; do + $cc -print-file-name=lib${lib}.${ext} | grep -q / + if [ $? -eq 0 ]; then +@@ -19,14 +21,13 @@ + # Where is ncurses.h? + ccflags() + { +- if [ -f /usr/include/ncursesw/ncurses.h ]; then +- echo '-I/usr/include/ncursesw -DCURSES_LOC=""' +- elif [ -f /usr/include/ncursesw/curses.h ]; then +- echo '-I/usr/include/ncursesw -DCURSES_LOC=""' ++ if [ -f /usr/include/ncursesw/curses.h ]; then ++ echo '-I/usr/include/ncursesw -DCURSES_LOC=""' ++ echo ' -DNCURSES_WIDECHAR=1' + elif [ -f /usr/include/ncurses/ncurses.h ]; then + echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncurses/curses.h ]; then +- echo '-I/usr/include/ncurses -DCURSES_LOC=""' ++ echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncurses.h ]; then + echo '-DCURSES_LOC=""' + else +@@ -40,7 +41,7 @@ + + # Check if we can link to ncurses + check() { +- $cc -xc - -o $tmp 2>/dev/null <<'EOF' ++ $cc -x c - -o $tmp 2>/dev/null <<'EOF' + #include CURSES_LOC + main() {} + EOF +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/dialog.h uClibc-git/extra/config/lxdialog/dialog.h +--- uClibc-0.9.33.2/extra/config/lxdialog/dialog.h 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/dialog.h 2014-02-03 12:32:56.000000000 +0100 +@@ -106,8 +106,14 @@ + int hl; /* highlight this item */ + }; + ++struct subtitle_list { ++ struct subtitle_list *next; ++ const char *text; ++}; ++ + struct dialog_info { + const char *backtitle; ++ struct subtitle_list *subtitles; + struct dialog_color screen; + struct dialog_color shadow; + struct dialog_color dialog; +@@ -144,6 +150,7 @@ + */ + extern struct dialog_info dlg; + extern char dialog_input_result[]; ++extern int saved_x, saved_y; /* Needed in signal handler in mconf.c */ + + /* + * Function prototypes +@@ -193,8 +200,23 @@ + int on_key_esc(WINDOW *win); + int on_key_resize(void); + ++/* minimum (re)size values */ ++#define CHECKLIST_HEIGTH_MIN 6 /* For dialog_checklist() */ ++#define CHECKLIST_WIDTH_MIN 6 ++#define INPUTBOX_HEIGTH_MIN 2 /* For dialog_inputbox() */ ++#define INPUTBOX_WIDTH_MIN 2 ++#define MENUBOX_HEIGTH_MIN 15 /* For dialog_menu() */ ++#define MENUBOX_WIDTH_MIN 65 ++#define TEXTBOX_HEIGTH_MIN 8 /* For dialog_textbox() */ ++#define TEXTBOX_WIDTH_MIN 8 ++#define YESNO_HEIGTH_MIN 4 /* For dialog_yesno() */ ++#define YESNO_WIDTH_MIN 4 ++#define WINDOW_HEIGTH_MIN 19 /* For init_dialog() */ ++#define WINDOW_WIDTH_MIN 80 ++ + int init_dialog(const char *backtitle); + void set_dialog_backtitle(const char *backtitle); ++void set_dialog_subtitles(struct subtitle_list *subtitles); + void end_dialog(int x, int y); + void attr_clear(WINDOW * win, int height, int width, chtype attr); + void dialog_clear(void); +@@ -209,12 +231,17 @@ + int dialog_yesno(const char *title, const char *prompt, int height, int width); + int dialog_msgbox(const char *title, const char *prompt, int height, + int width, int pause); +-int dialog_textbox(const char *title, const char *file, int height, int width); ++ ++ ++typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void ++ *_data); ++int dialog_textbox(const char *title, char *tbuf, int initial_height, ++ int initial_width, int *keys, int *_vscroll, int *_hscroll, ++ update_text_fn update_text, void *data); + int dialog_menu(const char *title, const char *prompt, + const void *selected, int *s_scroll); + int dialog_checklist(const char *title, const char *prompt, int height, + int width, int list_height); +-extern char dialog_input_result[]; + int dialog_inputbox(const char *title, const char *prompt, int height, + int width, const char *init); + +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/inputbox.c uClibc-git/extra/config/lxdialog/inputbox.c +--- uClibc-0.9.33.2/extra/config/lxdialog/inputbox.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/inputbox.c 2014-02-03 12:32:56.000000000 +0100 +@@ -45,7 +45,8 @@ + const char *init) + { + int i, x, y, box_y, box_x, box_width; +- int input_x = 0, scroll = 0, key = 0, button = -1; ++ int input_x = 0, key = 0, button = -1; ++ int show_x, len, pos; + char *instr = dialog_input_result; + WINDOW *dialog; + +@@ -55,14 +56,14 @@ + strcpy(instr, init); + + do_resize: +- if (getmaxy(stdscr) <= (height - 2)) ++ if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN)) + return -ERRDISPLAYTOOSMALL; +- if (getmaxx(stdscr) <= (width - 2)) ++ if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN)) + return -ERRDISPLAYTOOSMALL; + + /* center dialog box on screen */ +- x = (COLS - width) / 2; +- y = (LINES - height) / 2; ++ x = (getmaxx(stdscr) - width) / 2; ++ y = (getmaxy(stdscr) - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + +@@ -97,14 +98,17 @@ + wmove(dialog, box_y, box_x); + wattrset(dialog, dlg.inputbox.atr); + +- input_x = strlen(instr); ++ len = strlen(instr); ++ pos = len; + +- if (input_x >= box_width) { +- scroll = input_x - box_width + 1; ++ if (len >= box_width) { ++ show_x = len - box_width + 1; + input_x = box_width - 1; + for (i = 0; i < box_width - 1; i++) +- waddch(dialog, instr[scroll + i]); ++ waddch(dialog, instr[show_x + i]); + } else { ++ show_x = 0; ++ input_x = len; + waddstr(dialog, instr); + } + +@@ -121,45 +125,104 @@ + case KEY_UP: + case KEY_DOWN: + break; +- case KEY_LEFT: +- continue; +- case KEY_RIGHT: +- continue; + case KEY_BACKSPACE: + case 127: +- if (input_x || scroll) { ++ if (pos) { + wattrset(dialog, dlg.inputbox.atr); +- if (!input_x) { +- scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); +- wmove(dialog, box_y, box_x); +- for (i = 0; i < box_width; i++) +- waddch(dialog, +- instr[scroll + input_x + i] ? +- instr[scroll + input_x + i] : ' '); +- input_x = strlen(instr) - scroll; ++ if (input_x == 0) { ++ show_x--; + } else + input_x--; +- instr[scroll + input_x] = '\0'; +- mvwaddch(dialog, box_y, input_x + box_x, ' '); ++ ++ if (pos < len) { ++ for (i = pos - 1; i < len; i++) { ++ instr[i] = instr[i+1]; ++ } ++ } ++ ++ pos--; ++ len--; ++ instr[len] = '\0'; ++ wmove(dialog, box_y, box_x); ++ for (i = 0; i < box_width; i++) { ++ if (!instr[show_x + i]) { ++ waddch(dialog, ' '); ++ break; ++ } ++ waddch(dialog, instr[show_x + i]); ++ } + wmove(dialog, box_y, input_x + box_x); + wrefresh(dialog); + } + continue; ++ case KEY_LEFT: ++ if (pos > 0) { ++ if (input_x > 0) { ++ wmove(dialog, box_y, --input_x + box_x); ++ } else if (input_x == 0) { ++ show_x--; ++ wmove(dialog, box_y, box_x); ++ for (i = 0; i < box_width; i++) { ++ if (!instr[show_x + i]) { ++ waddch(dialog, ' '); ++ break; ++ } ++ waddch(dialog, instr[show_x + i]); ++ } ++ wmove(dialog, box_y, box_x); ++ } ++ pos--; ++ } ++ continue; ++ case KEY_RIGHT: ++ if (pos < len) { ++ if (input_x < box_width - 1) { ++ wmove(dialog, box_y, ++input_x + box_x); ++ } else if (input_x == box_width - 1) { ++ show_x++; ++ wmove(dialog, box_y, box_x); ++ for (i = 0; i < box_width; i++) { ++ if (!instr[show_x + i]) { ++ waddch(dialog, ' '); ++ break; ++ } ++ waddch(dialog, instr[show_x + i]); ++ } ++ wmove(dialog, box_y, input_x + box_x); ++ } ++ pos++; ++ } ++ continue; + default: + if (key < 0x100 && isprint(key)) { +- if (scroll + input_x < MAX_LEN) { ++ if (len < MAX_LEN) { + wattrset(dialog, dlg.inputbox.atr); +- instr[scroll + input_x] = key; +- instr[scroll + input_x + 1] = '\0'; ++ if (pos < len) { ++ for (i = len; i > pos; i--) ++ instr[i] = instr[i-1]; ++ instr[pos] = key; ++ } else { ++ instr[len] = key; ++ } ++ pos++; ++ len++; ++ instr[len] = '\0'; ++ + if (input_x == box_width - 1) { +- scroll++; +- wmove(dialog, box_y, box_x); +- for (i = 0; i < box_width - 1; i++) +- waddch(dialog, instr [scroll + i]); ++ show_x++; + } else { +- wmove(dialog, box_y, input_x++ + box_x); +- waddch(dialog, key); ++ input_x++; ++ } ++ ++ wmove(dialog, box_y, box_x); ++ for (i = 0; i < box_width; i++) { ++ if (!instr[show_x + i]) { ++ waddch(dialog, ' '); ++ break; ++ } ++ waddch(dialog, instr[show_x + i]); + } ++ wmove(dialog, box_y, input_x + box_x); + wrefresh(dialog); + } else + flash(); /* Alarm user about overflow */ +@@ -180,7 +243,7 @@ + case KEY_LEFT: + switch (button) { + case -1: +- button = 1; /* Indicates "Cancel" button is selected */ ++ button = 1; /* Indicates "Help" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 0: +@@ -204,7 +267,7 @@ + print_buttons(dialog, height, width, 0); + break; + case 0: +- button = 1; /* Indicates "Cancel" button is selected */ ++ button = 1; /* Indicates "Help" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 1: +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/menubox.c uClibc-git/extra/config/lxdialog/menubox.c +--- uClibc-0.9.33.2/extra/config/lxdialog/menubox.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/menubox.c 2014-02-03 12:32:56.000000000 +0100 +@@ -154,12 +154,14 @@ + */ + static void print_buttons(WINDOW * win, int height, int width, int selected) + { +- int x = width / 2 - 16; ++ int x = width / 2 - 28; + int y = height - 2; + + print_button(win, gettext("Select"), y, x, selected == 0); + print_button(win, gettext(" Exit "), y, x + 12, selected == 1); + print_button(win, gettext(" Help "), y, x + 24, selected == 2); ++ print_button(win, gettext(" Save "), y, x + 36, selected == 3); ++ print_button(win, gettext(" Load "), y, x + 48, selected == 4); + + wmove(win, y, x + 1 + 12 * selected); + wrefresh(win); +@@ -191,7 +193,7 @@ + do_resize: + height = getmaxy(stdscr); + width = getmaxx(stdscr); +- if (height < 15 || width < 65) ++ if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN) + return -ERRDISPLAYTOOSMALL; + + height -= 4; +@@ -201,8 +203,8 @@ + max_choice = MIN(menu_height, item_count()); + + /* center dialog box on screen */ +- x = (COLS - width) / 2; +- y = (LINES - height) / 2; ++ x = (getmaxx(stdscr) - width) / 2; ++ y = (getmaxy(stdscr) - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + +@@ -301,10 +303,11 @@ + } + } + +- if (i < max_choice || +- key == KEY_UP || key == KEY_DOWN || +- key == '-' || key == '+' || +- key == KEY_PPAGE || key == KEY_NPAGE) { ++ if (item_count() != 0 && ++ (i < max_choice || ++ key == KEY_UP || key == KEY_DOWN || ++ key == '-' || key == '+' || ++ key == KEY_PPAGE || key == KEY_NPAGE)) { + /* Remove highligt of current item */ + print_item(scroll + choice, choice, FALSE); + +@@ -372,7 +375,7 @@ + case TAB: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) +- ? 2 : (button > 2 ? 0 : button); ++ ? 4 : (button > 4 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh(menu); +@@ -383,6 +386,10 @@ + case 'n': + case 'm': + case '/': ++ case 'h': ++ case '?': ++ case 'z': ++ case '\n': + /* save scroll info */ + *s_scroll = scroll; + delwin(menu); +@@ -390,30 +397,26 @@ + item_set(scroll + choice); + item_set_selected(1); + switch (key) { ++ case 'h': ++ case '?': ++ return 2; + case 's': +- return 3; + case 'y': +- return 3; ++ return 5; + case 'n': +- return 4; ++ return 6; + case 'm': +- return 5; ++ return 7; + case ' ': +- return 6; ++ return 8; + case '/': +- return 7; ++ return 9; ++ case 'z': ++ return 10; ++ case '\n': ++ return button; + } + return 0; +- case 'h': +- case '?': +- button = 2; +- case '\n': +- *s_scroll = scroll; +- delwin(menu); +- delwin(dialog); +- item_set(scroll + choice); +- item_set_selected(1); +- return button; + case 'e': + case 'x': + key = KEY_ESC; +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/textbox.c uClibc-git/extra/config/lxdialog/textbox.c +--- uClibc-0.9.33.2/extra/config/lxdialog/textbox.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/textbox.c 2014-02-03 12:32:56.000000000 +0100 +@@ -22,23 +22,25 @@ + #include "dialog.h" + + static void back_lines(int n); +-static void print_page(WINDOW * win, int height, int width); +-static void print_line(WINDOW * win, int row, int width); ++static void print_page(WINDOW *win, int height, int width, update_text_fn ++ update_text, void *data); ++static void print_line(WINDOW *win, int row, int width); + static char *get_line(void); + static void print_position(WINDOW * win); + + static int hscroll; + static int begin_reached, end_reached, page_length; +-static const char *buf; +-static const char *page; ++static char *buf; ++static char *page; + + /* + * refresh window content + */ + static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, +- int cur_y, int cur_x) ++ int cur_y, int cur_x, update_text_fn update_text, ++ void *data) + { +- print_page(box, boxh, boxw); ++ print_page(box, boxh, boxw, update_text, data); + print_position(dialog); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); +@@ -47,14 +49,18 @@ + + /* + * Display text from a file in a dialog box. ++ * ++ * keys is a null-terminated array ++ * update_text() may not add or remove any '\n' or '\0' in tbuf + */ +-int dialog_textbox(const char *title, const char *tbuf, +- int initial_height, int initial_width) ++int dialog_textbox(const char *title, char *tbuf, int initial_height, ++ int initial_width, int *keys, int *_vscroll, int *_hscroll, ++ update_text_fn update_text, void *data) + { + int i, x, y, cur_x, cur_y, key = 0; + int height, width, boxh, boxw; +- int passed_end; + WINDOW *dialog, *box; ++ bool done = false; + + begin_reached = 1; + end_reached = 0; +@@ -63,9 +69,18 @@ + buf = tbuf; + page = buf; /* page is pointer to start of page to be displayed */ + ++ if (_vscroll && *_vscroll) { ++ begin_reached = 0; ++ ++ for (i = 0; i < *_vscroll; i++) ++ get_line(); ++ } ++ if (_hscroll) ++ hscroll = *_hscroll; ++ + do_resize: + getmaxyx(stdscr, height, width); +- if (height < 8 || width < 8) ++ if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN) + return -ERRDISPLAYTOOSMALL; + if (initial_height != 0) + height = initial_height; +@@ -83,8 +98,8 @@ + width = 0; + + /* center dialog box on screen */ +- x = (COLS - width) / 2; +- y = (LINES - height) / 2; ++ x = (getmaxx(stdscr) - width) / 2; ++ y = (getmaxy(stdscr) - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + +@@ -120,25 +135,28 @@ + + /* Print first page of text */ + attr_clear(box, boxh, boxw, dlg.dialog.atr); +- refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text, ++ data); + +- while ((key != KEY_ESC) && (key != '\n')) { ++ while (!done) { + key = wgetch(dialog); + switch (key) { + case 'E': /* Exit */ + case 'e': + case 'X': + case 'x': +- delwin(box); +- delwin(dialog); +- return 0; ++ case 'q': ++ case '\n': ++ done = true; ++ break; + case 'g': /* First page */ + case KEY_HOME: + if (!begin_reached) { + begin_reached = 1; + page = buf; + refresh_text_box(dialog, box, boxh, boxw, +- cur_y, cur_x); ++ cur_y, cur_x, update_text, ++ data); + } + break; + case 'G': /* Last page */ +@@ -148,78 +166,48 @@ + /* point to last char in buf */ + page = buf + strlen(buf); + back_lines(boxh); +- refresh_text_box(dialog, box, boxh, boxw, +- cur_y, cur_x); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, ++ cur_x, update_text, data); + break; + case 'K': /* Previous line */ + case 'k': + case KEY_UP: +- if (!begin_reached) { +- back_lines(page_length + 1); +- +- /* We don't call print_page() here but use +- * scrolling to ensure faster screen update. +- * However, 'end_reached' and 'page_length' +- * should still be updated, and 'page' should +- * point to start of next page. This is done +- * by calling get_line() in the following +- * 'for' loop. */ +- scrollok(box, TRUE); +- wscrl(box, -1); /* Scroll box region down one line */ +- scrollok(box, FALSE); +- page_length = 0; +- passed_end = 0; +- for (i = 0; i < boxh; i++) { +- if (!i) { +- /* print first line of page */ +- print_line(box, 0, boxw); +- wnoutrefresh(box); +- } else +- /* Called to update 'end_reached' and 'page' */ +- get_line(); +- if (!passed_end) +- page_length++; +- if (end_reached && !passed_end) +- passed_end = 1; +- } ++ if (begin_reached) ++ break; + +- print_position(dialog); +- wmove(dialog, cur_y, cur_x); /* Restore cursor position */ +- wrefresh(dialog); +- } ++ back_lines(page_length + 1); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, ++ cur_x, update_text, data); + break; + case 'B': /* Previous page */ + case 'b': ++ case 'u': + case KEY_PPAGE: + if (begin_reached) + break; + back_lines(page_length + boxh); +- refresh_text_box(dialog, box, boxh, boxw, +- cur_y, cur_x); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, ++ cur_x, update_text, data); + break; + case 'J': /* Next line */ + case 'j': + case KEY_DOWN: +- if (!end_reached) { +- begin_reached = 0; +- scrollok(box, TRUE); +- scroll(box); /* Scroll box region up one line */ +- scrollok(box, FALSE); +- print_line(box, boxh - 1, boxw); +- wnoutrefresh(box); +- print_position(dialog); +- wmove(dialog, cur_y, cur_x); /* Restore cursor position */ +- wrefresh(dialog); +- } ++ if (end_reached) ++ break; ++ ++ back_lines(page_length - 1); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, ++ cur_x, update_text, data); + break; + case KEY_NPAGE: /* Next page */ + case ' ': ++ case 'd': + if (end_reached) + break; + + begin_reached = 0; +- refresh_text_box(dialog, box, boxh, boxw, +- cur_y, cur_x); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, ++ cur_x, update_text, data); + break; + case '0': /* Beginning of line */ + case 'H': /* Scroll left */ +@@ -234,8 +222,8 @@ + hscroll--; + /* Reprint current page to scroll horizontally */ + back_lines(page_length); +- refresh_text_box(dialog, box, boxh, boxw, +- cur_y, cur_x); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, ++ cur_x, update_text, data); + break; + case 'L': /* Scroll right */ + case 'l': +@@ -245,11 +233,12 @@ + hscroll++; + /* Reprint current page to scroll horizontally */ + back_lines(page_length); +- refresh_text_box(dialog, box, boxh, boxw, +- cur_y, cur_x); ++ refresh_text_box(dialog, box, boxh, boxw, cur_y, ++ cur_x, update_text, data); + break; + case KEY_ESC: +- key = on_key_esc(dialog); ++ if (on_key_esc(dialog) == KEY_ESC) ++ done = true; + break; + case KEY_RESIZE: + back_lines(height); +@@ -257,11 +246,31 @@ + delwin(dialog); + on_key_resize(); + goto do_resize; ++ default: ++ for (i = 0; keys[i]; i++) { ++ if (key == keys[i]) { ++ done = true; ++ break; ++ } ++ } + } + } + delwin(box); + delwin(dialog); +- return key; /* ESC pressed */ ++ if (_vscroll) { ++ const char *s; ++ ++ s = buf; ++ *_vscroll = 0; ++ back_lines(page_length); ++ while (s < page && (s = strchr(s, '\n'))) { ++ (*_vscroll)++; ++ s++; ++ } ++ } ++ if (_hscroll) ++ *_hscroll = hscroll; ++ return key; + } + + /* +@@ -298,12 +307,23 @@ + } + + /* +- * Print a new page of text. Called by dialog_textbox(). ++ * Print a new page of text. + */ +-static void print_page(WINDOW * win, int height, int width) ++static void print_page(WINDOW *win, int height, int width, update_text_fn ++ update_text, void *data) + { + int i, passed_end = 0; + ++ if (update_text) { ++ char *end; ++ ++ for (i = 0; i < height; i++) ++ get_line(); ++ end = page; ++ back_lines(height); ++ update_text(buf, page - buf, end - buf, data); ++ } ++ + page_length = 0; + for (i = 0; i < height; i++) { + print_line(win, i, width); +@@ -316,11 +336,10 @@ + } + + /* +- * Print a new line of text. Called by dialog_textbox() and print_page(). ++ * Print a new line of text. + */ + static void print_line(WINDOW * win, int row, int width) + { +- int y, x; + char *line; + + line = get_line(); +@@ -329,10 +348,10 @@ + waddch(win, ' '); + waddnstr(win, line, MIN(strlen(line), width - 2)); + +- getyx(win, y, x); + /* Clear 'residue' of previous line */ + #if OLD_NCURSES + { ++ int x = getcurx(win); + int i; + for (i = 0; i < width - x; i++) + waddch(win, ' '); +@@ -355,10 +374,8 @@ + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { +- if (!end_reached) { +- end_reached = 1; +- break; +- } ++ end_reached = 1; ++ break; + } else if (i < MAX_LEN) + line[i++] = *(page++); + else { +@@ -371,7 +388,7 @@ + if (i <= MAX_LEN) + line[i] = '\0'; + if (!end_reached) +- page++; /* move pass '\n' */ ++ page++; /* move past '\n' */ + + return line; + } +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/util.c uClibc-git/extra/config/lxdialog/util.c +--- uClibc-0.9.33.2/extra/config/lxdialog/util.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/util.c 2014-02-03 12:32:56.000000000 +0100 +@@ -19,8 +19,13 @@ + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#include ++ + #include "dialog.h" + ++/* Needed in signal handler in mconf.c */ ++int saved_x, saved_y; ++ + struct dialog_info dlg; + + static void set_mono_theme(void) +@@ -249,15 +254,56 @@ + + void dialog_clear(void) + { +- attr_clear(stdscr, LINES, COLS, dlg.screen.atr); ++ int lines, columns; ++ ++ lines = getmaxy(stdscr); ++ columns = getmaxx(stdscr); ++ ++ attr_clear(stdscr, lines, columns, dlg.screen.atr); + /* Display background title if it exists ... - SLH */ + if (dlg.backtitle != NULL) { +- int i; ++ int i, len = 0, skip = 0; ++ struct subtitle_list *pos; + + wattrset(stdscr, dlg.screen.atr); + mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); ++ ++ for (pos = dlg.subtitles; pos != NULL; pos = pos->next) { ++ /* 3 is for the arrow and spaces */ ++ len += strlen(pos->text) + 3; ++ } ++ + wmove(stdscr, 1, 1); +- for (i = 1; i < COLS - 1; i++) ++ if (len > columns - 2) { ++ const char *ellipsis = "[...] "; ++ waddstr(stdscr, ellipsis); ++ skip = len - (columns - 2 - strlen(ellipsis)); ++ } ++ ++ for (pos = dlg.subtitles; pos != NULL; pos = pos->next) { ++ if (skip == 0) ++ waddch(stdscr, ACS_RARROW); ++ else ++ skip--; ++ ++ if (skip == 0) ++ waddch(stdscr, ' '); ++ else ++ skip--; ++ ++ if (skip < strlen(pos->text)) { ++ waddstr(stdscr, pos->text + skip); ++ skip = 0; ++ } else ++ skip -= strlen(pos->text); ++ ++ if (skip == 0) ++ waddch(stdscr, ' '); ++ else ++ skip--; ++ } ++ ++ for (i = len + 1; i < columns - 1; i++) + waddch(stdscr, ACS_HLINE); + } + wnoutrefresh(stdscr); +@@ -271,8 +317,12 @@ + int height, width; + + initscr(); /* Init curses */ ++ ++ /* Get current cursor position for signal handler in mconf.c */ ++ getyx(stdscr, saved_y, saved_x); ++ + getmaxyx(stdscr, height, width); +- if (height < 19 || width < 80) { ++ if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) { + endwin(); + return -ERRDISPLAYTOOSMALL; + } +@@ -293,6 +343,11 @@ + dlg.backtitle = backtitle; + } + ++void set_dialog_subtitles(struct subtitle_list *subtitles) ++{ ++ dlg.subtitles = subtitles; ++} ++ + /* + * End using dialog functions. + */ +@@ -321,27 +376,19 @@ + /* + * Print a string of text in a window, automatically wrap around to the + * next line if the string is too long to fit on one line. Newline +- * characters '\n' are replaced by spaces. We start on a new line ++ * characters '\n' are propperly processed. We start on a new line + * if there is no room for at least 4 nonblanks following a double-space. + */ + void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) + { + int newl, cur_x, cur_y; +- int i, prompt_len, room, wlen; +- char tempstr[MAX_LEN + 1], *word, *sp, *sp2; ++ int prompt_len, room, wlen; ++ char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0; + + strcpy(tempstr, prompt); + + prompt_len = strlen(tempstr); + +- /* +- * Remove newlines +- */ +- for (i = 0; i < prompt_len; i++) { +- if (tempstr[i] == '\n') +- tempstr[i] = ' '; +- } +- + if (prompt_len <= width - x * 2) { /* If prompt is short */ + wmove(win, y, (width - prompt_len) / 2); + waddstr(win, tempstr); +@@ -351,7 +398,10 @@ + newl = 1; + word = tempstr; + while (word && *word) { +- sp = strchr(word, ' '); ++ sp = strpbrk(word, "\n "); ++ if (sp && *sp == '\n') ++ newline_separator = sp; ++ + if (sp) + *sp++ = 0; + +@@ -363,7 +413,7 @@ + if (wlen > room || + (newl && wlen < 4 && sp + && wlen + 1 + strlen(sp) > room +- && (!(sp2 = strchr(sp, ' ')) ++ && (!(sp2 = strpbrk(sp, "\n ")) + || wlen + 1 + (sp2 - sp) > room))) { + cur_y++; + cur_x = x; +@@ -371,7 +421,15 @@ + wmove(win, cur_y, cur_x); + waddstr(win, word); + getyx(win, cur_y, cur_x); +- cur_x++; ++ ++ /* Move to the next line if the word separator was a newline */ ++ if (newline_separator) { ++ cur_y++; ++ cur_x = x; ++ newline_separator = 0; ++ } else ++ cur_x++; ++ + if (sp && *sp == ' ') { + cur_x++; /* double space */ + while (*++sp == ' ') ; +diff -Nur uClibc-0.9.33.2/extra/config/lxdialog/yesno.c uClibc-git/extra/config/lxdialog/yesno.c +--- uClibc-0.9.33.2/extra/config/lxdialog/yesno.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/lxdialog/yesno.c 2014-02-03 12:32:56.000000000 +0100 +@@ -45,14 +45,14 @@ + WINDOW *dialog; + + do_resize: +- if (getmaxy(stdscr) < (height + 4)) ++ if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN)) + return -ERRDISPLAYTOOSMALL; +- if (getmaxx(stdscr) < (width + 4)) ++ if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN)) + return -ERRDISPLAYTOOSMALL; + + /* center dialog box on screen */ +- x = (COLS - width) / 2; +- y = (LINES - height) / 2; ++ x = (getmaxx(stdscr) - width) / 2; ++ y = (getmaxy(stdscr) - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + +diff -Nur uClibc-0.9.33.2/extra/config/Makefile uClibc-git/extra/config/Makefile +--- uClibc-0.9.33.2/extra/config/Makefile 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/Makefile 2014-02-03 12:32:56.000000000 +0100 +@@ -1,16 +1,17 @@ + top_srcdir ?= ../../ + +-include $(top_srcdir)Rules.mak +-include $(top_srcdir)Makerules +- +-# ugh +-top_srcdir:=$(shell cd $(top_srcdir) && pwd)/ + ifdef O + top_builddir ?= ../../ + else + top_builddir = ../../ + endif +-srctree := $(top_srcdir) ++ ++include $(top_srcdir)Rules.mak ++include $(top_srcdir)Makerules ++ ++# ugh ++top_srcdir:=$(shell cd $(top_srcdir) && pwd)/ ++ + src := extra/config + obj := $(top_builddir)$(src) + +@@ -18,29 +19,23 @@ + generated := $(addprefix $(obj)/,$(generated:.c=.o)) + + include $(top_srcdir)extra/config/Makefile.kconfig +-PHONY += $(always) +-chk-lxdialog := $(top_srcdir)$(src)/lxdialog/check-lxdialog.sh +-check-lxdialog := cd $(obj) && $(CONFIG_SHELL) $(chk-lxdialog) +-HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) -c '$(check-lxdialog) -ccflags') +-HOST_LOADLIBES = $(shell $(CONFIG_SHELL) -c '$(check-lxdialog) -ldflags $(HOSTCC)') +-HOST_EXTRACFLAGS += -DLOCALE +-HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) -c '$(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)') ++HOST_EXTRACFLAGS += -DCONFIG_='""' + + # do not create temporary object in the readonly srctree +-$(obj)/dochecklxdialog: +- $(Q)cd $(obj) && $(CONFIG_SHELL) $(chk-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) +-HOSTCFLAGS_lex.zconf.o := -I$(top_srcdir)$(src) ++$(obj)/dochecklxdialog: CONFIG_SHELL:=cd $(obj) && $(CONFIG_SHELL) ++HOSTCFLAGS_zconf.lex.o := -I$(top_srcdir)$(src) + HOSTCFLAGS_zconf.tab.o := -I$(top_srcdir)$(src) + conf-objs := $(addprefix $(obj)/,$(conf-objs)) + mconf-objs := $(addprefix $(obj)/,$(mconf-objs)) ++nconf-objs := $(addprefix $(obj)/,$(nconf-objs)) + kxgettext-objs := $(addprefix $(obj)/,$(kxgettext-objs)) + + ifeq ($(findstring mconf,$(MAKECMDGOALS)),mconf) + hostprogs-y += mconf + endif +- +-#BUILD_CFLAGS-config = -W -Wall -pedantic +-#BUILD_CFLAGS-lxdialog = -W -Wall -pedantic ++ifeq ($(findstring nconf,$(MAKECMDGOALS)),nconf) ++hostprogs-y += nconf ++endif + + __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) + host-csingle:= $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) +@@ -48,16 +43,18 @@ + $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) + host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs))) + +-conf mconf kxgettext: %: $(obj)/% +-$(obj)/conf $(obj)/mconf $(obj)/kxgettext: BUILD_LDFLAGS=$(HOST_LOADLIBES) ++conf mconf nconf kxgettext: %: $(obj)/% ++$(obj)/conf $(obj)/mconf $(obj)/nconf $(obj)/kxgettext: BUILD_LDFLAGS=$(HOSTLOADLIBES_$(@F)) + $(obj)/conf: $(conf-objs) + $(hcompile.u) + $(obj)/mconf: $(mconf-objs) + $(hcompile.u) ++$(obj)/nconf: $(nconf-objs) ++ $(hcompile.u) + $(obj)/kxgettext: $(kxgettext-objs) + $(hcompile.u) + +-$(host-csingle) $(host-cmulti) $(host-cobjs): BUILD_CFLAGS=$(HOST_EXTRACFLAGS) \ ++$(host-csingle) $(host-cmulti) $(host-cobjs): BUILD_CFLAGS+=$(HOST_EXTRACFLAGS) \ + $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) + + host-cobjs.nogen := $(filter-out $(generated),$(host-cobjs)) +@@ -68,19 +65,18 @@ + $(host-cobjs.generated): $(obj)/%.o: $(obj)/%.c + $(hcompile.o) + +-ifndef LKC_GENPARSER ++# we use the pre-generated always + $(obj)/%:: $(top_srcdir)$(src)/%_shipped + @$(disp_gen) + $(Q)cat $< > $@ +-endif ++ + CLEAN_extra/config menuconfig_clean: + $(do_rm) $(clean-files) $(lxdialog) conf $(wildcard *.o) +-distclean: clean +- $(do_rm) $(lxdialog) $(conf-objs) $(mconf-objs) \ ++distclean: CLEAN_extra/config ++ $(Q)$(RM) -r $(lxdialog) $(conf-objs) $(mconf-objs) $(nconf-objs) \ + $(kxgettext-objs) \ + $(hostprogs-y) $(qconf-cxxobjs) $(qconf-objs) $(gconf-objs) \ +- .depend +- $(do_rm) -r $(top_builddir)include/config ++ .depend \ ++ $(top_builddir)include/config $(top_builddir)include/generated + +-FORCE: +-.PHONY: FORCE clean distclean $(always) ++.PHONY: clean distclean $(PHONY) +diff -Nur uClibc-0.9.33.2/extra/config/Makefile.kconfig uClibc-git/extra/config/Makefile.kconfig +--- uClibc-0.9.33.2/extra/config/Makefile.kconfig 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/Makefile.kconfig 2014-02-03 12:32:56.000000000 +0100 +@@ -2,14 +2,18 @@ + # Kernel configuration targets + # These targets are used from top-level makefile + +-PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config ++PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \ ++ localmodconfig localyesconfig + + ifdef KBUILD_KCONFIG + Kconfig := $(KBUILD_KCONFIG) + else +-Kconfig := arch/$(SRCARCH)/Kconfig ++Kconfig := Kconfig + endif + ++# We need this, in case the user has it in its environment ++unexport CONFIG_ ++ + xconfig: $(obj)/qconf + $< $(Kconfig) + +@@ -20,91 +24,121 @@ + $< $(Kconfig) + + config: $(obj)/conf ++ $< --oldaskconfig $(Kconfig) ++ ++nconfig: $(obj)/nconf + $< $(Kconfig) + + oldconfig: $(obj)/conf +- $< -o $(Kconfig) ++ $< --$@ $(Kconfig) + + silentoldconfig: $(obj)/conf +- $< -s $(Kconfig) ++ $(Q)mkdir -p include/generated ++ $< --$@ $(Kconfig) ++ ++localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf ++ $(Q)mkdir -p include/generated ++ $(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config ++ $(Q)if [ -f .config ]; then \ ++ cmp -s .tmp.config .config || \ ++ (mv -f .config .config.old.1; \ ++ mv -f .tmp.config .config; \ ++ $(obj)/conf --silentoldconfig $(Kconfig); \ ++ mv -f .config.old.1 .config.old) \ ++ else \ ++ mv -f .tmp.config .config; \ ++ $(obj)/conf --silentoldconfig $(Kconfig); \ ++ fi ++ $(Q)rm -f .tmp.config + + # Create new linux.pot file + # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files +-# The symlink is used to repair a deficiency in arch/um + update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h +- $(Q)echo " GEN config" +- $(Q)xgettext --default-domain=linux \ +- --add-comments --keyword=_ --keyword=N_ \ +- --from-code=UTF-8 \ +- --files-from=scripts/kconfig/POTFILES.in \ ++ $(Q)echo " GEN config.pot" ++ $(Q)xgettext --default-domain=linux \ ++ --add-comments --keyword=_ --keyword=N_ \ ++ --from-code=UTF-8 \ ++ --files-from=$(srctree)/scripts/kconfig/POTFILES.in \ ++ --directory=$(srctree) --directory=$(objtree) \ + --output $(obj)/config.pot + $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot +- $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch +- $(Q)(for i in `ls arch/*/Kconfig`; \ ++ $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ ++ $(srctree)/arch/*/um/Kconfig`; \ + do \ +- echo " GEN $$i"; \ ++ echo " GEN $$i"; \ + $(obj)/kxgettext $$i \ + >> $(obj)/config.pot; \ + done ) ++ $(Q)echo " GEN linux.pot" + $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ + --output $(obj)/linux.pot +- $(Q)rm -f arch/um/Kconfig.arch + $(Q)rm -f $(obj)/config.pot + +-PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig ++PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig + +-randconfig: $(obj)/conf +- $< -r $(Kconfig) ++allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf ++ $< --$@ $(Kconfig) + +-allyesconfig: $(obj)/conf +- $< -y $(Kconfig) ++PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig + +-allnoconfig: $(obj)/conf +- $< -n $(Kconfig) ++listnewconfig olddefconfig: $(obj)/conf ++ $< --$@ $(Kconfig) + +-allmodconfig: $(obj)/conf +- $< -m $(Kconfig) ++# oldnoconfig is an alias of olddefconfig, because people already are dependent ++# on its behavior(sets new symbols to their default value but not 'n') with the ++# counter-intuitive name. ++oldnoconfig: $(obj)/conf ++ $< --olddefconfig $(Kconfig) ++ ++savedefconfig: $(obj)/conf ++ $< --$@=defconfig $(Kconfig) + + defconfig: $(obj)/conf + ifeq ($(KBUILD_DEFCONFIG),) +- $< -d $(Kconfig) ++ $< --defconfig $(Kconfig) + else + @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" +- $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) ++ $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) + endif + + %_defconfig: $(obj)/conf +- $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) ++ $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) + + # Help text used by make help + help: + @echo ' config - Update current config utilising a line-oriented program' ++ @echo ' nconfig - Update current config utilising a ncurses menu based program' + @echo ' menuconfig - Update current config utilising a menu based program' + @echo ' xconfig - Update current config utilising a QT based front-end' + @echo ' gconfig - Update current config utilising a GTK based front-end' + @echo ' oldconfig - Update current config utilising a provided .config as base' +- @echo ' silentoldconfig - Same as oldconfig, but quietly' +- @echo ' randconfig - New config with random answer to all options' +- @echo ' defconfig - New config with default answer to all options' +- @echo ' allmodconfig - New config selecting modules when possible' +- @echo ' allyesconfig - New config where all options are accepted with yes' ++ @echo ' localmodconfig - Update current config disabling modules not loaded' ++ @echo ' localyesconfig - Update current config converting local mods to core' ++ @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' ++ @echo ' defconfig - New config with default from ARCH supplied defconfig' ++ @echo ' savedefconfig - Save current config as ./defconfig (minimal config)' + @echo ' allnoconfig - New config where all options are answered with no' ++ @echo ' allyesconfig - New config where all options are accepted with yes' ++ @echo ' allmodconfig - New config selecting modules when possible' ++ @echo ' alldefconfig - New config with all symbols set to default' ++ @echo ' randconfig - New config with random answer to all options' ++ @echo ' listnewconfig - List new options' ++ @echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value' + + # lxdialog stuff + check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh + + # Use recursively expanded variables so we do not call gcc unless + # we really need to do so. (Do not call gcc as part of make mrproper) +-HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) +-HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) +- +-HOST_EXTRACFLAGS += -DLOCALE +- ++HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ ++ -DLOCALE + + # =========================================================================== + # Shared Makefile for the various kconfig executables: + # conf: Used for defconfig, oldconfig and related targets +-# mconf: Used for the mconfig target. ++# nconf: Used for the nconfig target. ++# Utilizes ncurses ++# mconf: Used for the menuconfig target + # Utilizes the lxdialog package + # qconf: Used for the xconfig target + # Based on QT which needs to be installed to compile it +@@ -116,15 +150,27 @@ + lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o + + conf-objs := conf.o zconf.tab.o +-mconf-objs := mconf.o zconf.tab.o $(lxdialog) ++mconf-objs := mconf.o zconf.tab.o $(lxdialog) ++nconf-objs := nconf.o zconf.tab.o nconf.gui.o + kxgettext-objs := kxgettext.o zconf.tab.o ++qconf-cxxobjs := qconf.o ++qconf-objs := zconf.tab.o ++gconf-objs := gconf.o zconf.tab.o ++ ++hostprogs-y := conf + +-hostprogs-y := conf qconf gconf kxgettext ++ifeq ($(MAKECMDGOALS),nconfig) ++ hostprogs-y += nconf ++endif + + ifeq ($(MAKECMDGOALS),menuconfig) + hostprogs-y += mconf + endif + ++ifeq ($(MAKECMDGOALS),update-po-config) ++ hostprogs-y += kxgettext ++endif ++ + ifeq ($(MAKECMDGOALS),xconfig) + qconf-target := 1 + endif +@@ -134,24 +180,23 @@ + + + ifeq ($(qconf-target),1) +-qconf-cxxobjs := qconf.o +-qconf-objs := kconfig_load.o zconf.tab.o ++ hostprogs-y += qconf + endif + + ifeq ($(gconf-target),1) +-gconf-objs := gconf.o kconfig_load.o zconf.tab.o ++ hostprogs-y += gconf + endif + +-clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ +- .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h +-clean-files += mconf qconf gconf ++clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck ++clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h ++clean-files += mconf qconf gconf nconf + clean-files += config.pot linux.pot + + # Check that we have the required ncurses stuff installed for lxdialog (menuconfig) + PHONY += $(obj)/dochecklxdialog + $(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog +-#$(obj)/dochecklxdialog: +-# $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) ++$(obj)/dochecklxdialog: ++ $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf) + + always := dochecklxdialog + +@@ -159,16 +204,24 @@ + HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)) + + # generated files seem to need this to find local include files +-HOSTCFLAGS_lex.zconf.o := -I$(src) ++HOSTCFLAGS_zconf.lex.o := -I$(src) + HOSTCFLAGS_zconf.tab.o := -I$(src) + +-HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl +-HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK ++LEX_PREFIX_zconf := zconf ++YACC_PREFIX_zconf := zconf ++ ++HOSTLOADLIBES_qconf = $(KC_QT_LIBS) ++HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) + + HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` + HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ +- -D LKC_DIRECT_LINK ++ -Wno-missing-prototypes + ++HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) ++ ++HOSTLOADLIBES_nconf = $(shell \ ++ pkg-config --libs menu panel ncurses 2>/dev/null \ ++ || echo "-lmenu -lpanel -lncurses" ) + $(obj)/qconf.o: $(obj)/.tmp_qtcheck + + ifeq ($(qconf-target),1) +@@ -178,40 +231,48 @@ + # QT needs some extra effort... + $(obj)/.tmp_qtcheck: + @set -e; echo " CHECK qt"; dir=""; pkg=""; \ +- pkg-config --exists qt 2> /dev/null && pkg=qt; \ +- pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ +- if [ -n "$$pkg" ]; then \ +- cflags="\$$(shell pkg-config $$pkg --cflags)"; \ +- libs="\$$(shell pkg-config $$pkg --libs)"; \ +- moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ +- dir="$$(pkg-config $$pkg --variable=prefix)"; \ ++ if ! pkg-config --exists QtCore 2> /dev/null; then \ ++ echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \ ++ pkg-config --exists qt 2> /dev/null && pkg=qt; \ ++ pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ ++ if [ -n "$$pkg" ]; then \ ++ cflags="\$$(shell pkg-config $$pkg --cflags)"; \ ++ libs="\$$(shell pkg-config $$pkg --libs)"; \ ++ moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ ++ dir="$$(pkg-config $$pkg --variable=prefix)"; \ ++ else \ ++ for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ ++ if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ ++ done; \ ++ if [ -z "$$dir" ]; then \ ++ echo >&2 "*"; \ ++ echo >&2 "* Unable to find any QT installation. Please make sure that"; \ ++ echo >&2 "* the QT4 or QT3 development package is correctly installed and"; \ ++ echo >&2 "* either qmake can be found or install pkg-config or set"; \ ++ echo >&2 "* the QTDIR environment variable to the correct location."; \ ++ echo >&2 "*"; \ ++ false; \ ++ fi; \ ++ libpath=$$dir/lib; lib=qt; osdir=""; \ ++ $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ ++ osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ ++ test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ ++ test -f $$libpath/libqt-mt.so && lib=qt-mt; \ ++ cflags="-I$$dir/include"; \ ++ libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ ++ moc="$$dir/bin/moc"; \ ++ fi; \ ++ if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \ ++ echo "*"; \ ++ echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \ ++ echo "*"; \ ++ moc="/usr/bin/moc"; \ ++ fi; \ + else \ +- for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ +- if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ +- done; \ +- if [ -z "$$dir" ]; then \ +- echo "*"; \ +- echo "* Unable to find the QT3 installation. Please make sure that"; \ +- echo "* the QT3 development package is correctly installed and"; \ +- echo "* either install pkg-config or set the QTDIR environment"; \ +- echo "* variable to the correct location."; \ +- echo "*"; \ +- false; \ +- fi; \ +- libpath=$$dir/lib; lib=qt; osdir=""; \ +- $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ +- osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ +- test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ +- test -f $$libpath/libqt-mt.so && lib=qt-mt; \ +- cflags="-I$$dir/include"; \ +- libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ +- moc="$$dir/bin/moc"; \ +- fi; \ +- if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \ +- echo "*"; \ +- echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \ +- echo "*"; \ +- moc="/usr/bin/moc"; \ ++ cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \ ++ libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \ ++ moc="\$$(shell pkg-config QtCore --variable=moc_location)"; \ ++ [ -n "$$moc" ] || moc="\$$(shell pkg-config QtCore --variable=prefix)/bin/moc"; \ + fi; \ + echo "KC_QT_CFLAGS=$$cflags" > $@; \ + echo "KC_QT_LIBS=$$libs" >> $@; \ +@@ -229,61 +290,33 @@ + if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \ + touch $@; \ + else \ +- echo "*"; \ +- echo "* GTK+ is present but version >= 2.0.0 is required."; \ +- echo "*"; \ ++ echo >&2 "*"; \ ++ echo >&2 "* GTK+ is present but version >= 2.0.0 is required."; \ ++ echo >&2 "*"; \ + false; \ + fi \ + else \ +- echo "*"; \ +- echo "* Unable to find the GTK+ installation. Please make sure that"; \ +- echo "* the GTK+ 2.0 development package is correctly installed..."; \ +- echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ +- echo "*"; \ ++ echo >&2 "*"; \ ++ echo >&2 "* Unable to find the GTK+ installation. Please make sure that"; \ ++ echo >&2 "* the GTK+ 2.0 development package is correctly installed..."; \ ++ echo >&2 "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ ++ echo >&2 "*"; \ + false; \ + fi + endif + +-$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c +- +-$(obj)/kconfig_load.o: $(obj)/lkc_defs.h ++$(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c + +-$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h ++$(obj)/qconf.o: $(obj)/qconf.moc + +-$(obj)/gconf.o: $(obj)/lkc_defs.h ++quiet_cmd_moc = MOC $@ ++ cmd_moc = $(KC_QT_MOC) -i $< -o $@ + +-$(obj)/%.moc: $(src)/%.h +- $(KC_QT_MOC) -i $< -o $@ +- +-$(obj)/lkc_defs.h: $(src)/lkc_proto.h +- sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' ++$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck ++ $(call cmd,moc) + + # Extract gconf menu items for I18N support + $(obj)/gconf.glade.h: $(obj)/gconf.glade +- intltool-extract --type=gettext/glade $(obj)/gconf.glade +- +-### +-# The following requires flex/bison/gperf +-# By default we use the _shipped versions, uncomment the following line if +-# you are modifying the flex/bison src. +-# LKC_GENPARSER := 1 +- +-ifdef LKC_GENPARSER +- +-$(obj)/zconf.tab.c: $(src)/zconf.y +-$(obj)/lex.zconf.c: $(src)/zconf.l +-$(obj)/zconf.hash.c: $(src)/zconf.gperf +- +-%.tab.c: %.y +- bison -l -b $* -p $(notdir $*) $< +- cp $@ $@_shipped +- +-lex.%.c: %.l +- flex -L -P$(notdir $*) -o$@ $< +- cp $@ $@_shipped +- +-%.hash.c: %.gperf +- gperf < $< > $@ +- cp $@ $@_shipped ++ $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ ++ $(obj)/gconf.glade + +-endif +diff -Nur uClibc-0.9.33.2/extra/config/mconf.c uClibc-git/extra/config/mconf.c +--- uClibc-0.9.33.2/extra/config/mconf.c 2012-05-15 09:20:09.000000000 +0200 ++++ uClibc-git/extra/config/mconf.c 2014-02-03 12:32:56.000000000 +0100 +@@ -15,20 +15,19 @@ + #include + #include + #include ++#include + #include + #include + +-#define LKC_DIRECT_LINK + #include "lkc.h" + #include "lxdialog/dialog.h" + + static const char mconf_readme[] = N_( + "Overview\n" + "--------\n" +-"Some features may be built directly into uClibc. Some features\n" +-"may be completely removed altogether. There are also certain\n" +-"parameters which are not really features, but must be\n" +-"entered in as decimal or hexadecimal numbers or possibly text.\n" ++"This interface let you select features and parameters for the build.\n" ++"Features can either be built-in, modularized, or ignored. Parameters\n" ++"must be entered in as decimal or hexadecimal numbers or text.\n" + "\n" + "Menu items beginning with following braces represent features that\n" + " [ ] can be built in or removed\n" +@@ -49,7 +48,7 @@ + "----------\n" + "o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" + " you wish to change or submenu wish to select and press .\n" +-" Submenus are designated by \"--->\".\n" ++" Submenus are designated by \"--->\", empty ones by \"----\".\n" + "\n" + " Shortcut: Press the option's highlighted letter (hotkey).\n" + " Pressing a hotkey more than once will sequence\n" +@@ -66,13 +65,15 @@ + " there is a delayed response which you may find annoying.\n" + "\n" + " Also, the and cursor keys will cycle between