diff options
author | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2014-12-22 10:10:40 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2014-12-22 10:10:40 +0100 |
commit | d18bf841d7c4867c06862147122de5cc2f01b4c6 (patch) | |
tree | 7da8495a47fb6a8ef9fc762421a81f12f7292cc4 /adk/config | |
parent | b390eafdcf03f34ac6e2c22be43c27fbc93f01f0 (diff) | |
parent | f919a87612241c71e924588610f22260a3e9370e (diff) |
Merge branch 'master' of git+ssh://openadk.org/git/openadk
Diffstat (limited to 'adk/config')
35 files changed, 11495 insertions, 2051 deletions
diff --git a/adk/config/Makefile b/adk/config/Makefile index 7e91da1bf..b6c253f18 100644 --- a/adk/config/Makefile +++ b/adk/config/Makefile @@ -78,7 +78,7 @@ lkc_defs.h: lkc_proto.h # The following requires flex/bison # By default we use the _shipped versions, uncomment the # following line if you are modifying the flex/bison src. -#LKC_GENPARSER:= 1 +# LKC_GENPARSER:= 1 ifdef LKC_GENPARSER @@ -86,7 +86,7 @@ ifdef LKC_GENPARSER bison -t -d -v -b $* -p $(notdir $*) $< %.hash.c: %.gperf - gperf < $< > $@ + gperf -t --output-file zconf.hash.c -a -C -E -g -k '1,3,$$' -p -t zconf.gperf lex.%.c: %.l flex -P$(notdir $*) -o$@ $< diff --git a/adk/config/conf.c b/adk/config/conf.c index 412656fec..fef75fc75 100644 --- a/adk/config/conf.c +++ b/adk/config/conf.c @@ -10,42 +10,48 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <getopt.h> #include <sys/stat.h> #include <sys/time.h> +#include <errno.h> -#define LKC_DIRECT_LINK #include "lkc.h" static void conf(struct menu *menu); static void check_conf(struct menu *menu); - -enum { - ask_all, - ask_new, - ask_silent, - set_default, - set_yes, - set_mod, - set_no, - set_random -} input_mode = ask_all; -char *defconfig_file; +static void xfgets(char *str, int size, FILE *in); + +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) @@ -68,9 +74,9 @@ static void strip(char *str) static void check_stdin(void) { if (!valid_stdin) { - printf("aborted!\n\n"); - printf("Console input/output is redirected. "); - printf("Run 'make oldconfig' to update configuration.\n\n"); + printf(_("aborted!\n\n")); + printf(_("Console input/output is redirected. ")); + printf(_("Run 'make oldconfig' to update configuration.\n\n")); exit(1); } } @@ -80,7 +86,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) enum symbol_type type = sym_get_type(sym); if (!sym_has_value(sym)) - printf("(NEW) "); + printf(_("(NEW) ")); line[0] = '\n'; line[1] = 0; @@ -93,17 +99,20 @@ static int conf_askvalue(struct symbol *sym, const char *def) } 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); - if (fgets(line, 128, stdin) != NULL) - return 1; + xfgets(line, 128, stdin); + if (!tty_stdio) + printf("\n"); + return 1; default: break; } @@ -121,7 +130,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) 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 @@ int conf_string(struct menu *menu) 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 @@ int conf_string(struct menu *menu) 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 @@ static int conf_sym(struct menu *menu) if (sym_set_tristate_value(sym, newval)) return 0; help: - printf("\n%s\n", get_help(menu)); + print_help(menu); } } @@ -228,11 +236,9 @@ static int conf_choice(struct menu *menu) { 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); @@ -281,7 +287,7 @@ static int conf_choice(struct menu *menu) if (child->sym->name) printf(" (%s)", child->sym->name); if (!sym_has_value(child->sym)) - printf(" (NEW)"); + printf(_(" (NEW)")); printf("\n"); } printf(_("%*schoice"), indent - 1, ""); @@ -294,20 +300,21 @@ static int conf_choice(struct menu *menu) 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); - if (fgets(line, 128, stdin) != NULL) - strip(line); + 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 @@ static int conf_choice(struct menu *menu) } 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 @@ static void conf(struct menu *menu) 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 @@ static void check_conf(struct menu *menu) 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,71 +446,114 @@ static void check_conf(struct menu *menu) check_conf(child); } +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] <kconfig-file>\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 <file> New config with default defined in <file>\n"); + printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n"); + printf(" --allnoconfig New config where all options are answered with no\n"); + 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"); +} + int main(int ac, char **av) { + const char *progname = av[0]; int opt; - const char *name; + const char *name, *defconfig_file = NULL /* gcc uninit */; struct stat tmpstat; -#ifndef KBUILD_NO_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); -#endif - while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { + tty_stdio = isatty(0) && isatty(1) && isatty(2); + + while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) { + 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]; @@ -503,8 +563,7 @@ int main(int ac, char **av) name = conf_get_configname(); if (stat(name, &tmpstat)) { fprintf(stderr, _("***\n" - "*** You have not yet configured your kernel!\n" - "*** (missing kernel config file \"%s\")\n" + "*** Configuration file \"%s\" not found!\n" "***\n" "*** Please run some configurator (e.g. \"make oldconfig\" or\n" "*** \"make menuconfig\" or \"make xconfig\").\n" @@ -514,7 +573,7 @@ int main(int ac, char **av) } switch (input_mode) { - case set_default: + case defconfig: if (!defconfig_file) defconfig_file = conf_get_default_confname(); if (conf_read(defconfig_file)) { @@ -524,31 +583,46 @@ int main(int ac, char **av) 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; @@ -559,41 +633,51 @@ int main(int ac, char **av) name = getenv("KCONFIG_NOSILENTUPDATE"); if (name && *name) { fprintf(stderr, - "\n*** Kernel 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; } @@ -602,18 +686,33 @@ int main(int ac, char **av) * All other commands are only used to generate a config. */ if (conf_get_changed() && conf_write(NULL)) { - fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n"); + fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); exit(1); } if (conf_write_autoconf()) { - fprintf(stderr, "\n*** Error during update of the kernel configuration.\n\n"); + 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 kernel configuration.\n\n"); + fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); exit(1); } } return 0; } + +/* + * Helper function to facilitate fgets() by Jean Sacren. + */ +void xfgets(char *str, int size, FILE *in) +{ + if (fgets(str, size, in) == NULL) + fprintf(stderr, "\nError in reading or end of file.\n"); +} diff --git a/adk/config/confdata.c b/adk/config/confdata.c index f603456d0..f88d90f20 100644 --- a/adk/config/confdata.c +++ b/adk/config/confdata.c @@ -5,19 +5,23 @@ #include <sys/stat.h> #include <ctype.h> +#include <errno.h> #include <fcntl.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> -#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; @@ -34,6 +38,29 @@ static void conf_warning(const char *fmt, ...) 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"); @@ -101,6 +128,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) sym->flags |= def_flags; break; } + /* fall through */ case S_BOOLEAN: if (p[0] == 'y') { sym->def[def].tri = yes; @@ -112,8 +140,10 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) sym->flags |= def_flags; break; } - conf_warning("symbol value '%s' invalid for %s", p, sym->name); - break; + if (def != S_DEF_AUTO) + conf_warning("symbol value '%s' invalid for %s", + p, sym->name); + return 1; case S_OTHER: if (*p != '"') { for (p2 = p; *p2 && !isspace(*p2); p2++) @@ -121,6 +151,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) sym->type = S_STRING; goto done; } + /* fall through */ case S_STRING: if (*p++ != '"') break; @@ -132,9 +163,11 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) memmove(p2, p2 + 1, strlen(p2)); } if (!p2) { - conf_warning("invalid string found"); + if (def != S_DEF_AUTO) + conf_warning("invalid string found"); return 1; } + /* fall through */ case S_INT: case S_HEX: done: @@ -142,7 +175,9 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) sym->def[def].val = strdup(p); sym->flags |= def_flags; } else { - conf_warning("symbol value '%s' invalid for %s", p, sym->name); + if (def != S_DEF_AUTO) + conf_warning("symbol value '%s' invalid for %s", + p, sym->name); return 1; } break; @@ -152,10 +187,66 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 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; @@ -170,8 +261,11 @@ int conf_read_simple(const char *name, int def) 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 || @@ -180,9 +274,8 @@ int conf_read_simple(const char *name, int def) 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; } } @@ -208,31 +301,33 @@ load: 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 '#': - p = strchr(line + 2, ' '); + if (line[0] == '#') { + if (memcmp(line + 2, CONFIG_, strlen(CONFIG_))) + continue; + 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; } @@ -248,9 +343,8 @@ load: default: ; } - break; - default: - p = strchr(line, '='); + } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) { + p = strchr(line + strlen(CONFIG_), '='); if (!p) continue; *p++ = 0; @@ -261,13 +355,13 @@ load: *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; } @@ -276,11 +370,12 @@ load: } if (conf_set_sym_val(sym, def, def_flags, p)) continue; - break; - case '\r': - case '\n': - break; + } 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) { @@ -301,6 +396,7 @@ load: cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); } } + free(line); fclose(in); if (modules_sym) @@ -310,10 +406,8 @@ load: 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); @@ -323,7 +417,7 @@ int conf_read(const char *name) for_all_symbols(i, sym) { sym_calc_value(sym); if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) - goto sym_ok; + continue; if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { /* check that calculated value agrees with saved value */ switch (sym->type) { @@ -332,29 +426,18 @@ int conf_read(const char *name) 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) { @@ -387,17 +470,276 @@ int conf_read(const char *name) 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 dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; char *env; dirname[0] = 0; @@ -434,18 +776,7 @@ int conf_write(const char *name) if (!out) return 1; - time(&now); - env = getenv("KCONFIG_NOTIMESTAMP"); - if (env && *env) - use_timestamp = 0; - - fprintf(out, _("#\n" - "# Automatically generated make config: don't edit\n" - "# OpenADK\n" - "%s%s" - "#\n"), - use_timestamp ? "# " : "", - use_timestamp ? ctime(&now) : ""); + conf_write_heading(out, &kconfig_printer_cb, NULL); if (!conf_get_changed()) sym_clear_all_valid(); @@ -466,56 +797,11 @@ int conf_write(const char *name) 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; @@ -539,15 +825,17 @@ int conf_write(const char *name) return 1; } + 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) { const char *name; - char path[128]; + char path[PATH_MAX+1]; char *s, *d, c; struct symbol *sym; struct stat sb; @@ -659,11 +947,9 @@ out: int conf_write_autoconf(void) { struct symbol *sym; - const char *str; const char *name; - FILE *out, *out_h; - time_t now; - int i, l; + FILE *out, *tristate, *out_h; + int i; sym_clear_all_valid(); @@ -676,91 +962,51 @@ int conf_write_autoconf(void) if (!out) return 1; + tristate = fopen(".tmpconfig_tristate", "w"); + if (!tristate) { + fclose(out); + return 1; + } + out_h = fopen(".tmpconfig.h", "w"); if (!out_h) { fclose(out); + fclose(tristate); return 1; } - time(&now); - fprintf(out, "#\n" - "# Automatically generated make config: don't edit\n" - "# OpenADK\n" - "# %s" - "#\n", - ctime(&now)); - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" - " * OpenADK\n" - " * %s" - " */\n" - "#define AUTOCONF_INCLUDED\n", - 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, "%s=m\n", sym->name); - fprintf(out_h, "#define %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/linux/autoconf.h"; + name = "include/generated/autoconf.h"; if (rename(".tmpconfig.h", name)) return 1; + name = getenv("KCONFIG_TRISTATE"); + if (!name) + name = "include/config/tristate.conf"; + if (rename(".tmpconfig_tristate", name)) + return 1; name = conf_get_autoconfig_name(); /* * This must be the last step, kbuild has a dependency on auto.conf @@ -799,20 +1045,131 @@ void conf_set_changed_callback(void (*fn)(void)) conf_changed_callback = fn; } +static bool randomize_choice_values(struct symbol *csym) +{ + struct property *prop; + struct symbol *sym; + struct expr *e; + int cnt, def; + + /* + * 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 conf_set_all_new_symbols(enum conf_def_mode mode) +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; @@ -821,10 +1178,21 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) sym->def[S_DEF_USER].tri = mod; break; case def_no: - sym->def[S_DEF_USER].tri = no; + if (sym->flags & SYMBOL_ALLNOCONFIG_Y) + sym->def[S_DEF_USER].tri = yes; + else + 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; @@ -840,51 +1208,35 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) 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 --git a/adk/config/expr.c b/adk/config/expr.c index 579ece4fa..d6626521f 100644 --- a/adk/config/expr.c +++ b/adk/config/expr.c @@ -7,15 +7,13 @@ #include <stdlib.h> #include <string.h> -#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_symbol(struct symbol *sym) 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_one(enum expr_type type, struct expr *ce) 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_two(enum expr_type type, struct expr *e1, struct expr *e 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 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) 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 @@ struct expr *expr_trans_bool(struct expr *e) /* * 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 @@ struct expr *expr_join_or(struct expr *e1, struct expr *e2) 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 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) #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 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * 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 @@ void expr_fprint(struct expr *e, FILE *out) 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 --git a/adk/config/expr.h b/adk/config/expr.h index 6408fefae..94d891937 100644 --- a/adk/config/expr.h +++ b/adk/config/expr.h @@ -10,7 +10,9 @@ extern "C" { #endif +#include <assert.h> #include <stdio.h> +#include "list.h" #ifndef __cplusplus #include <stdbool.h> #endif @@ -18,14 +20,10 @@ extern "C" { 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; @@ -56,6 +54,13 @@ struct expr_value { tristate tri; }; +struct expr_select_value { + struct expr *expr; + tristate tri; + struct expr *value; + struct expr_select_value *next; +}; + struct symbol_value { void *val; tristate tri; @@ -83,10 +88,12 @@ struct symbol { tristate visible; int flags; struct property *prop; + struct expr_value dir_dep; struct expr_value rev_dep; + struct expr_select_value *val_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 */ @@ -94,7 +101,7 @@ struct symbol { #define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ #define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ -#define SYMBOL_WRITE 0x0200 /* ? */ +#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_CHANGED 0x0400 /* ? */ #define SYMBOL_AUTO 0x1000 /* value from environment variable */ #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ @@ -107,9 +114,14 @@ struct symbol { #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 + +/* Set symbol to y if allnoconfig; used for symbols that hide others */ +#define SYMBOL_ALLNOCONFIG_Y 0x200000 + #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 +144,7 @@ enum prop_type { 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 { @@ -146,6 +159,7 @@ struct property { * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ struct file *file; /* what file was this property defined */ int lineno; /* what lineno was this property defined */ + struct expr *value; /* the optional P_SELECT value */ }; #define for_all_properties(sym, st, tok) \ @@ -163,6 +177,7 @@ struct menu { struct menu *list; struct symbol *sym; struct property *prompt; + struct expr *visibility; struct expr *dep; unsigned int flags; char *help; @@ -174,7 +189,14 @@ struct menu { #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 +212,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e 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 +227,7 @@ struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); 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 +242,6 @@ static inline int expr_is_no(struct expr *e) { return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); } -#endif #ifdef __cplusplus } diff --git a/adk/config/gconf.c b/adk/config/gconf.c index 681125e11..d0a35b21f 100644 --- a/adk/config/gconf.c +++ b/adk/config/gconf.c @@ -10,6 +10,7 @@ # include <config.h> #endif +#include <stdlib.h> #include "lkc.h" #include "images.c" @@ -22,7 +23,6 @@ #include <string.h> #include <unistd.h> #include <time.h> -#include <stdlib.h> //#define DEBUG @@ -30,13 +30,16 @@ enum { 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 @@ static void conf_changed(void); /* 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 @@ const char *dbg_print_flags(int val) 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 @@ void init_main_window(const gchar * glade_file) GladeXML *xml; GtkWidget *widget; GtkTextBuffer *txtbuf; - char title[256]; GtkStyle *style; xml = glade_xml_new(glade_file, "window1", NULL); @@ -266,8 +209,7 @@ void init_main_window(const gchar * glade_file) /*"style", PANGO_STYLE_OBLIQUE, */ NULL); - sprintf(title, _("OpenADK Configuration")); - 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); } @@ -311,7 +253,7 @@ void init_left_tree(void) 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); @@ -343,8 +285,6 @@ void init_left_tree(void) 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) { @@ -356,7 +296,7 @@ void init_right_tree(void) 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); @@ -378,8 +318,6 @@ void init_right_tree(void) "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); @@ -696,20 +634,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) 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 */ } @@ -717,8 +664,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; const gchar *intro_text = _( - "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" - "for Linux.\n" + "Welcome to gkc, the GTK+ graphical configuration tool\n" "For each option, a blank box indicates the feature is disabled, a\n" "check indicates it is enabled, and a dot indicates that it is to\n" "be compiled as a module. Clicking on the box will cycle through the three states.\n" @@ -737,7 +683,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) 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)); @@ -755,7 +701,7 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) 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)); @@ -774,7 +720,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) 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)); @@ -806,7 +752,6 @@ void on_load_clicked(GtkButton * button, gpointer user_data) 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(); @@ -832,7 +777,6 @@ void on_split_clicked(GtkButton * button, gpointer user_data) 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); @@ -886,7 +830,7 @@ static void renderer_edited(GtkCellRendererText * cell, static void change_sym_value(struct menu *menu, gint col) { struct symbol *sym = menu->sym; - tristate oldval, newval; + tristate newval; if (!sym) return; @@ -903,7 +847,6 @@ static void change_sym_value(struct menu *menu, gint col) 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); @@ -940,35 +883,6 @@ static void toggle_sym_value(struct menu *menu) 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; @@ -1160,9 +1074,12 @@ static gchar **fill_row(struct menu *menu) 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"); @@ -1221,6 +1138,7 @@ static gchar **fill_row(struct menu *menu) 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) { @@ -1359,7 +1277,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) gboolean valid; GtkTreeIter *sibling; struct symbol *sym; - struct property *prop; struct menu *menu1, *menu2; if (src == &rootmenu) @@ -1368,7 +1285,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) valid = gtk_tree_model_iter_children(model2, child2, dst); for (child1 = src->list; child1; child1 = child1->next) { - prop = child1->prompt; sym = child1->sym; reparse: @@ -1385,16 +1301,20 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) 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; } @@ -1463,17 +1383,19 @@ static void display_tree(struct menu *menu) && (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"); @@ -1482,9 +1404,15 @@ static void display_tree(struct menu *menu) && (tree == tree2)) continue; /* - if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) + 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)) { @@ -1543,10 +1471,6 @@ int main(int ac, char *av[]) char *env; gchar *glade_file; -#ifndef LKC_DIRECT_LINK - kconfig_load(); -#endif - bindtextdomain(PACKAGE, LOCALEDIR); bind_textdomain_codeset(PACKAGE, "UTF-8"); textdomain(PACKAGE); @@ -1568,12 +1492,6 @@ int main(int ac, char *av[]) 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]) { @@ -1593,6 +1511,12 @@ int main(int ac, char *av[]) 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 --git a/adk/config/Kconfig-language.txt b/adk/config/kconfig-language.txt index c412c2458..68ec5d1f9 100644 --- a/adk/config/Kconfig-language.txt +++ b/adk/config/kconfig-language.txt @@ -95,14 +95,15 @@ applicable everywhere (see syntax). bool "foo" default y -- reverse dependencies: "select" <symbol> ["if" <expr>] +- reverse dependencies: "select" <symbol> [<expr>] ["if" <expr>] While normal dependencies reduce the upper limit of a symbol (see below), reverse dependencies can be used to force a lower limit of another symbol. The value of the current menu symbol is used as the minimal value <symbol> can be set to. If <symbol> is selected multiple times, the limit is set to the largest selection. - Reverse dependencies can only be used with boolean or tristate - symbols. + Reverse dependencies without the optional <expr> can only be used with + boolean or tristate symbols. If the optional <expr> is supplied, + the <symbol> will be set to that value if possible. Note: select should be used with care. select will force a symbol to a value without visiting the dependencies. diff --git a/adk/config/kxgettext.c b/adk/config/kxgettext.c index 8d9ce22b0..2858738b2 100644 --- a/adk/config/kxgettext.c +++ b/adk/config/kxgettext.c @@ -7,7 +7,6 @@ #include <stdlib.h> #include <string.h> -#define LKC_DIRECT_LINK #include "lkc.h" static char *escape(const char* text, char *bf, int len) @@ -63,11 +62,11 @@ next: 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)); @@ -90,7 +89,8 @@ struct message { 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)); @@ -130,7 +130,8 @@ static struct message *mesage__find(const char *msg) 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); @@ -145,7 +146,8 @@ out: 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]; @@ -166,7 +168,7 @@ static int message__add(const char *msg, char *option, char *file, int lineno) return rc; } -void menu_build_message_list(struct menu *menu) +static void menu_build_message_list(struct menu *menu) { struct menu *child; @@ -211,7 +213,7 @@ static void message__print_gettext_msgid_msgstr(struct message *self) "msgstr \"\"\n", self->msg); } -void menu__xgettext(void) +static void menu__xgettext(void) { struct message *m = message__list; diff --git a/adk/config/lex.zconf.c_shipped b/adk/config/lex.zconf.c_shipped index dc3e81807..069e44b77 100644 --- a/adk/config/lex.zconf.c_shipped +++ b/adk/config/lex.zconf.c_shipped @@ -1,5 +1,6 @@ +#line 2 "lex.zconf.c" -#line 3 "scripts/kconfig/lex.zconf.c" +#line 4 "lex.zconf.c" #define YY_INT_ALIGNED short int @@ -160,7 +161,15 @@ typedef unsigned int flex_uint32_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -764,8 +773,10 @@ int zconf_flex_debug = 0; #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *zconftext; +#line 1 "zconf.l" #define YY_NO_INPUT 1 +#line 6 "zconf.l" /* * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> * Released under the terms of the GNU GPL v2.0. @@ -777,7 +788,6 @@ char *zconftext; #include <string.h> #include <unistd.h> -#define LKC_DIRECT_LINK #include "lkc.h" #define START_STRSIZE 16 @@ -791,8 +801,8 @@ static char *text; static int text_size, text_asize; struct buffer { - struct buffer *parent; - YY_BUFFER_STATE state; + struct buffer *parent; + YY_BUFFER_STATE state; }; struct buffer *current_buf; @@ -802,15 +812,15 @@ static int last_ts, first_ts; static void zconf_endhelp(void); static void zconf_endfile(void); -void new_string(void) +static void new_string(void) { - text = malloc(START_STRSIZE); + text = xmalloc(START_STRSIZE); text_asize = START_STRSIZE; text_size = 0; *text = 0; } -void append_string(const char *str, int size) +static void append_string(const char *str, int size) { int new_size = text_size + size + 1; if (new_size > text_asize) { @@ -824,12 +834,13 @@ void append_string(const char *str, int size) text[text_size] = 0; } -void alloc_string(const char *str, int size) +static void alloc_string(const char *str, int size) { - text = malloc(size + 1); + text = xmalloc(size + 1); memcpy(text, str, size); text[size] = 0; } +#line 844 "lex.zconf.c" #define INITIAL 0 #define COMMAND 1 @@ -914,7 +925,12 @@ static int input (void ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -922,7 +938,7 @@ static int input (void ); /* 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 ) +#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -999,9 +1015,13 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; +#line 73 "zconf.l" + int str = 0; int ts, i; +#line 1024 "lex.zconf.c" + if ( !(yy_init) ) { (yy_init) = 1; @@ -1058,9 +1078,11 @@ do_action: /* This label is used only to access EOF actions. */ { /* beginning of action switch */ case 1: /* rule 1 can match eol */ +#line 78 "zconf.l" case 2: /* rule 2 can match eol */ YY_RULE_SETUP +#line 78 "zconf.l" { current_file->lineno++; return T_EOL; @@ -1068,16 +1090,19 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP +#line 82 "zconf.l" YY_BREAK case 4: YY_RULE_SETUP +#line 85 "zconf.l" { BEGIN(COMMAND); } YY_BREAK case 5: YY_RULE_SETUP +#line 89 "zconf.l" { unput(zconftext[0]); BEGIN(COMMAND); @@ -1086,8 +1111,9 @@ YY_RULE_SETUP case 6: YY_RULE_SETUP +#line 96 "zconf.l" { - struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); + const struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); BEGIN(PARAM); current_pos.file = current_file; current_pos.lineno = current_file->lineno; @@ -1102,11 +1128,13 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP +#line 109 "zconf.l" YY_BREAK case 8: /* rule 8 can match eol */ YY_RULE_SETUP +#line 110 "zconf.l" { BEGIN(INITIAL); current_file->lineno++; @@ -1114,36 +1142,45 @@ YY_RULE_SETUP } YY_BREAK + case 9: YY_RULE_SETUP +#line 118 "zconf.l" return T_AND; YY_BREAK case 10: YY_RULE_SETUP +#line 119 "zconf.l" return T_OR; YY_BREAK case 11: YY_RULE_SETUP +#line 120 "zconf.l" return T_OPEN_PAREN; YY_BREAK case 12: YY_RULE_SETUP +#line 121 "zconf.l" return T_CLOSE_PAREN; YY_BREAK case 13: YY_RULE_SETUP +#line 122 "zconf.l" return T_NOT; YY_BREAK case 14: YY_RULE_SETUP +#line 123 "zconf.l" return T_EQUAL; YY_BREAK case 15: YY_RULE_SETUP +#line 124 "zconf.l" return T_UNEQUAL; YY_BREAK case 16: YY_RULE_SETUP +#line 125 "zconf.l" { str = zconftext[0]; new_string(); @@ -1153,16 +1190,19 @@ YY_RULE_SETUP case 17: /* rule 17 can match eol */ YY_RULE_SETUP +#line 130 "zconf.l" BEGIN(INITIAL); current_file->lineno++; return T_EOL; YY_BREAK case 18: YY_RULE_SETUP +#line 131 "zconf.l" /* ignore */ YY_BREAK case 19: YY_RULE_SETUP +#line 132 "zconf.l" { - struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); + const struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); if (id && id->flags & TF_PARAM) { zconflval.id = id; return id->token; @@ -1174,29 +1214,35 @@ YY_RULE_SETUP YY_BREAK case 20: YY_RULE_SETUP +#line 142 "zconf.l" /* comment */ YY_BREAK case 21: /* rule 21 can match eol */ YY_RULE_SETUP +#line 143 "zconf.l" current_file->lineno++; YY_BREAK case 22: YY_RULE_SETUP +#line 144 "zconf.l" YY_BREAK case YY_STATE_EOF(PARAM): +#line 145 "zconf.l" { 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 +#line 151 "zconf.l" { append_string(zconftext, zconfleng); zconflval.string = text; @@ -1205,6 +1251,7 @@ YY_RULE_SETUP YY_BREAK case 24: YY_RULE_SETUP +#line 156 "zconf.l" { append_string(zconftext, zconfleng); } @@ -1215,6 +1262,7 @@ case 25: (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up zconftext again */ YY_RULE_SETUP +#line 159 "zconf.l" { append_string(zconftext + 1, zconfleng - 1); zconflval.string = text; @@ -1223,12 +1271,14 @@ YY_RULE_SETUP YY_BREAK case 26: YY_RULE_SETUP +#line 164 "zconf.l" { append_string(zconftext + 1, zconfleng - 1); } YY_BREAK case 27: YY_RULE_SETUP +#line 167 "zconf.l" { if (str == zconftext[0]) { BEGIN(PARAM); @@ -1241,6 +1291,7 @@ YY_RULE_SETUP case 28: /* rule 28 can match eol */ YY_RULE_SETUP +#line 175 "zconf.l" { printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); current_file->lineno++; @@ -1249,13 +1300,16 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(STRING): +#line 181 "zconf.l" { BEGIN(INITIAL); } YY_BREAK + case 29: YY_RULE_SETUP +#line 187 "zconf.l" { ts = 0; for (i = 0; i < zconfleng; i++) { @@ -1285,6 +1339,7 @@ case 30: (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up zconftext again */ YY_RULE_SETUP +#line 209 "zconf.l" { current_file->lineno++; zconf_endhelp(); @@ -1294,6 +1349,7 @@ YY_RULE_SETUP case 31: /* rule 31 can match eol */ YY_RULE_SETUP +#line 214 "zconf.l" { current_file->lineno++; append_string("\n", 1); @@ -1301,6 +1357,7 @@ YY_RULE_SETUP YY_BREAK case 32: YY_RULE_SETUP +#line 218 "zconf.l" { while (zconfleng) { if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t')) @@ -1313,6 +1370,7 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(HELP): +#line 228 "zconf.l" { zconf_endhelp(); return T_HELPTEXT; @@ -1321,6 +1379,7 @@ case YY_STATE_EOF(HELP): case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(COMMAND): +#line 234 "zconf.l" { if (current_file) { zconf_endfile(); @@ -1332,8 +1391,10 @@ case YY_STATE_EOF(COMMAND): YY_BREAK case 33: YY_RULE_SETUP +#line 243 "zconf.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK +#line 1398 "lex.zconf.c" case YY_END_OF_BUFFER: { @@ -2060,8 +2121,8 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * 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. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ @@ -2300,6 +2361,9 @@ void zconffree (void * ptr ) #define YYTABLES_NAME "yytables" +#line 243 "zconf.l" + + void zconf_starthelp(void) { new_string(); @@ -2313,6 +2377,7 @@ static void zconf_endhelp(void) BEGIN(INITIAL); } + /* * Try to open specified file with following names: * ./name @@ -2345,42 +2410,50 @@ void zconf_initscan(const char *name) exit(1); } - current_buf = malloc(sizeof(*current_buf)); + current_buf = xmalloc(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 *iter; struct file *file = file_lookup(name); - struct buffer *buf = malloc(sizeof(*buf)); + struct buffer *buf = xmalloc(sizeof(*buf)); memset(buf, 0, sizeof(*buf)); current_buf->state = YY_CURRENT_BUFFER; - zconfin = zconf_fopen(name); + zconfin = zconf_fopen(file->name); if (!zconfin) { - printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + printf("%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->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); + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } } - file->flags |= FILE_BUSY; file->lineno = 1; file->parent = current_file; current_file = file; @@ -2390,8 +2463,6 @@ 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; @@ -2409,7 +2480,7 @@ int zconf_lineno(void) return current_pos.lineno; } -char *zconf_curname(void) +const char *zconf_curname(void) { return current_pos.file ? current_pos.file->name : "<none>"; } diff --git a/adk/config/list.h b/adk/config/list.h new file mode 100644 index 000000000..685d80e1b --- /dev/null +++ b/adk/config/list.h @@ -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 --git a/adk/config/lkc.h b/adk/config/lkc.h index f379b0bf8..f53f5d446 100644 --- a/adk/config/lkc.h +++ b/adk/config/lkc.h @@ -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_ "" +#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 @@ -53,6 +61,7 @@ enum conf_def_mode { #define T_OPT_MODULES 1 #define T_OPT_DEFCONFIG_LIST 2 #define T_OPT_ENV 3 +#define T_OPT_ALLNOCONFIG_Y 4 struct kconf_id { int name; @@ -61,16 +70,16 @@ struct kconf_id { 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); @@ -78,23 +87,37 @@ 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 *); +}; + +/* confdata.c and expr.c */ +static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) +{ + assert(len != 0); -/* kconfig_load.c */ -void kconfig_load(void); + 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); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); +void menu_add_select(struct symbol *sym, struct expr *value, struct expr *dep); void menu_add_option(int token, char *arg); void menu_finalize(struct menu *parent); void menu_set_type(int type); @@ -102,10 +125,17 @@ void menu_set_type(int type); /* util.c */ struct file *file_lookup(const char *name); int file_write_dep(const char *name); +void *xmalloc(size_t size); +void *xcalloc(size_t nmemb, size_t size); 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); @@ -121,6 +151,8 @@ void sym_init(void); 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 --git a/adk/config/lkc_proto.h b/adk/config/lkc_proto.h index 8e6946131..ecdb9659b 100644 --- a/adk/config/lkc_proto.h +++ b/adk/config/lkc_proto.h @@ -1,28 +1,40 @@ +#include <stdarg.h> /* 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 --git a/adk/config/lxdialog/checklist.c b/adk/config/lxdialog/checklist.c index bcc6f19c3..8d016faa2 100644 --- a/adk/config/lxdialog/checklist.c +++ b/adk/config/lxdialog/checklist.c @@ -31,6 +31,10 @@ static int list_width, check_x, item_x; 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); @@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected) 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); } /* @@ -127,16 +132,16 @@ int dialog_checklist(const char *title, const char *prompt, int height, } 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); @@ -163,18 +168,19 @@ do_resize: /* create new window for the list */ list = subwin(dialog, list_height, list_width, y + box_y + 1, - x + box_x + 1); + x + box_x + 1); keypad(list, TRUE); /* draw a box around the list items */ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, - dlg.menubox_border.atr, dlg.menubox.atr); + dlg.menubox_border.atr, dlg.menubox.atr); /* Find length of longest item in order to center checklist */ 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 --git a/adk/config/lxdialog/dialog.h b/adk/config/lxdialog/dialog.h index b5211fce0..b4343d384 100644 --- a/adk/config/lxdialog/dialog.h +++ b/adk/config/lxdialog/dialog.h @@ -106,8 +106,14 @@ struct dialog_color { 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 @@ struct dialog_info { */ 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 item_is_tag(char tag); 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 first_alpha(const char *string, const char *exempt); int dialog_yesno(const char *title, const char *prompt, int height, int width); int dialog_msgbox(const char *title, const char *prompt, int height, int width, int pause); -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 --git a/adk/config/lxdialog/inputbox.c b/adk/config/lxdialog/inputbox.c index 616c60138..d58de1dc5 100644 --- a/adk/config/lxdialog/inputbox.c +++ b/adk/config/lxdialog/inputbox.c @@ -42,10 +42,11 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) * Display a dialog box for inputing a string */ int dialog_inputbox(const char *title, const char *prompt, int height, int width, - const char *init) + 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 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width 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 @@ do_resize: 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 @@ do_resize: 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 @@ do_resize: 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 @@ do_resize: 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 --git a/adk/config/lxdialog/menubox.c b/adk/config/lxdialog/menubox.c index fa9d633f2..11ae9ad7a 100644 --- a/adk/config/lxdialog/menubox.c +++ b/adk/config/lxdialog/menubox.c @@ -26,7 +26,7 @@ * * *) A bugfix for the Page-Down problem * - * *) Formerly when I used Page Down and Page Up, the cursor would be set + * *) Formerly when I used Page Down and Page Up, the cursor would be set * to the first position in the menu box. Now lxdialog is a bit * smarter and works more like other menu systems (just have a look at * it). @@ -64,7 +64,7 @@ static int menu_width, item_x; * Print menu item */ static void do_print_item(WINDOW * win, const char *item, int line_y, - int selected, int hotkey) + int selected, int hotkey) { int j; char *menu_item = malloc(menu_width + 1); @@ -154,12 +154,14 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, */ 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); @@ -180,7 +182,7 @@ static void do_scroll(WINDOW *win, int *scroll, int n) * Display a menu for choosing among a number of options */ int dialog_menu(const char *title, const char *prompt, - const void *selected, int *s_scroll) + const void *selected, int *s_scroll) { int i, j, x, y, box_x, box_y; int height, width, menu_height; @@ -191,7 +193,7 @@ int dialog_menu(const char *title, const char *prompt, 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 @@ do_resize: 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 @@ do_resize: } } - 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 @@ do_resize: 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 @@ do_resize: case 'n': case 'm': case '/': + case 'h': + case '?': + case 'z': + case '\n': /* save scroll info */ *s_scroll = scroll; delwin(menu); @@ -390,30 +397,26 @@ do_resize: 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 --git a/adk/config/lxdialog/textbox.c b/adk/config/lxdialog/textbox.c index c704712d0..1773319b9 100644 --- a/adk/config/lxdialog/textbox.c +++ b/adk/config/lxdialog/textbox.c @@ -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 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, /* * 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 @@ int dialog_textbox(const char *title, const char *tbuf, 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 @@ do_resize: 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 @@ do_resize: /* Print first page of text */ attr_clear(box, boxh, boxw, dlg.dialog.atr); - refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); + 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 @@ do_resize: /* point to last char in buf */ page = buf + strlen(buf); back_lines(boxh); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); + 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 @@ do_resize: 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 @@ do_resize: 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 @@ do_resize: 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 @@ static void back_lines(int n) } /* - * 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 @@ static void print_page(WINDOW * win, int height, int width) } /* - * 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 @@ static void print_line(WINDOW * win, int row, int width) 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 @@ static char *get_line(void) 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 @@ static char *get_line(void) if (i <= MAX_LEN) line[i] = '\0'; if (!end_reached) - page++; /* move pass '\n' */ + page++; /* move past '\n' */ return line; } diff --git a/adk/config/lxdialog/util.c b/adk/config/lxdialog/util.c index f2375ad7e..f7abdeb92 100644 --- a/adk/config/lxdialog/util.c +++ b/adk/config/lxdialog/util.c @@ -23,6 +23,9 @@ #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) @@ -251,15 +254,56 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr) 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); @@ -273,8 +317,12 @@ int init_dialog(const char *backtitle) 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; } @@ -295,6 +343,11 @@ void set_dialog_backtitle(const char *backtitle) dlg.backtitle = backtitle; } +void set_dialog_subtitles(struct subtitle_list *subtitles) +{ + dlg.subtitles = subtitles; +} + /* * End using dialog functions. */ @@ -323,27 +376,19 @@ void print_title(WINDOW *dialog, const char *title, int width) /* * 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); @@ -353,7 +398,10 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) 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; @@ -365,7 +413,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) 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; @@ -373,7 +421,15 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) 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 == ' ') ; @@ -567,7 +623,7 @@ void item_make(const char *fmt, ...) void item_add_str(const char *fmt, ...) { va_list ap; - size_t avail; + size_t avail; avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); diff --git a/adk/config/lxdialog/yesno.c b/adk/config/lxdialog/yesno.c index 4e6e8090c..676fb2f82 100644 --- a/adk/config/lxdialog/yesno.c +++ b/adk/config/lxdialog/yesno.c @@ -45,14 +45,14 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) 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 --git a/adk/config/mconf.c b/adk/config/mconf.c index 8a491e3bb..14cea7463 100644 --- a/adk/config/mconf.c +++ b/adk/config/mconf.c @@ -15,21 +15,19 @@ #include <stdarg.h> #include <stdlib.h> #include <string.h> +#include <signal.h> #include <unistd.h> #include <locale.h> -#define LKC_DIRECT_LINK #include "lkc.h" #include "lxdialog/dialog.h" static const char mconf_readme[] = N_( "Overview\n" "--------\n" -"Some kernel features may be built directly into the kernel.\n" -"Some may be made into loadable runtime modules. Some features\n" -"may be completely removed altogether. There are also certain\n" -"kernel parameters which are not really features, but must be\n" -"entered in as decimal or hexadecimal numbers or possibly text.\n" +"This interface lets 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" @@ -41,16 +39,16 @@ static const char mconf_readme[] = N_( "\n" "To change any of these features, highlight it with the cursor\n" "keys and press <Y> to build it in, <M> to make it a module or\n" -"<N> to removed it. You may also press the <Space Bar> to cycle\n" -"through the available options (ie. Y->N->M->Y).\n" +"<N> to remove it. You may also press the <Space Bar> to cycle\n" +"through the available options (i.e. Y->N->M->Y).\n" "\n" "Some additional keyboard hints:\n" "\n" "Menus\n" "----------\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 <Enter>.\n" -" Submenus are designated by \"--->\".\n" +"o Use the Up/Down arrow keys (cursor keys) to highlight the item you\n" +" wish to change or the submenu you wish to select and press <Enter>.\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" @@ -67,13 +65,15 @@ static const char mconf_readme[] = N_( " there is a delayed response which you may find annoying.\n" "\n" " Also, the <TAB> and cursor keys will cycle between <Select>,\n" -" <Exit> and <Help>\n" +" <Exit>, <Help>, <Save>, and <Load>.\n" "\n" "o To get help with an item, use the cursor keys to highlight <Help>\n" -" and Press <ENTER>.\n" +" and press <ENTER>.\n" "\n" " Shortcut: Press <H> or <?>.\n" "\n" +"o To toggle the display of hidden options, press <Z>.\n" +"\n" "\n" "Radiolists (Choice lists)\n" "-----------\n" @@ -105,35 +105,33 @@ static const char mconf_readme[] = N_( "Text Box (Help Window)\n" "--------\n" "o Use the cursor keys to scroll up/down/left/right. The VI editor\n" -" keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n" -" who are familiar with less and lynx.\n" +" keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for\n" +" those who are familiar with less and lynx.\n" "\n" -"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n" +"o Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n" "\n" "\n" "Alternate Configuration Files\n" "-----------------------------\n" "Menuconfig supports the use of alternate configuration files for\n" "those who, for various reasons, find it necessary to switch\n" -"between different kernel configurations.\n" +"between different configurations.\n" "\n" -"At the end of the main menu you will find two options. One is\n" -"for saving the current configuration to a file of your choosing.\n" -"The other option is for loading a previously saved alternate\n" -"configuration.\n" +"The <Save> button will let you save the current configuration to\n" +"a file of your choosing. Use the <Load> button to load a previously\n" +"saved alternate configuration.\n" "\n" -"Even if you don't use alternate configuration files, but you\n" -"find during a Menuconfig session that you have completely messed\n" -"up your settings, you may use the \"Load Alternate...\" option to\n" -"restore your previously saved settings from \".config\" without\n" -"restarting Menuconfig.\n" +"Even if you don't use alternate configuration files, but you find\n" +"during a Menuconfig session that you have completely messed up your\n" +"settings, you may use the <Load> button to restore your previously\n" +"saved settings from \".config\" without restarting Menuconfig.\n" "\n" "Other information\n" "-----------------\n" -"If you use Menuconfig in an XTERM window make sure you have your\n" -"$TERM variable set to point to a xterm definition which supports color.\n" -"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n" -"display correctly in a RXVT window because rxvt displays only one\n" +"If you use Menuconfig in an XTERM window, make sure you have your\n" +"$TERM variable set to point to an xterm definition which supports\n" +"color. Otherwise, Menuconfig will look rather bad. Menuconfig will\n" +"not display correctly in an RXVT window because rxvt displays only one\n" "intensity of color, bright.\n" "\n" "Menuconfig will display larger menus on screens or xterms which are\n" @@ -148,9 +146,9 @@ static const char mconf_readme[] = N_( "\n" "Optional personality available\n" "------------------------------\n" -"If you prefer to have all of the kernel options listed in a single\n" -"menu, rather than the default multimenu hierarchy, run the menuconfig\n" -"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" +"If you prefer to have all of the options listed in a single menu,\n" +"rather than the default multimenu hierarchy, run the menuconfig with\n" +"MENUCONFIG_MODE environment variable set to single_menu. Example:\n" "\n" "make MENUCONFIG_MODE=single_menu menuconfig\n" "\n" @@ -172,11 +170,11 @@ static const char mconf_readme[] = N_( " mono => selects colors suitable for monochrome displays\n" " blackbg => selects a color scheme with black background\n" " classic => theme with blue background. The classic look\n" -" bluetitle => a LCD friendly version of classic. (default)\n" +" bluetitle => an LCD friendly version of classic. (default)\n" "\n"), menu_instructions[] = N_( "Arrow keys navigate the menu. " - "<Enter> selects submenus --->. " + "<Enter> selects submenus ---> (or empty submenus ----). " "Highlighted letters are hotkeys. " "Pressing <Y> includes, <N> excludes, <M> modularizes features. " "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " @@ -199,30 +197,28 @@ inputbox_instructions_string[] = N_( setmod_text[] = N_( "This feature depends on another which has been configured as a module.\n" "As a result, this feature will be built as a module."), -nohelp_text[] = N_( - "There is no help available for this kernel option.\n"), load_config_text[] = N_( "Enter the name of the configuration file you wish to load. " "Accept the name shown to restore the configuration you " "last retrieved. Leave blank to abort."), load_config_help[] = N_( "\n" - "For various reasons, one may wish to keep several different kernel\n" + "For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" "\n" "If you have saved a previous configuration in a file other than the\n" - "kernel's default, entering the name of the file here will allow you\n" - "to modify that configuration.\n" + "default one, entering its name here will allow you to modify that\n" + "configuration.\n" "\n" "If you are uncertain, then you have probably never used alternate\n" - "configuration files. You should therefor leave this blank to abort.\n"), + "configuration files. You should therefore leave this blank to abort.\n"), save_config_text[] = N_( "Enter a filename to which this configuration should be saved " "as an alternate. Leave blank to abort."), save_config_help[] = N_( "\n" - "For various reasons, one may wish to keep different kernel\n" - "configurations available on a single machine.\n" + "For various reasons, one may wish to keep different configurations\n" + "available on a single machine.\n" "\n" "Entering a file name here will allow you to later retrieve, modify\n" "and use the current configuration as an alternate to whatever\n" @@ -232,161 +228,184 @@ save_config_help[] = N_( "leave this blank.\n"), search_help[] = N_( "\n" - "Search for CONFIG_ symbols and display their relations.\n" + "Search for symbols and display their relations.\n" "Regular expressions are allowed.\n" "Example: search for \"^FOO\"\n" "Result:\n" "-----------------------------------------------------------------\n" "Symbol: FOO [=m]\n" + "Type : tristate\n" "Prompt: Foo bus is used to drive the bar HW\n" - "Defined at drivers/pci/Kconfig:47\n" - "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" - "Location:\n" - " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" - " -> PCI support (PCI [=y])\n" - " -> PCI access mode (<choice> [=y])\n" - "Selects: LIBCRC32\n" - "Selected by: BAR\n" + " Location:\n" + " -> Bus options (PCI, PCMCIA, EISA, ISA)\n" + " -> PCI support (PCI [=y])\n" + "(1) -> PCI access mode (<choice> [=y])\n" + " Defined at drivers/pci/Kconfig:47\n" + " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" + " Selects: LIBCRC32\n" + " Selected by: BAR [=n]\n" "-----------------------------------------------------------------\n" + "o The line 'Type:' shows the type of the configuration option for\n" + " this symbol (boolean, tristate, string, ...)\n" "o The line 'Prompt:' shows the text used in the menu structure for\n" - " this CONFIG_ symbol\n" - "o The 'Defined at' line tell at what file / line number the symbol\n" + " this symbol\n" + "o The 'Defined at' line tells at what file / line number the symbol\n" " is defined\n" - "o The 'Depends on:' line tell what symbols needs to be defined for\n" + "o The 'Depends on:' line tells what symbols need to be defined for\n" " this symbol to be visible in the menu (selectable)\n" - "o The 'Location:' lines tell where in the menu structure this symbol\n" + "o The 'Location:' lines tells where in the menu structure this symbol\n" " is located\n" - " A location followed by a [=y] indicate that this is a selectable\n" - " menu item - and current value is displayed inside brackets.\n" - "o The 'Selects:' line tell what symbol will be automatically\n" + " A location followed by a [=y] indicates that this is a\n" + " selectable menu item - and the current value is displayed inside\n" + " brackets.\n" + " Press the key in the (#) prefix to jump directly to that\n" + " location. You will be returned to the current search results\n" + " after exiting this new menu.\n" + "o The 'Selects:' line tells what symbols will be automatically\n" " selected if this symbol is selected (y or m)\n" - "o The 'Selected by' line tell what symbol has selected this symbol\n" + "o The 'Selected by' line tells what symbol has selected this symbol\n" "\n" "Only relevant lines are shown.\n" "\n\n" "Search examples:\n" - "Examples: USB => find all CONFIG_ symbols containing USB\n" - " ^USB => find all CONFIG_ symbols starting with USB\n" - " USB$ => find all CONFIG_ symbols ending with USB\n" + "Examples: USB => find all symbols containing USB\n" + " ^USB => find all symbols starting with USB\n" + " USB$ => find all symbols ending with USB\n" "\n"); static int indent; static struct menu *current_menu; static int child_count; static int single_menu_mode; +static int show_all_options; +static int save_and_exit; -static void conf(struct menu *menu); +static void conf(struct menu *menu, struct menu *active_menu); static void conf_choice(struct menu *menu); static void conf_string(struct menu *menu); static void conf_load(void); static void conf_save(void); +static int show_textbox_ext(const char *title, char *text, int r, int c, + int *keys, int *vscroll, int *hscroll, + update_text_fn update_text, void *data); static void show_textbox(const char *title, const char *text, int r, int c); static void show_helptext(const char *title, const char *text); static void show_help(struct menu *menu); -static void get_prompt_str(struct gstr *r, struct property *prop) +static char filename[PATH_MAX+1]; +static void set_config_filename(const char *config_filename) { - int i, j; - struct menu *submenu[8], *menu; - - str_printf(r, _("Prompt: %s\n"), _(prop->text)); - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); + static char menu_backtitle[PATH_MAX+128]; + int size; + + size = snprintf(menu_backtitle, sizeof(menu_backtitle), + "%s - %s", config_filename, rootmenu.prompt->text); + if (size >= sizeof(menu_backtitle)) + menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; + set_dialog_backtitle(menu_backtitle); + + size = snprintf(filename, sizeof(filename), "%s", config_filename); + if (size >= sizeof(filename)) + filename[sizeof(filename)-1] = '\0'; +} + +struct subtitle_part { + struct list_head entries; + const char *text; +}; +static LIST_HEAD(trail); + +static struct subtitle_list *subtitles; +static void set_subtitle(void) +{ + struct subtitle_part *sp; + struct subtitle_list *pos, *tmp; + + for (pos = subtitles; pos != NULL; pos = tmp) { + tmp = pos->next; + free(pos); } - menu = prop->menu->parent; - for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) - submenu[i++] = menu; - if (i > 0) { - str_printf(r, _(" Location:\n")); - for (j = 4; --i >= 0; j += 2) { - menu = submenu[i]; - str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); - if (menu->sym) { - str_printf(r, " (%s [=%s])", menu->sym->name ? - menu->sym->name : _("<choice>"), - sym_get_string_value(menu->sym)); + + subtitles = NULL; + list_for_each_entry(sp, &trail, entries) { + if (sp->text) { + if (pos) { + pos->next = xcalloc(sizeof(*pos), 1); + pos = pos->next; + } else { + subtitles = pos = xcalloc(sizeof(*pos), 1); } - str_append(r, "\n"); + pos->text = sp->text; } } + + set_dialog_subtitles(subtitles); } -static void get_symbol_str(struct gstr *r, struct symbol *sym) +static void reset_subtitle(void) { - bool hit; - struct property *prop; + struct subtitle_list *pos, *tmp; - if (sym && sym->name) - str_printf(r, "Symbol: %s [=%s]\n", sym->name, - sym_get_string_value(sym)); - for_all_prompts(sym, prop) - get_prompt_str(r, prop); - hit = false; - for_all_properties(sym, prop, P_SELECT) { - if (!hit) { - str_append(r, " Selects: "); - hit = true; - } else - str_printf(r, " && "); - expr_gstr_print(prop->expr, r); + for (pos = subtitles; pos != NULL; pos = tmp) { + tmp = pos->next; + free(pos); } - if (hit) - str_append(r, "\n"); - if (sym->rev_dep.expr) { - str_append(r, _(" Selected by: ")); - expr_gstr_print(sym->rev_dep.expr, r); - str_append(r, "\n"); - } - str_append(r, "\n\n"); + subtitles = NULL; + set_dialog_subtitles(subtitles); } -static struct gstr get_relations_str(struct symbol **sym_arr) +struct search_data { + struct list_head *head; + struct menu **targets; + int *keys; +}; + +static void update_text(char *buf, size_t start, size_t end, void *_data) { - struct symbol *sym; - struct gstr res = str_new(); - int i; + struct search_data *data = _data; + struct jump_key *pos; + int k = 0; - for (i = 0; sym_arr && (sym = sym_arr[i]); i++) - get_symbol_str(&res, sym); - if (!i) - str_append(&res, _("No matches found.\n")); - return res; -} + list_for_each_entry(pos, data->head, entries) { + if (pos->offset >= start && pos->offset < end) { + char header[4]; -static char filename[PATH_MAX+1]; -static void set_config_filename(const char *config_filename) -{ - static char menu_backtitle[PATH_MAX+128]; - int size; + if (k < JUMP_NB) { + int key = '0' + (pos->index % JUMP_NB) + 1; - size = snprintf(menu_backtitle, sizeof(menu_backtitle), - _("%s - OpenADK Configuration"), - config_filename); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; - set_dialog_backtitle(menu_backtitle); + sprintf(header, "(%c)", key); + data->keys[k] = key; + data->targets[k] = pos->target; + k++; + } else { + sprintf(header, " "); + } - size = snprintf(filename, sizeof(filename), "%s", config_filename); - if (size >= sizeof(filename)) - filename[sizeof(filename)-1] = '\0'; + memcpy(buf + pos->offset, header, sizeof(header) - 1); + } + } + data->keys[k] = 0; } - static void search_conf(void) { struct symbol **sym_arr; struct gstr res; + struct gstr title; char *dialog_input; - int dres; + int dres, vscroll = 0, hscroll = 0; + bool again; + struct gstr sttext; + struct subtitle_part stpart; + + title = str_new(); + str_printf( &title, _("Enter (sub)string or regexp to search for " + "(with or without \"%s\")"), CONFIG_); + again: dialog_clear(); dres = dialog_inputbox(_("Search Configuration Parameter"), - _("Enter CONFIG_ (sub)string to search for " - "(with or without \"CONFIG\")"), + str_get(&title), 10, 75, ""); switch (dres) { case 0: @@ -395,19 +414,52 @@ again: show_helptext(_("Search Configuration"), search_help); goto again; default: + str_free(&title); return; } - /* strip CONFIG_ if necessary */ + /* strip the prefix if necessary */ dialog_input = dialog_input_result; - if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) - dialog_input += 7; + if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) + dialog_input += strlen(CONFIG_); + + sttext = str_new(); + str_printf(&sttext, "Search (%s)", dialog_input_result); + stpart.text = str_get(&sttext); + list_add_tail(&stpart.entries, &trail); sym_arr = sym_re_search(dialog_input); - res = get_relations_str(sym_arr); + do { + LIST_HEAD(head); + struct menu *targets[JUMP_NB]; + int keys[JUMP_NB + 1], i; + struct search_data data = { + .head = &head, + .targets = targets, + .keys = keys, + }; + struct jump_key *pos, *tmp; + + res = get_relations_str(sym_arr, &head); + set_subtitle(); + dres = show_textbox_ext(_("Search Results"), (char *) + str_get(&res), 0, 0, keys, &vscroll, + &hscroll, &update_text, (void *) + &data); + again = false; + for (i = 0; i < JUMP_NB && keys[i]; i++) + if (dres == keys[i]) { + conf(targets[i]->parent, targets[i]); + again = true; + } + str_free(&res); + list_for_each_entry_safe(pos, tmp, &head, entries) + free(pos); + } while (again); free(sym_arr); - show_textbox(_("Search Results"), str_get(&res), 0, 0); - str_free(&res); + str_free(&title); + list_del(trail.prev); + str_free(&sttext); } static void build_conf(struct menu *menu) @@ -418,8 +470,16 @@ static void build_conf(struct menu *menu) int type, tmp, doint = 2; tristate val; char ch; + bool visible; - if (!menu_is_visible(menu)) + /* + * note: menu_is_visible() has side effect that it will + * recalc the value of the symbol. + */ + visible = menu_is_visible(menu); + if (show_all_options && !menu_has_prompt(menu)) + return; + else if (!show_all_options && !visible) return; sym = menu->sym; @@ -436,8 +496,9 @@ static void build_conf(struct menu *menu) menu->data ? "-->" : "++>", indent + 1, ' ', prompt); } else - item_make(" %*c%s --->", indent + 1, ' ', prompt); - + item_make(" %*c%s %s", + indent + 1, ' ', prompt, + menu_is_empty(menu) ? "----" : "--->"); item_set_tag('m'); item_set_data(menu); if (single_menu_mode && menu->data) @@ -568,7 +629,7 @@ static void build_conf(struct menu *menu) (sym_has_value(sym) || !sym_is_changable(sym)) ? "" : _(" (NEW)")); if (menu->prompt->type == P_MENU) { - item_add_str(" --->"); + item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); return; } } @@ -580,40 +641,40 @@ conf_childs: indent -= doint; } -static void conf(struct menu *menu) +static void conf(struct menu *menu, struct menu *active_menu) { struct menu *submenu; const char *prompt = menu_get_prompt(menu); + struct subtitle_part stpart; struct symbol *sym; - struct menu *active_menu = NULL; int res; int s_scroll = 0; + if (menu != &rootmenu) + stpart.text = menu_get_prompt(menu); + else + stpart.text = NULL; + list_add_tail(&stpart.entries, &trail); + while (1) { item_reset(); current_menu = menu; build_conf(menu); if (!child_count) break; - if (menu == &rootmenu) { - item_make("--- "); - item_set_tag(':'); - item_make(_(" Load an Alternate Configuration File")); - item_set_tag('L'); - item_make(_(" Save an Alternate Configuration File")); - item_set_tag('S'); - } + set_subtitle(); dialog_clear(); res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), _(menu_instructions), active_menu, &s_scroll); if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) break; - if (!item_activate_selected()) - continue; - if (!item_tag()) - continue; - + if (item_count() != 0) { + if (!item_activate_selected()) + continue; + if (!item_tag()) + continue; + } submenu = item_data(); active_menu = item_data(); if (submenu) @@ -628,32 +689,36 @@ static void conf(struct menu *menu) if (single_menu_mode) submenu->data = (void *) (long) !submenu->data; else - conf(submenu); + conf(submenu, NULL); break; case 't': if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) conf_choice(submenu); else if (submenu->prompt->type == P_MENU) - conf(submenu); + conf(submenu, NULL); break; case 's': conf_string(submenu); break; - case 'L': - conf_load(); - break; - case 'S': - conf_save(); - break; } break; case 2: if (sym) show_help(submenu); - else + else { + reset_subtitle(); show_helptext(_("README"), _(mconf_readme)); + } break; case 3: + reset_subtitle(); + conf_save(); + break; + case 4: + reset_subtitle(); + conf_load(); + break; + case 5: if (item_is_tag('t')) { if (sym_set_tristate_value(sym, yes)) break; @@ -661,31 +726,45 @@ static void conf(struct menu *menu) show_textbox(NULL, setmod_text, 6, 74); } break; - case 4: + case 6: if (item_is_tag('t')) sym_set_tristate_value(sym, no); break; - case 5: + case 7: if (item_is_tag('t')) sym_set_tristate_value(sym, mod); break; - case 6: + case 8: if (item_is_tag('t')) sym_toggle_tristate_value(sym); else if (item_is_tag('m')) - conf(submenu); + conf(submenu, NULL); break; - case 7: + case 9: search_conf(); break; + case 10: + show_all_options = !show_all_options; + break; } } + + list_del(trail.prev); } -static void show_textbox(const char *title, const char *text, int r, int c) +static int show_textbox_ext(const char *title, char *text, int r, int c, int + *keys, int *vscroll, int *hscroll, update_text_fn + update_text, void *data) { dialog_clear(); - dialog_textbox(title, text, r, c); + return dialog_textbox(title, text, r, c, keys, vscroll, hscroll, + update_text, data); +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ + show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL, + NULL, NULL); } static void show_helptext(const char *title, const char *text) @@ -693,22 +772,24 @@ static void show_helptext(const char *title, const char *text) show_textbox(title, text, 0, 0); } +static void conf_message_callback(const char *fmt, va_list ap) +{ + char buf[PATH_MAX+1]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + if (save_and_exit) + printf("%s", buf); + else + show_textbox(NULL, buf, 6, 60); +} + static void show_help(struct menu *menu) { struct gstr help = str_new(); - struct symbol *sym = menu->sym; - - if (menu_has_help(menu)) - { - if (sym->name) { - str_printf(&help, "CONFIG_%s:\n\n", sym->name); - str_append(&help, _(menu_get_help(menu))); - str_append(&help, "\n"); - } - } else { - str_append(&help, nohelp_text); - } - get_symbol_str(&help, sym); + + help.max_width = getmaxx(stdscr) - 10; + menu_get_ext_help(menu, &help); + show_helptext(_(menu_get_prompt(menu)), str_get(&help)); str_free(&help); } @@ -744,7 +825,9 @@ static void conf_choice(struct menu *menu) dialog_clear(); res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), _(radiolist_instructions), - 15, 70, 6); + MENUBOX_HEIGTH_MIN, + MENUBOX_WIDTH_MIN, + CHECKLIST_HEIGTH_MIN); selected = item_activate_selected(); switch (res) { case 0: @@ -866,17 +949,66 @@ static void conf_save(void) } } +static int handle_exit(void) +{ + int res; + + save_and_exit = 1; + reset_subtitle(); + dialog_clear(); + if (conf_get_changed()) + res = dialog_yesno(NULL, + _("Do you wish to save your new configuration?\n" + "(Press <ESC><ESC> to continue kernel configuration.)"), + 6, 60); + else + res = -1; + + end_dialog(saved_x, saved_y); + + switch (res) { + case 0: + if (conf_write(filename)) { + fprintf(stderr, _("\n\n" + "Error while writing of the configuration.\n" + "Your configuration changes were NOT saved." + "\n\n")); + return 1; + } + /* fall through */ + case -1: + printf(_("\n\n" + "*** End of the configuration.\n" + "*** Execute 'make' to start the build or try 'make help'." + "\n\n")); + res = 0; + break; + default: + fprintf(stderr, _("\n\n" + "Your configuration changes were NOT saved." + "\n\n")); + if (res != KEY_ESC) + res = 0; + } + + return res; +} + +static void sig_handler(int signo) +{ + exit(handle_exit()); +} + int main(int ac, char **av) { - int saved_x, saved_y; char *mode; int res; -#ifndef KBUILD_NO_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); -#endif + + signal(SIGINT, sig_handler); conf_parse(av[1]); conf_read(NULL); @@ -887,9 +1019,6 @@ int main(int ac, char **av) single_menu_mode = 1; } - initscr(); - - getyx(stdscr, saved_y, saved_x); if (init_dialog(NULL)) { fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); @@ -897,41 +1026,11 @@ int main(int ac, char **av) } set_config_filename(conf_get_configname()); + conf_set_message_callback(conf_message_callback); do { - conf(&rootmenu); - dialog_clear(); - if (conf_get_changed()) - res = dialog_yesno(NULL, - _("Do you wish to save your " - "new OpenADK configuration?\n" - "<ESC><ESC> to continue."), - 6, 60); - else - res = -1; + conf(&rootmenu, NULL); + res = handle_exit(); } while (res == KEY_ESC); - end_dialog(saved_x, saved_y); - switch (res) { - case 0: - if (conf_write(filename)) { - fprintf(stderr, _("\n\n" - "Error during writing of the OpenADK configuration.\n" - "Your OpenADK configuration changes were NOT saved." - "\n\n")); - return 1; - } - case -1: - printf(_("\n\n" - "*** End of OpenADK configuration.\n" - "*** Execute 'make' to build the firmware or try 'make help'." - "\n\n")); - break; - default: - fprintf(stderr, _("\n\n" - "Your OpenADK configuration changes were NOT saved." - "\n\n")); - } - - return 0; + return res; } - diff --git a/adk/config/menu.c b/adk/config/menu.c index 3e6405ac2..cd3a75451 100644 --- a/adk/config/menu.c +++ b/adk/config/menu.c @@ -3,14 +3,14 @@ * Released under the terms of the GNU GPL v2.0. */ +#include <ctype.h> +#include <stdarg.h> #include <stdlib.h> #include <string.h> -#define LKC_DIRECT_LINK #include "lkc.h" -static const char nohelp_text[] = N_( - "There is no help available for this OpenADK option.\n"); +static const char nohelp_text[] = "There is no help available for this option."; struct menu rootmenu; static struct menu **last_entry_ptr; @@ -38,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...) va_end(ap); } -void menu_init(void) +void _menu_init(void) { current_entry = current_menu = &rootmenu; last_entry_ptr = &rootmenu.list; @@ -48,7 +48,7 @@ void menu_add_entry(struct symbol *sym) { struct menu *menu; - menu = malloc(sizeof(*menu)); + menu = xmalloc(sizeof(*menu)); memset(menu, 0, sizeof(*menu)); menu->sym = sym; menu->parent = current_menu; @@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym) *last_entry_ptr = menu; last_entry_ptr = &menu->next; current_entry = menu; + if (sym) + menu_add_symbol(P_SYMBOL, sym, NULL); } void menu_end_entry(void) @@ -117,9 +119,10 @@ void menu_set_type(int type) sym->type = type; return; } - menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'", - sym->name ? sym->name : "<choice>", - sym_type_name(sym->type), sym_type_name(type)); + menu_warn(current_entry, + "ignoring type redefinition of '%s' from '%s' to '%s'", + sym->name ? sym->name : "<choice>", + sym_type_name(sym->type), sym_type_name(type)); } struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) @@ -136,8 +139,35 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e while (isspace(*prompt)) prompt++; } - if (current_entry->prompt) + if (current_entry->prompt && current_entry != &rootmenu) prop_warn(prop, "prompt redefined"); + + /* Apply all upper menus' visibilities to actual prompts. */ + if(type == P_PROMPT) { + struct menu *menu = current_entry; + + while ((menu = menu->parent) != NULL) { + struct expr *dup_expr; + + if (!menu->visibility) + continue; + /* + * Do not add a reference to the + * menu's visibility expression but + * use a copy of it. Otherwise the + * expression reduction functions + * will modify expressions that have + * multiple references which can + * cause unwanted side effects. + */ + dup_expr = expr_copy(menu->visibility); + + prop->visible.expr + = expr_alloc_and(prop->visible.expr, + dup_expr); + } + } + current_entry->prompt = prop; } prop->text = prompt; @@ -150,6 +180,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr return menu_add_prop(type, prompt, NULL, dep); } +void menu_add_visibility(struct expr *expr) +{ + current_entry->visibility = expr_alloc_and(current_entry->visibility, + expr); +} + void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) { menu_add_prop(type, NULL, expr, dep); @@ -160,14 +196,25 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); } -void menu_add_option(int token, char *arg) +void menu_add_select(struct symbol *sym, struct expr *value, struct expr *dep) { - struct property *prop; + struct property *p; + + p = menu_add_prop(P_SELECT, NULL, expr_alloc_symbol(sym), dep); + p->value = value; +} +void menu_add_option(int token, char *arg) +{ switch (token) { case T_OPT_MODULES: - prop = prop_alloc(P_DEFAULT, modules_sym); - prop->expr = expr_alloc_symbol(current_entry->sym); + if (modules_sym) + zconf_error("symbol '%s' redefines option 'modules'" + " already defined by symbol '%s'", + current_entry->sym->name, + modules_sym->name + ); + modules_sym = current_entry->sym; break; case T_OPT_DEFCONFIG_LIST: if (!sym_defconfig_list) @@ -178,10 +225,13 @@ void menu_add_option(int token, char *arg) case T_OPT_ENV: prop_add_env(arg); break; + case T_OPT_ALLNOCONFIG_Y: + current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; + break; } } -static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) +static int menu_validate_number(struct symbol *sym, struct symbol *sym2) { return sym2->type == S_INT || sym2->type == S_HEX || (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); @@ -197,8 +247,17 @@ static void sym_check_prop(struct symbol *sym) if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && prop->expr->type != E_SYMBOL) prop_warn(prop, - "default for config symbol '%'" + "default for config symbol '%s'" " must be a single symbol", sym->name); + if (prop->expr->type != E_SYMBOL) + break; + sym2 = prop_get_symbol(prop); + if (sym->type == S_HEX || sym->type == S_INT) { + if (!menu_validate_number(sym, sym2)) + prop_warn(prop, + "'%s': number is invalid", + sym->name); + } break; case P_SELECT: sym2 = prop_get_symbol(prop); @@ -206,20 +265,29 @@ static void sym_check_prop(struct symbol *sym) prop_warn(prop, "config symbol '%s' uses select, but is " "not boolean or tristate", sym->name); - else if (sym2->type != S_UNKNOWN && - sym2->type != S_BOOLEAN && - sym2->type != S_TRISTATE) + else if (prop->value == NULL && + sym2->type != S_UNKNOWN && + sym2->type != S_BOOLEAN && + sym2->type != S_TRISTATE) prop_warn(prop, - "'%s' has wrong type. 'select' only " - "accept arguments of boolean and " - "tristate type", sym2->name); + "'%s' has wrong type. 'select' without a " + "value only accepts arguments of boolean " + "and tristate type", sym2->name); + else if (prop->value != NULL && + (sym2->type == S_INT || + sym2->type == S_HEX || + sym2->type == S_STRING) && + prop->value->type != E_SYMBOL) + prop_warn(prop, + "select value for config symbol '%s'" + " must be a single symbol", sym2->name); break; case P_RANGE: if (sym->type != S_INT && sym->type != S_HEX) prop_warn(prop, "range is only allowed " - "for int or hex symbols"); - if (!menu_range_valid_sym(sym, prop->expr->left.sym) || - !menu_range_valid_sym(sym, prop->expr->right.sym)) + "for int or hex symbols"); + if (!menu_validate_number(sym, prop->expr->left.sym) || + !menu_validate_number(sym, prop->expr->right.sym)) prop_warn(prop, "range is invalid"); break; default: @@ -228,6 +296,25 @@ static void sym_check_prop(struct symbol *sym) } } +static void finalize_select(struct symbol *sym, struct property *prop, + struct expr *dep) +{ + struct symbol *es = prop_get_symbol(prop); + struct expr_select_value *esv; + + if (prop->value) { + esv = malloc(sizeof *esv); + esv->expr = expr_alloc_and(expr_alloc_symbol(sym), + expr_copy(dep)); + esv->value = prop->value; + esv->next = es->val_dep; + es->val_dep = esv; + } else { + es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, + expr_alloc_and(expr_alloc_symbol(sym), expr_copy(dep))); + } +} + void menu_finalize(struct menu *parent) { struct menu *menu, *last_menu; @@ -278,11 +365,8 @@ void menu_finalize(struct menu *parent) if (menu->sym && menu->sym->type != S_TRISTATE) dep = expr_trans_bool(dep); prop->visible.expr = dep; - if (prop->type == P_SELECT) { - struct symbol *es = prop_get_symbol(prop); - es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); - } + if (prop->type == P_SELECT) + finalize_select(menu->sym, prop, dep); } } for (menu = parent->list; menu; menu = menu->next) @@ -318,6 +402,8 @@ void menu_finalize(struct menu *parent) parent->next = last_menu->next; last_menu->next = NULL; } + + sym->dir_dep.expr = expr_alloc_or(sym->dir_dep.expr, parent->dep); } for (menu = parent->list; menu; menu = menu->next) { if (sym && sym_is_choice(sym) && @@ -384,10 +470,39 @@ void menu_finalize(struct menu *parent) } if (sym && !sym_is_optional(sym) && parent->prompt) { + struct expr_select_value *esv; + sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, expr_alloc_and(parent->prompt->visible.expr, expr_alloc_symbol(&symbol_mod))); + for (esv = sym->val_dep; esv; esv = esv->next) + esv->expr = expr_alloc_or(esv->expr, + expr_alloc_and(parent->prompt->visible.expr, + expr_alloc_symbol(&symbol_mod))); + } +} + +bool menu_has_prompt(struct menu *menu) +{ + if (!menu->prompt) + return false; + return true; +} + +/* + * Determine if a menu is empty. + * A menu is considered empty if it contains no or only + * invisible entries. + */ +bool menu_is_empty(struct menu *menu) +{ + struct menu *child; + + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child)) + return(false); } + return(true); } bool menu_is_visible(struct menu *menu) @@ -398,6 +513,12 @@ bool menu_is_visible(struct menu *menu) if (!menu->prompt) return false; + + if (menu->visibility) { + if (expr_calc_value(menu->visibility) == no) + return no; + } + sym = menu->sym; if (sym) { sym_calc_value(sym); @@ -407,12 +528,18 @@ bool menu_is_visible(struct menu *menu) if (visible != no) return true; + if (!sym || sym_get_tristate_value(menu->sym) == no) return false; - for (child = menu->list; child; child = child->next) - if (menu_is_visible(child)) + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child)) { + if (sym) + sym->flags |= SYMBOL_DEF_USER; return true; + } + } + return false; } @@ -455,27 +582,53 @@ const char *menu_get_help(struct menu *menu) return ""; } -static void get_prompt_str(struct gstr *r, struct property *prop) +static void get_prompt_str(struct gstr *r, struct property *prop, + struct list_head *head) { int i, j; - struct menu *submenu[8], *menu; + struct menu *submenu[8], *menu, *location = NULL; + struct jump_key *jump; str_printf(r, _("Prompt: %s\n"), _(prop->text)); - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); - } menu = prop->menu->parent; - for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) + for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { + bool accessible = menu_is_visible(menu); + submenu[i++] = menu; + if (location == NULL && accessible) + location = menu; + } + if (head && location) { + jump = xmalloc(sizeof(struct jump_key)); + + if (menu_is_visible(prop->menu)) { + /* + * There is not enough room to put the hint at the + * beginning of the "Prompt" line. Put the hint on the + * last "Location" line even when it would belong on + * the former. + */ + jump->target = prop->menu; + } else + jump->target = location; + + if (list_empty(head)) + jump->index = 0; + else + jump->index = list_entry(head->prev, struct jump_key, + entries)->index + 1; + + list_add_tail(&jump->entries, head); + } + if (i > 0) { str_printf(r, _(" Location:\n")); for (j = 4; --i >= 0; j += 2) { menu = submenu[i]; - str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); + if (head && location && menu == location) + jump->offset = strlen(r->s); + str_printf(r, "%*c-> %s", j, ' ', + _(menu_get_prompt(menu))); if (menu->sym) { str_printf(r, " (%s [=%s])", menu->sym->name ? menu->sym->name : _("<choice>"), @@ -486,16 +639,55 @@ static void get_prompt_str(struct gstr *r, struct property *prop) } } -void get_symbol_str(struct gstr *r, struct symbol *sym) +/* + * get property of type P_SYMBOL + */ +static struct property *get_symbol_prop(struct symbol *sym) +{ + struct property *prop = NULL; + + for_all_properties(sym, prop, P_SYMBOL) + break; + return prop; +} + +/* + * head is optional and may be NULL + */ +void get_symbol_str(struct gstr *r, struct symbol *sym, + struct list_head *head) { bool hit; struct property *prop; + struct expr_select_value *esv; - if (sym && sym->name) + if (sym && sym->name) { str_printf(r, "Symbol: %s [=%s]\n", sym->name, sym_get_string_value(sym)); + str_printf(r, "Type : %s\n", sym_type_name(sym->type)); + if (sym->type == S_INT || sym->type == S_HEX) { + prop = sym_get_range_prop(sym); + if (prop) { + str_printf(r, "Range : "); + expr_gstr_print(prop->expr, r); + str_append(r, "\n"); + } + } + } for_all_prompts(sym, prop) - get_prompt_str(r, prop); + get_prompt_str(r, prop, head); + + prop = get_symbol_prop(sym); + if (prop) { + str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, + prop->menu->lineno); + if (!expr_is_yes(prop->visible.expr)) { + str_append(r, _(" Depends on: ")); + expr_gstr_print(prop->visible.expr, r); + str_append(r, "\n"); + } + } + hit = false; for_all_properties(sym, prop, P_SELECT) { if (!hit) { @@ -504,6 +696,11 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) } else str_printf(r, " && "); expr_gstr_print(prop->expr, r); + if (prop->value) { + str_printf(r, " (value="); + expr_gstr_print(prop->value, r); + str_printf(r, ")"); + } } if (hit) str_append(r, "\n"); @@ -512,22 +709,41 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) expr_gstr_print(sym->rev_dep.expr, r); str_append(r, "\n"); } + for (esv = sym->val_dep; esv; esv = esv->next) { + str_append(r, " Selected by: "); + expr_gstr_print(esv->expr, r); + str_append(r, " with value: "); + expr_gstr_print(esv->value, r); + str_append(r, "\n"); + } str_append(r, "\n\n"); } +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) +{ + struct symbol *sym; + struct gstr res = str_new(); + int i; + + for (i = 0; sym_arr && (sym = sym_arr[i]); i++) + get_symbol_str(&res, sym, head); + if (!i) + str_append(&res, _("No matches found.\n")); + return res; +} + + void menu_get_ext_help(struct menu *menu, struct gstr *help) { struct symbol *sym = menu->sym; + const char *help_text = nohelp_text; if (menu_has_help(menu)) { - if (sym->name) { - str_printf(help, "CONFIG_%s:\n\n", sym->name); - str_append(help, _(menu_get_help(menu))); - str_append(help, "\n"); - } - } else { - str_append(help, nohelp_text); + if (sym->name) + str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); + help_text = menu_get_help(menu); } + str_printf(help, "%s\n", _(help_text)); if (sym) - get_symbol_str(help, sym); + get_symbol_str(help, sym, NULL); } diff --git a/adk/config/nconf.c b/adk/config/nconf.c new file mode 100644 index 000000000..984489ef2 --- /dev/null +++ b/adk/config/nconf.c @@ -0,0 +1,1556 @@ +/* + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? + * Released under the terms of the GNU GPL v2.0. + * + * Derived from menuconfig. + * + */ +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> + +#include "lkc.h" +#include "nconf.h" +#include <ctype.h> + +static const char nconf_global_help[] = N_( +"Help windows\n" +"------------\n" +"o Global help: Unless in a data entry window, pressing <F1> will give \n" +" you the global help window, which you are just reading.\n" +"\n" +"o A short version of the global help is available by pressing <F3>.\n" +"\n" +"o Local help: To get help related to the current menu entry, use any\n" +" of <?> <h>, or if in a data entry window then press <F1>.\n" +"\n" +"\n" +"Menu entries\n" +"------------\n" +"This interface lets you select features and parameters for the kernel\n" +"build. Kernel features can either be built-in, modularized, or removed.\n" +"Parameters must be entered as text or decimal or hexadecimal numbers.\n" +"\n" +"Menu entries beginning with following braces represent features that\n" +" [ ] can be built in or removed\n" +" < > can be built in, modularized or removed\n" +" { } can be built in or modularized, are selected by another feature\n" +" - - are selected by another feature\n" +" XXX cannot be selected. Symbol Info <F2> tells you why.\n" +"*, M or whitespace inside braces means to build in, build as a module\n" +"or to exclude the feature respectively.\n" +"\n" +"To change any of these features, highlight it with the movement keys\n" +"listed below and press <y> to build it in, <m> to make it a module or\n" +"<n> to remove it. You may press the <Space> key to cycle through the\n" +"available options.\n" +"\n" +"A trailing \"--->\" designates a submenu, a trailing \"----\" an\n" +"empty submenu.\n" +"\n" +"Menu navigation keys\n" +"----------------------------------------------------------------------\n" +"Linewise up <Up>\n" +"Linewise down <Down>\n" +"Pagewise up <Page Up>\n" +"Pagewise down <Page Down>\n" +"First entry <Home>\n" +"Last entry <End>\n" +"Enter a submenu <Right> <Enter>\n" +"Go back to parent menu <Left> <Esc> <F5>\n" +"Close a help window <Enter> <Esc> <F5>\n" +"Close entry window, apply <Enter>\n" +"Close entry window, forget <Esc> <F5>\n" +"Start incremental, case-insensitive search for STRING in menu entries,\n" +" no regex support, STRING is displayed in upper left corner\n" +" </>STRING\n" +" Remove last character <Backspace>\n" +" Jump to next hit <Down>\n" +" Jump to previous hit <Up>\n" +"Exit menu search mode </> <Esc>\n" +"Search for configuration variables with or without leading CONFIG_\n" +" <F8>RegExpr<Enter>\n" +"Verbose search help <F8><F1>\n" +"----------------------------------------------------------------------\n" +"\n" +"Unless in a data entry window, key <1> may be used instead of <F1>,\n" +"<2> instead of <F2>, etc.\n" +"\n" +"\n" +"Radiolist (Choice list)\n" +"-----------------------\n" +"Use the movement keys listed above to select the option you wish to set\n" +"and press <Space>.\n" +"\n" +"\n" +"Data entry\n" +"----------\n" +"Enter the requested information and press <Enter>. Hexadecimal values\n" +"may be entered without the \"0x\" prefix.\n" +"\n" +"\n" +"Text Box (Help Window)\n" +"----------------------\n" +"Use movement keys as listed in table above.\n" +"\n" +"Press any of <Enter> <Esc> <q> <F5> <F9> to exit.\n" +"\n" +"\n" +"Alternate configuration files\n" +"-----------------------------\n" +"nconfig supports switching between different configurations.\n" +"Press <F6> to save your current configuration. Press <F7> and enter\n" +"a file name to load a previously saved configuration.\n" +"\n" +"\n" +"Terminal configuration\n" +"----------------------\n" +"If you use nconfig in a xterm window, make sure your TERM environment\n" +"variable specifies a terminal configuration which supports at least\n" +"16 colors. Otherwise nconfig will look rather bad.\n" +"\n" +"If the \"stty size\" command reports the current terminalsize correctly,\n" +"nconfig will adapt to sizes larger than the traditional 80x25 \"standard\"\n" +"and display longer menus properly.\n" +"\n" +"\n" +"Single menu mode\n" +"----------------\n" +"If you prefer to have all of the menu entries listed in a single menu,\n" +"rather than the default multimenu hierarchy, run nconfig with\n" +"NCONFIG_MODE environment variable set to single_menu. Example:\n" +"\n" +"make NCONFIG_MODE=single_menu nconfig\n" +"\n" +"<Enter> will then unfold the appropriate category, or fold it if it\n" +"is already unfolded. Folded menu entries will be designated by a\n" +"leading \"++>\" and unfolded entries by a leading \"-->\".\n" +"\n" +"Note that this mode can eventually be a little more CPU expensive than\n" +"the default mode, especially with a larger number of unfolded submenus.\n" +"\n"), +menu_no_f_instructions[] = N_( +"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" +"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" +"\n" +"Use the following keys to navigate the menus:\n" +"Move up or down with <Up> and <Down>.\n" +"Enter a submenu with <Enter> or <Right>.\n" +"Exit a submenu to its parent menu with <Esc> or <Left>.\n" +"Pressing <y> includes, <n> excludes, <m> modularizes features.\n" +"Pressing <Space> cycles through the available options.\n" +"To search for menu entries press </>.\n" +"<Esc> always leaves the current window.\n" +"\n" +"You do not have function keys support.\n" +"Press <1> instead of <F1>, <2> instead of <F2>, etc.\n" +"For verbose global help use key <1>.\n" +"For help related to the current menu entry press <?> or <h>.\n"), +menu_instructions[] = N_( +"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" +"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" +"\n" +"Use the following keys to navigate the menus:\n" +"Move up or down with <Up> or <Down>.\n" +"Enter a submenu with <Enter> or <Right>.\n" +"Exit a submenu to its parent menu with <Esc> or <Left>.\n" +"Pressing <y> includes, <n> excludes, <m> modularizes features.\n" +"Pressing <Space> cycles through the available options.\n" +"To search for menu entries press </>.\n" +"<Esc> always leaves the current window.\n" +"\n" +"Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n" +"For verbose global help press <F1>.\n" +"For help related to the current menu entry press <?> or <h>.\n"), +radiolist_instructions[] = N_( +"Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n" +"with <Space>.\n" +"For help related to the current entry press <?> or <h>.\n" +"For global help press <F1>.\n"), +inputbox_instructions_int[] = N_( +"Please enter a decimal value.\n" +"Fractions will not be accepted.\n" +"Press <Enter> to apply, <Esc> to cancel."), +inputbox_instructions_hex[] = N_( +"Please enter a hexadecimal value.\n" +"Press <Enter> to apply, <Esc> to cancel."), +inputbox_instructions_string[] = N_( +"Please enter a string value.\n" +"Press <Enter> to apply, <Esc> to cancel."), +setmod_text[] = N_( +"This feature depends on another feature which has been configured as a\n" +"module. As a result, the current feature will be built as a module too."), +load_config_text[] = N_( +"Enter the name of the configuration file you wish to load.\n" +"Accept the name shown to restore the configuration you last\n" +"retrieved. Leave empty to abort."), +load_config_help[] = N_( +"For various reasons, one may wish to keep several different\n" +"configurations available on a single machine.\n" +"\n" +"If you have saved a previous configuration in a file other than the\n" +"default one, entering its name here will allow you to load and modify\n" +"that configuration.\n" +"\n" +"Leave empty to abort.\n"), +save_config_text[] = N_( +"Enter a filename to which this configuration should be saved\n" +"as an alternate. Leave empty to abort."), +save_config_help[] = N_( +"For various reasons, one may wish to keep several different\n" +"configurations available on a single machine.\n" +"\n" +"Entering a file name here will allow you to later retrieve, modify\n" +"and use the current configuration as an alternate to whatever\n" +"configuration options you have selected at that time.\n" +"\n" +"Leave empty to abort.\n"), +search_help[] = N_( +"Search for symbols (configuration variable names CONFIG_*) and display\n" +"their relations. Regular expressions are supported.\n" +"Example: Search for \"^FOO\".\n" +"Result:\n" +"-----------------------------------------------------------------\n" +"Symbol: FOO [ = m]\n" +"Prompt: Foo bus is used to drive the bar HW\n" +"Defined at drivers/pci/Kconfig:47\n" +"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" +"Location:\n" +" -> Bus options (PCI, PCMCIA, EISA, ISA)\n" +" -> PCI support (PCI [ = y])\n" +" -> PCI access mode (<choice> [ = y])\n" +"Selects: LIBCRC32\n" +"Selected by: BAR\n" +"-----------------------------------------------------------------\n" +"o The line 'Prompt:' shows the text displayed for this symbol in\n" +" the menu hierarchy.\n" +"o The 'Defined at' line tells at what file / line number the symbol is\n" +" defined.\n" +"o The 'Depends on:' line lists symbols that need to be defined for\n" +" this symbol to be visible and selectable in the menu.\n" +"o The 'Location:' lines tell, where in the menu structure this symbol\n" +" is located. A location followed by a [ = y] indicates that this is\n" +" a selectable menu item, and the current value is displayed inside\n" +" brackets.\n" +"o The 'Selects:' line tells, what symbol will be automatically selected\n" +" if this symbol is selected (y or m).\n" +"o The 'Selected by' line tells what symbol has selected this symbol.\n" +"\n" +"Only relevant lines are shown.\n" +"\n\n" +"Search examples:\n" +"USB => find all symbols containing USB\n" +"^USB => find all symbols starting with USB\n" +"USB$ => find all symbols ending with USB\n" +"\n"); + +struct mitem { + char str[256]; + char tag; + void *usrptr; + int is_visible; +}; + +#define MAX_MENU_ITEMS 4096 +static int show_all_items; +static int indent; +static struct menu *current_menu; +static int child_count; +static int single_menu_mode; +/* the window in which all information appears */ +static WINDOW *main_window; +/* the largest size of the menu window */ +static int mwin_max_lines; +static int mwin_max_cols; +/* the window in which we show option buttons */ +static MENU *curses_menu; +static ITEM *curses_menu_items[MAX_MENU_ITEMS]; +static struct mitem k_menu_items[MAX_MENU_ITEMS]; +static int items_num; +static int global_exit; +/* the currently selected button */ +const char *current_instructions = menu_instructions; + +static char *dialog_input_result; +static int dialog_input_result_len; + +static void conf(struct menu *menu); +static void conf_choice(struct menu *menu); +static void conf_string(struct menu *menu); +static void conf_load(void); +static void conf_save(void); +static void show_help(struct menu *menu); +static int do_exit(void); +static void setup_windows(void); +static void search_conf(void); + +typedef void (*function_key_handler_t)(int *key, struct menu *menu); +static void handle_f1(int *key, struct menu *current_item); +static void handle_f2(int *key, struct menu *current_item); +static void handle_f3(int *key, struct menu *current_item); +static void handle_f4(int *key, struct menu *current_item); +static void handle_f5(int *key, struct menu *current_item); +static void handle_f6(int *key, struct menu *current_item); +static void handle_f7(int *key, struct menu *current_item); +static void handle_f8(int *key, struct menu *current_item); +static void handle_f9(int *key, struct menu *current_item); + +struct function_keys { + const char *key_str; + const char *func; + function_key key; + function_key_handler_t handler; +}; + +static const int function_keys_num = 9; +struct function_keys function_keys[] = { + { + .key_str = "F1", + .func = "Help", + .key = F_HELP, + .handler = handle_f1, + }, + { + .key_str = "F2", + .func = "SymInfo", + .key = F_SYMBOL, + .handler = handle_f2, + }, + { + .key_str = "F3", + .func = "Help 2", + .key = F_INSTS, + .handler = handle_f3, + }, + { + .key_str = "F4", + .func = "ShowAll", + .key = F_CONF, + .handler = handle_f4, + }, + { + .key_str = "F5", + .func = "Back", + .key = F_BACK, + .handler = handle_f5, + }, + { + .key_str = "F6", + .func = "Save", + .key = F_SAVE, + .handler = handle_f6, + }, + { + .key_str = "F7", + .func = "Load", + .key = F_LOAD, + .handler = handle_f7, + }, + { + .key_str = "F8", + .func = "SymSearch", + .key = F_SEARCH, + .handler = handle_f8, + }, + { + .key_str = "F9", + .func = "Exit", + .key = F_EXIT, + .handler = handle_f9, + }, +}; + +static void print_function_line(void) +{ + int i; + int offset = 1; + const int skip = 1; + int lines = getmaxy(stdscr); + + for (i = 0; i < function_keys_num; i++) { + (void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); + mvwprintw(main_window, lines-3, offset, + "%s", + function_keys[i].key_str); + (void) wattrset(main_window, attributes[FUNCTION_TEXT]); + offset += strlen(function_keys[i].key_str); + mvwprintw(main_window, lines-3, + offset, "%s", + function_keys[i].func); + offset += strlen(function_keys[i].func) + skip; + } + (void) wattrset(main_window, attributes[NORMAL]); +} + +/* help */ +static void handle_f1(int *key, struct menu *current_item) +{ + show_scroll_win(main_window, + _("Global help"), _(nconf_global_help)); + return; +} + +/* symbole help */ +static void handle_f2(int *key, struct menu *current_item) +{ + show_help(current_item); + return; +} + +/* instructions */ +static void handle_f3(int *key, struct menu *current_item) +{ + show_scroll_win(main_window, + _("Short help"), + _(current_instructions)); + return; +} + +/* config */ +static void handle_f4(int *key, struct menu *current_item) +{ + int res = btn_dialog(main_window, + _("Show all symbols?"), + 2, + " <Show All> ", + "<Don't show all>"); + if (res == 0) + show_all_items = 1; + else if (res == 1) + show_all_items = 0; + + return; +} + +/* back */ +static void handle_f5(int *key, struct menu *current_item) +{ + *key = KEY_LEFT; + return; +} + +/* save */ +static void handle_f6(int *key, struct menu *current_item) +{ + conf_save(); + return; +} + +/* load */ +static void handle_f7(int *key, struct menu *current_item) +{ + conf_load(); + return; +} + +/* search */ +static void handle_f8(int *key, struct menu *current_item) +{ + search_conf(); + return; +} + +/* exit */ +static void handle_f9(int *key, struct menu *current_item) +{ + do_exit(); + return; +} + +/* return != 0 to indicate the key was handles */ +static int process_special_keys(int *key, struct menu *menu) +{ + int i; + + if (*key == KEY_RESIZE) { + setup_windows(); + return 1; + } + + for (i = 0; i < function_keys_num; i++) { + if (*key == KEY_F(function_keys[i].key) || + *key == '0' + function_keys[i].key){ + function_keys[i].handler(key, menu); + return 1; + } + } + + return 0; +} + +static void clean_items(void) +{ + int i; + for (i = 0; curses_menu_items[i]; i++) + free_item(curses_menu_items[i]); + bzero(curses_menu_items, sizeof(curses_menu_items)); + bzero(k_menu_items, sizeof(k_menu_items)); + items_num = 0; +} + +typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, + FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f; + +/* return the index of the matched item, or -1 if no such item exists */ +static int get_mext_match(const char *match_str, match_f flag) +{ + int match_start = item_index(current_item(curses_menu)); + int index; + + if (flag == FIND_NEXT_MATCH_DOWN) + ++match_start; + else if (flag == FIND_NEXT_MATCH_UP) + --match_start; + + index = match_start; + index = (index + items_num) % items_num; + while (true) { + char *str = k_menu_items[index].str; + if (strcasestr(str, match_str) != 0) + return index; + if (flag == FIND_NEXT_MATCH_UP || + flag == MATCH_TINKER_PATTERN_UP) + --index; + else + ++index; + index = (index + items_num) % items_num; + if (index == match_start) + return -1; + } +} + +/* Make a new item. */ +static void item_make(struct menu *menu, char tag, const char *fmt, ...) +{ + va_list ap; + + if (items_num > MAX_MENU_ITEMS-1) + return; + + bzero(&k_menu_items[items_num], sizeof(k_menu_items[0])); + k_menu_items[items_num].tag = tag; + k_menu_items[items_num].usrptr = menu; + if (menu != NULL) + k_menu_items[items_num].is_visible = + menu_is_visible(menu); + else + k_menu_items[items_num].is_visible = 1; + + va_start(ap, fmt); + vsnprintf(k_menu_items[items_num].str, + sizeof(k_menu_items[items_num].str), + fmt, ap); + va_end(ap); + + if (!k_menu_items[items_num].is_visible) + memcpy(k_menu_items[items_num].str, "XXX", 3); + + curses_menu_items[items_num] = new_item( + k_menu_items[items_num].str, + k_menu_items[items_num].str); + set_item_userptr(curses_menu_items[items_num], + &k_menu_items[items_num]); + /* + if (!k_menu_items[items_num].is_visible) + item_opts_off(curses_menu_items[items_num], O_SELECTABLE); + */ + + items_num++; + curses_menu_items[items_num] = NULL; +} + +/* very hackish. adds a string to the last item added */ +static void item_add_str(const char *fmt, ...) +{ + va_list ap; + int index = items_num-1; + char new_str[256]; + char tmp_str[256]; + + if (index < 0) + return; + + va_start(ap, fmt); + vsnprintf(new_str, sizeof(new_str), fmt, ap); + va_end(ap); + snprintf(tmp_str, sizeof(tmp_str), "%s%s", + k_menu_items[index].str, new_str); + strncpy(k_menu_items[index].str, + tmp_str, + sizeof(k_menu_items[index].str)); + + free_item(curses_menu_items[index]); + curses_menu_items[index] = new_item( + k_menu_items[index].str, + k_menu_items[index].str); + set_item_userptr(curses_menu_items[index], + &k_menu_items[index]); +} + +/* get the tag of the currently selected item */ +static char item_tag(void) +{ + ITEM *cur; + struct mitem *mcur; + + cur = current_item(curses_menu); + if (cur == NULL) + return 0; + mcur = (struct mitem *) item_userptr(cur); + return mcur->tag; +} + +static int curses_item_index(void) +{ + return item_index(current_item(curses_menu)); +} + +static void *item_data(void) +{ + ITEM *cur; + struct mitem *mcur; + + cur = current_item(curses_menu); + if (!cur) + return NULL; + mcur = (struct mitem *) item_userptr(cur); + return mcur->usrptr; + +} + +static int item_is_tag(char tag) +{ + return item_tag() == tag; +} + +static char filename[PATH_MAX+1]; +static char menu_backtitle[PATH_MAX+128]; +static const char *set_config_filename(const char *config_filename) +{ + int size; + + size = snprintf(menu_backtitle, sizeof(menu_backtitle), + "%s - %s", config_filename, rootmenu.prompt->text); + if (size >= sizeof(menu_backtitle)) + menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; + + size = snprintf(filename, sizeof(filename), "%s", config_filename); + if (size >= sizeof(filename)) + filename[sizeof(filename)-1] = '\0'; + return menu_backtitle; +} + +/* return = 0 means we are successful. + * -1 means go on doing what you were doing + */ +static int do_exit(void) +{ + int res; + if (!conf_get_changed()) { + global_exit = 1; + return 0; + } + res = btn_dialog(main_window, + _("Do you wish to save your new configuration?\n" + "<ESC> to cancel and resume nconfig."), + 2, + " <save> ", + "<don't save>"); + if (res == KEY_EXIT) { + global_exit = 0; + return -1; + } + + /* if we got here, the user really wants to exit */ + switch (res) { + case 0: + res = conf_write(filename); + if (res) + btn_dialog( + main_window, + _("Error during writing of configuration.\n" + "Your configuration changes were NOT saved."), + 1, + "<OK>"); + break; + default: + btn_dialog( + main_window, + _("Your configuration changes were NOT saved."), + 1, + "<OK>"); + break; + } + global_exit = 1; + return 0; +} + + +static void search_conf(void) +{ + struct symbol **sym_arr; + struct gstr res; + struct gstr title; + char *dialog_input; + int dres; + + title = str_new(); + str_printf( &title, _("Enter (sub)string or regexp to search for " + "(with or without \"%s\")"), CONFIG_); + +again: + dres = dialog_inputbox(main_window, + _("Search Configuration Parameter"), + str_get(&title), + "", &dialog_input_result, &dialog_input_result_len); + switch (dres) { + case 0: + break; + case 1: + show_scroll_win(main_window, + _("Search Configuration"), search_help); + goto again; + default: + str_free(&title); + return; + } + + /* strip the prefix if necessary */ + dialog_input = dialog_input_result; + if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) + dialog_input += strlen(CONFIG_); + + sym_arr = sym_re_search(dialog_input); + res = get_relations_str(sym_arr, NULL); + free(sym_arr); + show_scroll_win(main_window, + _("Search Results"), str_get(&res)); + str_free(&res); + str_free(&title); +} + + +static void build_conf(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + int type, tmp, doint = 2; + tristate val; + char ch; + + if (!menu || (!show_all_items && !menu_is_visible(menu))) + return; + + sym = menu->sym; + prop = menu->prompt; + if (!sym) { + if (prop && menu != current_menu) { + const char *prompt = menu_get_prompt(menu); + enum prop_type ptype; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + switch (ptype) { + case P_MENU: + child_count++; + prompt = _(prompt); + if (single_menu_mode) { + item_make(menu, 'm', + "%s%*c%s", + menu->data ? "-->" : "++>", + indent + 1, ' ', prompt); + } else + item_make(menu, 'm', + " %*c%s %s", + indent + 1, ' ', prompt, + menu_is_empty(menu) ? "----" : "--->"); + + if (single_menu_mode && menu->data) + goto conf_childs; + return; + case P_COMMENT: + if (prompt) { + child_count++; + item_make(menu, ':', + " %*c*** %s ***", + indent + 1, ' ', + _(prompt)); + } + break; + default: + if (prompt) { + child_count++; + item_make(menu, ':', "---%*c%s", + indent + 1, ' ', + _(prompt)); + } + } + } else + doint = 0; + goto conf_childs; + } + + type = sym_get_type(sym); + if (sym_is_choice(sym)) { + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + child_count++; + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) && child->sym == def_sym) + def_menu = child; + } + + val = sym_get_tristate_value(sym); + if (sym_is_changable(sym)) { + switch (type) { + case S_BOOLEAN: + item_make(menu, 't', "[%c]", + val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: + ch = '*'; + break; + case mod: + ch = 'M'; + break; + default: + ch = ' '; + break; + } + item_make(menu, 't', "<%c>", ch); + break; + } + } else { + item_make(menu, def_menu ? 't' : ':', " "); + } + + item_add_str("%*c%s", indent + 1, + ' ', _(menu_get_prompt(menu))); + if (val == yes) { + if (def_menu) { + item_add_str(" (%s)", + _(menu_get_prompt(def_menu))); + item_add_str(" --->"); + if (def_menu->list) { + indent += 2; + build_conf(def_menu); + indent -= 2; + } + } + return; + } + } else { + if (menu == current_menu) { + item_make(menu, ':', + "---%*c%s", indent + 1, + ' ', _(menu_get_prompt(menu))); + goto conf_childs; + } + child_count++; + val = sym_get_tristate_value(sym); + if (sym_is_choice_value(sym) && val == yes) { + item_make(menu, ':', " "); + } else { + switch (type) { + case S_BOOLEAN: + if (sym_is_changable(sym)) + item_make(menu, 't', "[%c]", + val == no ? ' ' : '*'); + else + item_make(menu, 't', "-%c-", + val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: + ch = '*'; + break; + case mod: + ch = 'M'; + break; + default: + ch = ' '; + break; + } + if (sym_is_changable(sym)) { + if (sym->rev_dep.tri == mod) + item_make(menu, + 't', "{%c}", ch); + else + item_make(menu, + 't', "<%c>", ch); + } else + item_make(menu, 't', "-%c-", ch); + break; + default: + tmp = 2 + strlen(sym_get_string_value(sym)); + item_make(menu, 's', " (%s)", + sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + item_add_str("%*c%s%s", tmp, ' ', + _(menu_get_prompt(menu)), + (sym_has_value(sym) || + !sym_is_changable(sym)) ? "" : + _(" (NEW)")); + goto conf_childs; + } + } + item_add_str("%*c%s%s", indent + 1, ' ', + _(menu_get_prompt(menu)), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : _(" (NEW)")); + if (menu->prompt && menu->prompt->type == P_MENU) { + item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); + return; + } + } + +conf_childs: + indent += doint; + for (child = menu->list; child; child = child->next) + build_conf(child); + indent -= doint; +} + +static void reset_menu(void) +{ + unpost_menu(curses_menu); + clean_items(); +} + +/* adjust the menu to show this item. + * prefer not to scroll the menu if possible*/ +static void center_item(int selected_index, int *last_top_row) +{ + int toprow; + + set_top_row(curses_menu, *last_top_row); + toprow = top_row(curses_menu); + if (selected_index < toprow || + selected_index >= toprow+mwin_max_lines) { + toprow = max(selected_index-mwin_max_lines/2, 0); + if (toprow >= item_count(curses_menu)-mwin_max_lines) + toprow = item_count(curses_menu)-mwin_max_lines; + set_top_row(curses_menu, toprow); + } + set_current_item(curses_menu, + curses_menu_items[selected_index]); + *last_top_row = toprow; + post_menu(curses_menu); + refresh_all_windows(main_window); +} + +/* this function assumes reset_menu has been called before */ +static void show_menu(const char *prompt, const char *instructions, + int selected_index, int *last_top_row) +{ + int maxx, maxy; + WINDOW *menu_window; + + current_instructions = instructions; + + clear(); + (void) wattrset(main_window, attributes[NORMAL]); + print_in_middle(stdscr, 1, 0, getmaxx(stdscr), + menu_backtitle, + attributes[MAIN_HEADING]); + + (void) wattrset(main_window, attributes[MAIN_MENU_BOX]); + box(main_window, 0, 0); + (void) wattrset(main_window, attributes[MAIN_MENU_HEADING]); + mvwprintw(main_window, 0, 3, " %s ", prompt); + (void) wattrset(main_window, attributes[NORMAL]); + + set_menu_items(curses_menu, curses_menu_items); + + /* position the menu at the middle of the screen */ + scale_menu(curses_menu, &maxy, &maxx); + maxx = min(maxx, mwin_max_cols-2); + maxy = mwin_max_lines; + menu_window = derwin(main_window, + maxy, + maxx, + 2, + (mwin_max_cols-maxx)/2); + keypad(menu_window, TRUE); + set_menu_win(curses_menu, menu_window); + set_menu_sub(curses_menu, menu_window); + + /* must reassert this after changing items, otherwise returns to a + * default of 16 + */ + set_menu_format(curses_menu, maxy, 1); + center_item(selected_index, last_top_row); + set_menu_format(curses_menu, maxy, 1); + + print_function_line(); + + /* Post the menu */ + post_menu(curses_menu); + refresh_all_windows(main_window); +} + +static void adj_match_dir(match_f *match_direction) +{ + if (*match_direction == FIND_NEXT_MATCH_DOWN) + *match_direction = + MATCH_TINKER_PATTERN_DOWN; + else if (*match_direction == FIND_NEXT_MATCH_UP) + *match_direction = + MATCH_TINKER_PATTERN_UP; + /* else, do no change.. */ +} + +struct match_state +{ + int in_search; + match_f match_direction; + char pattern[256]; +}; + +/* Return 0 means I have handled the key. In such a case, ans should hold the + * item to center, or -1 otherwise. + * Else return -1 . + */ +static int do_match(int key, struct match_state *state, int *ans) +{ + char c = (char) key; + int terminate_search = 0; + *ans = -1; + if (key == '/' || (state->in_search && key == 27)) { + move(0, 0); + refresh(); + clrtoeol(); + state->in_search = 1-state->in_search; + bzero(state->pattern, sizeof(state->pattern)); + state->match_direction = MATCH_TINKER_PATTERN_DOWN; + return 0; + } else if (!state->in_search) + return 1; + + if (isalnum(c) || isgraph(c) || c == ' ') { + state->pattern[strlen(state->pattern)] = c; + state->pattern[strlen(state->pattern)] = '\0'; + adj_match_dir(&state->match_direction); + *ans = get_mext_match(state->pattern, + state->match_direction); + } else if (key == KEY_DOWN) { + state->match_direction = FIND_NEXT_MATCH_DOWN; + *ans = get_mext_match(state->pattern, + state->match_direction); + } else if (key == KEY_UP) { + state->match_direction = FIND_NEXT_MATCH_UP; + *ans = get_mext_match(state->pattern, + state->match_direction); + } else if (key == KEY_BACKSPACE || key == 127) { + state->pattern[strlen(state->pattern)-1] = '\0'; + adj_match_dir(&state->match_direction); + } else + terminate_search = 1; + + if (terminate_search) { + state->in_search = 0; + bzero(state->pattern, sizeof(state->pattern)); + move(0, 0); + refresh(); + clrtoeol(); + return -1; + } + return 0; +} + +static void conf(struct menu *menu) +{ + struct menu *submenu = 0; + const char *prompt = menu_get_prompt(menu); + struct symbol *sym; + int res; + int current_index = 0; + int last_top_row = 0; + struct match_state match_state = { + .in_search = 0, + .match_direction = MATCH_TINKER_PATTERN_DOWN, + .pattern = "", + }; + + while (!global_exit) { + reset_menu(); + current_menu = menu; + build_conf(menu); + if (!child_count) + break; + + show_menu(prompt ? _(prompt) : _("Main Menu"), + _(menu_instructions), + current_index, &last_top_row); + keypad((menu_win(curses_menu)), TRUE); + while (!global_exit) { + if (match_state.in_search) { + mvprintw(0, 0, + "searching: %s", match_state.pattern); + clrtoeol(); + } + refresh_all_windows(main_window); + res = wgetch(menu_win(curses_menu)); + if (!res) + break; + if (do_match(res, &match_state, ¤t_index) == 0) { + if (current_index != -1) + center_item(current_index, + &last_top_row); + continue; + } + if (process_special_keys(&res, + (struct menu *) item_data())) + break; + switch (res) { + case KEY_DOWN: + menu_driver(curses_menu, REQ_DOWN_ITEM); + break; + case KEY_UP: + menu_driver(curses_menu, REQ_UP_ITEM); + break; + case KEY_NPAGE: + menu_driver(curses_menu, REQ_SCR_DPAGE); + break; + case KEY_PPAGE: + menu_driver(curses_menu, REQ_SCR_UPAGE); + break; + case KEY_HOME: + menu_driver(curses_menu, REQ_FIRST_ITEM); + break; + case KEY_END: + menu_driver(curses_menu, REQ_LAST_ITEM); + break; + case 'h': + case '?': + show_help((struct menu *) item_data()); + break; + } + if (res == 10 || res == 27 || + res == 32 || res == 'n' || res == 'y' || + res == KEY_LEFT || res == KEY_RIGHT || + res == 'm') + break; + refresh_all_windows(main_window); + } + + refresh_all_windows(main_window); + /* if ESC or left*/ + if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) + break; + + /* remember location in the menu */ + last_top_row = top_row(curses_menu); + current_index = curses_item_index(); + + if (!item_tag()) + continue; + + submenu = (struct menu *) item_data(); + if (!submenu || !menu_is_visible(submenu)) + continue; + sym = submenu->sym; + + switch (res) { + case ' ': + if (item_is_tag('t')) + sym_toggle_tristate_value(sym); + else if (item_is_tag('m')) + conf(submenu); + break; + case KEY_RIGHT: + case 10: /* ENTER WAS PRESSED */ + switch (item_tag()) { + case 'm': + if (single_menu_mode) + submenu->data = + (void *) (long) !submenu->data; + else + conf(submenu); + break; + case 't': + if (sym_is_choice(sym) && + sym_get_tristate_value(sym) == yes) + conf_choice(submenu); + else if (submenu->prompt && + submenu->prompt->type == P_MENU) + conf(submenu); + else if (res == 10) + sym_toggle_tristate_value(sym); + break; + case 's': + conf_string(submenu); + break; + } + break; + case 'y': + if (item_is_tag('t')) { + if (sym_set_tristate_value(sym, yes)) + break; + if (sym_set_tristate_value(sym, mod)) + btn_dialog(main_window, setmod_text, 0); + } + break; + case 'n': + if (item_is_tag('t')) + sym_set_tristate_value(sym, no); + break; + case 'm': + if (item_is_tag('t')) + sym_set_tristate_value(sym, mod); + break; + } + } +} + +static void conf_message_callback(const char *fmt, va_list ap) +{ + char buf[1024]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + btn_dialog(main_window, buf, 1, "<OK>"); +} + +static void show_help(struct menu *menu) +{ + struct gstr help; + + if (!menu) + return; + + help = str_new(); + menu_get_ext_help(menu, &help); + show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); + str_free(&help); +} + +static void conf_choice(struct menu *menu) +{ + const char *prompt = _(menu_get_prompt(menu)); + struct menu *child = 0; + struct symbol *active; + int selected_index = 0; + int last_top_row = 0; + int res, i = 0; + struct match_state match_state = { + .in_search = 0, + .match_direction = MATCH_TINKER_PATTERN_DOWN, + .pattern = "", + }; + + active = sym_get_choice_value(menu->sym); + /* this is mostly duplicated from the conf() function. */ + while (!global_exit) { + reset_menu(); + + for (i = 0, child = menu->list; child; child = child->next) { + if (!show_all_items && !menu_is_visible(child)) + continue; + + if (child->sym == sym_get_choice_value(menu->sym)) + item_make(child, ':', "<X> %s", + _(menu_get_prompt(child))); + else if (child->sym) + item_make(child, ':', " %s", + _(menu_get_prompt(child))); + else + item_make(child, ':', "*** %s ***", + _(menu_get_prompt(child))); + + if (child->sym == active){ + last_top_row = top_row(curses_menu); + selected_index = i; + } + i++; + } + show_menu(prompt ? _(prompt) : _("Choice Menu"), + _(radiolist_instructions), + selected_index, + &last_top_row); + while (!global_exit) { + if (match_state.in_search) { + mvprintw(0, 0, "searching: %s", + match_state.pattern); + clrtoeol(); + } + refresh_all_windows(main_window); + res = wgetch(menu_win(curses_menu)); + if (!res) + break; + if (do_match(res, &match_state, &selected_index) == 0) { + if (selected_index != -1) + center_item(selected_index, + &last_top_row); + continue; + } + if (process_special_keys( + &res, + (struct menu *) item_data())) + break; + switch (res) { + case KEY_DOWN: + menu_driver(curses_menu, REQ_DOWN_ITEM); + break; + case KEY_UP: + menu_driver(curses_menu, REQ_UP_ITEM); + break; + case KEY_NPAGE: + menu_driver(curses_menu, REQ_SCR_DPAGE); + break; + case KEY_PPAGE: + menu_driver(curses_menu, REQ_SCR_UPAGE); + break; + case KEY_HOME: + menu_driver(curses_menu, REQ_FIRST_ITEM); + break; + case KEY_END: + menu_driver(curses_menu, REQ_LAST_ITEM); + break; + case 'h': + case '?': + show_help((struct menu *) item_data()); + break; + } + if (res == 10 || res == 27 || res == ' ' || + res == KEY_LEFT){ + break; + } + refresh_all_windows(main_window); + } + /* if ESC or left */ + if (res == 27 || res == KEY_LEFT) + break; + + child = item_data(); + if (!child || !menu_is_visible(child) || !child->sym) + continue; + switch (res) { + case ' ': + case 10: + case KEY_RIGHT: + sym_set_tristate_value(child->sym, yes); + return; + case 'h': + case '?': + show_help(child); + active = child->sym; + break; + case KEY_EXIT: + return; + } + } +} + +static void conf_string(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + + while (1) { + int res; + const char *heading; + + switch (sym_get_type(menu->sym)) { + case S_INT: + heading = _(inputbox_instructions_int); + break; + case S_HEX: + heading = _(inputbox_instructions_hex); + break; + case S_STRING: + heading = _(inputbox_instructions_string); + break; + default: + heading = _("Internal nconf error!"); + } + res = dialog_inputbox(main_window, + prompt ? _(prompt) : _("Main Menu"), + heading, + sym_get_string_value(menu->sym), + &dialog_input_result, + &dialog_input_result_len); + switch (res) { + case 0: + if (sym_set_string_value(menu->sym, + dialog_input_result)) + return; + btn_dialog(main_window, + _("You have made an invalid entry."), 0); + break; + case 1: + show_help(menu); + break; + case KEY_EXIT: + return; + } + } +} + +static void conf_load(void) +{ + while (1) { + int res; + res = dialog_inputbox(main_window, + NULL, load_config_text, + filename, + &dialog_input_result, + &dialog_input_result_len); + switch (res) { + case 0: + if (!dialog_input_result[0]) + return; + if (!conf_read(dialog_input_result)) { + set_config_filename(dialog_input_result); + sym_set_change_count(1); + return; + } + btn_dialog(main_window, _("File does not exist!"), 0); + break; + case 1: + show_scroll_win(main_window, + _("Load Alternate Configuration"), + load_config_help); + break; + case KEY_EXIT: + return; + } + } +} + +static void conf_save(void) +{ + while (1) { + int res; + res = dialog_inputbox(main_window, + NULL, save_config_text, + filename, + &dialog_input_result, + &dialog_input_result_len); + switch (res) { + case 0: + if (!dialog_input_result[0]) + return; + res = conf_write(dialog_input_result); + if (!res) { + set_config_filename(dialog_input_result); + return; + } + btn_dialog(main_window, _("Can't create file! " + "Probably a nonexistent directory."), + 1, "<OK>"); + break; + case 1: + show_scroll_win(main_window, + _("Save Alternate Configuration"), + save_config_help); + break; + case KEY_EXIT: + return; + } + } +} + +void setup_windows(void) +{ + int lines, columns; + + getmaxyx(stdscr, lines, columns); + + if (main_window != NULL) + delwin(main_window); + + /* set up the menu and menu window */ + main_window = newwin(lines-2, columns-2, 2, 1); + keypad(main_window, TRUE); + mwin_max_lines = lines-7; + mwin_max_cols = columns-6; + + /* panels order is from bottom to top */ + new_panel(main_window); +} + +int main(int ac, char **av) +{ + int lines, columns; + char *mode; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + conf_parse(av[1]); + conf_read(NULL); + + mode = getenv("NCONFIG_MODE"); + if (mode) { + if (!strcasecmp(mode, "single_menu")) + single_menu_mode = 1; + } + + /* Initialize curses */ + initscr(); + /* set color theme */ + set_colors(); + + cbreak(); + noecho(); + keypad(stdscr, TRUE); + curs_set(0); + + getmaxyx(stdscr, lines, columns); + if (columns < 75 || lines < 20) { + endwin(); + printf("Your terminal should have at " + "least 20 lines and 75 columns\n"); + return 1; + } + + notimeout(stdscr, FALSE); +#if NCURSES_REENTRANT + set_escdelay(1); +#else + ESCDELAY = 1; +#endif + + /* set btns menu */ + curses_menu = new_menu(curses_menu_items); + menu_opts_off(curses_menu, O_SHOWDESC); + menu_opts_on(curses_menu, O_SHOWMATCH); + menu_opts_on(curses_menu, O_ONEVALUE); + menu_opts_on(curses_menu, O_NONCYCLIC); + menu_opts_on(curses_menu, O_IGNORECASE); + set_menu_mark(curses_menu, " "); + set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); + set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); + set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]); + + set_config_filename(conf_get_configname()); + setup_windows(); + + /* check for KEY_FUNC(1) */ + if (has_key(KEY_F(1)) == FALSE) { + show_scroll_win(main_window, + _("Instructions"), + _(menu_no_f_instructions)); + } + + conf_set_message_callback(conf_message_callback); + /* do the work */ + while (!global_exit) { + conf(&rootmenu); + if (!global_exit && do_exit() == 0) + break; + } + /* ok, we are done */ + unpost_menu(curses_menu); + free_menu(curses_menu); + delwin(main_window); + clear(); + refresh(); + endwin(); + return 0; +} diff --git a/adk/config/nconf.gui.c b/adk/config/nconf.gui.c new file mode 100644 index 000000000..8275f0e55 --- /dev/null +++ b/adk/config/nconf.gui.c @@ -0,0 +1,656 @@ +/* + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? + * Released under the terms of the GNU GPL v2.0. + * + * Derived from menuconfig. + * + */ +#include "nconf.h" + +/* a list of all the different widgets we use */ +attributes_t attributes[ATTR_MAX+1] = {0}; + +/* available colors: + COLOR_BLACK 0 + COLOR_RED 1 + COLOR_GREEN 2 + COLOR_YELLOW 3 + COLOR_BLUE 4 + COLOR_MAGENTA 5 + COLOR_CYAN 6 + COLOR_WHITE 7 + */ +static void set_normal_colors(void) +{ + init_pair(NORMAL, -1, -1); + init_pair(MAIN_HEADING, COLOR_MAGENTA, -1); + + /* FORE is for the selected item */ + init_pair(MAIN_MENU_FORE, -1, -1); + /* BACK for all the rest */ + init_pair(MAIN_MENU_BACK, -1, -1); + init_pair(MAIN_MENU_GREY, -1, -1); + init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1); + init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1); + + init_pair(SCROLLWIN_TEXT, -1, -1); + init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1); + init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1); + + init_pair(DIALOG_TEXT, -1, -1); + init_pair(DIALOG_BOX, COLOR_YELLOW, -1); + init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1); + init_pair(DIALOG_MENU_FORE, COLOR_RED, -1); + + init_pair(INPUT_BOX, COLOR_YELLOW, -1); + init_pair(INPUT_HEADING, COLOR_GREEN, -1); + init_pair(INPUT_TEXT, -1, -1); + init_pair(INPUT_FIELD, -1, -1); + + init_pair(FUNCTION_HIGHLIGHT, -1, -1); + init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1); +} + +/* available attributes: + A_NORMAL Normal display (no highlight) + A_STANDOUT Best highlighting mode of the terminal. + A_UNDERLINE Underlining + A_REVERSE Reverse video + A_BLINK Blinking + A_DIM Half bright + A_BOLD Extra bright or bold + A_PROTECT Protected mode + A_INVIS Invisible or blank mode + A_ALTCHARSET Alternate character set + A_CHARTEXT Bit-mask to extract a character + COLOR_PAIR(n) Color-pair number n + */ +static void normal_color_theme(void) +{ + /* automatically add color... */ +#define mkattr(name, attr) do { \ +attributes[name] = attr | COLOR_PAIR(name); } while (0) + mkattr(NORMAL, NORMAL); + mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE); + + mkattr(MAIN_MENU_FORE, A_REVERSE); + mkattr(MAIN_MENU_BACK, A_NORMAL); + mkattr(MAIN_MENU_GREY, A_NORMAL); + mkattr(MAIN_MENU_HEADING, A_BOLD); + mkattr(MAIN_MENU_BOX, A_NORMAL); + + mkattr(SCROLLWIN_TEXT, A_NORMAL); + mkattr(SCROLLWIN_HEADING, A_BOLD); + mkattr(SCROLLWIN_BOX, A_BOLD); + + mkattr(DIALOG_TEXT, A_BOLD); + mkattr(DIALOG_BOX, A_BOLD); + mkattr(DIALOG_MENU_FORE, A_STANDOUT); + mkattr(DIALOG_MENU_BACK, A_NORMAL); + + mkattr(INPUT_BOX, A_NORMAL); + mkattr(INPUT_HEADING, A_BOLD); + mkattr(INPUT_TEXT, A_NORMAL); + mkattr(INPUT_FIELD, A_UNDERLINE); + + mkattr(FUNCTION_HIGHLIGHT, A_BOLD); + mkattr(FUNCTION_TEXT, A_REVERSE); +} + +static void no_colors_theme(void) +{ + /* automatically add highlight, no color */ +#define mkattrn(name, attr) { attributes[name] = attr; } + + mkattrn(NORMAL, NORMAL); + mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE); + + mkattrn(MAIN_MENU_FORE, A_STANDOUT); + mkattrn(MAIN_MENU_BACK, A_NORMAL); + mkattrn(MAIN_MENU_GREY, A_NORMAL); + mkattrn(MAIN_MENU_HEADING, A_BOLD); + mkattrn(MAIN_MENU_BOX, A_NORMAL); + + mkattrn(SCROLLWIN_TEXT, A_NORMAL); + mkattrn(SCROLLWIN_HEADING, A_BOLD); + mkattrn(SCROLLWIN_BOX, A_BOLD); + + mkattrn(DIALOG_TEXT, A_NORMAL); + mkattrn(DIALOG_BOX, A_BOLD); + mkattrn(DIALOG_MENU_FORE, A_STANDOUT); + mkattrn(DIALOG_MENU_BACK, A_NORMAL); + + mkattrn(INPUT_BOX, A_BOLD); + mkattrn(INPUT_HEADING, A_BOLD); + mkattrn(INPUT_TEXT, A_NORMAL); + mkattrn(INPUT_FIELD, A_UNDERLINE); + + mkattrn(FUNCTION_HIGHLIGHT, A_BOLD); + mkattrn(FUNCTION_TEXT, A_REVERSE); +} + +void set_colors() +{ + start_color(); + use_default_colors(); + set_normal_colors(); + if (has_colors()) { + normal_color_theme(); + } else { + /* give defaults */ + no_colors_theme(); + } +} + + +/* this changes the windows attributes !!! */ +void print_in_middle(WINDOW *win, + int starty, + int startx, + int width, + const char *string, + chtype color) +{ int length, x, y; + float temp; + + + if (win == NULL) + win = stdscr; + getyx(win, y, x); + if (startx != 0) + x = startx; + if (starty != 0) + y = starty; + if (width == 0) + width = 80; + + length = strlen(string); + temp = (width - length) / 2; + x = startx + (int)temp; + (void) wattrset(win, color); + mvwprintw(win, y, x, "%s", string); + refresh(); +} + +int get_line_no(const char *text) +{ + int i; + int total = 1; + + if (!text) + return 0; + + for (i = 0; text[i] != '\0'; i++) + if (text[i] == '\n') + total++; + return total; +} + +const char *get_line(const char *text, int line_no) +{ + int i; + int lines = 0; + + if (!text) + return 0; + + for (i = 0; text[i] != '\0' && lines < line_no; i++) + if (text[i] == '\n') + lines++; + return text+i; +} + +int get_line_length(const char *line) +{ + int res = 0; + while (*line != '\0' && *line != '\n') { + line++; + res++; + } + return res; +} + +/* print all lines to the window. */ +void fill_window(WINDOW *win, const char *text) +{ + int x, y; + int total_lines = get_line_no(text); + int i; + + getmaxyx(win, y, x); + /* do not go over end of line */ + total_lines = min(total_lines, y); + for (i = 0; i < total_lines; i++) { + char tmp[x+10]; + const char *line = get_line(text, i); + int len = get_line_length(line); + strncpy(tmp, line, min(len, x)); + tmp[len] = '\0'; + mvwprintw(win, i, 0, "%s", tmp); + } +} + +/* get the message, and buttons. + * each button must be a char* + * return the selected button + * + * this dialog is used for 2 different things: + * 1) show a text box, no buttons. + * 2) show a dialog, with horizontal buttons + */ +int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) +{ + va_list ap; + char *btn; + int btns_width = 0; + int msg_lines = 0; + int msg_width = 0; + int total_width; + int win_rows = 0; + WINDOW *win; + WINDOW *msg_win; + WINDOW *menu_win; + MENU *menu; + ITEM *btns[btn_num+1]; + int i, x, y; + int res = -1; + + + va_start(ap, btn_num); + for (i = 0; i < btn_num; i++) { + btn = va_arg(ap, char *); + btns[i] = new_item(btn, ""); + btns_width += strlen(btn)+1; + } + va_end(ap); + btns[btn_num] = NULL; + + /* find the widest line of msg: */ + msg_lines = get_line_no(msg); + for (i = 0; i < msg_lines; i++) { + const char *line = get_line(msg, i); + int len = get_line_length(line); + if (msg_width < len) + msg_width = len; + } + + total_width = max(msg_width, btns_width); + /* place dialog in middle of screen */ + y = (getmaxy(stdscr)-(msg_lines+4))/2; + x = (getmaxx(stdscr)-(total_width+4))/2; + + + /* create the windows */ + if (btn_num > 0) + win_rows = msg_lines+4; + else + win_rows = msg_lines+2; + + win = newwin(win_rows, total_width+4, y, x); + keypad(win, TRUE); + menu_win = derwin(win, 1, btns_width, win_rows-2, + 1+(total_width+2-btns_width)/2); + menu = new_menu(btns); + msg_win = derwin(win, win_rows-2, msg_width, 1, + 1+(total_width+2-msg_width)/2); + + set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); + set_menu_back(menu, attributes[DIALOG_MENU_BACK]); + + (void) wattrset(win, attributes[DIALOG_BOX]); + box(win, 0, 0); + + /* print message */ + (void) wattrset(msg_win, attributes[DIALOG_TEXT]); + fill_window(msg_win, msg); + + set_menu_win(menu, win); + set_menu_sub(menu, menu_win); + set_menu_format(menu, 1, btn_num); + menu_opts_off(menu, O_SHOWDESC); + menu_opts_off(menu, O_SHOWMATCH); + menu_opts_on(menu, O_ONEVALUE); + menu_opts_on(menu, O_NONCYCLIC); + set_menu_mark(menu, ""); + post_menu(menu); + + + touchwin(win); + refresh_all_windows(main_window); + while ((res = wgetch(win))) { + switch (res) { + case KEY_LEFT: + menu_driver(menu, REQ_LEFT_ITEM); + break; + case KEY_RIGHT: + menu_driver(menu, REQ_RIGHT_ITEM); + break; + case 10: /* ENTER */ + case 27: /* ESCAPE */ + case ' ': + case KEY_F(F_BACK): + case KEY_F(F_EXIT): + break; + } + touchwin(win); + refresh_all_windows(main_window); + + if (res == 10 || res == ' ') { + res = item_index(current_item(menu)); + break; + } else if (res == 27 || res == KEY_F(F_BACK) || + res == KEY_F(F_EXIT)) { + res = KEY_EXIT; + break; + } + } + + unpost_menu(menu); + free_menu(menu); + for (i = 0; i < btn_num; i++) + free_item(btns[i]); + + delwin(win); + return res; +} + +int dialog_inputbox(WINDOW *main_window, + const char *title, const char *prompt, + const char *init, char **resultp, int *result_len) +{ + int prompt_lines = 0; + int prompt_width = 0; + WINDOW *win; + WINDOW *prompt_win; + WINDOW *form_win; + PANEL *panel; + int i, x, y; + int res = -1; + int cursor_position = strlen(init); + int cursor_form_win; + char *result = *resultp; + + if (strlen(init)+1 > *result_len) { + *result_len = strlen(init)+1; + *resultp = result = realloc(result, *result_len); + } + + /* find the widest line of msg: */ + prompt_lines = get_line_no(prompt); + for (i = 0; i < prompt_lines; i++) { + const char *line = get_line(prompt, i); + int len = get_line_length(line); + prompt_width = max(prompt_width, len); + } + + if (title) + prompt_width = max(prompt_width, strlen(title)); + + /* place dialog in middle of screen */ + y = (getmaxy(stdscr)-(prompt_lines+4))/2; + x = (getmaxx(stdscr)-(prompt_width+4))/2; + + strncpy(result, init, *result_len); + + /* create the windows */ + win = newwin(prompt_lines+6, prompt_width+7, y, x); + prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); + form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); + keypad(form_win, TRUE); + + (void) wattrset(form_win, attributes[INPUT_FIELD]); + + (void) wattrset(win, attributes[INPUT_BOX]); + box(win, 0, 0); + (void) wattrset(win, attributes[INPUT_HEADING]); + if (title) + mvwprintw(win, 0, 3, "%s", title); + + /* print message */ + (void) wattrset(prompt_win, attributes[INPUT_TEXT]); + fill_window(prompt_win, prompt); + + mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); + cursor_form_win = min(cursor_position, prompt_width-1); + mvwprintw(form_win, 0, 0, "%s", + result + cursor_position-cursor_form_win); + + /* create panels */ + panel = new_panel(win); + + /* show the cursor */ + curs_set(1); + + touchwin(win); + refresh_all_windows(main_window); + while ((res = wgetch(form_win))) { + int len = strlen(result); + switch (res) { + case 10: /* ENTER */ + case 27: /* ESCAPE */ + case KEY_F(F_HELP): + case KEY_F(F_EXIT): + case KEY_F(F_BACK): + break; + case 127: + case KEY_BACKSPACE: + if (cursor_position > 0) { + memmove(&result[cursor_position-1], + &result[cursor_position], + len-cursor_position+1); + cursor_position--; + cursor_form_win--; + len--; + } + break; + case KEY_DC: + if (cursor_position >= 0 && cursor_position < len) { + memmove(&result[cursor_position], + &result[cursor_position+1], + len-cursor_position+1); + len--; + } + break; + case KEY_UP: + case KEY_RIGHT: + if (cursor_position < len) { + cursor_position++; + cursor_form_win++; + } + break; + case KEY_DOWN: + case KEY_LEFT: + if (cursor_position > 0) { + cursor_position--; + cursor_form_win--; + } + break; + case KEY_HOME: + cursor_position = 0; + cursor_form_win = 0; + break; + case KEY_END: + cursor_position = len; + cursor_form_win = min(cursor_position, prompt_width-1); + break; + default: + if ((isgraph(res) || isspace(res))) { + /* one for new char, one for '\0' */ + if (len+2 > *result_len) { + *result_len = len+2; + *resultp = result = realloc(result, + *result_len); + } + /* insert the char at the proper position */ + memmove(&result[cursor_position+1], + &result[cursor_position], + len-cursor_position+1); + result[cursor_position] = res; + cursor_position++; + cursor_form_win++; + len++; + } else { + mvprintw(0, 0, "unknown key: %d\n", res); + } + break; + } + if (cursor_form_win < 0) + cursor_form_win = 0; + else if (cursor_form_win > prompt_width-1) + cursor_form_win = prompt_width-1; + + wmove(form_win, 0, 0); + wclrtoeol(form_win); + mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); + mvwprintw(form_win, 0, 0, "%s", + result + cursor_position-cursor_form_win); + wmove(form_win, 0, cursor_form_win); + touchwin(win); + refresh_all_windows(main_window); + + if (res == 10) { + res = 0; + break; + } else if (res == 27 || res == KEY_F(F_BACK) || + res == KEY_F(F_EXIT)) { + res = KEY_EXIT; + break; + } else if (res == KEY_F(F_HELP)) { + res = 1; + break; + } + } + + /* hide the cursor */ + curs_set(0); + del_panel(panel); + delwin(prompt_win); + delwin(form_win); + delwin(win); + return res; +} + +/* refresh all windows in the correct order */ +void refresh_all_windows(WINDOW *main_window) +{ + update_panels(); + touchwin(main_window); + refresh(); +} + +/* layman's scrollable window... */ +void show_scroll_win(WINDOW *main_window, + const char *title, + const char *text) +{ + int res; + int total_lines = get_line_no(text); + int x, y, lines, columns; + int start_x = 0, start_y = 0; + int text_lines = 0, text_cols = 0; + int total_cols = 0; + int win_cols = 0; + int win_lines = 0; + int i = 0; + WINDOW *win; + WINDOW *pad; + PANEL *panel; + + getmaxyx(stdscr, lines, columns); + + /* find the widest line of msg: */ + total_lines = get_line_no(text); + for (i = 0; i < total_lines; i++) { + const char *line = get_line(text, i); + int len = get_line_length(line); + total_cols = max(total_cols, len+2); + } + + /* create the pad */ + pad = newpad(total_lines+10, total_cols+10); + (void) wattrset(pad, attributes[SCROLLWIN_TEXT]); + fill_window(pad, text); + + win_lines = min(total_lines+4, lines-2); + win_cols = min(total_cols+2, columns-2); + text_lines = max(win_lines-4, 0); + text_cols = max(win_cols-2, 0); + + /* place window in middle of screen */ + y = (lines-win_lines)/2; + x = (columns-win_cols)/2; + + win = newwin(win_lines, win_cols, y, x); + keypad(win, TRUE); + /* show the help in the help window, and show the help panel */ + (void) wattrset(win, attributes[SCROLLWIN_BOX]); + box(win, 0, 0); + (void) wattrset(win, attributes[SCROLLWIN_HEADING]); + mvwprintw(win, 0, 3, " %s ", title); + panel = new_panel(win); + + /* handle scrolling */ + do { + + copywin(pad, win, start_y, start_x, 2, 2, text_lines, + text_cols, 0); + print_in_middle(win, + text_lines+2, + 0, + text_cols, + "<OK>", + attributes[DIALOG_MENU_FORE]); + wrefresh(win); + + res = wgetch(win); + switch (res) { + case KEY_NPAGE: + case ' ': + case 'd': + start_y += text_lines-2; + break; + case KEY_PPAGE: + case 'u': + start_y -= text_lines+2; + break; + case KEY_HOME: + start_y = 0; + break; + case KEY_END: + start_y = total_lines-text_lines; + break; + case KEY_DOWN: + case 'j': + start_y++; + break; + case KEY_UP: + case 'k': + start_y--; + break; + case KEY_LEFT: + case 'h': + start_x--; + break; + case KEY_RIGHT: + case 'l': + start_x++; + break; + } + if (res == 10 || res == 27 || res == 'q' || + res == KEY_F(F_HELP) || res == KEY_F(F_BACK) || + res == KEY_F(F_EXIT)) + break; + if (start_y < 0) + start_y = 0; + if (start_y >= total_lines-text_lines) + start_y = total_lines-text_lines; + if (start_x < 0) + start_x = 0; + if (start_x >= total_cols-text_cols) + start_x = total_cols-text_cols; + } while (res); + + del_panel(panel); + delwin(win); + refresh_all_windows(main_window); +} diff --git a/adk/config/nconf.h b/adk/config/nconf.h new file mode 100644 index 000000000..0d5261705 --- /dev/null +++ b/adk/config/nconf.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? + * Released under the terms of the GNU GPL v2.0. + * + * Derived from menuconfig. + * + */ + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <locale.h> +#include <curses.h> +#include <menu.h> +#include <panel.h> +#include <form.h> + +#include <stdio.h> +#include <time.h> +#include <sys/time.h> + +#include "ncurses.h" + +#define max(a, b) ({\ + typeof(a) _a = a;\ + typeof(b) _b = b;\ + _a > _b ? _a : _b; }) + +#define min(a, b) ({\ + typeof(a) _a = a;\ + typeof(b) _b = b;\ + _a < _b ? _a : _b; }) + +typedef enum { + NORMAL = 1, + MAIN_HEADING, + MAIN_MENU_BOX, + MAIN_MENU_FORE, + MAIN_MENU_BACK, + MAIN_MENU_GREY, + MAIN_MENU_HEADING, + SCROLLWIN_TEXT, + SCROLLWIN_HEADING, + SCROLLWIN_BOX, + DIALOG_TEXT, + DIALOG_MENU_FORE, + DIALOG_MENU_BACK, + DIALOG_BOX, + INPUT_BOX, + INPUT_HEADING, + INPUT_TEXT, + INPUT_FIELD, + FUNCTION_TEXT, + FUNCTION_HIGHLIGHT, + ATTR_MAX +} attributes_t; +extern attributes_t attributes[]; + +typedef enum { + F_HELP = 1, + F_SYMBOL = 2, + F_INSTS = 3, + F_CONF = 4, + F_BACK = 5, + F_SAVE = 6, + F_LOAD = 7, + F_SEARCH = 8, + F_EXIT = 9, +} function_key; + +void set_colors(void); + +/* this changes the windows attributes !!! */ +void print_in_middle(WINDOW *win, + int starty, + int startx, + int width, + const char *string, + chtype color); +int get_line_length(const char *line); +int get_line_no(const char *text); +const char *get_line(const char *text, int line_no); +void fill_window(WINDOW *win, const char *text); +int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...); +int dialog_inputbox(WINDOW *main_window, + const char *title, const char *prompt, + const char *init, char **resultp, int *result_len); +void refresh_all_windows(WINDOW *main_window); +void show_scroll_win(WINDOW *main_window, + const char *title, + const char *text); diff --git a/adk/config/qconf.h b/adk/config/qconf.h new file mode 100644 index 000000000..bde0c6b6f --- /dev/null +++ b/adk/config/qconf.h @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + */ + +#if QT_VERSION < 0x040000 +#include <qlistview.h> +#else +#include <q3listview.h> +#endif +#include <qsettings.h> + +#if QT_VERSION < 0x040000 +#define Q3ValueList QValueList +#define Q3PopupMenu QPopupMenu +#define Q3ListView QListView +#define Q3ListViewItem QListViewItem +#define Q3VBox QVBox +#define Q3TextBrowser QTextBrowser +#define Q3MainWindow QMainWindow +#define Q3Action QAction +#define Q3ToolBar QToolBar +#define Q3ListViewItemIterator QListViewItemIterator +#define Q3FileDialog QFileDialog +#endif + +class ConfigView; +class ConfigList; +class ConfigItem; +class ConfigLineEdit; +class ConfigMainWindow; + +class ConfigSettings : public QSettings { +public: + ConfigSettings(); + Q3ValueList<int> readSizes(const QString& key, bool *ok); + bool writeSizes(const QString& key, const Q3ValueList<int>& value); +}; + +enum colIdx { + promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr +}; +enum listMode { + singleMode, menuMode, symbolMode, fullMode, listMode +}; +enum optionMode { + normalOpt = 0, allOpt, promptOpt +}; + +class ConfigList : public Q3ListView { + Q_OBJECT + typedef class Q3ListView Parent; +public: + ConfigList(ConfigView* p, const char *name = 0); + void reinit(void); + ConfigView* parent(void) const + { + return (ConfigView*)Parent::parent(); + } + ConfigItem* findConfigItem(struct menu *); + +protected: + void keyPressEvent(QKeyEvent *e); + void contentsMousePressEvent(QMouseEvent *e); + void contentsMouseReleaseEvent(QMouseEvent *e); + void contentsMouseMoveEvent(QMouseEvent *e); + void contentsMouseDoubleClickEvent(QMouseEvent *e); + void focusInEvent(QFocusEvent *e); + void contextMenuEvent(QContextMenuEvent *e); + +public slots: + void setRootMenu(struct menu *menu); + + void updateList(ConfigItem *item); + void setValue(ConfigItem* item, tristate val); + void changeValue(ConfigItem* item); + void updateSelection(void); + void saveSettings(void); +signals: + void menuChanged(struct menu *menu); + void menuSelected(struct menu *menu); + void parentSelected(void); + void gotFocus(struct menu *); + +public: + void updateListAll(void) + { + updateAll = true; + updateList(NULL); + updateAll = false; + } + ConfigList* listView() + { + return this; + } + ConfigItem* firstChild() const + { + return (ConfigItem *)Parent::firstChild(); + } + int mapIdx(colIdx idx) + { + return colMap[idx]; + } + void addColumn(colIdx idx, const QString& label) + { + colMap[idx] = Parent::addColumn(label); + colRevMap[colMap[idx]] = idx; + } + void removeColumn(colIdx idx) + { + int col = colMap[idx]; + if (col >= 0) { + Parent::removeColumn(col); + colRevMap[col] = colMap[idx] = -1; + } + } + void setAllOpen(bool open); + void setParentMenu(void); + + bool menuSkip(struct menu *); + + template <class P> + void updateMenuList(P*, struct menu*); + + bool updateAll; + + QPixmap symbolYesPix, symbolModPix, symbolNoPix; + QPixmap choiceYesPix, choiceNoPix; + QPixmap menuPix, menuInvPix, menuBackPix, voidPix; + + bool showName, showRange, showData; + enum listMode mode; + enum optionMode optMode; + struct menu *rootEntry; + QColorGroup disabledColorGroup; + QColorGroup inactivedColorGroup; + Q3PopupMenu* headerPopup; + +private: + int colMap[colNr]; + int colRevMap[colNr]; +}; + +class ConfigItem : public Q3ListViewItem { + typedef class Q3ListViewItem Parent; +public: + ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v) + : Parent(parent, after), menu(m), visible(v), goParent(false) + { + init(); + } + ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) + : Parent(parent, after), menu(m), visible(v), goParent(false) + { + init(); + } + ConfigItem(Q3ListView *parent, ConfigItem *after, bool v) + : Parent(parent, after), menu(0), visible(v), goParent(true) + { + init(); + } + ~ConfigItem(void); + void init(void); + void okRename(int col); + void updateMenu(void); + void testUpdateMenu(bool v); + ConfigList* listView() const + { + return (ConfigList*)Parent::listView(); + } + ConfigItem* firstChild() const + { + return (ConfigItem *)Parent::firstChild(); + } + ConfigItem* nextSibling() const + { + return (ConfigItem *)Parent::nextSibling(); + } + void setText(colIdx idx, const QString& text) + { + Parent::setText(listView()->mapIdx(idx), text); + } + QString text(colIdx idx) const + { + return Parent::text(listView()->mapIdx(idx)); + } + void setPixmap(colIdx idx, const QPixmap& pm) + { + Parent::setPixmap(listView()->mapIdx(idx), pm); + } + const QPixmap* pixmap(colIdx idx) const + { + return Parent::pixmap(listView()->mapIdx(idx)); + } + void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align); + + ConfigItem* nextItem; + struct menu *menu; + bool visible; + bool goParent; +}; + +class ConfigLineEdit : public QLineEdit { + Q_OBJECT + typedef class QLineEdit Parent; +public: + ConfigLineEdit(ConfigView* parent); + ConfigView* parent(void) const + { + return (ConfigView*)Parent::parent(); + } + void show(ConfigItem *i); + void keyPressEvent(QKeyEvent *e); + +public: + ConfigItem *item; +}; + +class ConfigView : public Q3VBox { + Q_OBJECT + typedef class Q3VBox Parent; +public: + ConfigView(QWidget* parent, const char *name = 0); + ~ConfigView(void); + static void updateList(ConfigItem* item); + static void updateListAll(void); + + bool showName(void) const { return list->showName; } + bool showRange(void) const { return list->showRange; } + bool showData(void) const { return list->showData; } +public slots: + void setShowName(bool); + void setShowRange(bool); + void setShowData(bool); + void setOptionMode(QAction *); +signals: + void showNameChanged(bool); + void showRangeChanged(bool); + void showDataChanged(bool); +public: + ConfigList* list; + ConfigLineEdit* lineEdit; + + static ConfigView* viewList; + ConfigView* nextView; + + static QAction *showNormalAction; + static QAction *showAllAction; + static QAction *showPromptAction; +}; + +class ConfigInfoView : public Q3TextBrowser { + Q_OBJECT + typedef class Q3TextBrowser Parent; +public: + ConfigInfoView(QWidget* parent, const char *name = 0); + bool showDebug(void) const { return _showDebug; } + +public slots: + void setInfo(struct menu *menu); + void saveSettings(void); + void setShowDebug(bool); + +signals: + void showDebugChanged(bool); + void menuSelected(struct menu *); + +protected: + void symbolInfo(void); + void menuInfo(void); + QString debug_info(struct symbol *sym); + static QString print_filter(const QString &str); + static void expr_print_help(void *data, struct symbol *sym, const char *str); + Q3PopupMenu* createPopupMenu(const QPoint& pos); + void contentsContextMenuEvent(QContextMenuEvent *e); + + struct symbol *sym; + struct menu *_menu; + bool _showDebug; +}; + +class ConfigSearchWindow : public QDialog { + Q_OBJECT + typedef class QDialog Parent; +public: + ConfigSearchWindow(ConfigMainWindow* parent, const char *name = 0); + +public slots: + void saveSettings(void); + void search(void); + +protected: + QLineEdit* editField; + QPushButton* searchButton; + QSplitter* split; + ConfigView* list; + ConfigInfoView* info; + + struct symbol **result; +}; + +class ConfigMainWindow : public Q3MainWindow { + Q_OBJECT + + static Q3Action *saveAction; + static void conf_changed(void); +public: + ConfigMainWindow(void); +public slots: + void changeMenu(struct menu *); + void setMenuLink(struct menu *); + void listFocusChanged(void); + void goBack(void); + void loadConfig(void); + bool saveConfig(void); + void saveConfigAs(void); + void searchConfig(void); + void showSingleView(void); + void showSplitView(void); + void showFullView(void); + void showIntro(void); + void showAbout(void); + void saveSettings(void); + +protected: + void closeEvent(QCloseEvent *e); + + ConfigSearchWindow *searchWindow; + ConfigView *menuView; + ConfigList *menuList; + ConfigView *configView; + ConfigList *configList; + ConfigInfoView *helpText; + Q3ToolBar *toolBar; + Q3Action *backAction; + QSplitter* split1; + QSplitter* split2; +}; diff --git a/adk/config/symbol.c b/adk/config/symbol.c index 18f3e5c33..27f8117d4 100644 --- a/adk/config/symbol.c +++ b/adk/config/symbol.c @@ -9,7 +9,6 @@ #include <regex.h> #include <sys/utsname.h> -#define LKC_DIRECT_LINK #include "lkc.h" struct symbol symbol_yes = { @@ -36,7 +35,7 @@ tristate modules_val; struct expr *sym_env_list; -void sym_add_default(struct symbol *sym, const char *def) +static void sym_add_default(struct symbol *sym, const char *def) { struct property *prop = prop_alloc(P_DEFAULT, sym); @@ -125,7 +124,7 @@ struct property *sym_get_default_prop(struct symbol *sym) return NULL; } -struct property *sym_get_range_prop(struct symbol *sym) +static struct property *sym_get_range_prop(struct symbol *sym) { struct property *prop; @@ -137,7 +136,7 @@ struct property *sym_get_range_prop(struct symbol *sym) return NULL; } -static int sym_get_range_val(struct symbol *sym, int base) +static long long sym_get_range_val(struct symbol *sym, int base) { sym_calc_value(sym); switch (sym->type) { @@ -150,13 +149,14 @@ static int sym_get_range_val(struct symbol *sym, int base) default: break; } - return strtol(sym->curr.val, NULL, base); + return strtoll(sym->curr.val, NULL, base); } static void sym_validate_range(struct symbol *sym) { struct property *prop; - int base, val, val2; + int base; + long long val, val2; char str[64]; switch (sym->type) { @@ -172,7 +172,7 @@ static void sym_validate_range(struct symbol *sym) prop = sym_get_range_prop(sym); if (!prop) return; - val = strtol(sym->curr.val, NULL, base); + val = strtoll(sym->curr.val, NULL, base); val2 = sym_get_range_val(prop->expr->left.sym, base); if (val >= val2) { val2 = sym_get_range_val(prop->expr->right.sym, base); @@ -180,9 +180,9 @@ static void sym_validate_range(struct symbol *sym) return; } if (sym->type == S_INT) - sprintf(str, "%d", val2); + sprintf(str, "%lld", val2); else - sprintf(str, "0x%x", val2); + sprintf(str, "0x%llx", val2); sym->curr.val = strdup(str); } @@ -190,6 +190,7 @@ static void sym_calc_visibility(struct symbol *sym) { struct property *prop; tristate tri; + struct expr_select_value *esv; /* any prompt visible? */ tri = no; @@ -203,8 +204,16 @@ static void sym_calc_visibility(struct symbol *sym) sym->visible = tri; sym_set_changed(sym); } - if (sym_is_choice_value(sym)) - return; + /* defaulting to "yes" if no explicit "depends on" are given */ + tri = yes; + if (sym->dir_dep.expr) + tri = expr_calc_value(sym->dir_dep.expr); + if (tri == mod) + tri = yes; + if (sym->dir_dep.tri != tri) { + sym->dir_dep.tri = tri; + sym_set_changed(sym); + } tri = no; if (sym->rev_dep.expr) tri = expr_calc_value(sym->rev_dep.expr); @@ -214,21 +223,42 @@ static void sym_calc_visibility(struct symbol *sym) sym->rev_dep.tri = tri; sym_set_changed(sym); } + for (esv = sym->val_dep; esv; esv = esv->next) { + tri = expr_calc_value(esv->expr); + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) + tri = yes; + if (esv->tri != tri) { + esv->tri = tri; + sym_set_changed(sym); + } + } } -static struct symbol *sym_calc_choice(struct symbol *sym) +/* + * Find the default symbol for a choice. + * First try the default values for the choice symbol + * Next locate the first visible choice value + * Return NULL if none was found + */ +struct symbol *sym_choice_default(struct symbol *sym) { struct symbol *def_sym; + struct symbol *ret = NULL; struct property *prop; struct expr *e; - /* is the user choice visible? */ - def_sym = sym->def[S_DEF_USER].val; - if (def_sym) { - sym_calc_visibility(def_sym); - if (def_sym->visible != no) - return def_sym; - } + /* check to see if any are selected */ + prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, def_sym) + if (def_sym->rev_dep.tri != no) { + if (ret) + fprintf(stderr, "warning: conflicting selects " + "on choice block: %s\n", sym->name); + else + ret = def_sym; + } + if (ret) + return ret; /* any of the defaults visible? */ for_all_defaults(sym, prop) { @@ -236,22 +266,50 @@ static struct symbol *sym_calc_choice(struct symbol *sym) if (prop->visible.tri == no) continue; def_sym = prop_get_symbol(prop); - sym_calc_visibility(def_sym); if (def_sym->visible != no) return def_sym; } /* just get the first visible value */ prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, def_sym) + if (def_sym->visible != no) + return def_sym; + + /* failed to locate any defaults */ + return NULL; +} + +static struct symbol *sym_calc_choice(struct symbol *sym) +{ + struct symbol *def_sym; + struct property *prop; + struct expr *e; + int flags; + + /* first calculate all choice values' visibilities */ + flags = sym->flags; + prop = sym_get_choice_prop(sym); expr_list_for_each_sym(prop->expr, e, def_sym) { sym_calc_visibility(def_sym); if (def_sym->visible != no) - return def_sym; + flags &= def_sym->flags; } - /* no choice? reset tristate value */ - sym->curr.tri = no; - return NULL; + sym->flags &= flags | ~SYMBOL_DEF_USER; + + /* is the user choice visible? */ + def_sym = sym->def[S_DEF_USER].val; + if (def_sym && def_sym->visible != no) + return def_sym; + + def_sym = sym_choice_default(sym); + + if (def_sym == NULL) + /* no choice? reset tristate value */ + sym->curr.tri = no; + + return def_sym; } void sym_calc_value(struct symbol *sym) @@ -259,12 +317,22 @@ void sym_calc_value(struct symbol *sym) struct symbol_value newval, oldval; struct property *prop; struct expr *e; + struct expr_select_value *esv; + int got_sel_val; if (!sym) return; if (sym->flags & SYMBOL_VALID) return; + + if (sym_is_choice_value(sym) && + sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) { + sym->flags &= ~SYMBOL_NEED_SET_CHOICE_VALUES; + prop = sym_get_choice_prop(sym); + sym_calc_value(prop_get_symbol(prop)); + } + sym->flags |= SYMBOL_VALID; oldval = sym->curr; @@ -312,6 +380,9 @@ void sym_calc_value(struct symbol *sym) } if (sym->rev_dep.tri != no) sym->flags |= SYMBOL_WRITE; + for (esv = sym->val_dep; esv; esv = esv->next) + if (esv->tri != no) + sym->flags |= SYMBOL_WRITE; if (!sym_is_choice(sym)) { prop = sym_get_default_prop(sym); if (prop) { @@ -321,7 +392,34 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: - newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); + if (sym->dir_dep.tri == no) { + if (sym->rev_dep.tri != no) { + fprintf(stderr, "warning: ("); + expr_fprint(sym->rev_dep.expr, stderr); + fprintf(stderr, ") selects %s which has unmet direct dependencies (", + sym->name); + expr_fprint(sym->dir_dep.expr, stderr); + fprintf(stderr, ")\n"); + } + for (esv = sym->val_dep; esv; esv = esv->next) { + if ((esv->tri != no) && + (expr_calc_value(esv->value) != no)) { + fprintf(stderr, "warning: ("); + expr_fprint(esv->expr, stderr); + fprintf(stderr, ") selects %s (with value ", + sym->name); + expr_fprint(esv->value, stderr); + fprintf(stderr, ") which has unmet direct dependencies ("); + expr_fprint(sym->dir_dep.expr, stderr); + fprintf(stderr, ")\n"); + } + } + } + newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); + for (esv = sym->val_dep; esv; esv = esv->next) + if (esv->tri != no) + newval.tri = EXPR_OR(newval.tri, + expr_calc_value(esv->value)); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) newval.tri = yes; @@ -336,6 +434,23 @@ void sym_calc_value(struct symbol *sym) break; } } + got_sel_val = 0; + for (esv = sym->val_dep; esv; esv = esv->next) { + if (esv->tri != no) { + struct symbol *ss = esv->value->left.sym; + + if (got_sel_val) { + /* warn of more than one value selected */ + } else { + sym->flags |= SYMBOL_WRITE; + sym_calc_value(ss); + newval.val = ss->curr.val; + got_sel_val = 1; + } + } + } + if (got_sel_val) + break; prop = sym_get_default_prop(sym); if (prop) { struct symbol *ds = prop_get_symbol(prop); @@ -365,18 +480,22 @@ void sym_calc_value(struct symbol *sym) if (sym_is_choice(sym)) { struct symbol *choice_sym; - int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); prop = sym_get_choice_prop(sym); expr_list_for_each_sym(prop->expr, e, choice_sym) { - choice_sym->flags |= flags; - if (flags & SYMBOL_CHANGED) + if ((sym->flags & SYMBOL_WRITE) && + choice_sym->visible != no) + choice_sym->flags |= SYMBOL_WRITE; + if (sym->flags & SYMBOL_CHANGED) sym_set_changed(choice_sym); } } if (sym->flags & SYMBOL_AUTO) sym->flags &= ~SYMBOL_WRITE; + + if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) + set_all_choice_values(sym); } void sym_clear_all_valid(void) @@ -414,6 +533,8 @@ void sym_set_all_changed(void) bool sym_tristate_within_range(struct symbol *sym, tristate val) { int type = sym_get_type(sym); + struct expr_select_value *esv; + tristate tri; if (sym->visible == no) return false; @@ -423,11 +544,14 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) if (type == S_BOOLEAN && val == mod) return false; - if (sym->visible <= sym->rev_dep.tri) + tri = sym->rev_dep.tri; + for (esv = sym->val_dep; esv; esv = esv->next) + tri = EXPR_OR(tri, esv->tri); + if (sym->visible <= tri) return false; if (sym_is_choice_value(sym) && sym->visible == yes) return val == yes; - return val >= sym->rev_dep.tri && val <= sym->visible; + return val >= tri && val <= sym->visible; } bool sym_set_tristate_value(struct symbol *sym, tristate val) @@ -535,7 +659,7 @@ bool sym_string_valid(struct symbol *sym, const char *str) bool sym_string_within_range(struct symbol *sym, const char *str) { struct property *prop; - int val; + long long val; switch (sym->type) { case S_STRING: @@ -546,7 +670,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str) prop = sym_get_range_prop(sym); if (!prop) return true; - val = strtol(str, NULL, 10); + val = strtoll(str, NULL, 10); return val >= sym_get_range_val(prop->expr->left.sym, 10) && val <= sym_get_range_val(prop->expr->right.sym, 10); case S_HEX: @@ -555,7 +679,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str) prop = sym_get_range_prop(sym); if (!prop) return true; - val = strtol(str, NULL, 16); + val = strtoll(str, NULL, 16); return val >= sym_get_range_val(prop->expr->left.sym, 16) && val <= sym_get_range_val(prop->expr->right.sym, 16); case S_BOOLEAN: @@ -608,11 +732,11 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) size = strlen(newval) + 1; if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { size += 2; - sym->def[S_DEF_USER].val = val = malloc(size); + sym->def[S_DEF_USER].val = val = xmalloc(size); *val++ = '0'; *val++ = 'x'; } else if (!oldval || strcmp(oldval, newval)) - sym->def[S_DEF_USER].val = val = malloc(size); + sym->def[S_DEF_USER].val = val = xmalloc(size); else return true; @@ -623,6 +747,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) return true; } +/* + * Find the default value associated to a symbol. + * For tristate symbol handle the modules=n case + * in which case "m" becomes "y". + * If the symbol does not have any default then fallback + * to the fixed default values. + */ +const char *sym_get_string_default(struct symbol *sym) +{ + struct property *prop; + struct symbol *ds; + const char *str; + tristate val; + + sym_calc_visibility(sym); + sym_calc_value(modules_sym); + val = symbol_no.curr.tri; + str = symbol_empty.curr.val; + + /* If symbol has a default value look it up */ + prop = sym_get_default_prop(sym); + if (prop != NULL) { + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + /* The visibility may limit the value from yes => mod */ + val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); + break; + default: + /* + * The following fails to handle the situation + * where a default value is further limited by + * the valid range. + */ + ds = prop_get_symbol(prop); + if (ds != NULL) { + sym_calc_value(ds); + str = (const char *)ds->curr.val; + } + } + } + + /* Handle select statements */ + val = EXPR_OR(val, sym->rev_dep.tri); + + /* transpose mod to yes if modules are not enabled */ + if (val == mod) + if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no) + val = yes; + + /* transpose mod to yes if type is bool */ + if (sym->type == S_BOOLEAN && val == mod) + val = yes; + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (val) { + case no: return "n"; + case mod: return "m"; + case yes: return "y"; + } + case S_INT: + case S_HEX: + return str; + case S_STRING: + return str; + case S_OTHER: + case S_UNKNOWN: + break; + } + return ""; +} + const char *sym_get_string_value(struct symbol *sym) { tristate val; @@ -635,7 +833,8 @@ const char *sym_get_string_value(struct symbol *sym) case no: return "n"; case mod: - return "m"; + sym_calc_value(modules_sym); + return (modules_sym->curr.tri == no) ? "n" : "m"; case yes: return "y"; } @@ -648,15 +847,29 @@ const char *sym_get_string_value(struct symbol *sym) bool sym_is_changable(struct symbol *sym) { - return sym->visible > sym->rev_dep.tri; + tristate tri = sym->rev_dep.tri; + struct expr_select_value *esv; + + for (esv = sym->val_dep; esv; esv = esv->next) + tri = EXPR_OR(tri, esv->tri); + + return sym->visible > tri; +} + +static unsigned strhash(const char *s) +{ + /* fnv32 hash */ + unsigned hash = 2166136261U; + for (; *s; s++) + hash = (hash ^ *s) * 0x01000193; + return hash; } struct symbol *sym_lookup(const char *name, int flags) { struct symbol *symbol; - const char *ptr; char *new_name; - int hash = 0; + int hash; if (name) { if (name[0] && !name[1]) { @@ -666,12 +879,11 @@ struct symbol *sym_lookup(const char *name, int flags) case 'n': return &symbol_no; } } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; + hash = strhash(name) % SYMBOL_HASHSIZE; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && + if (symbol->name && + !strcmp(symbol->name, name) && (flags ? symbol->flags & flags : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) return symbol; @@ -679,10 +891,10 @@ struct symbol *sym_lookup(const char *name, int flags) new_name = strdup(name); } else { new_name = NULL; - hash = 256; + hash = 0; } - symbol = malloc(sizeof(*symbol)); + symbol = xmalloc(sizeof(*symbol)); memset(symbol, 0, sizeof(*symbol)); symbol->name = new_name; symbol->type = S_UNKNOWN; @@ -697,7 +909,6 @@ struct symbol *sym_lookup(const char *name, int flags) struct symbol *sym_find(const char *name) { struct symbol *symbol = NULL; - const char *ptr; int hash = 0; if (!name) @@ -710,12 +921,11 @@ struct symbol *sym_find(const char *name) case 'n': return &symbol_no; } } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; + hash = strhash(name) % SYMBOL_HASHSIZE; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && + if (symbol->name && + !strcmp(symbol->name, name) && !(symbol->flags & SYMBOL_CONST)) break; } @@ -723,42 +933,292 @@ struct symbol *sym_find(const char *name) return symbol; } +/* + * Expand symbol's names embedded in the string given in argument. Symbols' + * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to + * the empty string. + */ +const char *sym_expand_string_value(const char *in) +{ + const char *src; + char *res; + size_t reslen; + + reslen = strlen(in) + 1; + res = xmalloc(reslen); + res[0] = '\0'; + + while ((src = strchr(in, '$'))) { + char *p, name[SYMBOL_MAXLENGTH]; + const char *symval = ""; + struct symbol *sym; + size_t newlen; + + strncat(res, in, src - in); + src++; + + p = name; + while (isalnum(*src) || *src == '_') + *p++ = *src++; + *p = '\0'; + + sym = sym_find(name); + if (sym != NULL) { + sym_calc_value(sym); + symval = sym_get_string_value(sym); + } + + newlen = strlen(res) + strlen(symval) + strlen(src) + 1; + if (newlen > reslen) { + reslen = newlen; + res = realloc(res, reslen); + } + + strcat(res, symval); + in = src; + } + strcat(res, in); + + return res; +} + +const char *sym_escape_string_value(const char *in) +{ + const char *p; + size_t reslen; + char *res; + size_t l; + + reslen = strlen(in) + strlen("\"\"") + 1; + + p = in; + for (;;) { + l = strcspn(p, "\"\\"); + p += l; + + if (p[0] == '\0') + break; + + reslen++; + p++; + } + + res = xmalloc(reslen); + res[0] = '\0'; + + strcat(res, "\""); + + p = in; + for (;;) { + l = strcspn(p, "\"\\"); + strncat(res, p, l); + p += l; + + if (p[0] == '\0') + break; + + strcat(res, "\\"); + strncat(res, p++, 1); + } + + strcat(res, "\""); + return res; +} + +struct sym_match { + struct symbol *sym; + off_t so, eo; +}; + +/* Compare matched symbols as thus: + * - first, symbols that match exactly + * - then, alphabetical sort + */ +static int sym_rel_comp(const void *sym1, const void *sym2) +{ + const struct sym_match *s1 = sym1; + const struct sym_match *s2 = sym2; + int exact1, exact2; + + /* Exact match: + * - if matched length on symbol s1 is the length of that symbol, + * then this symbol should come first; + * - if matched length on symbol s2 is the length of that symbol, + * then this symbol should come first. + * Note: since the search can be a regexp, both symbols may match + * exactly; if this is the case, we can't decide which comes first, + * and we fallback to sorting alphabetically. + */ + exact1 = (s1->eo - s1->so) == strlen(s1->sym->name); + exact2 = (s2->eo - s2->so) == strlen(s2->sym->name); + if (exact1 && !exact2) + return -1; + if (!exact1 && exact2) + return 1; + + /* As a fallback, sort symbols alphabetically */ + return strcmp(s1->sym->name, s2->sym->name); +} + struct symbol **sym_re_search(const char *pattern) { struct symbol *sym, **sym_arr = NULL; + struct sym_match *sym_match_arr = NULL; int i, cnt, size; regex_t re; + regmatch_t match[1]; cnt = size = 0; /* Skip if empty */ if (strlen(pattern) == 0) return NULL; - if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) + if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE)) return NULL; for_all_symbols(i, sym) { if (sym->flags & SYMBOL_CONST || !sym->name) continue; - if (regexec(&re, sym->name, 0, NULL, 0)) + if (regexec(&re, sym->name, 1, match, 0)) continue; - if (cnt + 1 >= size) { - void *tmp = sym_arr; + if (cnt >= size) { + void *tmp; size += 16; - sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); - if (!sym_arr) { - free(tmp); - return NULL; - } + tmp = realloc(sym_match_arr, size * sizeof(struct sym_match)); + if (!tmp) + goto sym_re_search_free; + sym_match_arr = tmp; } - sym_arr[cnt++] = sym; + sym_calc_value(sym); + /* As regexec returned 0, we know we have a match, so + * we can use match[0].rm_[se]o without further checks + */ + sym_match_arr[cnt].so = match[0].rm_so; + sym_match_arr[cnt].eo = match[0].rm_eo; + sym_match_arr[cnt++].sym = sym; } - if (sym_arr) + if (sym_match_arr) { + qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp); + sym_arr = malloc((cnt+1) * sizeof(struct symbol)); + if (!sym_arr) + goto sym_re_search_free; + for (i = 0; i < cnt; i++) + sym_arr[i] = sym_match_arr[i].sym; sym_arr[cnt] = NULL; + } +sym_re_search_free: + /* sym_match_arr can be NULL if no match, but free(NULL) is OK */ + free(sym_match_arr); regfree(&re); return sym_arr; } +/* + * When we check for recursive dependencies we use a stack to save + * current state so we can print out relevant info to user. + * The entries are located on the call stack so no need to free memory. + * Note insert() remove() must always match to properly clear the stack. + */ +static struct dep_stack { + struct dep_stack *prev, *next; + struct symbol *sym; + struct property *prop; + struct expr *expr; +} *check_top; + +static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) +{ + memset(stack, 0, sizeof(*stack)); + if (check_top) + check_top->next = stack; + stack->prev = check_top; + stack->sym = sym; + check_top = stack; +} + +static void dep_stack_remove(void) +{ + check_top = check_top->prev; + if (check_top) + check_top->next = NULL; +} + +/* + * Called when we have detected a recursive dependency. + * check_top point to the top of the stact so we use + * the ->prev pointer to locate the bottom of the stack. + */ +static void sym_check_print_recursive(struct symbol *last_sym) +{ + struct dep_stack *stack; + struct symbol *sym, *next_sym; + struct menu *menu = NULL; + struct property *prop; + struct dep_stack cv_stack; + + if (sym_is_choice_value(last_sym)) { + dep_stack_insert(&cv_stack, last_sym); + last_sym = prop_get_symbol(sym_get_choice_prop(last_sym)); + } + + for (stack = check_top; stack != NULL; stack = stack->prev) + if (stack->sym == last_sym) + break; + if (!stack) { + fprintf(stderr, "unexpected recursive dependency error\n"); + return; + } + + for (; stack; stack = stack->next) { + sym = stack->sym; + next_sym = stack->next ? stack->next->sym : last_sym; + prop = stack->prop; + if (prop == NULL) + prop = stack->sym->prop; + + /* for choice values find the menu entry (used below) */ + if (sym_is_choice(sym) || sym_is_choice_value(sym)) { + for (prop = sym->prop; prop; prop = prop->next) { + menu = prop->menu; + if (prop->menu) + break; + } + } + if (stack->sym == last_sym) + fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", + prop->file->name, prop->lineno); + if (stack->expr) { + fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "<choice>", + prop_get_type_name(prop->type), + next_sym->name ? next_sym->name : "<choice>"); + } else if (stack->prop) { + fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } else if (sym_is_choice(sym)) { + fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } else if (sym_is_choice_value(sym)) { + fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } else { + fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } + } + + if (check_top == &cv_stack) + dep_stack_remove(); +} static struct symbol *sym_check_expr_deps(struct expr *e) { @@ -795,24 +1255,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) { struct symbol *sym2; struct property *prop; + struct dep_stack stack; + + dep_stack_insert(&stack, sym); sym2 = sym_check_expr_deps(sym->rev_dep.expr); if (sym2) - return sym2; + goto out; for (prop = sym->prop; prop; prop = prop->next) { if (prop->type == P_CHOICE || prop->type == P_SELECT) continue; + stack.prop = prop; sym2 = sym_check_expr_deps(prop->visible.expr); if (sym2) break; if (prop->type != P_DEFAULT || sym_is_choice(sym)) continue; + stack.expr = prop->expr; sym2 = sym_check_expr_deps(prop->expr); if (sym2) break; + stack.expr = NULL; } +out: + dep_stack_remove(); + return sym2; } @@ -821,6 +1290,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) struct symbol *sym, *sym2; struct property *prop; struct expr *e; + struct dep_stack stack; + + dep_stack_insert(&stack, choice); prop = sym_get_choice_prop(choice); expr_list_for_each_sym(prop->expr, e, sym) @@ -834,10 +1306,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) expr_list_for_each_sym(prop->expr, e, sym) { sym2 = sym_check_sym_deps(sym); - if (sym2) { - fprintf(stderr, " -> %s", sym->name); + if (sym2) break; - } } out: expr_list_for_each_sym(prop->expr, e, sym) @@ -847,6 +1317,8 @@ out: prop_get_symbol(sym_get_choice_prop(sym2)) == choice) sym2 = choice; + dep_stack_remove(); + return sym2; } @@ -856,18 +1328,20 @@ struct symbol *sym_check_deps(struct symbol *sym) struct property *prop; if (sym->flags & SYMBOL_CHECK) { - fprintf(stderr, "%s:%d:error: found recursive dependency: %s", - sym->prop->file->name, sym->prop->lineno, - sym->name ? sym->name : "<choice>"); + sym_check_print_recursive(sym); return sym; } if (sym->flags & SYMBOL_CHECKED) return NULL; if (sym_is_choice_value(sym)) { + struct dep_stack stack; + /* for choice groups start the check with main choice symbol */ + dep_stack_insert(&stack, sym); prop = sym_get_choice_prop(sym); sym2 = sym_check_deps(prop_get_symbol(prop)); + dep_stack_remove(); } else if (sym_is_choice(sym)) { sym2 = sym_check_choice_deps(sym); } else { @@ -876,14 +1350,8 @@ struct symbol *sym_check_deps(struct symbol *sym) sym->flags &= ~SYMBOL_CHECK; } - if (sym2) { - fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); - if (sym2 == sym) { - fprintf(stderr, "\n"); - zconfnerrs++; - sym2 = NULL; - } - } + if (sym2 && sym2 == sym) + sym2 = NULL; return sym2; } @@ -893,7 +1361,7 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym) struct property *prop; struct property **propp; - prop = malloc(sizeof(*prop)); + prop = xmalloc(sizeof(*prop)); memset(prop, 0, sizeof(*prop)); prop->type = type; prop->sym = sym; @@ -937,13 +1405,15 @@ const char *prop_get_type_name(enum prop_type type) return "select"; case P_RANGE: return "range"; + case P_SYMBOL: + return "symbol"; case P_UNKNOWN: break; } return "unknown"; } -void prop_add_env(const char *env) +static void prop_add_env(const char *env) { struct symbol *sym, *sym2; struct property *prop; diff --git a/adk/config/util.c b/adk/config/util.c index b6b2a46af..94f9c83e3 100644 --- a/adk/config/util.c +++ b/adk/config/util.c @@ -5,6 +5,8 @@ * Released under the terms of the GNU GPL v2.0. */ +#include <stdarg.h> +#include <stdlib.h> #include <string.h> #include "lkc.h" @@ -12,15 +14,18 @@ struct file *file_lookup(const char *name) { struct file *file; + const char *file_name = sym_expand_string_value(name); for (file = file_list; file; file = file->next) { - if (!strcmp(name, file->name)) + if (!strcmp(name, file->name)) { + free((void *)file_name); return file; + } } - file = malloc(sizeof(*file)); + file = xmalloc(sizeof(*file)); memset(file, 0, sizeof(*file)); - file->name = strdup(name); + file->name = file_name; file->next = file_list; file_list = file; return file; @@ -72,12 +77,13 @@ int file_write_dep(const char *name) } -/* Allocate initial growable sting */ +/* Allocate initial growable string */ struct gstr str_new(void) { struct gstr gs; - gs.s = malloc(sizeof(char) * 64); + gs.s = xmalloc(sizeof(char) * 64); gs.len = 64; + gs.max_width = 0; strcpy(gs.s, "\0"); return gs; } @@ -88,6 +94,7 @@ struct gstr str_assign(const char *s) struct gstr gs; gs.s = strdup(s); gs.len = strlen(s) + 1; + gs.max_width = 0; return gs; } @@ -131,3 +138,20 @@ const char *str_get(struct gstr *gs) return gs->s; } +void *xmalloc(size_t size) +{ + void *p = malloc(size); + if (p) + return p; + fprintf(stderr, "Out of memory.\n"); + exit(1); +} + +void *xcalloc(size_t nmemb, size_t size) +{ + void *p = calloc(nmemb, size); + if (p) + return p; + fprintf(stderr, "Out of memory.\n"); + exit(1); +} diff --git a/adk/config/zconf.gperf b/adk/config/zconf.gperf index 25ef5d01c..b6ac02d60 100644 --- a/adk/config/zconf.gperf +++ b/adk/config/zconf.gperf @@ -9,6 +9,8 @@ struct kconf_id; +static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); + %% mainmenu, T_MAINMENU, TF_COMMAND menu, T_MENU, TF_COMMAND @@ -36,9 +38,11 @@ hex, T_TYPE, TF_COMMAND, S_HEX string, T_TYPE, TF_COMMAND, S_STRING select, T_SELECT, TF_COMMAND range, T_RANGE, TF_COMMAND +visible, T_VISIBLE, TF_COMMAND option, T_OPTION, TF_COMMAND on, T_ON, TF_PARAM modules, T_OPT_MODULES, TF_OPTION defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION env, T_OPT_ENV, TF_OPTION +allnoconfig_y, T_OPT_ALLNOCONFIG_Y,TF_OPTION %% diff --git a/adk/config/zconf.hash.c_shipped b/adk/config/zconf.hash.c_shipped index 5c73d5133..5f3e06f16 100644 --- a/adk/config/zconf.hash.c_shipped +++ b/adk/config/zconf.hash.c_shipped @@ -1,6 +1,5 @@ /* ANSI-C code produced by gperf version 3.0.3 */ -/* Command-line: gperf */ -/* Computed positions: -k'1,3' */ +/* Command-line: gperf -t --output-file zconf.hash.c -a -C -E -g -k 1,3, -p -t zconf.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -29,8 +28,11 @@ #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." #endif +#line 10 "zconf.gperf" struct kconf_id; -/* maximum key range = 47, duplicates = 0 */ + +static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); +/* maximum key range = 50, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -42,34 +44,34 @@ inline static unsigned int kconf_id_hash (register const char *str, register unsigned int len) { - static unsigned char asso_values[] = + static const unsigned char asso_values[] = { - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 11, 5, - 0, 0, 5, 49, 5, 20, 49, 49, 5, 20, - 5, 0, 30, 49, 0, 15, 0, 10, 0, 49, - 25, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49 + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 10, 40, 5, + 0, 0, 5, 52, 0, 20, 52, 52, 10, 20, + 5, 0, 35, 52, 0, 30, 0, 15, 0, 52, + 15, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52 }; register int hval = len; @@ -100,27 +102,29 @@ struct kconf_id_strings_t char kconf_id_strings_str12[sizeof("default")]; char kconf_id_strings_str13[sizeof("def_bool")]; char kconf_id_strings_str14[sizeof("help")]; - char kconf_id_strings_str15[sizeof("bool")]; char kconf_id_strings_str16[sizeof("config")]; char kconf_id_strings_str17[sizeof("def_tristate")]; - char kconf_id_strings_str18[sizeof("boolean")]; + char kconf_id_strings_str18[sizeof("hex")]; char kconf_id_strings_str19[sizeof("defconfig_list")]; - char kconf_id_strings_str21[sizeof("string")]; char kconf_id_strings_str22[sizeof("if")]; char kconf_id_strings_str23[sizeof("int")]; - char kconf_id_strings_str26[sizeof("select")]; char kconf_id_strings_str27[sizeof("modules")]; char kconf_id_strings_str28[sizeof("tristate")]; char kconf_id_strings_str29[sizeof("menu")]; - char kconf_id_strings_str31[sizeof("source")]; char kconf_id_strings_str32[sizeof("comment")]; - char kconf_id_strings_str33[sizeof("hex")]; + char kconf_id_strings_str33[sizeof("allnoconfig_y")]; char kconf_id_strings_str35[sizeof("menuconfig")]; - char kconf_id_strings_str36[sizeof("prompt")]; - char kconf_id_strings_str37[sizeof("depends")]; + char kconf_id_strings_str36[sizeof("string")]; + char kconf_id_strings_str37[sizeof("visible")]; + char kconf_id_strings_str41[sizeof("prompt")]; + char kconf_id_strings_str42[sizeof("depends")]; + char kconf_id_strings_str44[sizeof("bool")]; + char kconf_id_strings_str46[sizeof("select")]; + char kconf_id_strings_str47[sizeof("boolean")]; char kconf_id_strings_str48[sizeof("mainmenu")]; + char kconf_id_strings_str51[sizeof("source")]; }; -static struct kconf_id_strings_t kconf_id_strings_contents = +static const struct kconf_id_strings_t kconf_id_strings_contents = { "on", "env", @@ -134,25 +138,27 @@ static struct kconf_id_strings_t kconf_id_strings_contents = "default", "def_bool", "help", - "bool", "config", "def_tristate", - "boolean", + "hex", "defconfig_list", - "string", "if", "int", - "select", "modules", "tristate", "menu", - "source", "comment", - "hex", + "allnoconfig_y", "menuconfig", + "string", + "visible", "prompt", "depends", - "mainmenu" + "bool", + "select", + "boolean", + "mainmenu", + "source" }; #define kconf_id_strings ((const char *) &kconf_id_strings_contents) #ifdef __GNUC__ @@ -161,59 +167,97 @@ __inline __attribute__ ((__gnu_inline__)) #endif #endif -struct kconf_id * +const struct kconf_id * kconf_id_lookup (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 31, + TOTAL_KEYWORDS = 33, MIN_WORD_LENGTH = 2, MAX_WORD_LENGTH = 14, MIN_HASH_VALUE = 2, - MAX_HASH_VALUE = 48 + MAX_HASH_VALUE = 51 }; - static struct kconf_id wordlist[] = + static const struct kconf_id wordlist[] = { {-1}, {-1}, +#line 43 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM}, +#line 46 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_OPT_ENV, TF_OPTION}, {-1}, +#line 26 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, +#line 42 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND}, +#line 17 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND}, +#line 28 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_OPTIONAL, TF_COMMAND}, +#line 20 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, +#line 40 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND}, +#line 19 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_CHOICE, TF_COMMAND}, +#line 29 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, +#line 35 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, +#line 24 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, +#line 22 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND}, +#line 32 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN}, +#line 37 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_HEX}, +#line 45 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING}, + {-1}, {-1}, +#line 25 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM}, +#line 36 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT}, - {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND}, + {-1}, {-1}, {-1}, +#line 44 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, +#line 31 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE}, +#line 16 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND}, + {-1}, {-1}, +#line 21 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX}, +#line 47 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ALLNOCONFIG_Y,TF_OPTION}, {-1}, +#line 23 "zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 38 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_TYPE, TF_COMMAND, S_STRING}, +#line 41 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_VISIBLE, TF_COMMAND}, + {-1}, {-1}, {-1}, +#line 30 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_PROMPT, TF_COMMAND}, +#line 27 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_DEPENDS, TF_COMMAND}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND} +#line 33 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, +#line 39 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND}, +#line 34 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN}, +#line 15 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND}, + {-1}, {-1}, +#line 18 "zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_SOURCE, TF_COMMAND} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) @@ -234,4 +278,5 @@ kconf_id_lookup (register const char *str, register unsigned int len) } return 0; } +#line 48 "zconf.gperf" diff --git a/adk/config/zconf.l b/adk/config/zconf.l index 21ff69c9a..6c62d93b4 100644 --- a/adk/config/zconf.l +++ b/adk/config/zconf.l @@ -1,5 +1,5 @@ -%option backup nostdinit noyywrap never-interactive full ecs -%option 8bit backup nodefault perf-report perf-report +%option nostdinit noyywrap never-interactive full ecs +%option 8bit nodefault perf-report perf-report %option noinput %x COMMAND HELP STRING PARAM %{ @@ -14,7 +14,6 @@ #include <string.h> #include <unistd.h> -#define LKC_DIRECT_LINK #include "lkc.h" #define START_STRSIZE 16 @@ -28,8 +27,8 @@ static char *text; static int text_size, text_asize; struct buffer { - struct buffer *parent; - YY_BUFFER_STATE state; + struct buffer *parent; + YY_BUFFER_STATE state; }; struct buffer *current_buf; @@ -39,15 +38,15 @@ static int last_ts, first_ts; static void zconf_endhelp(void); static void zconf_endfile(void); -void new_string(void) +static void new_string(void) { - text = malloc(START_STRSIZE); + text = xmalloc(START_STRSIZE); text_asize = START_STRSIZE; text_size = 0; *text = 0; } -void append_string(const char *str, int size) +static void append_string(const char *str, int size) { int new_size = text_size + size + 1; if (new_size > text_asize) { @@ -61,15 +60,14 @@ void append_string(const char *str, int size) text[text_size] = 0; } -void alloc_string(const char *str, int size) +static void alloc_string(const char *str, int size) { - text = malloc(size + 1); + text = xmalloc(size + 1); memcpy(text, str, size); text[size] = 0; } %} -ws [ \n\t] n [A-Za-z0-9_] %% @@ -96,7 +94,7 @@ n [A-Za-z0-9_] <COMMAND>{ {n}+ { - struct kconf_id *id = kconf_id_lookup(yytext, yyleng); + const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); BEGIN(PARAM); current_pos.file = current_file; current_pos.lineno = current_file->lineno; @@ -132,7 +130,7 @@ n [A-Za-z0-9_] \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; --- /* ignore */ ({n}|[-/.])+ { - struct kconf_id *id = kconf_id_lookup(yytext, yyleng); + const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); if (id && id->flags & TF_PARAM) { zconflval.id = id; return id->token; @@ -289,42 +287,50 @@ void zconf_initscan(const char *name) exit(1); } - current_buf = malloc(sizeof(*current_buf)); + current_buf = xmalloc(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 *iter; struct file *file = file_lookup(name); - struct buffer *buf = malloc(sizeof(*buf)); + struct buffer *buf = xmalloc(sizeof(*buf)); memset(buf, 0, sizeof(*buf)); current_buf->state = YY_CURRENT_BUFFER; - yyin = zconf_fopen(name); + yyin = zconf_fopen(file->name); if (!yyin) { - printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + printf("%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->name); exit(1); } yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); buf->parent = current_buf; current_buf = buf; - 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); + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } } - file->flags |= FILE_BUSY; file->lineno = 1; file->parent = current_file; current_file = file; @@ -334,8 +340,6 @@ 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; @@ -353,7 +357,7 @@ int zconf_lineno(void) return current_pos.lineno; } -char *zconf_curname(void) +const char *zconf_curname(void) { return current_pos.file ? current_pos.file->name : "<none>"; } diff --git a/adk/config/zconf.lex.c b/adk/config/zconf.lex.c new file mode 100644 index 000000000..349a7f243 --- /dev/null +++ b/adk/config/zconf.lex.c @@ -0,0 +1,2420 @@ + +#line 3 "scripts/kconfig/zconf.lex.c_shipped" + +#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 <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. 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 <inttypes.h> +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; +#endif /* ! C99 */ + +/* 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 /* ! 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 <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + */ + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#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); + +static void new_string(void) +{ + text = xmalloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_size = 0; + *text = 0; +} + +static void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + new_size += START_STRSIZE - 1; + new_size &= -START_STRSIZE; + text = realloc(text, new_size); + text_asize = new_size; + } + memcpy(text + text_size, str, size); + text_size += size; + text[text_size] = 0; +} + +static void alloc_string(const char *str, int size) +{ + text = xmalloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} + +#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 <unistd.h> +#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 do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0) +#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 +{ + const 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 +{ + const 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 = xmalloc(sizeof(*current_buf)); + memset(current_buf, 0, sizeof(*current_buf)); + + current_file = file_lookup(name); + current_file->lineno = 1; +} + +void zconf_nextfile(const char *name) +{ + struct file *iter; + struct file *file = file_lookup(name); + struct buffer *buf = xmalloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + zconfin = zconf_fopen(file->name); + if (!zconfin) { + printf("%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->name); + exit(1); + } + zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } + } + file->lineno = 1; + file->parent = current_file; + current_file = file; +} + +static void zconf_endfile(void) +{ + struct buffer *parent; + + 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; +} + +const char *zconf_curname(void) +{ + return current_pos.file ? current_pos.file->name : "<none>"; +} + diff --git a/adk/config/zconf.lex.c_shipped b/adk/config/zconf.lex.c_shipped new file mode 100644 index 000000000..349a7f243 --- /dev/null +++ b/adk/config/zconf.lex.c_shipped @@ -0,0 +1,2420 @@ + +#line 3 "scripts/kconfig/zconf.lex.c_shipped" + +#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 <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. 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 <inttypes.h> +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; +#endif /* ! C99 */ + +/* 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 /* ! 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 <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + */ + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#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); + +static void new_string(void) +{ + text = xmalloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_size = 0; + *text = 0; +} + +static void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + new_size += START_STRSIZE - 1; + new_size &= -START_STRSIZE; + text = realloc(text, new_size); + text_asize = new_size; + } + memcpy(text + text_size, str, size); + text_size += size; + text[text_size] = 0; +} + +static void alloc_string(const char *str, int size) +{ + text = xmalloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} + +#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 <unistd.h> +#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 do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0) +#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 +{ + const 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 +{ + const 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 = xmalloc(sizeof(*current_buf)); + memset(current_buf, 0, sizeof(*current_buf)); + + current_file = file_lookup(name); + current_file->lineno = 1; +} + +void zconf_nextfile(const char *name) +{ + struct file *iter; + struct file *file = file_lookup(name); + struct buffer *buf = xmalloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + zconfin = zconf_fopen(file->name); + if (!zconfin) { + printf("%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->name); + exit(1); + } + zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } + } + file->lineno = 1; + file->parent = current_file; + current_file = file; +} + +static void zconf_endfile(void) +{ + struct buffer *parent; + + 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; +} + +const char *zconf_curname(void) +{ + return current_pos.file ? current_pos.file->name : "<none>"; +} + diff --git a/adk/config/zconf.tab.c_shipped b/adk/config/zconf.tab.c_shipped index 3bdcb3a97..1f6c1bb4a 100644 --- a/adk/config/zconf.tab.c_shipped +++ b/adk/config/zconf.tab.c_shipped @@ -1,24 +1,21 @@ -/* A Bison parser, made by GNU Bison 2.3. */ +/* A Bison parser, made by GNU Bison 2.5. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,98 +52,29 @@ /* Pure parsers. */ #define YYPURE 0 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ -#define yyparse zconfparse -#define yylex zconflex -#define yyerror zconferror -#define yylval zconflval -#define yychar zconfchar -#define yydebug zconfdebug -#define yynerrs zconfnerrs - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_MAINMENU = 258, - T_MENU = 259, - T_ENDMENU = 260, - T_SOURCE = 261, - T_CHOICE = 262, - T_ENDCHOICE = 263, - T_COMMENT = 264, - T_CONFIG = 265, - T_MENUCONFIG = 266, - T_HELP = 267, - T_HELPTEXT = 268, - T_IF = 269, - T_ENDIF = 270, - T_DEPENDS = 271, - T_OPTIONAL = 272, - T_PROMPT = 273, - T_TYPE = 274, - T_DEFAULT = 275, - T_SELECT = 276, - T_RANGE = 277, - T_OPTION = 278, - T_ON = 279, - T_WORD = 280, - T_WORD_QUOTE = 281, - T_UNEQUAL = 282, - T_CLOSE_PAREN = 283, - T_OPEN_PAREN = 284, - T_EOL = 285, - T_OR = 286, - T_AND = 287, - T_EQUAL = 288, - T_NOT = 289 - }; -#endif -/* Tokens. */ -#define T_MAINMENU 258 -#define T_MENU 259 -#define T_ENDMENU 260 -#define T_SOURCE 261 -#define T_CHOICE 262 -#define T_ENDCHOICE 263 -#define T_COMMENT 264 -#define T_CONFIG 265 -#define T_MENUCONFIG 266 -#define T_HELP 267 -#define T_HELPTEXT 268 -#define T_IF 269 -#define T_ENDIF 270 -#define T_DEPENDS 271 -#define T_OPTIONAL 272 -#define T_PROMPT 273 -#define T_TYPE 274 -#define T_DEFAULT 275 -#define T_SELECT 276 -#define T_RANGE 277 -#define T_OPTION 278 -#define T_ON 279 -#define T_WORD 280 -#define T_WORD_QUOTE 281 -#define T_UNEQUAL 282 -#define T_CLOSE_PAREN 283 -#define T_OPEN_PAREN 284 -#define T_EOL 285 -#define T_OR 286 -#define T_AND 287 -#define T_EQUAL 288 -#define T_NOT 289 - - +#define yyparse zconfparse +#define yylex zconflex +#define yyerror zconferror +#define yylval zconflval +#define yychar zconfchar +#define yydebug zconfdebug +#define yynerrs zconfnerrs /* Copy the first part of user declarations. */ +/* Line 268 of yacc.c */ +#line 1 "zconf.y" /* * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> @@ -160,11 +88,8 @@ #include <string.h> #include <stdbool.h> -#define LKC_DIRECT_LINK #include "lkc.h" -#include "zconf.hash.c" - #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) #define PRINTD 0x0001 @@ -176,21 +101,20 @@ extern int zconflex(void); static void zconfprint(const char *err, ...); static void zconf_error(const char *err, ...); static void zconferror(const char *err); -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); +static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); -struct symbol *symbol_hash[257]; +struct symbol *symbol_hash[SYMBOL_HASHSIZE]; static struct menu *current_menu, *current_entry; -#define YYDEBUG 0 -#if YYDEBUG -#define YYERROR_VERBOSE -#endif +/* Line 268 of yacc.c */ +#line 114 "zconf.tab.c" + /* Enabling traces. */ #ifndef YYDEBUG -# define YYDEBUG 0 +# define YYDEBUG 1 #endif /* Enabling verbose error messages. */ @@ -206,33 +130,88 @@ static struct menu *current_menu, *current_entry; # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_MAINMENU = 258, + T_MENU = 259, + T_ENDMENU = 260, + T_SOURCE = 261, + T_CHOICE = 262, + T_ENDCHOICE = 263, + T_COMMENT = 264, + T_CONFIG = 265, + T_MENUCONFIG = 266, + T_HELP = 267, + T_HELPTEXT = 268, + T_IF = 269, + T_ENDIF = 270, + T_DEPENDS = 271, + T_OPTIONAL = 272, + T_PROMPT = 273, + T_TYPE = 274, + T_DEFAULT = 275, + T_SELECT = 276, + T_RANGE = 277, + T_VISIBLE = 278, + T_OPTION = 279, + T_ON = 280, + T_WORD = 281, + T_WORD_QUOTE = 282, + T_UNEQUAL = 283, + T_CLOSE_PAREN = 284, + T_OPEN_PAREN = 285, + T_EOL = 286, + T_OR = 287, + T_AND = 288, + T_EQUAL = 289, + T_NOT = 290 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE - { + +/* Line 293 of yacc.c */ +#line 37 "zconf.y" + char *string; struct file *file; struct symbol *symbol; struct expr *expr; struct menu *menu; - struct kconf_id *id; -} -/* Line 187 of yacc.c. */ + const struct kconf_id *id; + - YYSTYPE; + +/* Line 293 of yacc.c */ +#line 196 "zconf.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif - /* Copy the second part of user declarations. */ +/* Line 343 of yacc.c */ +#line 97 "zconf.y" -/* Line 216 of yacc.c. */ +/* Include zconf.hash.c here so it can see the token constants. */ +#include "zconf.hash.c" +/* Line 343 of yacc.c */ +#line 214 "zconf.tab.c" + #ifdef short # undef short #endif @@ -281,7 +260,7 @@ typedef short int yytype_int16; #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -306,14 +285,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -334,11 +313,11 @@ YYID (i) # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 # endif # endif # endif @@ -361,24 +340,24 @@ YYID (i) # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif -# if (defined __cplusplus && ! defined _STDLIB_H \ +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif @@ -394,9 +373,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - }; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) @@ -407,6 +386,27 @@ union yyalloc ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY @@ -424,42 +424,25 @@ union yyalloc while (YYID (0)) # endif # endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif +#endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 3 +#define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 259 +#define YYLAST 296 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 35 +#define YYNTOKENS 36 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 46 +#define YYNNTS 50 /* YYNRULES -- Number of rules. */ -#define YYNRULES 110 +#define YYNRULES 119 /* YYNRULES -- Number of states. */ -#define YYNSTATES 180 +#define YYNSTATES 194 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 289 +#define YYMAXUTOK 290 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -495,7 +478,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35 }; #if YYDEBUG @@ -503,73 +487,75 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint16 yyprhs[] = { - 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, - 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, - 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, - 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, - 112, 117, 122, 128, 132, 133, 137, 138, 141, 145, - 148, 150, 154, 155, 158, 161, 164, 167, 170, 175, - 179, 182, 187, 188, 191, 195, 197, 201, 202, 205, - 208, 211, 215, 218, 220, 224, 225, 228, 231, 234, - 238, 242, 245, 248, 251, 252, 255, 258, 261, 266, - 267, 270, 272, 274, 277, 280, 283, 285, 288, 289, - 292, 294, 298, 302, 306, 309, 313, 317, 319, 321, - 322 + 0, 0, 3, 6, 8, 11, 13, 14, 17, 20, + 23, 26, 31, 36, 40, 42, 44, 46, 48, 50, + 52, 54, 56, 58, 60, 62, 64, 66, 68, 72, + 75, 79, 82, 86, 89, 90, 93, 96, 99, 102, + 105, 108, 112, 117, 122, 127, 133, 139, 143, 144, + 148, 149, 152, 156, 159, 161, 165, 166, 169, 172, + 175, 178, 181, 186, 190, 193, 198, 199, 202, 206, + 208, 212, 213, 216, 219, 222, 226, 230, 234, 236, + 240, 241, 244, 247, 250, 254, 258, 261, 264, 267, + 268, 271, 274, 277, 282, 283, 286, 289, 292, 293, + 296, 298, 300, 303, 306, 309, 311, 314, 315, 318, + 320, 324, 328, 332, 335, 339, 343, 345, 347, 348 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, - 53, -1, 37, 64, -1, 37, 3, 74, 76, -1, - 37, 75, -1, 37, 25, 1, 30, -1, 37, 38, - 1, 30, -1, 37, 1, 30, -1, 16, -1, 18, - -1, 19, -1, 21, -1, 17, -1, 22, -1, 20, - -1, 30, -1, 59, -1, 68, -1, 42, -1, 44, - -1, 66, -1, 25, 1, 30, -1, 1, 30, -1, - 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, - -1, 43, 45, -1, -1, 45, 46, -1, 45, 47, - -1, 45, 72, -1, 45, 70, -1, 45, 40, -1, - 45, 30, -1, 19, 73, 30, -1, 18, 74, 77, - 30, -1, 20, 78, 77, 30, -1, 21, 25, 77, - 30, -1, 22, 79, 79, 77, 30, -1, 23, 48, - 30, -1, -1, 48, 25, 49, -1, -1, 33, 74, - -1, 7, 80, 30, -1, 50, 54, -1, 75, -1, - 51, 56, 52, -1, -1, 54, 55, -1, 54, 72, - -1, 54, 70, -1, 54, 30, -1, 54, 40, -1, - 18, 74, 77, 30, -1, 19, 73, 30, -1, 17, - 30, -1, 20, 25, 77, 30, -1, -1, 56, 39, - -1, 14, 78, 76, -1, 75, -1, 57, 60, 58, - -1, -1, 60, 39, -1, 60, 64, -1, 60, 53, - -1, 4, 74, 30, -1, 61, 71, -1, 75, -1, - 62, 65, 63, -1, -1, 65, 39, -1, 65, 64, - -1, 65, 53, -1, 6, 74, 30, -1, 9, 74, - 30, -1, 67, 71, -1, 12, 30, -1, 69, 13, - -1, -1, 71, 72, -1, 71, 30, -1, 71, 40, - -1, 16, 24, 78, 30, -1, -1, 74, 77, -1, - 25, -1, 26, -1, 5, 30, -1, 8, 30, -1, - 15, 30, -1, 30, -1, 76, 30, -1, -1, 14, - 78, -1, 79, -1, 79, 33, 79, -1, 79, 27, - 79, -1, 29, 78, 28, -1, 34, 78, -1, 78, - 31, 78, -1, 78, 32, 78, -1, 25, -1, 26, - -1, -1, 25, -1 + 37, 0, -1, 81, 38, -1, 38, -1, 63, 39, + -1, 39, -1, -1, 39, 41, -1, 39, 55, -1, + 39, 67, -1, 39, 80, -1, 39, 26, 1, 31, + -1, 39, 40, 1, 31, -1, 39, 1, 31, -1, + 16, -1, 18, -1, 19, -1, 21, -1, 17, -1, + 22, -1, 20, -1, 23, -1, 31, -1, 61, -1, + 71, -1, 44, -1, 46, -1, 69, -1, 26, 1, + 31, -1, 1, 31, -1, 10, 26, 31, -1, 43, + 47, -1, 11, 26, 31, -1, 45, 47, -1, -1, + 47, 48, -1, 47, 49, -1, 47, 75, -1, 47, + 73, -1, 47, 42, -1, 47, 31, -1, 19, 78, + 31, -1, 18, 79, 82, 31, -1, 20, 83, 82, + 31, -1, 21, 26, 82, 31, -1, 21, 26, 83, + 82, 31, -1, 22, 84, 84, 82, 31, -1, 24, + 50, 31, -1, -1, 50, 26, 51, -1, -1, 34, + 79, -1, 7, 85, 31, -1, 52, 56, -1, 80, + -1, 53, 58, 54, -1, -1, 56, 57, -1, 56, + 75, -1, 56, 73, -1, 56, 31, -1, 56, 42, + -1, 18, 79, 82, 31, -1, 19, 78, 31, -1, + 17, 31, -1, 20, 26, 82, 31, -1, -1, 58, + 41, -1, 14, 83, 81, -1, 80, -1, 59, 62, + 60, -1, -1, 62, 41, -1, 62, 67, -1, 62, + 55, -1, 3, 79, 81, -1, 4, 79, 31, -1, + 64, 76, 74, -1, 80, -1, 65, 68, 66, -1, + -1, 68, 41, -1, 68, 67, -1, 68, 55, -1, + 6, 79, 31, -1, 9, 79, 31, -1, 70, 74, + -1, 12, 31, -1, 72, 13, -1, -1, 74, 75, + -1, 74, 31, -1, 74, 42, -1, 16, 25, 83, + 31, -1, -1, 76, 77, -1, 76, 31, -1, 23, + 82, -1, -1, 79, 82, -1, 26, -1, 27, -1, + 5, 31, -1, 8, 31, -1, 15, 31, -1, 31, + -1, 81, 31, -1, -1, 14, 83, -1, 84, -1, + 84, 34, 84, -1, 84, 28, 84, -1, 30, 83, + 29, -1, 35, 83, -1, 83, 32, 83, -1, 83, + 33, 83, -1, 26, -1, 27, -1, -1, 26, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 104, 104, 106, 108, 109, 110, 111, 112, 113, - 114, 118, 122, 122, 122, 122, 122, 122, 122, 126, - 127, 128, 129, 130, 131, 135, 136, 142, 150, 156, - 164, 174, 176, 177, 178, 179, 180, 181, 184, 192, - 198, 208, 214, 220, 223, 225, 236, 237, 242, 251, - 256, 264, 267, 269, 270, 271, 272, 273, 276, 282, - 293, 299, 309, 311, 316, 324, 332, 335, 337, 338, - 339, 344, 351, 356, 364, 367, 369, 370, 371, 374, - 382, 389, 396, 402, 409, 411, 412, 413, 416, 424, - 426, 431, 432, 435, 436, 437, 441, 442, 445, 446, - 449, 450, 451, 452, 453, 454, 455, 458, 459, 462, - 463 + 0, 103, 103, 103, 105, 105, 107, 109, 110, 111, + 112, 113, 114, 118, 122, 122, 122, 122, 122, 122, + 122, 122, 126, 127, 128, 129, 130, 131, 135, 136, + 142, 150, 156, 164, 174, 176, 177, 178, 179, 180, + 181, 184, 192, 198, 208, 214, 220, 226, 229, 231, + 242, 243, 248, 257, 262, 270, 273, 275, 276, 277, + 278, 279, 282, 288, 299, 305, 315, 317, 322, 330, + 338, 341, 343, 344, 345, 350, 357, 364, 369, 377, + 380, 382, 383, 384, 387, 395, 402, 409, 415, 422, + 424, 425, 426, 429, 437, 439, 440, 443, 450, 452, + 457, 458, 461, 462, 463, 467, 468, 471, 472, 475, + 476, 477, 478, 479, 480, 481, 484, 485, 488, 489 }; #endif @@ -582,19 +568,19 @@ static const char *const yytname[] = "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", - "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", + "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", - "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt", - "option_error", "config_entry_start", "config_stmt", + "T_NOT", "$accept", "input", "start", "stmt_list", "option_name", + "common_stmt", "option_error", "config_entry_start", "config_stmt", "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", "config_option", "symbol_option", "symbol_option_list", "symbol_option_arg", "choice", "choice_entry", "choice_end", "choice_stmt", "choice_option_list", "choice_option", "choice_block", - "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry", - "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", - "comment_stmt", "help_start", "help", "depends_list", "depends", - "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", - "word_opt", 0 + "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu", + "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt", + "comment", "comment_stmt", "help_start", "help", "depends_list", + "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt", + "end", "nl", "if_expr", "expr", "symbol", "word_opt", 0 }; #endif @@ -606,201 +592,220 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289 + 285, 286, 287, 288, 289, 290 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, - 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, - 44, 45, 45, 45, 45, 45, 45, 45, 46, 46, - 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, - 52, 53, 54, 54, 54, 54, 54, 54, 55, 55, - 55, 55, 56, 56, 57, 58, 59, 60, 60, 60, - 60, 61, 62, 63, 64, 65, 65, 65, 65, 66, - 67, 68, 69, 70, 71, 71, 71, 71, 72, 73, - 73, 74, 74, 75, 75, 75, 76, 76, 77, 77, - 78, 78, 78, 78, 78, 78, 78, 79, 79, 80, - 80 + 0, 36, 37, 37, 38, 38, 39, 39, 39, 39, + 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, + 40, 40, 41, 41, 41, 41, 41, 41, 42, 42, + 43, 44, 45, 46, 47, 47, 47, 47, 47, 47, + 47, 48, 48, 48, 48, 48, 48, 49, 50, 50, + 51, 51, 52, 53, 54, 55, 56, 56, 56, 56, + 56, 56, 57, 57, 57, 57, 58, 58, 59, 60, + 61, 62, 62, 62, 62, 63, 64, 65, 66, 67, + 68, 68, 68, 68, 69, 70, 71, 72, 73, 74, + 74, 74, 74, 75, 76, 76, 76, 77, 78, 78, + 79, 79, 80, 80, 80, 81, 81, 82, 82, 83, + 83, 83, 83, 83, 83, 83, 84, 84, 85, 85 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, - 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, - 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, - 4, 4, 5, 3, 0, 3, 0, 2, 3, 2, - 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, - 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, - 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, - 3, 2, 2, 2, 0, 2, 2, 2, 4, 0, - 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, - 1, 3, 3, 3, 2, 3, 3, 1, 1, 0, - 1 + 0, 2, 2, 1, 2, 1, 0, 2, 2, 2, + 2, 4, 4, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, + 3, 2, 3, 2, 0, 2, 2, 2, 2, 2, + 2, 3, 4, 4, 4, 5, 5, 3, 0, 3, + 0, 2, 3, 2, 1, 3, 0, 2, 2, 2, + 2, 2, 4, 3, 2, 4, 0, 2, 3, 1, + 3, 0, 2, 2, 2, 3, 3, 3, 1, 3, + 0, 2, 2, 2, 3, 3, 2, 2, 2, 0, + 2, 2, 2, 4, 0, 2, 2, 2, 0, 2, + 1, 1, 2, 2, 2, 1, 2, 0, 2, 1, + 3, 3, 3, 2, 3, 3, 1, 1, 0, 1 }; -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 1, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, - 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, - 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, - 84, 21, 8, 11, 91, 92, 0, 0, 93, 0, - 110, 0, 94, 0, 0, 0, 107, 108, 0, 0, - 0, 100, 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 7, 71, 79, 48, 80, 27, - 29, 0, 104, 0, 0, 64, 0, 0, 9, 10, - 0, 0, 0, 0, 89, 0, 0, 0, 44, 0, - 37, 36, 32, 33, 0, 35, 34, 0, 0, 89, - 0, 56, 57, 53, 55, 54, 63, 51, 50, 68, - 70, 66, 69, 65, 86, 87, 85, 76, 78, 74, - 77, 73, 97, 103, 105, 106, 102, 101, 26, 82, - 0, 98, 0, 98, 98, 98, 0, 0, 0, 83, - 60, 98, 0, 98, 0, 0, 0, 38, 90, 0, - 0, 98, 46, 43, 25, 0, 59, 0, 88, 99, - 39, 40, 41, 0, 0, 45, 58, 61, 42, 47 + 6, 0, 105, 0, 3, 0, 6, 6, 100, 101, + 0, 1, 0, 0, 0, 0, 118, 0, 0, 0, + 0, 0, 0, 14, 18, 15, 16, 20, 17, 19, + 21, 0, 22, 0, 7, 34, 25, 34, 26, 56, + 66, 8, 71, 23, 94, 80, 9, 27, 89, 24, + 10, 0, 106, 2, 75, 13, 0, 102, 0, 119, + 0, 103, 0, 0, 0, 116, 117, 0, 0, 0, + 109, 104, 0, 0, 0, 0, 0, 0, 0, 89, + 0, 0, 76, 84, 52, 85, 30, 32, 0, 113, + 0, 0, 68, 0, 0, 11, 12, 0, 0, 0, + 0, 98, 0, 0, 0, 48, 0, 40, 39, 35, + 36, 0, 38, 37, 0, 0, 98, 0, 60, 61, + 57, 59, 58, 67, 55, 54, 72, 74, 70, 73, + 69, 107, 96, 0, 95, 81, 83, 79, 82, 78, + 91, 92, 90, 112, 114, 115, 111, 110, 29, 87, + 0, 107, 0, 107, 107, 107, 0, 0, 0, 88, + 64, 107, 0, 107, 0, 97, 0, 0, 41, 99, + 0, 0, 107, 107, 50, 47, 28, 0, 63, 0, + 108, 93, 42, 43, 44, 0, 0, 0, 49, 62, + 65, 45, 46, 51 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 1, 2, 25, 26, 101, 27, 28, 29, 30, - 65, 102, 103, 147, 175, 31, 32, 117, 33, 67, - 113, 68, 34, 121, 35, 69, 36, 37, 129, 38, - 71, 39, 40, 41, 104, 105, 70, 106, 142, 143, - 42, 74, 156, 60, 61, 51 + -1, 3, 4, 5, 33, 34, 108, 35, 36, 37, + 38, 74, 109, 110, 157, 188, 39, 40, 124, 41, + 76, 120, 77, 42, 128, 43, 78, 6, 44, 45, + 137, 46, 80, 47, 48, 49, 111, 112, 81, 113, + 79, 134, 152, 153, 50, 7, 165, 69, 70, 60 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -80 +#define YYPACT_NINF -90 static const yytype_int16 yypact[] = { - -80, 2, 132, -80, -13, -1, -1, -2, -1, 9, - 33, -1, 27, 40, -3, 38, -80, -80, -80, -80, - -80, -80, -80, 71, -80, 77, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, 57, 61, -80, 63, - -80, 76, -80, 87, 101, 133, -80, -80, -3, -3, - 195, -6, -80, 136, 149, 39, 104, 65, 150, 5, - 194, 5, 167, -80, 176, -80, -80, -80, -80, -80, - -80, 68, -80, -3, -3, 176, 72, 72, -80, -80, - 177, 187, 78, -1, -1, -3, 196, 72, -80, 222, - -80, -80, -80, -80, 221, -80, -80, 205, -1, -1, - 211, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, 206, -80, -80, -80, -80, -80, - -3, 223, 209, 223, 197, 223, 72, 7, 210, -80, - -80, 223, 212, 223, 201, -3, 213, -80, -80, 214, - 215, 223, 208, -80, -80, 216, -80, 217, -80, 113, - -80, -80, -80, 218, -1, -80, -80, -80, -80, -80 + 4, 77, -90, 61, -90, 129, -90, 15, -90, -90, + 37, -90, 47, 77, 51, 77, 59, 63, 77, 66, + 71, 60, 69, -90, -90, -90, -90, -90, -90, -90, + -90, 125, -90, 127, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, 157, -90, -90, 100, -90, 128, -90, 154, -90, + 156, -90, 160, 161, 170, -90, -90, 60, 60, 203, + 49, -90, 171, 182, 33, 101, 213, 252, 241, -2, + 241, 189, -90, -90, -90, -90, -90, -90, -13, -90, + 60, 60, 100, 115, 115, -90, -90, 185, 186, 201, + 77, 77, 60, 211, 115, -90, 237, -90, -90, -90, + -90, 230, -90, -90, 222, 77, 77, 228, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, 245, -90, 65, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, 231, -90, -90, -90, -90, -90, + 60, 245, 234, 245, -5, -4, 115, 62, 238, -90, + -90, 245, 239, 245, 60, -90, 209, 240, -90, -90, + 242, 244, -5, 245, 246, -90, -90, 248, -90, 250, + 137, -90, -90, -90, -90, 251, 254, 77, -90, -90, + -90, -90, -90, -90 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -80, -80, -80, -80, 122, -34, -80, -80, -80, -80, - 220, -80, -80, -80, -80, -80, -80, -80, 59, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, 125, - -80, -80, -80, -80, -80, 183, 219, 22, 142, -5, - 147, 192, 69, -54, -79, -80 + -90, -90, 261, 281, -90, 76, -70, -90, -90, -90, + -90, 253, -90, -90, -90, -90, -90, -90, -90, -48, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -20, -90, -90, -90, -90, -90, 212, 210, -68, + -90, -90, 175, -1, 104, -7, 123, -66, -89, -90 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -82 + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -87 static const yytype_int16 yytable[] = { - 46, 47, 3, 49, 81, 82, 53, 136, 137, 6, - 7, 8, 9, 10, 11, 12, 13, 43, 146, 14, - 15, 86, 56, 57, 44, 45, 58, 87, 48, 134, - 135, 59, 162, 112, 50, 24, 125, 163, 125, -28, - 90, 144, -28, -28, -28, -28, -28, -28, -28, -28, - -28, 91, 54, -28, -28, 92, -28, 93, 94, 95, - 96, 97, 98, 52, 99, 55, 90, 161, 62, 100, - -49, -49, 63, -49, -49, -49, -49, 91, 64, -49, - -49, 92, 107, 108, 109, 110, 154, 73, 141, 115, - 99, 75, 126, 76, 126, 111, 133, 56, 57, 83, - 84, 169, 140, 151, -30, 90, 77, -30, -30, -30, - -30, -30, -30, -30, -30, -30, 91, 78, -30, -30, - 92, -30, 93, 94, 95, 96, 97, 98, 120, 99, - 128, 79, -2, 4, 100, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 83, 84, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 7, 8, 23, 10, 11, - 12, 13, 24, 80, 14, 15, 88, -81, 90, 179, - -81, -81, -81, -81, -81, -81, -81, -81, -81, 89, - 24, -81, -81, 92, -81, -81, -81, -81, -81, -81, - 116, 119, 99, 127, 122, 90, 130, 124, -72, -72, - -72, -72, -72, -72, -72, -72, 132, 138, -72, -72, - 92, 155, 158, 159, 160, 118, 123, 139, 131, 99, - 165, 145, 167, 148, 124, 73, 83, 84, 83, 84, - 173, 168, 83, 84, 149, 150, 153, 155, 84, 157, - 164, 174, 166, 170, 171, 172, 176, 177, 178, 66, - 114, 152, 85, 0, 0, 0, 0, 0, 0, 72 + 10, 88, 89, 54, 146, 147, 119, 1, 122, 164, + 164, 141, 56, 142, 58, 156, 143, 62, 1, 90, + 91, 131, 65, 66, 144, 145, 67, 90, 91, 132, + 127, 68, 136, -31, 97, 2, 154, -31, -31, -31, + -31, -31, -31, -31, -31, 98, 52, -31, -31, 99, + -31, 100, 101, 102, 103, 104, -31, 105, 129, 106, + 138, 11, 92, 141, 107, 142, 97, 173, 2, -77, + -77, -77, -77, -77, -77, -77, -77, 93, 55, -77, + -77, 99, 57, 94, 166, 59, 65, 66, 174, 172, + 67, 106, 63, 175, 61, 68, 140, 64, 180, 151, + 71, -33, 97, 8, 9, -33, -33, -33, -33, -33, + -33, -33, -33, 98, 161, -33, -33, 99, -33, 100, + 101, 102, 103, 104, -33, 105, 72, 106, 73, -5, + 12, 52, 107, 13, 14, 15, 16, 17, 18, 19, + 20, 65, 66, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 123, 126, 31, 135, -4, 12, 82, + 32, 13, 14, 15, 16, 17, 18, 19, 20, 90, + 91, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 125, 130, 31, 139, 83, 193, 84, 32, -86, + 97, 85, 86, -86, -86, -86, -86, -86, -86, -86, + -86, 87, 95, -86, -86, 99, -86, -86, -86, -86, + -86, -86, -86, 96, 97, 106, 148, 149, -53, -53, + 140, -53, -53, -53, -53, 98, 150, -53, -53, 99, + 114, 115, 116, 117, 2, 90, 91, 155, 158, 106, + 181, 90, 91, 159, 118, 13, 14, 15, 16, 17, + 18, 19, 20, 160, 163, 21, 22, 14, 15, 164, + 17, 18, 19, 20, 91, 168, 21, 22, 53, 176, + 178, 182, 32, 183, 167, 184, 169, 170, 171, 189, + 187, 190, 191, 32, 177, 192, 179, 51, 121, 133, + 75, 162, 0, 0, 0, 185, 186 }; +#define yypact_value_is_default(yystate) \ + ((yystate) == (-90)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + static const yytype_int16 yycheck[] = { - 5, 6, 0, 8, 58, 59, 11, 86, 87, 4, - 5, 6, 7, 8, 9, 10, 11, 30, 97, 14, - 15, 27, 25, 26, 25, 26, 29, 33, 30, 83, - 84, 34, 25, 67, 25, 30, 70, 30, 72, 0, - 1, 95, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 30, 25, 25, 1, 146, 30, 30, - 5, 6, 1, 8, 9, 10, 11, 12, 1, 14, - 15, 16, 17, 18, 19, 20, 140, 30, 93, 67, - 25, 30, 70, 30, 72, 30, 28, 25, 26, 31, - 32, 155, 24, 108, 0, 1, 30, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 69, 25, - 71, 30, 0, 1, 30, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 31, 32, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 5, 6, 25, 8, 9, - 10, 11, 30, 30, 14, 15, 30, 0, 1, 174, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 30, - 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 68, 69, 25, 71, 69, 1, 71, 30, 4, 5, - 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, - 16, 14, 143, 144, 145, 68, 69, 30, 71, 25, - 151, 25, 153, 1, 30, 30, 31, 32, 31, 32, - 161, 30, 31, 32, 13, 30, 25, 14, 32, 30, - 30, 33, 30, 30, 30, 30, 30, 30, 30, 29, - 67, 109, 60, -1, -1, -1, -1, -1, -1, 40 + 1, 67, 68, 10, 93, 94, 76, 3, 76, 14, + 14, 81, 13, 81, 15, 104, 29, 18, 3, 32, + 33, 23, 26, 27, 90, 91, 30, 32, 33, 31, + 78, 35, 80, 0, 1, 31, 102, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 31, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 78, 26, + 80, 0, 69, 133, 31, 133, 1, 156, 31, 4, + 5, 6, 7, 8, 9, 10, 11, 28, 31, 14, + 15, 16, 31, 34, 150, 26, 26, 27, 26, 155, + 30, 26, 26, 31, 31, 35, 31, 26, 164, 100, + 31, 0, 1, 26, 27, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 115, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 1, 26, 1, 0, + 1, 31, 31, 4, 5, 6, 7, 8, 9, 10, + 11, 26, 27, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 77, 78, 26, 80, 0, 1, 31, + 31, 4, 5, 6, 7, 8, 9, 10, 11, 32, + 33, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 77, 78, 26, 80, 31, 187, 31, 31, 0, + 1, 31, 31, 4, 5, 6, 7, 8, 9, 10, + 11, 31, 31, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 31, 1, 26, 31, 31, 5, 6, + 31, 8, 9, 10, 11, 12, 25, 14, 15, 16, + 17, 18, 19, 20, 31, 32, 33, 26, 1, 26, + 31, 32, 33, 13, 31, 4, 5, 6, 7, 8, + 9, 10, 11, 31, 26, 14, 15, 5, 6, 14, + 8, 9, 10, 11, 33, 31, 14, 15, 7, 31, + 31, 31, 31, 31, 151, 31, 153, 154, 155, 31, + 34, 31, 31, 31, 161, 31, 163, 6, 76, 79, + 37, 116, -1, -1, -1, 172, 173 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 25, 30, 38, 39, 41, 42, 43, - 44, 50, 51, 53, 57, 59, 61, 62, 64, 66, - 67, 68, 75, 30, 25, 26, 74, 74, 30, 74, - 25, 80, 30, 74, 25, 25, 25, 26, 29, 34, - 78, 79, 30, 1, 1, 45, 45, 54, 56, 60, - 71, 65, 71, 30, 76, 30, 30, 30, 30, 30, - 30, 78, 78, 31, 32, 76, 27, 33, 30, 30, - 1, 12, 16, 18, 19, 20, 21, 22, 23, 25, - 30, 40, 46, 47, 69, 70, 72, 17, 18, 19, - 20, 30, 40, 55, 70, 72, 39, 52, 75, 39, - 53, 58, 64, 75, 30, 40, 72, 39, 53, 63, - 64, 75, 30, 28, 78, 78, 79, 79, 30, 30, - 24, 74, 73, 74, 78, 25, 79, 48, 1, 13, - 30, 74, 73, 25, 78, 14, 77, 30, 77, 77, - 77, 79, 25, 30, 30, 77, 30, 77, 30, 78, - 30, 30, 30, 77, 33, 49, 30, 30, 30, 74 + 0, 3, 31, 37, 38, 39, 63, 81, 26, 27, + 79, 0, 1, 4, 5, 6, 7, 8, 9, 10, + 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 26, 31, 40, 41, 43, 44, 45, 46, 52, + 53, 55, 59, 61, 64, 65, 67, 69, 70, 71, + 80, 39, 31, 38, 81, 31, 79, 31, 79, 26, + 85, 31, 79, 26, 26, 26, 27, 30, 35, 83, + 84, 31, 1, 1, 47, 47, 56, 58, 62, 76, + 68, 74, 31, 31, 31, 31, 31, 31, 83, 83, + 32, 33, 81, 28, 34, 31, 31, 1, 12, 16, + 18, 19, 20, 21, 22, 24, 26, 31, 42, 48, + 49, 72, 73, 75, 17, 18, 19, 20, 31, 42, + 57, 73, 75, 41, 54, 80, 41, 55, 60, 67, + 80, 23, 31, 74, 77, 41, 55, 66, 67, 80, + 31, 42, 75, 29, 83, 83, 84, 84, 31, 31, + 25, 79, 78, 79, 83, 26, 84, 50, 1, 13, + 31, 79, 78, 26, 14, 82, 83, 82, 31, 82, + 82, 82, 83, 84, 26, 31, 31, 82, 31, 82, + 83, 31, 31, 31, 31, 82, 82, 34, 51, 31, + 31, 31, 31, 79 }; #define yyerrok (yyerrstatus = 0) @@ -815,9 +820,18 @@ static const yytype_uint8 yystos[] = /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ #define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif #define YYRECOVERING() (!!yyerrstatus) @@ -827,7 +841,6 @@ do \ { \ yychar = (Token); \ yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ @@ -869,19 +882,10 @@ while (YYID (0)) #endif -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ +/* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif @@ -985,17 +989,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -1029,11 +1036,11 @@ yy_reduce_print (yyvsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -1070,7 +1077,6 @@ int yydebug; # define YYMAXDEPTH 10000 #endif - #if YYERROR_VERBOSE @@ -1173,115 +1179,142 @@ yytnamerr (char *yyres, const char *yystr) } # endif -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = 0; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } - if (yysize_overflow) - return YYSIZE_MAXIMUM; + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; } #endif /* YYERROR_VERBOSE */ - /*-----------------------------------------------. | Release the memory associated to this symbol. | @@ -1308,8 +1341,10 @@ yydestruct (yymsg, yytype, yyvaluep) switch (yytype) { - case 51: /* "choice_entry" */ + case 53: /* "choice_entry" */ +/* Line 1391 of yacc.c */ +#line 90 "zconf.y" { fprintf(stderr, "%s:%d: missing end statement for this entry\n", (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); @@ -1317,9 +1352,13 @@ yydestruct (yymsg, yytype, yyvaluep) menu_end_menu(); }; +/* Line 1391 of yacc.c */ +#line 1357 "zconf.tab.c" break; - case 57: /* "if_entry" */ + case 59: /* "if_entry" */ +/* Line 1391 of yacc.c */ +#line 90 "zconf.y" { fprintf(stderr, "%s:%d: missing end statement for this entry\n", (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); @@ -1327,9 +1366,13 @@ yydestruct (yymsg, yytype, yyvaluep) menu_end_menu(); }; +/* Line 1391 of yacc.c */ +#line 1371 "zconf.tab.c" break; - case 62: /* "menu_entry" */ + case 65: /* "menu_entry" */ +/* Line 1391 of yacc.c */ +#line 90 "zconf.y" { fprintf(stderr, "%s:%d: missing end statement for this entry\n", (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); @@ -1337,16 +1380,17 @@ yydestruct (yymsg, yytype, yyvaluep) menu_end_menu(); }; +/* Line 1391 of yacc.c */ +#line 1385 "zconf.tab.c" break; default: break; } } - -/* Prevent warnings from -Wmissing-prototypes. */ +/* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -1362,18 +1406,16 @@ int yyparse (); #endif /* ! YYPARSE_PARAM */ - -/* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; - /*----------. | yyparse. | `----------*/ @@ -1400,66 +1442,66 @@ yyparse () #endif #endif { - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; @@ -1489,7 +1531,6 @@ yyparse () YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might @@ -1497,7 +1538,6 @@ yyparse () yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); yyss = yyss1; @@ -1520,9 +1560,8 @@ yyparse () (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -1533,7 +1572,6 @@ yyparse () yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); @@ -1543,6 +1581,9 @@ yyparse () YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -1551,16 +1592,16 @@ yyparse () yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) + if (yypact_value_is_default (yyn)) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1586,26 +1627,22 @@ yybackup: yyn = yytable[yyn]; if (yyn <= 0) { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + if (yytable_value_is_error (yyn)) + goto yyerrlab; yyn = -yyn; goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -1644,68 +1681,88 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 8: + case 10: - { zconf_error("unexpected end statement"); ;} +/* Line 1806 of yacc.c */ +#line 112 "zconf.y" + { zconf_error("unexpected end statement"); } break; - case 9: + case 11: - { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;} +/* Line 1806 of yacc.c */ +#line 113 "zconf.y" + { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); } break; - case 10: + case 12: +/* Line 1806 of yacc.c */ +#line 115 "zconf.y" { zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); -;} +} break; - case 11: + case 13: - { zconf_error("invalid statement"); ;} +/* Line 1806 of yacc.c */ +#line 118 "zconf.y" + { zconf_error("invalid statement"); } break; - case 25: + case 28: - { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;} +/* Line 1806 of yacc.c */ +#line 135 "zconf.y" + { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); } break; - case 26: + case 29: - { zconf_error("invalid option"); ;} +/* Line 1806 of yacc.c */ +#line 136 "zconf.y" + { zconf_error("invalid option"); } break; - case 27: + case 30: +/* Line 1806 of yacc.c */ +#line 143 "zconf.y" { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); sym->flags |= SYMBOL_OPTIONAL; menu_add_entry(sym); printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); -;} +} break; - case 28: + case 31: +/* Line 1806 of yacc.c */ +#line 151 "zconf.y" { menu_end_entry(); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 29: + case 32: +/* Line 1806 of yacc.c */ +#line 157 "zconf.y" { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); sym->flags |= SYMBOL_OPTIONAL; menu_add_entry(sym); printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); -;} +} break; - case 30: + case 33: +/* Line 1806 of yacc.c */ +#line 165 "zconf.y" { if (current_entry->prompt) current_entry->prompt->type = P_MENU; @@ -1713,29 +1770,35 @@ yyreduce: zconfprint("warning: menuconfig statement without prompt"); menu_end_entry(); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 38: + case 41: +/* Line 1806 of yacc.c */ +#line 185 "zconf.y" { menu_set_type((yyvsp[(1) - (3)].id)->stype); printd(DEBUG_PARSE, "%s:%d:type(%u)\n", zconf_curname(), zconf_lineno(), (yyvsp[(1) - (3)].id)->stype); -;} +} break; - case 39: + case 42: +/* Line 1806 of yacc.c */ +#line 193 "zconf.y" { menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 40: + case 43: +/* Line 1806 of yacc.c */ +#line 199 "zconf.y" { menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); if ((yyvsp[(1) - (4)].id)->stype != S_UNKNOWN) @@ -1743,85 +1806,115 @@ yyreduce: printd(DEBUG_PARSE, "%s:%d:default(%u)\n", zconf_curname(), zconf_lineno(), (yyvsp[(1) - (4)].id)->stype); -;} +} break; - case 41: + case 44: +/* Line 1806 of yacc.c */ +#line 209 "zconf.y" { - menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); + menu_add_select(sym_lookup((yyvsp[(2) - (4)].string), 0), NULL, (yyvsp[(3) - (4)].expr)); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 42: + case 45: + +/* Line 1806 of yacc.c */ +#line 215 "zconf.y" + { + menu_add_select(sym_lookup((yyvsp[(2) - (5)].string), 0), (yyvsp[(3) - (5)].expr), (yyvsp[(4) - (5)].expr)); + printd(DEBUG_PARSE, "%s:%d:select with value\n", zconf_curname(), zconf_lineno()); +} + break; + case 46: + +/* Line 1806 of yacc.c */ +#line 221 "zconf.y" { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 45: + case 49: +/* Line 1806 of yacc.c */ +#line 232 "zconf.y" { - struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); + const struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); if (id && id->flags & TF_OPTION) menu_add_option(id->token, (yyvsp[(3) - (3)].string)); else zconfprint("warning: ignoring unknown option %s", (yyvsp[(2) - (3)].string)); free((yyvsp[(2) - (3)].string)); -;} +} break; - case 46: + case 50: - { (yyval.string) = NULL; ;} +/* Line 1806 of yacc.c */ +#line 242 "zconf.y" + { (yyval.string) = NULL; } break; - case 47: + case 51: - { (yyval.string) = (yyvsp[(2) - (2)].string); ;} +/* Line 1806 of yacc.c */ +#line 243 "zconf.y" + { (yyval.string) = (yyvsp[(2) - (2)].string); } break; - case 48: + case 52: +/* Line 1806 of yacc.c */ +#line 249 "zconf.y" { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); sym->flags |= SYMBOL_AUTO; menu_add_entry(sym); menu_add_expr(P_CHOICE, NULL, NULL); printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 49: + case 53: +/* Line 1806 of yacc.c */ +#line 258 "zconf.y" { (yyval.menu) = menu_add_menu(); -;} +} break; - case 50: + case 54: +/* Line 1806 of yacc.c */ +#line 263 "zconf.y" { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); } -;} +} break; - case 58: + case 62: +/* Line 1806 of yacc.c */ +#line 283 "zconf.y" { menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 59: + case 63: +/* Line 1806 of yacc.c */ +#line 289 "zconf.y" { if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { menu_set_type((yyvsp[(1) - (3)].id)->stype); @@ -1830,19 +1923,23 @@ yyreduce: (yyvsp[(1) - (3)].id)->stype); } else YYERROR; -;} +} break; - case 60: + case 64: +/* Line 1806 of yacc.c */ +#line 300 "zconf.y" { current_entry->sym->flags |= SYMBOL_OPTIONAL; printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 61: + case 65: +/* Line 1806 of yacc.c */ +#line 306 "zconf.y" { if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); @@ -1850,189 +1947,273 @@ yyreduce: zconf_curname(), zconf_lineno()); } else YYERROR; -;} +} break; - case 64: + case 68: +/* Line 1806 of yacc.c */ +#line 323 "zconf.y" { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); menu_add_entry(NULL); menu_add_dep((yyvsp[(2) - (3)].expr)); (yyval.menu) = menu_add_menu(); -;} +} break; - case 65: + case 69: +/* Line 1806 of yacc.c */ +#line 331 "zconf.y" { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); } -;} +} + break; + + case 75: + +/* Line 1806 of yacc.c */ +#line 351 "zconf.y" + { + menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); +} break; - case 71: + case 76: +/* Line 1806 of yacc.c */ +#line 358 "zconf.y" { menu_add_entry(NULL); menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 72: + case 77: +/* Line 1806 of yacc.c */ +#line 365 "zconf.y" { (yyval.menu) = menu_add_menu(); -;} +} break; - case 73: + case 78: +/* Line 1806 of yacc.c */ +#line 370 "zconf.y" { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); } -;} +} break; - case 79: + case 84: +/* Line 1806 of yacc.c */ +#line 388 "zconf.y" { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); zconf_nextfile((yyvsp[(2) - (3)].string)); -;} +} break; - case 80: + case 85: +/* Line 1806 of yacc.c */ +#line 396 "zconf.y" { menu_add_entry(NULL); menu_add_prompt(P_COMMENT, (yyvsp[(2) - (3)].string), NULL); printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 81: + case 86: +/* Line 1806 of yacc.c */ +#line 403 "zconf.y" { menu_end_entry(); -;} +} break; - case 82: + case 87: +/* Line 1806 of yacc.c */ +#line 410 "zconf.y" { printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); zconf_starthelp(); -;} +} break; - case 83: + case 88: +/* Line 1806 of yacc.c */ +#line 416 "zconf.y" { current_entry->help = (yyvsp[(2) - (2)].string); -;} +} break; - case 88: + case 93: +/* Line 1806 of yacc.c */ +#line 430 "zconf.y" { menu_add_dep((yyvsp[(3) - (4)].expr)); printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); -;} +} break; - case 90: + case 97: +/* Line 1806 of yacc.c */ +#line 444 "zconf.y" + { + menu_add_visibility((yyvsp[(2) - (2)].expr)); +} + break; + + case 99: + +/* Line 1806 of yacc.c */ +#line 453 "zconf.y" { menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); -;} +} break; - case 93: + case 102: - { (yyval.id) = (yyvsp[(1) - (2)].id); ;} +/* Line 1806 of yacc.c */ +#line 461 "zconf.y" + { (yyval.id) = (yyvsp[(1) - (2)].id); } break; - case 94: + case 103: - { (yyval.id) = (yyvsp[(1) - (2)].id); ;} +/* Line 1806 of yacc.c */ +#line 462 "zconf.y" + { (yyval.id) = (yyvsp[(1) - (2)].id); } break; - case 95: + case 104: - { (yyval.id) = (yyvsp[(1) - (2)].id); ;} +/* Line 1806 of yacc.c */ +#line 463 "zconf.y" + { (yyval.id) = (yyvsp[(1) - (2)].id); } break; - case 98: + case 107: - { (yyval.expr) = NULL; ;} +/* Line 1806 of yacc.c */ +#line 471 "zconf.y" + { (yyval.expr) = NULL; } break; - case 99: + case 108: - { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} +/* Line 1806 of yacc.c */ +#line 472 "zconf.y" + { (yyval.expr) = (yyvsp[(2) - (2)].expr); } break; - case 100: + case 109: - { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} +/* Line 1806 of yacc.c */ +#line 475 "zconf.y" + { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); } break; - case 101: + case 110: - { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} +/* Line 1806 of yacc.c */ +#line 476 "zconf.y" + { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } break; - case 102: + case 111: - { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} +/* Line 1806 of yacc.c */ +#line 477 "zconf.y" + { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } break; - case 103: + case 112: - { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} +/* Line 1806 of yacc.c */ +#line 478 "zconf.y" + { (yyval.expr) = (yyvsp[(2) - (3)].expr); } break; - case 104: + case 113: - { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} +/* Line 1806 of yacc.c */ +#line 479 "zconf.y" + { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); } break; - case 105: + case 114: - { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +/* Line 1806 of yacc.c */ +#line 480 "zconf.y" + { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; - case 106: + case 115: - { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +/* Line 1806 of yacc.c */ +#line 481 "zconf.y" + { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; - case 107: + case 116: - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} +/* Line 1806 of yacc.c */ +#line 484 "zconf.y" + { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); } break; - case 108: + case 117: - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} +/* Line 1806 of yacc.c */ +#line 485 "zconf.y" + { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); } break; - case 109: + case 118: - { (yyval.string) = NULL; ;} +/* Line 1806 of yacc.c */ +#line 488 "zconf.y" + { (yyval.string) = NULL; } break; -/* Line 1267 of yacc.c. */ +/* Line 1806 of yacc.c */ +#line 2204 "zconf.tab.c" default: break; } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); @@ -2041,7 +2222,6 @@ yyreduce: *++yyvsp = yyval; - /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2061,6 +2241,10 @@ yyreduce: | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { @@ -2068,37 +2252,36 @@ yyerrlab: #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; } +# undef YYSYNTAX_ERROR #endif } @@ -2106,7 +2289,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -2123,7 +2306,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -2157,7 +2340,7 @@ yyerrlab1: for (;;) { yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) + if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) @@ -2180,9 +2363,6 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; @@ -2207,7 +2387,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -2218,9 +2398,14 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); @@ -2245,6 +2430,8 @@ yyreturn: +/* Line 2067 of yacc.c */ +#line 491 "zconf.y" void conf_parse(const char *name) @@ -2255,36 +2442,31 @@ void conf_parse(const char *name) zconf_initscan(name); sym_init(); - menu_init(); - modules_sym = sym_lookup(NULL, 0); - modules_sym->type = S_BOOLEAN; - modules_sym->flags |= SYMBOL_AUTO; - rootmenu.prompt = menu_add_prompt(P_MENU, "OpenADK Configuration", NULL); + _menu_init(); + rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); -#if YYDEBUG if (getenv("ZCONF_DEBUG")) zconfdebug = 1; -#endif zconfparse(); if (zconfnerrs) exit(1); - if (!modules_sym->prop) { - struct property *prop; + if (!modules_sym) + modules_sym = sym_find( "n" ); + + rootmenu.prompt->text = _(rootmenu.prompt->text); + rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); - prop = prop_alloc(P_DEFAULT, modules_sym); - prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); - } menu_finalize(&rootmenu); for_all_symbols(i, sym) { if (sym_check_deps(sym)) zconfnerrs++; - } + } if (zconfnerrs) exit(1); sym_set_change_count(1); } -const char *zconf_tokenname(int token) +static const char *zconf_tokenname(int token) { switch (token) { case T_MENU: return "menu"; @@ -2294,11 +2476,12 @@ const char *zconf_tokenname(int token) case T_IF: return "if"; case T_ENDIF: return "endif"; case T_DEPENDS: return "depends"; + case T_VISIBLE: return "visible"; } return "<token>"; } -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) +static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken) { if (id->token != endtoken) { zconf_error("unexpected '%s' within %s block", @@ -2343,12 +2526,10 @@ static void zconf_error(const char *err, ...) static void zconferror(const char *err) { -#if YYDEBUG fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); -#endif } -void print_quoted_string(FILE *out, const char *str) +static void print_quoted_string(FILE *out, const char *str) { const char *p; int len; @@ -2365,15 +2546,15 @@ void print_quoted_string(FILE *out, const char *str) putc('"', out); } -void print_symbol(FILE *out, struct menu *menu) +static void print_symbol(FILE *out, struct menu *menu) { struct symbol *sym = menu->sym; struct property *prop; if (sym_is_choice(sym)) - fprintf(out, "choice\n"); + fprintf(out, "\nchoice\n"); else - fprintf(out, "config %s\n", sym->name); + fprintf(out, "\nconfig %s\n", sym->name); switch (sym->type) { case S_BOOLEAN: fputs(" boolean\n", out); @@ -2419,6 +2600,30 @@ void print_symbol(FILE *out, struct menu *menu) case P_CHOICE: fputs(" #choice value\n", out); break; + case P_SELECT: + fputs( " select ", out); + expr_fprint(prop->expr, out); + if (prop->value) { + fputs(" (value=", out); + expr_fprint(prop->value, out); + fputc(')', out); + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_RANGE: + fputs( " range ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_MENU: + fputs( " menu ", out); + print_quoted_string(out, prop->text); + fputc('\n', out); + break; default: fprintf(out, " unknown prop %d!\n", prop->type); break; @@ -2430,7 +2635,6 @@ void print_symbol(FILE *out, struct menu *menu) menu->help[len] = 0; fprintf(out, " help\n%s\n", menu->help); } - fputc('\n', out); } void zconfdump(FILE *out) @@ -2463,7 +2667,6 @@ void zconfdump(FILE *out) expr_fprint(prop->visible.expr, out); fputc('\n', out); } - fputs("\n", out); } if (menu->list) @@ -2481,7 +2684,7 @@ void zconfdump(FILE *out) } } -#include "lex.zconf.c" +#include "zconf.lex.c" #include "util.c" #include "confdata.c" #include "expr.c" diff --git a/adk/config/zconf.tab.h_shipped b/adk/config/zconf.tab.h_shipped index 1b17df414..367ea34d4 100644 --- a/adk/config/zconf.tab.h_shipped +++ b/adk/config/zconf.tab.h_shipped @@ -1,24 +1,21 @@ -/* A Bison parser, made by GNU Bison 2.3. */ +/* A Bison parser, made by GNU Bison 2.5. */ -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,10 +26,11 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -59,75 +57,48 @@ T_DEFAULT = 275, T_SELECT = 276, T_RANGE = 277, - T_OPTION = 278, - T_ON = 279, - T_WORD = 280, - T_WORD_QUOTE = 281, - T_UNEQUAL = 282, - T_CLOSE_PAREN = 283, - T_OPEN_PAREN = 284, - T_EOL = 285, - T_OR = 286, - T_AND = 287, - T_EQUAL = 288, - T_NOT = 289 + T_VISIBLE = 278, + T_OPTION = 279, + T_ON = 280, + T_WORD = 281, + T_WORD_QUOTE = 282, + T_UNEQUAL = 283, + T_CLOSE_PAREN = 284, + T_OPEN_PAREN = 285, + T_EOL = 286, + T_OR = 287, + T_AND = 288, + T_EQUAL = 289, + T_NOT = 290 }; #endif -/* Tokens. */ -#define T_MAINMENU 258 -#define T_MENU 259 -#define T_ENDMENU 260 -#define T_SOURCE 261 -#define T_CHOICE 262 -#define T_ENDCHOICE 263 -#define T_COMMENT 264 -#define T_CONFIG 265 -#define T_MENUCONFIG 266 -#define T_HELP 267 -#define T_HELPTEXT 268 -#define T_IF 269 -#define T_ENDIF 270 -#define T_DEPENDS 271 -#define T_OPTIONAL 272 -#define T_PROMPT 273 -#define T_TYPE 274 -#define T_DEFAULT 275 -#define T_SELECT 276 -#define T_RANGE 277 -#define T_OPTION 278 -#define T_ON 279 -#define T_WORD 280 -#define T_WORD_QUOTE 281 -#define T_UNEQUAL 282 -#define T_CLOSE_PAREN 283 -#define T_OPEN_PAREN 284 -#define T_EOL 285 -#define T_OR 286 -#define T_AND 287 -#define T_EQUAL 288 -#define T_NOT 289 - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 44 "zconf.y" { + +/* Line 2068 of yacc.c */ +#line 37 "zconf.y" + char *string; struct file *file; struct symbol *symbol; struct expr *expr; struct menu *menu; - struct kconf_id *id; -} -/* Line 1489 of yacc.c. */ -#line 126 "zconf.tab.h" - YYSTYPE; + const struct kconf_id *id; + + + +/* Line 2068 of yacc.c */ +#line 96 "zconf.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE zconflval; + diff --git a/adk/config/zconf.y b/adk/config/zconf.y index b4240c846..fdc6fdce2 100644 --- a/adk/config/zconf.y +++ b/adk/config/zconf.y @@ -11,11 +11,8 @@ #include <string.h> #include <stdbool.h> -#define LKC_DIRECT_LINK #include "lkc.h" -#include "zconf.hash.c" - #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) #define PRINTD 0x0001 @@ -27,18 +24,14 @@ extern int zconflex(void); static void zconfprint(const char *err, ...); static void zconf_error(const char *err, ...); static void zconferror(const char *err); -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); +static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); -struct symbol *symbol_hash[257]; +struct symbol *symbol_hash[SYMBOL_HASHSIZE]; static struct menu *current_menu, *current_entry; -#define YYDEBUG 0 -#if YYDEBUG -#define YYERROR_VERBOSE -#endif %} -%expect 26 +%expect 30 %union { @@ -47,7 +40,7 @@ static struct menu *current_menu, *current_entry; struct symbol *symbol; struct expr *expr; struct menu *menu; - struct kconf_id *id; + const struct kconf_id *id; } %token <id>T_MAINMENU @@ -70,6 +63,7 @@ static struct menu *current_menu, *current_entry; %token <id>T_DEFAULT %token <id>T_SELECT %token <id>T_RANGE +%token <id>T_VISIBLE %token <id>T_OPTION %token <id>T_ON %token <string> T_WORD @@ -100,15 +94,21 @@ static struct menu *current_menu, *current_entry; menu_end_menu(); } if_entry menu_entry choice_entry +%{ +/* Include zconf.hash.c here so it can see the token constants. */ +#include "zconf.hash.c" +%} + %% -input: stmt_list; +input: nl start | start; + +start: mainmenu_stmt stmt_list | stmt_list; stmt_list: /* empty */ | stmt_list common_stmt | stmt_list choice_stmt | stmt_list menu_stmt - | stmt_list T_MAINMENU prompt nl | stmt_list end { zconf_error("unexpected end statement"); } | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } | stmt_list option_name error T_EOL @@ -119,7 +119,7 @@ stmt_list: ; option_name: - T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT + T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE ; common_stmt: @@ -207,10 +207,16 @@ config_option: T_DEFAULT expr if_expr T_EOL config_option: T_SELECT T_WORD if_expr T_EOL { - menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + menu_add_select(sym_lookup($2, 0), NULL, $3); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); }; +config_option: T_SELECT T_WORD expr if_expr T_EOL +{ + menu_add_select(sym_lookup($2, 0), $3, $4); + printd(DEBUG_PARSE, "%s:%d:select with value\n", zconf_curname(), zconf_lineno()); +}; + config_option: T_RANGE symbol symbol if_expr T_EOL { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); @@ -224,7 +230,7 @@ symbol_option_list: /* empty */ | symbol_option_list T_WORD symbol_option_arg { - struct kconf_id *id = kconf_id_lookup($2, strlen($2)); + const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); if (id && id->flags & TF_OPTION) menu_add_option(id->token, $3); else @@ -339,6 +345,13 @@ if_block: | if_block choice_stmt ; +/* mainmenu entry */ + +mainmenu_stmt: T_MAINMENU prompt nl +{ + menu_add_prompt(P_MENU, $2, NULL); +}; + /* menu entry */ menu: T_MENU prompt T_EOL @@ -348,7 +361,7 @@ menu: T_MENU prompt T_EOL printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); }; -menu_entry: menu depends_list +menu_entry: menu visibility_list depends_list { $$ = menu_add_menu(); }; @@ -419,6 +432,19 @@ depends: T_DEPENDS T_ON expr T_EOL printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); }; +/* visibility option */ + +visibility_list: + /* empty */ + | visibility_list visible + | visibility_list T_EOL +; + +visible: T_VISIBLE if_expr +{ + menu_add_visibility($2); +}; + /* prompt statement */ prompt_stmt_opt: @@ -472,36 +498,31 @@ void conf_parse(const char *name) zconf_initscan(name); sym_init(); - menu_init(); - modules_sym = sym_lookup(NULL, 0); - modules_sym->type = S_BOOLEAN; - modules_sym->flags |= SYMBOL_AUTO; - rootmenu.prompt = menu_add_prompt(P_MENU, "OpenADK Configuration", NULL); + _menu_init(); + rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); -#if YYDEBUG if (getenv("ZCONF_DEBUG")) zconfdebug = 1; -#endif zconfparse(); if (zconfnerrs) exit(1); - if (!modules_sym->prop) { - struct property *prop; + if (!modules_sym) + modules_sym = sym_find( "n" ); + + rootmenu.prompt->text = _(rootmenu.prompt->text); + rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); - prop = prop_alloc(P_DEFAULT, modules_sym); - prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); - } menu_finalize(&rootmenu); for_all_symbols(i, sym) { if (sym_check_deps(sym)) zconfnerrs++; - } + } if (zconfnerrs) exit(1); sym_set_change_count(1); } -const char *zconf_tokenname(int token) +static const char *zconf_tokenname(int token) { switch (token) { case T_MENU: return "menu"; @@ -511,11 +532,12 @@ const char *zconf_tokenname(int token) case T_IF: return "if"; case T_ENDIF: return "endif"; case T_DEPENDS: return "depends"; + case T_VISIBLE: return "visible"; } return "<token>"; } -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) +static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken) { if (id->token != endtoken) { zconf_error("unexpected '%s' within %s block", @@ -560,12 +582,10 @@ static void zconf_error(const char *err, ...) static void zconferror(const char *err) { -#if YYDEBUG fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); -#endif } -void print_quoted_string(FILE *out, const char *str) +static void print_quoted_string(FILE *out, const char *str) { const char *p; int len; @@ -582,15 +602,15 @@ void print_quoted_string(FILE *out, const char *str) putc('"', out); } -void print_symbol(FILE *out, struct menu *menu) +static void print_symbol(FILE *out, struct menu *menu) { struct symbol *sym = menu->sym; struct property *prop; if (sym_is_choice(sym)) - fprintf(out, "choice\n"); + fprintf(out, "\nchoice\n"); else - fprintf(out, "config %s\n", sym->name); + fprintf(out, "\nconfig %s\n", sym->name); switch (sym->type) { case S_BOOLEAN: fputs(" boolean\n", out); @@ -636,6 +656,30 @@ void print_symbol(FILE *out, struct menu *menu) case P_CHOICE: fputs(" #choice value\n", out); break; + case P_SELECT: + fputs( " select ", out); + expr_fprint(prop->expr, out); + if (prop->value) { + fputs(" (value=", out); + expr_fprint(prop->value, out); + fputc(')', out); + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_RANGE: + fputs( " range ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_MENU: + fputs( " menu ", out); + print_quoted_string(out, prop->text); + fputc('\n', out); + break; default: fprintf(out, " unknown prop %d!\n", prop->type); break; @@ -647,7 +691,6 @@ void print_symbol(FILE *out, struct menu *menu) menu->help[len] = 0; fprintf(out, " help\n%s\n", menu->help); } - fputc('\n', out); } void zconfdump(FILE *out) @@ -680,7 +723,6 @@ void zconfdump(FILE *out) expr_fprint(prop->visible.expr, out); fputc('\n', out); } - fputs("\n", out); } if (menu->list) @@ -698,7 +740,7 @@ void zconfdump(FILE *out) } } -#include "lex.zconf.c" +#include "zconf.lex.c" #include "util.c" #include "confdata.c" #include "expr.c" |