From 259d9bdaf2bfc6882910005a0ef4b3199139ebe2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 30 Dec 2018 22:59:24 +0900 Subject: kbuild: clean up *.lex.c and *.tab.[ch] patterns from top-level Makefile Linux commit 9a8dfb394c046742b2ac7444ba42272e11e9989d Files suffixed by .lex.c, .tab.[ch] are generated lexers, parsers, respectively. Clean them up globally from the top Makefile. Some of the final host programs those lexer/parser are linked into are necessary for building external modules, but the intermediates are unneeded. They can be cleaned away by 'make clean' instead of 'make mrproper'. Signed-off-by: Masahiro Yamada Signed-off-by: Sascha Hauer --- Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'Makefile') diff --git a/Makefile b/Makefile index a504dae471..1f4baa6679 100644 --- a/Makefile +++ b/Makefile @@ -997,6 +997,7 @@ clean: archclean $(clean-dirs) @find . $(RCS_FIND_IGNORE) \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ + -o -name '*lex.c' -o -name '.tab.[ch]' \ -o -name '*.symtypes' -o -name '*.bbenv.*' -o -name "*.bbenv" \) \ -type f -print | xargs rm -f -- cgit v1.2.3 From 273dbe5f87de8d6129a68ad40e87922fb6e783b6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 30 Dec 2018 22:59:26 +0900 Subject: kbuild: generate lexer and parser during build instead of shipping Recent kernel versions run flex and bison to generate lexers and parsers from real source files such as *.l and *.y . This provides better maintainability than version-controlling pre-generated C files with a "_shipped" suffix. This commit imports flex and bison rules from Linux, and deletes pre-generated parsers and lexers. Refer to the following commits in Linux: - 033dba2ec06c ("kbuild: prepare to remove C files pre-generated by flex and bison") - 29c833061c1d ("kconfig: generate lexer and parser during build instead of shipping") - e039139be8c2 ("scripts/dtc: generate lexer and parser during build instead of shipping") Signed-off-by: Masahiro Yamada Signed-off-by: Sascha Hauer --- Makefile | 3 + scripts/Makefile.lib | 26 + scripts/dtc/dtc-lexer.l | 306 ----- scripts/dtc/dtc-parser.y | 538 -------- scripts/kconfig/zconf.lex.c_shipped | 2420 --------------------------------- scripts/kconfig/zconf.tab.c_shipped | 2538 ----------------------------------- 6 files changed, 29 insertions(+), 5802 deletions(-) delete mode 100644 scripts/dtc/dtc-lexer.l delete mode 100644 scripts/dtc/dtc-parser.y delete mode 100644 scripts/kconfig/zconf.lex.c_shipped delete mode 100644 scripts/kconfig/zconf.tab.c_shipped (limited to 'Makefile') diff --git a/Makefile b/Makefile index 1f4baa6679..b014341db8 100644 --- a/Makefile +++ b/Makefile @@ -277,6 +277,8 @@ NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump +LEX = flex +YACC = bison AWK = awk GENKSYMS = scripts/genksyms/genksyms DEPMOD = /sbin/depmod @@ -322,6 +324,7 @@ KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE +export LEX YACC export HOSTCXX HOSTCXXFLAGS HOSTLDFLAGS HOST_LOADLIBES LDFLAGS_MODULE CHECK CHECKFLAGS export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3b4277e5ab..b0f6d68906 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -177,6 +177,32 @@ $(foreach m, $(notdir $1), \ $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) endef +# LEX +# --------------------------------------------------------------------------- +LEX_PREFIX = $(if $(LEX_PREFIX_${baseprereq}),$(LEX_PREFIX_${baseprereq}),yy) + +quiet_cmd_flex = LEX $@ + cmd_flex = $(LEX) -o$@ -L -P $(LEX_PREFIX) $< + +$(obj)/%.lex.c: $(src)/%.l FORCE + $(call if_changed,flex) + +# YACC +# --------------------------------------------------------------------------- +YACC_PREFIX = $(if $(YACC_PREFIX_${baseprereq}),$(YACC_PREFIX_${baseprereq}),yy) + +quiet_cmd_bison = YACC $@ + cmd_bison = $(YACC) -o$@ -t -l -p $(YACC_PREFIX) $< + +$(obj)/%.tab.c: $(src)/%.y FORCE + $(call if_changed,bison) + +quiet_cmd_bison_h = YACC $@ + cmd_bison_h = $(YACC) -o/dev/null --defines=$@ -t -l -p $(YACC_PREFIX) $< + +$(obj)/%.tab.h: $(src)/%.y FORCE + $(call if_changed,bison_h) + # Shipped files # =========================================================================== diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l deleted file mode 100644 index fd825ebba6..0000000000 --- a/scripts/dtc/dtc-lexer.l +++ /dev/null @@ -1,306 +0,0 @@ -/* - * (C) Copyright David Gibson , IBM Corporation. 2005. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -%option noyywrap nounput noinput never-interactive - -%x BYTESTRING -%x PROPNODENAME -%s V1 - -PROPNODECHAR [a-zA-Z0-9,._+*#?@-] -PATHCHAR ({PROPNODECHAR}|[/]) -LABEL [a-zA-Z_][a-zA-Z0-9_]* -STRING \"([^\\"]|\\.)*\" -CHAR_LITERAL '([^']|\\')*' -WS [[:space:]] -COMMENT "/*"([^*]|\*+[^*/])*\*+"/" -LINECOMMENT "//".*\n - -%{ -#include "dtc.h" -#include "srcpos.h" -#include "dtc-parser.tab.h" - -YYLTYPE yylloc; -extern bool treesource_error; - -/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ -#define YY_USER_ACTION \ - { \ - srcpos_update(&yylloc, yytext, yyleng); \ - } - -/*#define LEXDEBUG 1*/ - -#ifdef LEXDEBUG -#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) -#else -#define DPRINT(fmt, ...) do { } while (0) -#endif - -static int dts_version = 1; - -#define BEGIN_DEFAULT() DPRINT("\n"); \ - BEGIN(V1); \ - -static void push_input_file(const char *filename); -static bool pop_input_file(void); -static void PRINTF(1, 2) lexical_error(const char *fmt, ...); - -%} - -%% -<*>"/include/"{WS}*{STRING} { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; - push_input_file(name); - } - -<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { - char *line, *fnstart, *fnend; - struct data fn; - /* skip text before line # */ - line = yytext; - while (!isdigit((unsigned char)*line)) - line++; - - /* regexp ensures that first and list " - * in the whole yytext are those at - * beginning and end of the filename string */ - fnstart = memchr(yytext, '"', yyleng); - for (fnend = yytext + yyleng - 1; - *fnend != '"'; fnend--) - ; - assert(fnstart && fnend && (fnend > fnstart)); - - fn = data_copy_escape_string(fnstart + 1, - fnend - fnstart - 1); - - /* Don't allow nuls in filenames */ - if (memchr(fn.val, '\0', fn.len - 1)) - lexical_error("nul in line number directive"); - - /* -1 since #line is the number of the next line */ - srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); - data_free(fn); - } - -<*><> { - if (!pop_input_file()) { - yyterminate(); - } - } - -<*>{STRING} { - DPRINT("String: %s\n", yytext); - yylval.data = data_copy_escape_string(yytext+1, - yyleng-2); - return DT_STRING; - } - -<*>"/dts-v1/" { - DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; - BEGIN_DEFAULT(); - return DT_V1; - } - -<*>"/plugin/" { - DPRINT("Keyword: /plugin/\n"); - return DT_PLUGIN; - } - -<*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - -<*>"/bits/" { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - -<*>"/delete-property/" { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); - BEGIN(PROPNODENAME); - return DT_DEL_PROP; - } - -<*>"/delete-node/" { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); - BEGIN(PROPNODENAME); - return DT_DEL_NODE; - } - -<*>{LABEL}: { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); - yylval.labelref[yyleng-1] = '\0'; - return DT_LABEL; - } - -([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); - - errno = 0; - yylval.integer = strtoull(yytext, &e, 0); - - if (*e && e[strspn(e, "UL")]) { - lexical_error("Bad integer literal '%s'", - yytext); - } - - if (errno == ERANGE) - lexical_error("Integer literal '%s' out of range", - yytext); - else - /* ERANGE is the only strtoull error triggerable - * by strings matching the pattern */ - assert(errno == 0); - return DT_LITERAL; - } - -<*>{CHAR_LITERAL} { - struct data d; - DPRINT("Character literal: %s\n", yytext); - - d = data_copy_escape_string(yytext+1, yyleng-2); - if (d.len == 1) { - lexical_error("Empty character literal"); - yylval.integer = 0; - } else { - yylval.integer = (unsigned char)d.val[0]; - - if (d.len > 2) - lexical_error("Character literal has %d" - " characters instead of 1", - d.len - 1); - } - - data_free(d); - return DT_CHAR_LITERAL; - } - -<*>\&{LABEL} { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - -<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = xstrdup(yytext+2); - return DT_REF; - } - -[0-9a-fA-F]{2} { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - -"]" { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - -\\?{PROPNODECHAR}+ { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? - yytext + 1 : yytext); - BEGIN_DEFAULT(); - return DT_PROPNODENAME; - } - -"/incbin/" { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - -<*>{WS}+ /* eat whitespace */ -<*>{COMMENT}+ /* eat C-style comments */ -<*>{LINECOMMENT}+ /* eat C++-style comments */ - -<*>"<<" { return DT_LSHIFT; }; -<*>">>" { return DT_RSHIFT; }; -<*>"<=" { return DT_LE; }; -<*>">=" { return DT_GE; }; -<*>"==" { return DT_EQ; }; -<*>"!=" { return DT_NE; }; -<*>"&&" { return DT_AND; }; -<*>"||" { return DT_OR; }; - -<*>. { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); - if (yytext[0] == '[') { - DPRINT("\n"); - BEGIN(BYTESTRING); - } - if ((yytext[0] == '{') - || (yytext[0] == ';')) { - DPRINT("\n"); - BEGIN(PROPNODENAME); - } - return yytext[0]; - } - -%% - -static void push_input_file(const char *filename) -{ - assert(filename); - - srcfile_push(filename); - - yyin = current_srcfile->f; - - yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); -} - - -static bool pop_input_file(void) -{ - if (srcfile_pop() == 0) - return false; - - yypop_buffer_state(); - yyin = current_srcfile->f; - - return true; -} - -static void lexical_error(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - srcpos_verror(&yylloc, "Lexical error", fmt, ap); - va_end(ap); - - treesource_error = true; -} diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y deleted file mode 100644 index 44af170abf..0000000000 --- a/scripts/dtc/dtc-parser.y +++ /dev/null @@ -1,538 +0,0 @@ -/* - * (C) Copyright David Gibson , IBM Corporation. 2005. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -%{ -#include -#include - -#include "dtc.h" -#include "srcpos.h" - -extern int yylex(void); -extern void yyerror(char const *s); -#define ERROR(loc, ...) \ - do { \ - srcpos_error((loc), "Error", __VA_ARGS__); \ - treesource_error = true; \ - } while (0) - -extern struct dt_info *parser_output; -extern bool treesource_error; -%} - -%union { - char *propnodename; - char *labelref; - uint8_t byte; - struct data data; - - struct { - struct data data; - int bits; - } array; - - struct property *prop; - struct property *proplist; - struct node *node; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; - unsigned int flags; -} - -%token DT_V1 -%token DT_PLUGIN -%token DT_MEMRESERVE -%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR -%token DT_BITS -%token DT_DEL_PROP -%token DT_DEL_NODE -%token DT_PROPNODENAME -%token DT_LITERAL -%token DT_CHAR_LITERAL -%token DT_BYTE -%token DT_STRING -%token DT_LABEL -%token DT_REF -%token DT_INCBIN - -%type propdata -%type propdataprefix -%type header -%type headers -%type memreserve -%type memreserves -%type arrayprefix -%type bytestring -%type propdef -%type proplist - -%type devicetree -%type nodedef -%type subnode -%type subnodes - -%type integer_prim -%type integer_unary -%type integer_mul -%type integer_add -%type integer_shift -%type integer_rela -%type integer_eq -%type integer_bitand -%type integer_bitxor -%type integer_bitor -%type integer_and -%type integer_or -%type integer_trinary -%type integer_expr - -%% - -sourcefile: - headers memreserves devicetree - { - parser_output = build_dt_info($1, $2, $3, - guess_boot_cpuid($3)); - } - ; - -header: - DT_V1 ';' - { - $$ = DTSF_V1; - } - | DT_V1 ';' DT_PLUGIN ';' - { - $$ = DTSF_V1 | DTSF_PLUGIN; - } - ; - -headers: - header - | header headers - { - if ($2 != $1) - ERROR(&@2, "Header flags don't match earlier ones"); - $$ = $1; - } - ; - -memreserves: - /* empty */ - { - $$ = NULL; - } - | memreserve memreserves - { - $$ = chain_reserve_entry($1, $2); - } - ; - -memreserve: - DT_MEMRESERVE integer_prim integer_prim ';' - { - $$ = build_reserve_entry($2, $3); - } - | DT_LABEL memreserve - { - add_label(&$2->labels, $1); - $$ = $2; - } - ; - -devicetree: - '/' nodedef - { - $$ = name_node($2, ""); - } - | devicetree '/' nodedef - { - $$ = merge_nodes($1, $3); - } - | DT_REF nodedef - { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if (!($-1 & DTSF_PLUGIN)) - ERROR(&@2, "Label or path %s not found", $1); - $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); - } - | devicetree DT_LABEL DT_REF nodedef - { - struct node *target = get_node_by_ref($1, $3); - - if (target) { - add_label(&target->labels, $2); - merge_nodes(target, $4); - } else - ERROR(&@3, "Label or path %s not found", $3); - $$ = $1; - } - | devicetree DT_REF nodedef - { - struct node *target = get_node_by_ref($1, $2); - - if (target) { - merge_nodes(target, $3); - } else { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if ($-1 & DTSF_PLUGIN) - add_orphan_node($1, $3, $2); - else - ERROR(&@2, "Label or path %s not found", $2); - } - $$ = $1; - } - | devicetree DT_DEL_NODE DT_REF ';' - { - struct node *target = get_node_by_ref($1, $3); - - if (target) - delete_node(target); - else - ERROR(&@3, "Label or path %s not found", $3); - - - $$ = $1; - } - ; - -nodedef: - '{' proplist subnodes '}' ';' - { - $$ = build_node($2, $3); - } - ; - -proplist: - /* empty */ - { - $$ = NULL; - } - | proplist propdef - { - $$ = chain_property($2, $1); - } - ; - -propdef: - DT_PROPNODENAME '=' propdata ';' - { - $$ = build_property($1, $3); - } - | DT_PROPNODENAME ';' - { - $$ = build_property($1, empty_data); - } - | DT_DEL_PROP DT_PROPNODENAME ';' - { - $$ = build_property_delete($2); - } - | DT_LABEL propdef - { - add_label(&$2->labels, $1); - $$ = $2; - } - ; - -propdata: - propdataprefix DT_STRING - { - $$ = data_merge($1, $2); - } - | propdataprefix arrayprefix '>' - { - $$ = data_merge($1, $2.data); - } - | propdataprefix '[' bytestring ']' - { - $$ = data_merge($1, $3); - } - | propdataprefix DT_REF - { - $$ = data_add_marker($1, REF_PATH, $2); - } - | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')' - { - FILE *f = srcfile_relative_open($4.val, NULL); - struct data d; - - if ($6 != 0) - if (fseek(f, $6, SEEK_SET) != 0) - die("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)$6, $4.val, - strerror(errno)); - - d = data_copy_file(f, $8); - - $$ = data_merge($1, d); - fclose(f); - } - | propdataprefix DT_INCBIN '(' DT_STRING ')' - { - FILE *f = srcfile_relative_open($4.val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - - $$ = data_merge($1, d); - fclose(f); - } - | propdata DT_LABEL - { - $$ = data_add_marker($1, LABEL, $2); - } - ; - -propdataprefix: - /* empty */ - { - $$ = empty_data; - } - | propdata ',' - { - $$ = $1; - } - | propdataprefix DT_LABEL - { - $$ = data_add_marker($1, LABEL, $2); - } - ; - -arrayprefix: - DT_BITS DT_LITERAL '<' - { - unsigned long long bits; - - bits = $2; - - if ((bits != 8) && (bits != 16) && - (bits != 32) && (bits != 64)) { - ERROR(&@2, "Array elements must be" - " 8, 16, 32 or 64-bits"); - bits = 32; - } - - $$.data = empty_data; - $$.bits = bits; - } - | '<' - { - $$.data = empty_data; - $$.bits = 32; - } - | arrayprefix integer_prim - { - if ($1.bits < 64) { - uint64_t mask = (1ULL << $1.bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one - * (negative and sign-extended). The second - * condition is true if when we set all bits - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ - if (($2 > mask) && (($2 | mask) != -1ULL)) - ERROR(&@2, "Value out of range for" - " %d-bit array element", $1.bits); - } - - $$.data = data_append_integer($1.data, $2, $1.bits); - } - | arrayprefix DT_REF - { - uint64_t val = ~0ULL >> (64 - $1.bits); - - if ($1.bits == 32) - $1.data = data_add_marker($1.data, - REF_PHANDLE, - $2); - else - ERROR(&@2, "References are only allowed in " - "arrays with 32-bit elements."); - - $$.data = data_append_integer($1.data, val, $1.bits); - } - | arrayprefix DT_LABEL - { - $$.data = data_add_marker($1.data, LABEL, $2); - } - ; - -integer_prim: - DT_LITERAL - | DT_CHAR_LITERAL - | '(' integer_expr ')' - { - $$ = $2; - } - ; - -integer_expr: - integer_trinary - ; - -integer_trinary: - integer_or - | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; } - ; - -integer_or: - integer_and - | integer_or DT_OR integer_and { $$ = $1 || $3; } - ; - -integer_and: - integer_bitor - | integer_and DT_AND integer_bitor { $$ = $1 && $3; } - ; - -integer_bitor: - integer_bitxor - | integer_bitor '|' integer_bitxor { $$ = $1 | $3; } - ; - -integer_bitxor: - integer_bitand - | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; } - ; - -integer_bitand: - integer_eq - | integer_bitand '&' integer_eq { $$ = $1 & $3; } - ; - -integer_eq: - integer_rela - | integer_eq DT_EQ integer_rela { $$ = $1 == $3; } - | integer_eq DT_NE integer_rela { $$ = $1 != $3; } - ; - -integer_rela: - integer_shift - | integer_rela '<' integer_shift { $$ = $1 < $3; } - | integer_rela '>' integer_shift { $$ = $1 > $3; } - | integer_rela DT_LE integer_shift { $$ = $1 <= $3; } - | integer_rela DT_GE integer_shift { $$ = $1 >= $3; } - ; - -integer_shift: - integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; } - | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; } - | integer_add - ; - -integer_add: - integer_add '+' integer_mul { $$ = $1 + $3; } - | integer_add '-' integer_mul { $$ = $1 - $3; } - | integer_mul - ; - -integer_mul: - integer_mul '*' integer_unary { $$ = $1 * $3; } - | integer_mul '/' integer_unary - { - if ($3 != 0) { - $$ = $1 / $3; - } else { - ERROR(&@$, "Division by zero"); - $$ = 0; - } - } - | integer_mul '%' integer_unary - { - if ($3 != 0) { - $$ = $1 % $3; - } else { - ERROR(&@$, "Division by zero"); - $$ = 0; - } - } - | integer_unary - ; - -integer_unary: - integer_prim - | '-' integer_unary { $$ = -$2; } - | '~' integer_unary { $$ = ~$2; } - | '!' integer_unary { $$ = !$2; } - ; - -bytestring: - /* empty */ - { - $$ = empty_data; - } - | bytestring DT_BYTE - { - $$ = data_append_byte($1, $2); - } - | bytestring DT_LABEL - { - $$ = data_add_marker($1, LABEL, $2); - } - ; - -subnodes: - /* empty */ - { - $$ = NULL; - } - | subnode subnodes - { - $$ = chain_node($1, $2); - } - | subnode propdef - { - ERROR(&@2, "Properties must precede subnodes"); - YYERROR; - } - ; - -subnode: - DT_PROPNODENAME nodedef - { - $$ = name_node($2, $1); - } - | DT_DEL_NODE DT_PROPNODENAME ';' - { - $$ = name_node(build_node_delete(), $2); - } - | DT_LABEL subnode - { - add_label(&$2->labels, $1); - $$ = $2; - } - ; - -%% - -void yyerror(char const *s) -{ - ERROR(&yylloc, "%s", s); -} diff --git a/scripts/kconfig/zconf.lex.c_shipped b/scripts/kconfig/zconf.lex.c_shipped deleted file mode 100644 index 349a7f2431..0000000000 --- a/scripts/kconfig/zconf.lex.c_shipped +++ /dev/null @@ -1,2420 +0,0 @@ - -#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 -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#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 - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include - -#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 -#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 : ""; -} - diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped deleted file mode 100644 index 94cea5577f..0000000000 --- a/scripts/kconfig/zconf.tab.c_shipped +++ /dev/null @@ -1,2538 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.5. */ - -/* 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 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, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - 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. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.5" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* 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 - - -/* Copy the first part of user declarations. */ - - -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include -#include - -#include "lkc.h" - -#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) - -#define PRINTD 0x0001 -#define DEBUG_PARSE 0x0002 - -int cdebug = PRINTD; - -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(const struct kconf_id *id, int starttoken, int endtoken); - -struct symbol *symbol_hash[SYMBOL_HASHSIZE]; - -static struct menu *current_menu, *current_entry; - - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 1 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# 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 -{ - - - char *string; - struct file *file; - struct symbol *symbol; - struct expr *expr; - struct menu *menu; - const struct kconf_id *id; - - - -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - -/* Copy the second part of user declarations. */ - - -/* Include zconf.hash.c here so it can see the token constants. */ -#include "zconf.hash.c" - - - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# 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 EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - 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) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((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 -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 11 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 290 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 36 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 50 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 118 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 191 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 290 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 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, - 35 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 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, 137, 138, 142, - 143, 146, 150, 153, 155, 159, 160, 163, 166, 169, - 172, 175, 180, 184, 187, 192, 193, 196, 200, 202, - 206, 207, 210, 213, 216, 220, 224, 228, 230, 234, - 235, 238, 241, 244, 248, 252, 255, 258, 261, 262, - 265, 268, 271, 276, 277, 280, 283, 286, 287, 290, - 292, 294, 297, 300, 303, 305, 308, 309, 312, 314, - 318, 322, 326, 329, 333, 337, 339, 341, 342 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 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, 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, 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, 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, 358, 363, 371, 374, - 376, 377, 378, 381, 389, 396, 403, 409, 416, 418, - 419, 420, 423, 431, 433, 434, 437, 444, 446, 451, - 452, 455, 456, 457, 461, 462, 465, 466, 469, 470, - 471, 472, 473, 474, 475, 478, 479, 482, 483 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", - "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_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", "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", "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 - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -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, 290 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 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, 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, 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, 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 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[] = -{ - 6, 0, 104, 0, 3, 0, 6, 6, 99, 100, - 0, 1, 0, 0, 0, 0, 117, 0, 0, 0, - 0, 0, 0, 14, 18, 15, 16, 20, 17, 19, - 21, 0, 22, 0, 7, 34, 25, 34, 26, 55, - 65, 8, 70, 23, 93, 79, 9, 27, 88, 24, - 10, 0, 105, 2, 74, 13, 0, 101, 0, 118, - 0, 102, 0, 0, 0, 115, 116, 0, 0, 0, - 108, 103, 0, 0, 0, 0, 0, 0, 0, 88, - 0, 0, 75, 83, 51, 84, 30, 32, 0, 112, - 0, 0, 67, 0, 0, 11, 12, 0, 0, 0, - 0, 97, 0, 0, 0, 47, 0, 40, 39, 35, - 36, 0, 38, 37, 0, 0, 97, 0, 59, 60, - 56, 58, 57, 66, 54, 53, 71, 73, 69, 72, - 68, 106, 95, 0, 94, 80, 82, 78, 81, 77, - 90, 91, 89, 111, 113, 114, 110, 109, 29, 86, - 0, 106, 0, 106, 106, 106, 0, 0, 0, 87, - 63, 106, 0, 106, 0, 96, 0, 0, 41, 98, - 0, 0, 106, 49, 46, 28, 0, 62, 0, 107, - 92, 42, 43, 44, 0, 0, 48, 61, 64, 45, - 50 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 3, 4, 5, 33, 34, 108, 35, 36, 37, - 38, 74, 109, 110, 157, 186, 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 -90 -static const yytype_int16 yypact[] = -{ - 4, 42, -90, 96, -90, 111, -90, 15, -90, -90, - 75, -90, 82, 42, 104, 42, 110, 107, 42, 115, - 125, -4, 121, -90, -90, -90, -90, -90, -90, -90, - -90, 162, -90, 163, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, 139, -90, -90, 138, -90, 142, -90, 143, -90, - 152, -90, 164, 167, 168, -90, -90, -4, -4, 77, - -18, -90, 177, 185, 33, 71, 195, 247, 236, -2, - 236, 171, -90, -90, -90, -90, -90, -90, 41, -90, - -4, -4, 138, 97, 97, -90, -90, 186, 187, 194, - 42, 42, -4, 196, 97, -90, 219, -90, -90, -90, - -90, 210, -90, -90, 204, 42, 42, 199, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, 222, -90, 223, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, 215, -90, -90, -90, -90, -90, - -4, 222, 228, 222, -5, 222, 97, 35, 229, -90, - -90, 222, 232, 222, -4, -90, 135, 233, -90, -90, - 234, 235, 222, 240, -90, -90, 237, -90, 239, -13, - -90, -90, -90, -90, 244, 42, -90, -90, -90, -90, - -90 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -90, -90, 269, 271, -90, 23, -70, -90, -90, -90, - -90, 243, -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, 206, 205, -68, - -90, -90, 169, -1, 27, -7, 118, -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 YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -86 -static const yytype_int16 yytable[] = -{ - 10, 88, 89, 54, 146, 147, 119, 1, 122, 164, - 93, 141, 56, 142, 58, 156, 94, 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, 173, 92, 141, 107, 142, 174, 172, 8, 9, - 143, -33, 97, 90, 91, -33, -33, -33, -33, -33, - -33, -33, -33, 98, 166, -33, -33, 99, -33, 100, - 101, 102, 103, 104, -33, 105, 11, 106, 179, 151, - 123, 126, 107, 135, 125, 130, 2, 139, 2, 90, - 91, -5, 12, 55, 161, 13, 14, 15, 16, 17, - 18, 19, 20, 65, 66, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 57, 59, 31, 61, -4, - 12, 63, 32, 13, 14, 15, 16, 17, 18, 19, - 20, 64, 71, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 72, 73, 31, 180, 90, 91, 52, - 32, -85, 97, 82, 83, -85, -85, -85, -85, -85, - -85, -85, -85, 84, 190, -85, -85, 99, -85, -85, - -85, -85, -85, -85, -85, 85, 97, 106, 86, 87, - -52, -52, 140, -52, -52, -52, -52, 98, 95, -52, - -52, 99, 114, 115, 116, 117, 96, 148, 149, 150, - 158, 106, 155, 159, 97, 163, 118, -76, -76, -76, - -76, -76, -76, -76, -76, 160, 164, -76, -76, 99, - 13, 14, 15, 16, 17, 18, 19, 20, 91, 106, - 21, 22, 14, 15, 140, 17, 18, 19, 20, 168, - 175, 21, 22, 177, 181, 182, 183, 32, 187, 167, - 188, 169, 170, 171, 185, 189, 53, 51, 32, 176, - 75, 178, 121, 0, 133, 162, 0, 0, 0, 0, - 184 -}; - -#define yypact_value_is_default(yystate) \ - ((yystate) == (-90)) - -#define yytable_value_is_error(yytable_value) \ - YYID (0) - -static const yytype_int16 yycheck[] = -{ - 1, 67, 68, 10, 93, 94, 76, 3, 76, 14, - 28, 81, 13, 81, 15, 104, 34, 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, 26, 69, 133, 31, 133, 31, 156, 26, 27, - 29, 0, 1, 32, 33, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 150, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 0, 26, 164, 100, - 77, 78, 31, 80, 77, 78, 31, 80, 31, 32, - 33, 0, 1, 31, 115, 4, 5, 6, 7, 8, - 9, 10, 11, 26, 27, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 31, 26, 26, 31, 0, - 1, 26, 31, 4, 5, 6, 7, 8, 9, 10, - 11, 26, 31, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 1, 1, 26, 31, 32, 33, 31, - 31, 0, 1, 31, 31, 4, 5, 6, 7, 8, - 9, 10, 11, 31, 185, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 31, 1, 26, 31, 31, - 5, 6, 31, 8, 9, 10, 11, 12, 31, 14, - 15, 16, 17, 18, 19, 20, 31, 31, 31, 25, - 1, 26, 26, 13, 1, 26, 31, 4, 5, 6, - 7, 8, 9, 10, 11, 31, 14, 14, 15, 16, - 4, 5, 6, 7, 8, 9, 10, 11, 33, 26, - 14, 15, 5, 6, 31, 8, 9, 10, 11, 31, - 31, 14, 15, 31, 31, 31, 31, 31, 31, 151, - 31, 153, 154, 155, 34, 31, 7, 6, 31, 161, - 37, 163, 76, -1, 79, 116, -1, -1, -1, -1, - 172 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 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, 84, 26, 31, 31, 82, 31, 82, 83, - 31, 31, 31, 31, 82, 34, 51, 31, 31, 31, - 79 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* 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. 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) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* This macro is provided for backward compatibility. */ - -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* 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. - - 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 - - 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 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; - } - } - } - - 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_ - } - - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - - 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. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - case 53: /* "choice_entry" */ - - { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) - menu_end_menu(); -}; - - break; - case 59: /* "if_entry" */ - - { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) - menu_end_menu(); -}; - - break; - case 65: /* "menu_entry" */ - - { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) - menu_end_menu(); -}; - - break; - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - - 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; - - 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. */ - - /* 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; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - 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 - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 10: - - { zconf_error("unexpected end statement"); } - break; - - case 11: - - { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); } - break; - - case 12: - - { - zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); -} - break; - - case 13: - - { zconf_error("invalid statement"); } - break; - - case 28: - - { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); } - break; - - case 29: - - { zconf_error("invalid option"); } - break; - - case 30: - - { - 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 31: - - { - menu_end_entry(); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -} - break; - - case 32: - - { - 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 33: - - { - if (current_entry->prompt) - current_entry->prompt->type = P_MENU; - else - zconfprint("warning: menuconfig statement without prompt"); - menu_end_entry(); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -} - break; - - case 41: - - { - 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 42: - - { - 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 43: - - { - menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); - if ((yyvsp[(1) - (4)].id)->stype != S_UNKNOWN) - menu_set_type((yyvsp[(1) - (4)].id)->stype); - printd(DEBUG_PARSE, "%s:%d:default(%u)\n", - zconf_curname(), zconf_lineno(), - (yyvsp[(1) - (4)].id)->stype); -} - break; - - case 44: - - { - menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); -} - break; - - case 45: - - { - 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 48: - - { - 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 49: - - { (yyval.string) = NULL; } - break; - - case 50: - - { (yyval.string) = (yyvsp[(2) - (2)].string); } - break; - - case 51: - - { - 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 52: - - { - (yyval.menu) = menu_add_menu(); -} - break; - - case 53: - - { - 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 61: - - { - 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 62: - - { - if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { - 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); - } else - YYERROR; -} - break; - - case 63: - - { - current_entry->sym->flags |= SYMBOL_OPTIONAL; - printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); -} - break; - - case 64: - - { - if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { - menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:default\n", - zconf_curname(), zconf_lineno()); - } else - YYERROR; -} - break; - - case 67: - - { - 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 68: - - { - 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 74: - - { - menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); -} - break; - - case 75: - - { - 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 76: - - { - (yyval.menu) = menu_add_menu(); -} - break; - - case 77: - - { - 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 83: - - { - printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); - zconf_nextfile((yyvsp[(2) - (3)].string)); -} - break; - - case 84: - - { - 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 85: - - { - menu_end_entry(); -} - break; - - case 86: - - { - printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); - zconf_starthelp(); -} - break; - - case 87: - - { - current_entry->help = (yyvsp[(2) - (2)].string); -} - break; - - case 92: - - { - menu_add_dep((yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); -} - break; - - case 96: - - { - menu_add_visibility((yyvsp[(2) - (2)].expr)); -} - break; - - case 98: - - { - menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); -} - break; - - case 101: - - { (yyval.id) = (yyvsp[(1) - (2)].id); } - break; - - case 102: - - { (yyval.id) = (yyvsp[(1) - (2)].id); } - break; - - case 103: - - { (yyval.id) = (yyvsp[(1) - (2)].id); } - break; - - case 106: - - { (yyval.expr) = NULL; } - break; - - case 107: - - { (yyval.expr) = (yyvsp[(2) - (2)].expr); } - break; - - case 108: - - { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); } - break; - - case 109: - - { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } - break; - - case 110: - - { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } - break; - - case 111: - - { (yyval.expr) = (yyvsp[(2) - (3)].expr); } - break; - - case 112: - - { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); } - break; - - case 113: - - { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } - break; - - case 114: - - { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } - break; - - case 115: - - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); } - break; - - case 116: - - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); } - break; - - case 117: - - { (yyval.string) = NULL; } - break; - - - - 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); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++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. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| 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) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - 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 - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - 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); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - - - -void conf_parse(const char *name) -{ - struct symbol *sym; - int i; - - zconf_initscan(name); - - sym_init(); - _menu_init(); - rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); - - if (getenv("ZCONF_DEBUG")) - zconfdebug = 1; - zconfparse(); - if (zconfnerrs) - exit(1); - if (!modules_sym) - modules_sym = sym_find( "n" ); - - rootmenu.prompt->text = _(rootmenu.prompt->text); - rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); - - menu_finalize(&rootmenu); - for_all_symbols(i, sym) { - if (sym_check_deps(sym)) - zconfnerrs++; - } - if (zconfnerrs) - exit(1); - sym_set_change_count(1); -} - -static const char *zconf_tokenname(int token) -{ - switch (token) { - case T_MENU: return "menu"; - case T_ENDMENU: return "endmenu"; - case T_CHOICE: return "choice"; - case T_ENDCHOICE: return "endchoice"; - case T_IF: return "if"; - case T_ENDIF: return "endif"; - case T_DEPENDS: return "depends"; - case T_VISIBLE: return "visible"; - } - return ""; -} - -static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken) -{ - if (id->token != endtoken) { - zconf_error("unexpected '%s' within %s block", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); - zconfnerrs++; - return false; - } - if (current_menu->file != current_file) { - zconf_error("'%s' in different file than '%s'", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); - fprintf(stderr, "%s:%d: location of the '%s'\n", - current_menu->file->name, current_menu->lineno, - zconf_tokenname(starttoken)); - zconfnerrs++; - return false; - } - return true; -} - -static void zconfprint(const char *err, ...) -{ - va_list ap; - - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void zconf_error(const char *err, ...) -{ - va_list ap; - - zconfnerrs++; - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void zconferror(const char *err) -{ - fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); -} - -static void print_quoted_string(FILE *out, const char *str) -{ - const char *p; - int len; - - putc('"', out); - while ((p = strchr(str, '"'))) { - len = p - str; - if (len) - fprintf(out, "%.*s", len, str); - fputs("\\\"", out); - str = p + 1; - } - fputs(str, out); - putc('"', out); -} - -static void print_symbol(FILE *out, struct menu *menu) -{ - struct symbol *sym = menu->sym; - struct property *prop; - - if (sym_is_choice(sym)) - fprintf(out, "\nchoice\n"); - else - fprintf(out, "\nconfig %s\n", sym->name); - switch (sym->type) { - case S_BOOLEAN: - fputs(" boolean\n", out); - break; - case S_TRISTATE: - fputs(" tristate\n", out); - break; - case S_STRING: - fputs(" string\n", out); - break; - case S_INT: - fputs(" integer\n", out); - break; - case S_HEX: - fputs(" hex\n", out); - break; - default: - fputs(" ???\n", out); - break; - } - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu != menu) - continue; - switch (prop->type) { - case P_PROMPT: - fputs(" prompt ", out); - print_quoted_string(out, prop->text); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_DEFAULT: - fputs( " default ", out); - expr_fprint(prop->expr, out); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_CHOICE: - fputs(" #choice value\n", out); - break; - case P_SELECT: - fputs( " select ", out); - expr_fprint(prop->expr, out); - fputc('\n', out); - break; - case P_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; - } - } - if (menu->help) { - int len = strlen(menu->help); - while (menu->help[--len] == '\n') - menu->help[len] = 0; - fprintf(out, " help\n%s\n", menu->help); - } -} - -void zconfdump(FILE *out) -{ - struct property *prop; - struct symbol *sym; - struct menu *menu; - - menu = rootmenu.list; - while (menu) { - if ((sym = menu->sym)) - print_symbol(out, menu); - else if ((prop = menu->prompt)) { - switch (prop->type) { - case P_COMMENT: - fputs("\ncomment ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - case P_MENU: - fputs("\nmenu ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - default: - ; - } - if (!expr_is_yes(prop->visible.expr)) { - fputs(" depends ", out); - expr_fprint(prop->visible.expr, out); - fputc('\n', out); - } - } - - if (menu->list) - menu = menu->list; - else if (menu->next) - menu = menu->next; - else while ((menu = menu->parent)) { - if (menu->prompt && menu->prompt->type == P_MENU) - fputs("\nendmenu\n", out); - if (menu->next) { - menu = menu->next; - break; - } - } - } -} - -#include "zconf.lex.c" -#include "util.c" -#include "confdata.c" -#include "expr.c" -#include "symbol.c" -#include "menu.c" - -- cgit v1.2.3 From 997b70f585ef9bf2171c3f435efee3967e3036ec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 30 Dec 2018 22:59:27 +0900 Subject: kconfig: sync to Linux 4.20 The previous sync was commit 18895514dc5e ("kconfig: update to v3.18-rc6"). Some commits were applied on top of that since then, but equivalent fixups were done in Linux. So, this commit overwrites everything scripts/kconfig/ with the one from Linux 4.20 Highlights: - 'silentoldconfig' has been renamed to 'syncconfig' (the top Makefile needs to be adjusted) - 'testconfig' target has been added for unit-tests (the top Makefile needs to export PYTHON3 because the test frame relies on Python3 and pytest) - The perfect hash table generated by gperf has been removed - The localization support has been removed - The 'option env=VAR' has been replaced with more generic variable reference syntax $(VAR) (./Kconfig and common/Kconfig need to be adjusted) Signed-off-by: Masahiro Yamada Signed-off-by: Sascha Hauer --- Kconfig | 8 +- Makefile | 17 +- common/Kconfig | 12 +- scripts/kconfig/.gitignore | 6 - scripts/kconfig/Makefile | 346 ++++------ scripts/kconfig/POTFILES.in | 12 - scripts/kconfig/check.sh | 13 - scripts/kconfig/conf.c | 215 +++--- scripts/kconfig/confdata.c | 228 ++++-- scripts/kconfig/expr.c | 479 ++++++++----- scripts/kconfig/expr.h | 110 ++- scripts/kconfig/gconf-cfg.sh | 30 + scripts/kconfig/gconf.c | 82 +-- scripts/kconfig/kconf_id.c | 52 ++ scripts/kconfig/kxgettext.c | 235 ------- scripts/kconfig/list.h | 7 +- scripts/kconfig/lkc.h | 41 +- scripts/kconfig/lkc_proto.h | 105 +-- scripts/kconfig/lxdialog/check-lxdialog.sh | 91 --- scripts/kconfig/lxdialog/checklist.c | 4 +- scripts/kconfig/lxdialog/dialog.h | 8 +- scripts/kconfig/lxdialog/inputbox.c | 4 +- scripts/kconfig/lxdialog/menubox.c | 10 +- scripts/kconfig/lxdialog/textbox.c | 2 +- scripts/kconfig/lxdialog/yesno.c | 4 +- scripts/kconfig/mconf-cfg.sh | 47 ++ scripts/kconfig/mconf.c | 177 ++--- scripts/kconfig/menu.c | 269 ++++++-- scripts/kconfig/merge_config.sh | 63 +- scripts/kconfig/nconf-cfg.sh | 47 ++ scripts/kconfig/nconf.c | 175 ++--- scripts/kconfig/nconf.gui.c | 22 +- scripts/kconfig/nconf.h | 5 +- scripts/kconfig/preprocess.c | 572 +++++++++++++++ scripts/kconfig/qconf-cfg.sh | 32 + scripts/kconfig/qconf.cc | 765 +++++++++++---------- scripts/kconfig/qconf.h | 150 ++-- scripts/kconfig/streamline_config.pl | 53 +- scripts/kconfig/symbol.c | 335 ++++----- scripts/kconfig/tests/auto_submenu/Kconfig | 50 ++ scripts/kconfig/tests/auto_submenu/__init__.py | 12 + scripts/kconfig/tests/auto_submenu/expected_stdout | 10 + scripts/kconfig/tests/choice/Kconfig | 54 ++ scripts/kconfig/tests/choice/__init__.py | 40 ++ .../kconfig/tests/choice/alldef_expected_config | 5 + .../kconfig/tests/choice/allmod_expected_config | 9 + scripts/kconfig/tests/choice/allno_expected_config | 5 + .../kconfig/tests/choice/allyes_expected_config | 9 + .../kconfig/tests/choice/oldask0_expected_stdout | 10 + scripts/kconfig/tests/choice/oldask1_config | 2 + .../kconfig/tests/choice/oldask1_expected_stdout | 15 + .../kconfig/tests/choice_value_with_m_dep/Kconfig | 19 + .../tests/choice_value_with_m_dep/__init__.py | 15 + .../kconfig/tests/choice_value_with_m_dep/config | 2 + .../tests/choice_value_with_m_dep/expected_config | 3 + .../tests/choice_value_with_m_dep/expected_stdout | 4 + scripts/kconfig/tests/conftest.py | 291 ++++++++ scripts/kconfig/tests/err_recursive_dep/Kconfig | 63 ++ .../kconfig/tests/err_recursive_dep/__init__.py | 10 + .../tests/err_recursive_dep/expected_stderr | 38 + scripts/kconfig/tests/err_recursive_inc/Kconfig | 1 + .../kconfig/tests/err_recursive_inc/Kconfig.inc1 | 4 + .../kconfig/tests/err_recursive_inc/Kconfig.inc2 | 3 + .../kconfig/tests/err_recursive_inc/Kconfig.inc3 | 1 + .../kconfig/tests/err_recursive_inc/__init__.py | 10 + .../tests/err_recursive_inc/expected_stderr | 6 + scripts/kconfig/tests/inter_choice/Kconfig | 23 + scripts/kconfig/tests/inter_choice/__init__.py | 14 + scripts/kconfig/tests/inter_choice/defconfig | 1 + scripts/kconfig/tests/inter_choice/expected_config | 4 + scripts/kconfig/tests/new_choice_with_dep/Kconfig | 37 + .../kconfig/tests/new_choice_with_dep/__init__.py | 14 + scripts/kconfig/tests/new_choice_with_dep/config | 3 + .../tests/new_choice_with_dep/expected_stdout | 10 + .../kconfig/tests/no_write_if_dep_unmet/Kconfig | 14 + .../tests/no_write_if_dep_unmet/__init__.py | 19 + scripts/kconfig/tests/no_write_if_dep_unmet/config | 1 + .../tests/no_write_if_dep_unmet/expected_config | 5 + .../kconfig/tests/preprocess/builtin_func/Kconfig | 27 + .../tests/preprocess/builtin_func/__init__.py | 9 + .../tests/preprocess/builtin_func/expected_stderr | 5 + .../tests/preprocess/builtin_func/expected_stdout | 1 + .../tests/preprocess/circular_expansion/Kconfig | 5 + .../preprocess/circular_expansion/__init__.py | 11 + .../preprocess/circular_expansion/expected_stderr | 1 + scripts/kconfig/tests/preprocess/escape/Kconfig | 44 ++ .../kconfig/tests/preprocess/escape/__init__.py | 8 + .../tests/preprocess/escape/expected_stderr | 10 + scripts/kconfig/tests/preprocess/variable/Kconfig | 53 ++ .../kconfig/tests/preprocess/variable/__init__.py | 8 + .../tests/preprocess/variable/expected_stderr | 9 + scripts/kconfig/tests/pytest.ini | 7 + scripts/kconfig/tests/rand_nested_choice/Kconfig | 33 + .../kconfig/tests/rand_nested_choice/__init__.py | 16 + .../tests/rand_nested_choice/expected_stdout0 | 2 + .../tests/rand_nested_choice/expected_stdout1 | 4 + .../tests/rand_nested_choice/expected_stdout2 | 5 + scripts/kconfig/util.c | 93 +-- scripts/kconfig/zconf.gperf | 48 -- scripts/kconfig/zconf.hash.c | 289 ++++++++ scripts/kconfig/zconf.hash.c_shipped | 289 -------- scripts/kconfig/zconf.l | 194 ++++-- scripts/kconfig/zconf.y | 163 +++-- 103 files changed, 4502 insertions(+), 2501 deletions(-) delete mode 100644 scripts/kconfig/POTFILES.in delete mode 100755 scripts/kconfig/check.sh create mode 100755 scripts/kconfig/gconf-cfg.sh create mode 100644 scripts/kconfig/kconf_id.c delete mode 100644 scripts/kconfig/kxgettext.c delete mode 100755 scripts/kconfig/lxdialog/check-lxdialog.sh create mode 100755 scripts/kconfig/mconf-cfg.sh create mode 100644 scripts/kconfig/nconf-cfg.sh create mode 100644 scripts/kconfig/preprocess.c create mode 100755 scripts/kconfig/qconf-cfg.sh create mode 100644 scripts/kconfig/tests/auto_submenu/Kconfig create mode 100644 scripts/kconfig/tests/auto_submenu/__init__.py create mode 100644 scripts/kconfig/tests/auto_submenu/expected_stdout create mode 100644 scripts/kconfig/tests/choice/Kconfig create mode 100644 scripts/kconfig/tests/choice/__init__.py create mode 100644 scripts/kconfig/tests/choice/alldef_expected_config create mode 100644 scripts/kconfig/tests/choice/allmod_expected_config create mode 100644 scripts/kconfig/tests/choice/allno_expected_config create mode 100644 scripts/kconfig/tests/choice/allyes_expected_config create mode 100644 scripts/kconfig/tests/choice/oldask0_expected_stdout create mode 100644 scripts/kconfig/tests/choice/oldask1_config create mode 100644 scripts/kconfig/tests/choice/oldask1_expected_stdout create mode 100644 scripts/kconfig/tests/choice_value_with_m_dep/Kconfig create mode 100644 scripts/kconfig/tests/choice_value_with_m_dep/__init__.py create mode 100644 scripts/kconfig/tests/choice_value_with_m_dep/config create mode 100644 scripts/kconfig/tests/choice_value_with_m_dep/expected_config create mode 100644 scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout create mode 100644 scripts/kconfig/tests/conftest.py create mode 100644 scripts/kconfig/tests/err_recursive_dep/Kconfig create mode 100644 scripts/kconfig/tests/err_recursive_dep/__init__.py create mode 100644 scripts/kconfig/tests/err_recursive_dep/expected_stderr create mode 100644 scripts/kconfig/tests/err_recursive_inc/Kconfig create mode 100644 scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 create mode 100644 scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 create mode 100644 scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 create mode 100644 scripts/kconfig/tests/err_recursive_inc/__init__.py create mode 100644 scripts/kconfig/tests/err_recursive_inc/expected_stderr create mode 100644 scripts/kconfig/tests/inter_choice/Kconfig create mode 100644 scripts/kconfig/tests/inter_choice/__init__.py create mode 100644 scripts/kconfig/tests/inter_choice/defconfig create mode 100644 scripts/kconfig/tests/inter_choice/expected_config create mode 100644 scripts/kconfig/tests/new_choice_with_dep/Kconfig create mode 100644 scripts/kconfig/tests/new_choice_with_dep/__init__.py create mode 100644 scripts/kconfig/tests/new_choice_with_dep/config create mode 100644 scripts/kconfig/tests/new_choice_with_dep/expected_stdout create mode 100644 scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig create mode 100644 scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py create mode 100644 scripts/kconfig/tests/no_write_if_dep_unmet/config create mode 100644 scripts/kconfig/tests/no_write_if_dep_unmet/expected_config create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/expected_stdout create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/escape/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/escape/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/escape/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/variable/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/variable/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/variable/expected_stderr create mode 100644 scripts/kconfig/tests/pytest.ini create mode 100644 scripts/kconfig/tests/rand_nested_choice/Kconfig create mode 100644 scripts/kconfig/tests/rand_nested_choice/__init__.py create mode 100644 scripts/kconfig/tests/rand_nested_choice/expected_stdout0 create mode 100644 scripts/kconfig/tests/rand_nested_choice/expected_stdout1 create mode 100644 scripts/kconfig/tests/rand_nested_choice/expected_stdout2 delete mode 100644 scripts/kconfig/zconf.gperf create mode 100644 scripts/kconfig/zconf.hash.c delete mode 100644 scripts/kconfig/zconf.hash.c_shipped (limited to 'Makefile') diff --git a/Kconfig b/Kconfig index 5c99e666c0..2f2f1a6e3c 100644 --- a/Kconfig +++ b/Kconfig @@ -2,13 +2,9 @@ # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. # -mainmenu "Barebox/$ARCH $KERNELVERSION Configuration" +mainmenu "Barebox/$(ARCH) $(KERNELVERSION) Configuration" -config SRCARCH - string - option env="SRCARCH" - -source "arch/$SRCARCH/Kconfig" +source "arch/$(SRCARCH)/Kconfig" source common/Kconfig source commands/Kconfig diff --git a/Makefile b/Makefile index b014341db8..105c0d7f92 100644 --- a/Makefile +++ b/Makefile @@ -284,6 +284,7 @@ GENKSYMS = scripts/genksyms/genksyms DEPMOD = /sbin/depmod KALLSYMS = scripts/kallsyms PERL = perl +PYTHON3 = python3 CHECK = sparse CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF) @@ -323,7 +324,7 @@ KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC -export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE +export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL PYTHON3 UTS_MACHINE export LEX YACC export HOSTCXX HOSTCXXFLAGS HOSTLDFLAGS HOST_LOADLIBES LDFLAGS_MODULE CHECK CHECKFLAGS @@ -409,11 +410,9 @@ include $(srctree)/arch/$(ARCH)/Makefile export KBUILD_DEFCONFIG config: scripts_basic outputmakefile FORCE - $(Q)mkdir -p include/linux include/config $(Q)$(MAKE) $(build)=scripts/kconfig $@ %config: scripts_basic outputmakefile FORCE - $(Q)mkdir -p include/linux include/config $(Q)$(MAKE) $(build)=scripts/kconfig $@ else @@ -442,13 +441,11 @@ ifeq ($(dot-config),1) # To avoid any implicit rule to kick in, define an empty command $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; -# If .config is newer than include/config/auto.conf, someone tinkered -# with it and forgot to run make oldconfig. -# if auto.conf.cmd is missing then we are probably in a cleaned tree so -# we execute the config step to be sure to catch updated Kconfig files -include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd - $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig - +# The actual configuration files used during the build are stored in +# include/generated/ and include/config/. Update them if .config is newer than +# include/config/auto.conf (which mirrors .config). +include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd + $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig else # Dummy target needed, because used as prerequisite include/config/auto.conf: ; diff --git a/common/Kconfig b/common/Kconfig index 2ad92158c1..3ec3d46d40 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1,16 +1,8 @@ -config ARCH - string - option env="ARCH" - -config KERNELVERSION - string - option env="KERNELVERSION" - config DEFCONFIG_LIST string option defconfig_list - default "$ARCH_DEFCONFIG" - default "arch/$ARCH/defconfig" + default ARCH_DEFCONFIG + default "arch/$(ARCH)/defconfig" config GREGORIAN_CALENDER bool diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index bdbabbe08c..0aabc1d6a1 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -1,12 +1,7 @@ # # Generated files # -config* -zconf.hash.c *.moc -gconf.glade.h -*.pot -*.mo # # configuration programs @@ -16,4 +11,3 @@ mconf nconf qconf gconf -kxgettext diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index f9203d7f34..63b609243d 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -1,9 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 # =========================================================================== # Kernel configuration targets # These targets are used from top-level makefile -PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \ - localmodconfig localyesconfig +PHONY += xconfig gconfig menuconfig config localmodconfig localyesconfig \ + build_menuconfig build_nconfig build_gconfig build_xconfig ifdef KBUILD_KCONFIG Kconfig := $(KBUILD_KCONFIG) @@ -11,127 +12,120 @@ else Kconfig := Kconfig endif +ifeq ($(quiet),silent_) +silent := -s +endif + # We need this, in case the user has it in its environment unexport CONFIG_ xconfig: $(obj)/qconf - $< $(Kconfig) + $< $(silent) $(Kconfig) gconfig: $(obj)/gconf - $< $(Kconfig) + $< $(silent) $(Kconfig) menuconfig: $(obj)/mconf - $< $(Kconfig) + $< $(silent) $(Kconfig) config: $(obj)/conf - $< --oldaskconfig $(Kconfig) + $< $(silent) --oldaskconfig $(Kconfig) nconfig: $(obj)/nconf - $< $(Kconfig) + $< $(silent) $(Kconfig) + +build_menuconfig: $(obj)/mconf -oldconfig: $(obj)/conf - $< --$@ $(Kconfig) +build_nconfig: $(obj)/nconf -silentoldconfig: $(obj)/conf - $(Q)mkdir -p include/config include/generated - $< --$@ $(Kconfig) +build_gconfig: $(obj)/gconf -localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf - $(Q)mkdir -p include/config include/generated - $(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config +build_xconfig: $(obj)/qconf + +localyesconfig localmodconfig: $(obj)/conf + $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config $(Q)if [ -f .config ]; then \ cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ mv -f .tmp.config .config; \ - $(obj)/conf --silentoldconfig $(Kconfig); \ + $< $(silent) --oldconfig $(Kconfig); \ mv -f .config.old.1 .config.old) \ else \ mv -f .tmp.config .config; \ - $(obj)/conf --silentoldconfig $(Kconfig); \ + $< $(silent) --oldconfig $(Kconfig); \ fi $(Q)rm -f .tmp.config -# Create new linux.pot file -# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files -update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h - $(Q)echo " GEN config.pot" - $(Q)xgettext --default-domain=linux \ - --add-comments --keyword=_ --keyword=N_ \ - --from-code=UTF-8 \ - --files-from=$(srctree)/scripts/kconfig/POTFILES.in \ - --directory=$(srctree) --directory=$(objtree) \ - --output $(obj)/config.pot - $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot - $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ - $(srctree)/arch/*/um/Kconfig`; \ - do \ - echo " GEN $$i"; \ - $(obj)/kxgettext $$i \ - >> $(obj)/config.pot; \ - done ) - $(Q)echo " GEN linux.pot" - $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ - --output $(obj)/linux.pot - $(Q)rm -f $(obj)/config.pot - -PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig - -allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf - $< --$@ $(Kconfig) - -PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig - -listnewconfig olddefconfig: $(obj)/conf - $< --$@ $(Kconfig) - -# oldnoconfig is an alias of olddefconfig, because people already are dependent -# on its behavior(sets new symbols to their default value but not 'n') with the -# counter-intuitive name. -oldnoconfig: $(obj)/conf - $< --olddefconfig $(Kconfig) +# These targets map 1:1 to the commandline options of 'conf' +# +# Note: +# syncconfig has become an internal implementation detail and is now +# deprecated for external use +simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ + alldefconfig randconfig listnewconfig olddefconfig syncconfig +PHONY += $(simple-targets) + +$(simple-targets): $(obj)/conf + $< $(silent) --$@ $(Kconfig) + +PHONY += savedefconfig defconfig savedefconfig: $(obj)/conf - $< --$@=defconfig $(Kconfig) + $< $(silent) --$@=defconfig $(Kconfig) defconfig: $(obj)/conf ifeq ($(KBUILD_DEFCONFIG),) - $< --defconfig $(Kconfig) + $< $(silent) --defconfig $(Kconfig) +else +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) + @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" + $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) else - @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" - $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) + @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" + $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) +endif endif %_defconfig: $(obj)/conf - $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) + $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) -configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(SRCARCH)/configs/$(1).config) +configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@) -define mergeconfig -$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) -$(if $(call configfiles,$(1)),, $(error No configuration exists for this target on this architecture)) -$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(call configfiles,$(1)) -$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig -endef +%.config: $(obj)/conf + $(if $(call configfiles),, $(error No configuration exists for this target on this architecture)) + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles) + +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig PHONY += kvmconfig -kvmconfig: - $(call mergeconfig,kvm_guest) +kvmconfig: kvm_guest.config + @: + +PHONY += xenconfig +xenconfig: xen.config + @: PHONY += tinyconfig -tinyconfig: allnoconfig - $(call mergeconfig,tiny) +tinyconfig: + $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config + +# CHECK: -o cache_dir= working? +PHONY += testconfig +testconfig: $(obj)/conf + $(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ + -o cache_dir=$(abspath $(obj)/tests/.cache) \ + $(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no) +clean-dirs += tests/.cache # Help text used by make help help: @echo ' config - Update current config utilising a line-oriented program' @echo ' nconfig - Update current config utilising a ncurses menu based program' @echo ' menuconfig - Update current config utilising a menu based program' - @echo ' xconfig - Update current config utilising a QT based front-end' - @echo ' gconfig - Update current config utilising a GTK based front-end' + @echo ' xconfig - Update current config utilising a Qt based front-end' + @echo ' gconfig - Update current config utilising a GTK+ based front-end' @echo ' oldconfig - Update current config utilising a provided .config as base' @echo ' localmodconfig - Update current config disabling modules not loaded' @echo ' localyesconfig - Update current config converting local mods to core' - @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' @echo ' defconfig - New config with default from ARCH supplied defconfig' @echo ' savedefconfig - Save current config as ./defconfig (minimal config)' @echo ' allnoconfig - New config where all options are answered with no' @@ -140,173 +134,83 @@ help: @echo ' alldefconfig - New config with all symbols set to default' @echo ' randconfig - New config with random answer to all options' @echo ' listnewconfig - List new options' - @echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value' - @echo ' kvmconfig - Enable additional options for guest kernel support' + @echo ' olddefconfig - Same as oldconfig but sets new symbols to their' + @echo ' default value without prompting' + @echo ' kvmconfig - Enable additional options for kvm guest kernel support' + @echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support' @echo ' tinyconfig - Configure the tiniest possible kernel' - -# lxdialog stuff -check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh - -# Use recursively expanded variables so we do not call gcc unless -# we really need to do so. (Do not call gcc as part of make mrproper) -HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ - -DLOCALE + @echo ' testconfig - Run Kconfig unit tests (requires python3 and pytest)' # =========================================================================== # Shared Makefile for the various kconfig executables: # conf: Used for defconfig, oldconfig and related targets -# nconf: Used for the nconfig target. -# Utilizes ncurses -# mconf: Used for the menuconfig target -# Utilizes the lxdialog package -# qconf: Used for the xconfig target -# Based on QT which needs to be installed to compile it -# gconf: Used for the gconfig target -# Based on GTK which needs to be installed to compile it # object files used by all kconfig flavours -lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o -lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o - conf-objs := conf.o zconf.tab.o -mconf-objs := mconf.o zconf.tab.o $(lxdialog) -nconf-objs := nconf.o zconf.tab.o nconf.gui.o -kxgettext-objs := kxgettext.o zconf.tab.o -qconf-cxxobjs := qconf.o -qconf-objs := zconf.tab.o -gconf-objs := gconf.o zconf.tab.o - -hostprogs-y := conf nconf mconf kxgettext qconf gconf - -clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck -clean-files += zconf.hash.c gconf.glade.h -clean-files += config.pot linux.pot -# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) -PHONY += $(obj)/dochecklxdialog -$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog -$(obj)/dochecklxdialog: - $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLDLIBS_mconf) +hostprogs-y := conf -always := dochecklxdialog - -# Add environment specific flags -HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)) +targets += zconf.lex.c # generated files seem to need this to find local include files HOSTCFLAGS_zconf.lex.o := -I$(src) HOSTCFLAGS_zconf.tab.o := -I$(src) -LEX_PREFIX_zconf := zconf -YACC_PREFIX_zconf := zconf - -HOSTLDLIBS_qconf = $(KC_QT_LIBS) -HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) - -HOSTLDLIBS_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ - -Wno-missing-prototypes - -HOSTLDLIBS_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) - -HOSTLDLIBS_nconf = $(shell \ - pkg-config --libs menuw panelw ncursesw 2>/dev/null \ - || pkg-config --libs menu panel ncurses 2>/dev/null \ - || echo "-lmenu -lpanel -lncurses" ) -$(obj)/qconf.o: $(obj)/.tmp_qtcheck - -ifeq ($(MAKECMDGOALS),xconfig) -$(obj)/.tmp_qtcheck: $(src)/Makefile --include $(obj)/.tmp_qtcheck - -# QT needs some extra effort... -$(obj)/.tmp_qtcheck: - @set -e; echo " CHECK qt"; dir=""; pkg=""; \ - if ! pkg-config --exists QtCore 2> /dev/null; then \ - echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \ - pkg-config --exists qt 2> /dev/null && pkg=qt; \ - pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ - if [ -n "$$pkg" ]; then \ - cflags="\$$(shell pkg-config $$pkg --cflags)"; \ - libs="\$$(shell pkg-config $$pkg --libs)"; \ - moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ - dir="$$(pkg-config $$pkg --variable=prefix)"; \ - else \ - for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ - if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ - done; \ - if [ -z "$$dir" ]; then \ - echo >&2 "*"; \ - echo >&2 "* Unable to find any QT installation. Please make sure that"; \ - echo >&2 "* the QT4 or QT3 development package is correctly installed and"; \ - echo >&2 "* either qmake can be found or install pkg-config or set"; \ - echo >&2 "* the QTDIR environment variable to the correct location."; \ - echo >&2 "*"; \ - false; \ - fi; \ - libpath=$$dir/lib; lib=qt; osdir=""; \ - $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ - osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ - test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ - test -f $$libpath/libqt-mt.so && lib=qt-mt; \ - cflags="-I$$dir/include"; \ - libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ - moc="$$dir/bin/moc"; \ - fi; \ - if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \ - echo "*"; \ - echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \ - echo "*"; \ - moc="/usr/bin/moc"; \ - fi; \ - else \ - cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \ - libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \ - moc="\$$(shell pkg-config QtCore --variable=moc_location)"; \ - [ -n "$$moc" ] || moc="\$$(shell pkg-config QtCore --variable=prefix)/bin/moc"; \ - fi; \ - echo "KC_QT_CFLAGS=$$cflags" > $@; \ - echo "KC_QT_LIBS=$$libs" >> $@; \ - echo "KC_QT_MOC=$$moc" >> $@ -endif +# nconf: Used for the nconfig target based on ncurses +hostprogs-y += nconf +nconf-objs := nconf.o zconf.tab.o nconf.gui.o -$(obj)/gconf.o: $(obj)/.tmp_gtkcheck - -ifeq ($(MAKECMDGOALS),gconfig) --include $(obj)/.tmp_gtkcheck - -# GTK needs some extra effort, too... -$(obj)/.tmp_gtkcheck: - @if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ - if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \ - touch $@; \ - else \ - echo >&2 "*"; \ - echo >&2 "* GTK+ is present but version >= 2.0.0 is required."; \ - echo >&2 "*"; \ - false; \ - fi \ - else \ - echo >&2 "*"; \ - echo >&2 "* Unable to find the GTK+ installation. Please make sure that"; \ - echo >&2 "* the GTK+ 2.0 development package is correctly installed..."; \ - echo >&2 "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ - echo >&2 "*"; \ - false; \ - fi -endif +HOSTLDLIBS_nconf = $(shell . $(obj)/.nconf-cfg && echo $$libs) +HOSTCFLAGS_nconf.o = $(shell . $(obj)/.nconf-cfg && echo $$cflags) +HOSTCFLAGS_nconf.gui.o = $(shell . $(obj)/.nconf-cfg && echo $$cflags) + +$(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/.nconf-cfg -$(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c +# mconf: Used for the menuconfig target based on lxdialog +hostprogs-y += mconf +lxdialog := checklist.o inputbox.o menubox.o textbox.o util.o yesno.o +mconf-objs := mconf.o zconf.tab.o $(addprefix lxdialog/, $(lxdialog)) + +HOSTLDLIBS_mconf = $(shell . $(obj)/.mconf-cfg && echo $$libs) +$(foreach f, mconf.o $(lxdialog), \ + $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/.mconf-cfg && echo $$$$cflags))) + +$(obj)/mconf.o: $(obj)/.mconf-cfg +$(addprefix $(obj)/lxdialog/, $(lxdialog)): $(obj)/.mconf-cfg + +# qconf: Used for the xconfig target based on Qt +hostprogs-y += qconf +qconf-cxxobjs := qconf.o +qconf-objs := zconf.tab.o -$(obj)/qconf.o: $(obj)/qconf.moc +HOSTLDLIBS_qconf = $(shell . $(obj)/.qconf-cfg && echo $$libs) +HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/.qconf-cfg && echo $$cflags) + +$(obj)/qconf.o: $(obj)/.qconf-cfg $(obj)/qconf.moc quiet_cmd_moc = MOC $@ - cmd_moc = $(KC_QT_MOC) -i $< -o $@ + cmd_moc = $(shell . $(obj)/.qconf-cfg && echo $$moc) -i $< -o $@ -$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck +$(obj)/%.moc: $(src)/%.h $(obj)/.qconf-cfg $(call cmd,moc) -# Extract gconf menu items for I18N support -$(obj)/gconf.glade.h: $(obj)/gconf.glade - $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ - $(obj)/gconf.glade +# gconf: Used for the gconfig target based on GTK+ +hostprogs-y += gconf +gconf-objs := gconf.o zconf.tab.o + +HOSTLDLIBS_gconf = $(shell . $(obj)/.gconf-cfg && echo $$libs) +HOSTCFLAGS_gconf.o = $(shell . $(obj)/.gconf-cfg && echo $$cflags) + +$(obj)/gconf.o: $(obj)/.gconf-cfg + +$(obj)/zconf.tab.o: $(obj)/zconf.lex.c + +# check if necessary packages are available, and configure build flags +define filechk_conf_cfg + $(CONFIG_SHELL) $< +endef + +$(obj)/.%conf-cfg: $(src)/%conf-cfg.sh FORCE + $(call filechk,conf_cfg) + +clean-files += .*conf-cfg diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in deleted file mode 100644 index 9674573969..0000000000 --- a/scripts/kconfig/POTFILES.in +++ /dev/null @@ -1,12 +0,0 @@ -scripts/kconfig/lxdialog/checklist.c -scripts/kconfig/lxdialog/inputbox.c -scripts/kconfig/lxdialog/menubox.c -scripts/kconfig/lxdialog/textbox.c -scripts/kconfig/lxdialog/util.c -scripts/kconfig/lxdialog/yesno.c -scripts/kconfig/mconf.c -scripts/kconfig/conf.c -scripts/kconfig/confdata.c -scripts/kconfig/gconf.c -scripts/kconfig/gconf.glade.h -scripts/kconfig/qconf.cc diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh deleted file mode 100755 index 55b79ba1ba..0000000000 --- a/scripts/kconfig/check.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Needed for systems without gettext -$* -x c -o /dev/null - > /dev/null 2>&1 << EOF -#include -int main() -{ - gettext(""); - return 0; -} -EOF -if [ ! "$?" -eq "0" ]; then - echo -DKBUILD_NO_NLS; -fi diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index fef75fc756..98e0c7a346 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -3,8 +3,8 @@ * Released under the terms of the GNU GPL v2.0. */ -#include #include +#include #include #include #include @@ -19,11 +19,10 @@ static void conf(struct menu *menu); static void check_conf(struct menu *menu); -static void xfgets(char *str, int size, FILE *in); enum input_mode { oldaskconfig, - silentoldconfig, + syncconfig, oldconfig, allnoconfig, allyesconfig, @@ -34,14 +33,14 @@ enum input_mode { savedefconfig, listnewconfig, olddefconfig, -} input_mode = oldaskconfig; +}; +static enum input_mode input_mode = oldaskconfig; static int indent = 1; static int tty_stdio; -static int valid_stdin = 1; static int sync_kconfig; static int conf_cnt; -static char line[128]; +static char line[PATH_MAX]; static struct menu *rootEntry; static void print_help(struct menu *menu) @@ -71,14 +70,14 @@ static void strip(char *str) *p-- = 0; } -static void check_stdin(void) +/* Helper function to facilitate fgets() by Jean Sacren. */ +static void xfgets(char *str, int size, FILE *in) { - if (!valid_stdin) { - printf(_("aborted!\n\n")); - printf(_("Console input/output is redirected. ")); - printf(_("Run 'make oldconfig' to update configuration.\n\n")); - exit(1); - } + if (!fgets(str, size, in)) + fprintf(stderr, "\nError in reading or end of file.\n"); + + if (!tty_stdio) + printf("%s", str); } static int conf_askvalue(struct symbol *sym, const char *def) @@ -86,7 +85,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) enum symbol_type type = sym_get_type(sym); if (!sym_has_value(sym)) - printf(_("(NEW) ")); + printf("(NEW) "); line[0] = '\n'; line[1] = 0; @@ -100,18 +99,15 @@ static int conf_askvalue(struct symbol *sym, const char *def) switch (input_mode) { case oldconfig: - case silentoldconfig: + case syncconfig: if (sym_has_value(sym)) { printf("%s\n", def); return 0; } - check_stdin(); /* fall through */ case oldaskconfig: fflush(stdout); - xfgets(line, 128, stdin); - if (!tty_stdio) - printf("\n"); + xfgets(line, sizeof(line), stdin); return 1; default: break; @@ -136,7 +132,7 @@ static int conf_string(struct menu *menu) const char *def; while (1) { - printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); + printf("%*s%s ", indent - 1, "", menu->prompt->text); printf("(%s) ", sym->name); def = sym_get_string_value(sym); if (sym_get_string_value(sym)) @@ -169,7 +165,7 @@ static int conf_sym(struct menu *menu) tristate oldval, newval; while (1) { - printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); + printf("%*s%s ", indent - 1, "", menu->prompt->text); if (sym->name) printf("(%s) ", sym->name); putchar('['); @@ -191,9 +187,7 @@ static int conf_sym(struct menu *menu) printf("/m"); if (oldval != yes && sym_tristate_within_range(sym, yes)) printf("/y"); - if (menu_has_help(menu)) - printf("/?"); - printf("] "); + printf("/?] "); if (!conf_askvalue(sym, sym_get_string_value(sym))) return 0; strip(line); @@ -256,7 +250,7 @@ static int conf_choice(struct menu *menu) case no: return 1; case mod: - printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); return 0; case yes: break; @@ -266,7 +260,7 @@ static int conf_choice(struct menu *menu) while (1) { int cnt, def; - printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); def_sym = sym_get_choice_value(sym); cnt = def = 0; line[0] = 0; @@ -274,7 +268,7 @@ static int conf_choice(struct menu *menu) if (!menu_is_visible(child)) continue; if (!child->sym) { - printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); + printf("%*c %s\n", indent, '*', menu_get_prompt(child)); continue; } cnt++; @@ -283,35 +277,31 @@ static int conf_choice(struct menu *menu) printf("%*c", indent, '>'); } else printf("%*c", indent, ' '); - printf(" %d. %s", cnt, _(menu_get_prompt(child))); + printf(" %d. %s", cnt, menu_get_prompt(child)); if (child->sym->name) printf(" (%s)", child->sym->name); if (!sym_has_value(child->sym)) - printf(_(" (NEW)")); + printf(" (NEW)"); printf("\n"); } - printf(_("%*schoice"), indent - 1, ""); + printf("%*schoice", indent - 1, ""); if (cnt == 1) { printf("[1]: 1\n"); goto conf_childs; } - printf("[1-%d", cnt); - if (menu_has_help(menu)) - printf("?"); - printf("]: "); + printf("[1-%d?]: ", cnt); switch (input_mode) { case oldconfig: - case silentoldconfig: + case syncconfig: if (!is_new) { cnt = def; printf("%d\n", cnt); break; } - check_stdin(); /* fall through */ case oldaskconfig: fflush(stdout); - xfgets(line, 128, stdin); + xfgets(line, sizeof(line), stdin); strip(line); if (line[0] == '?') { print_help(menu); @@ -367,10 +357,11 @@ static void conf(struct menu *menu) switch (prop->type) { case P_MENU: - if ((input_mode == silentoldconfig || - input_mode == listnewconfig || - input_mode == olddefconfig) && - rootEntry != menu) { + /* + * Except in oldaskconfig mode, we show only menus that + * contain new symbols. + */ + if (input_mode != oldaskconfig && rootEntry != menu) { check_conf(menu); return; } @@ -380,7 +371,7 @@ static void conf(struct menu *menu) if (prompt) printf("%*c\n%*c %s\n%*c\n", indent, '*', - indent, '*', _(prompt), + indent, '*', prompt, indent, '*'); default: ; @@ -430,12 +421,22 @@ static void check_conf(struct menu *menu) if (sym_is_changable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { if (input_mode == listnewconfig) { - if (sym->name && !sym_is_choice_value(sym)) { - printf("%s%s\n", CONFIG_, sym->name); + if (sym->name) { + const char *str; + + if (sym->type == S_STRING) { + str = sym_get_string_value(sym); + str = sym_escape_string_value(str); + printf("%s%s=%s\n", CONFIG_, sym->name, str); + free((void *)str); + } else { + str = sym_get_string_value(sym); + printf("%s%s=%s\n", CONFIG_, sym->name, str); + } } - } else if (input_mode != olddefconfig) { + } else { if (!conf_cnt++) - printf(_("*\n* Restart config...\n*\n")); + printf("*\n* Restart config...\n*\n"); rootEntry = menu_get_parent_menu(menu); conf(rootEntry); } @@ -449,7 +450,7 @@ static void check_conf(struct menu *menu) static struct option long_opts[] = { {"oldaskconfig", no_argument, NULL, oldaskconfig}, {"oldconfig", no_argument, NULL, oldconfig}, - {"silentoldconfig", no_argument, NULL, silentoldconfig}, + {"syncconfig", no_argument, NULL, syncconfig}, {"defconfig", optional_argument, NULL, defconfig}, {"savedefconfig", required_argument, NULL, savedefconfig}, {"allnoconfig", no_argument, NULL, allnoconfig}, @@ -459,26 +460,20 @@ static struct option long_opts[] = { {"randconfig", no_argument, NULL, randconfig}, {"listnewconfig", no_argument, NULL, listnewconfig}, {"olddefconfig", no_argument, NULL, olddefconfig}, - /* - * oldnoconfig is an alias of olddefconfig, because people already - * are dependent on its behavior(sets new symbols to their default - * value but not 'n') with the counter-intuitive name. - */ - {"oldnoconfig", no_argument, NULL, olddefconfig}, {NULL, 0, NULL, 0} }; static void conf_usage(const char *progname) { - printf("Usage: %s [option] \n", progname); + printf("Usage: %s [-s] [option] \n", progname); printf("[option] is _one_ of the following:\n"); printf(" --listnewconfig List new options\n"); printf(" --oldaskconfig Start a new configuration using a line-oriented program\n"); printf(" --oldconfig Update a configuration using a provided .config as base\n"); - printf(" --silentoldconfig Same as oldconfig, but quietly, additionally update deps\n"); - printf(" --olddefconfig Same as silentoldconfig but sets new symbols to their default value\n"); - printf(" --oldnoconfig An alias of olddefconfig\n"); + printf(" --syncconfig Similar to oldconfig but generates configuration in\n" + " include/{generated/,config/}\n"); + printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n"); printf(" --defconfig New config with default defined in \n"); printf(" --savedefconfig Save the minimal current configuration to \n"); printf(" --allnoconfig New config where all options are answered with no\n"); @@ -494,17 +489,23 @@ int main(int ac, char **av) int opt; const char *name, *defconfig_file = NULL /* gcc uninit */; struct stat tmpstat; + int no_conf_write = 0; - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); + tty_stdio = isatty(0) && isatty(1); - tty_stdio = isatty(0) && isatty(1) && isatty(2); - - while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) { + while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) { + if (opt == 's') { + conf_set_message_callback(NULL); + continue; + } input_mode = (enum input_mode)opt; switch (opt) { - case silentoldconfig: + case syncconfig: + /* + * syncconfig is invoked during the build stage. + * Suppress distracting "configuration written to ..." + */ + conf_set_message_callback(NULL); sync_kconfig = 1; break; case defconfig: @@ -552,7 +553,7 @@ int main(int ac, char **av) } } if (ac == optind) { - printf(_("%s: Kconfig file missing\n"), av[0]); + fprintf(stderr, "%s: Kconfig file missing\n", av[0]); conf_usage(progname); exit(1); } @@ -562,12 +563,12 @@ int main(int ac, char **av) if (sync_kconfig) { name = conf_get_configname(); if (stat(name, &tmpstat)) { - fprintf(stderr, _("***\n" + fprintf(stderr, "***\n" "*** Configuration file \"%s\" not found!\n" "***\n" "*** Please run some configurator (e.g. \"make oldconfig\" or\n" "*** \"make menuconfig\" or \"make xconfig\").\n" - "***\n"), name); + "***\n", name); exit(1); } } @@ -577,14 +578,16 @@ int main(int ac, char **av) if (!defconfig_file) defconfig_file = conf_get_default_confname(); if (conf_read(defconfig_file)) { - printf(_("***\n" - "*** Can't find default configuration \"%s\"!\n" - "***\n"), defconfig_file); + fprintf(stderr, + "***\n" + "*** Can't find default configuration \"%s\"!\n" + "***\n", + defconfig_file); exit(1); } break; case savedefconfig: - case silentoldconfig: + case syncconfig: case oldaskconfig: case oldconfig: case listnewconfig: @@ -602,7 +605,7 @@ int main(int ac, char **av) if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { if (conf_read_simple(name, S_DEF_USER)) { fprintf(stderr, - _("*** Can't read seed configuration \"%s\"!\n"), + "*** Can't read seed configuration \"%s\"!\n", name); exit(1); } @@ -619,7 +622,7 @@ int main(int ac, char **av) if (conf_read_simple(name, S_DEF_USER) && conf_read_simple("all.config", S_DEF_USER)) { fprintf(stderr, - _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), + "*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n", name); exit(1); } @@ -629,15 +632,15 @@ int main(int ac, char **av) } if (sync_kconfig) { - if (conf_get_changed()) { - name = getenv("KCONFIG_NOSILENTUPDATE"); - if (name && *name) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + if (conf_get_changed()) { fprintf(stderr, - _("\n*** The configuration requires explicit update.\n\n")); + "\n*** The configuration requires explicit update.\n\n"); return 1; } + no_conf_write = 1; } - valid_stdin = tty_stdio; } switch (input_mode) { @@ -665,54 +668,48 @@ int main(int ac, char **av) case oldaskconfig: rootEntry = &rootmenu; conf(&rootmenu); - input_mode = silentoldconfig; + input_mode = oldconfig; /* fall through */ case oldconfig: case listnewconfig: - case olddefconfig: - case silentoldconfig: + case syncconfig: /* Update until a loop caused no more changes */ do { conf_cnt = 0; check_conf(&rootmenu); - } while (conf_cnt && - (input_mode != listnewconfig && - input_mode != olddefconfig)); + } while (conf_cnt); + break; + case olddefconfig: + default: break; } - if (sync_kconfig) { - /* silentoldconfig is used during the build so we shall update autoconf. - * All other commands are only used to generate a config. - */ - if (conf_get_changed() && conf_write(NULL)) { - fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); - exit(1); - } - if (conf_write_autoconf()) { - fprintf(stderr, _("\n*** Error during update of the configuration.\n\n")); - return 1; - } - } else if (input_mode == savedefconfig) { + if (input_mode == savedefconfig) { if (conf_write_defconfig(defconfig_file)) { - fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), + fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n", defconfig_file); return 1; } } else if (input_mode != listnewconfig) { - if (conf_write(NULL)) { - fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); + if (!no_conf_write && conf_write(NULL)) { + fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); exit(1); } + + /* + * Create auto.conf if it does not exist. + * This prevents GNU Make 4.1 or older from emitting + * "include/config/auto.conf: No such file or directory" + * in the top-level Makefile + * + * syncconfig always creates or updates auto.conf because it is + * used during the build. + */ + if (conf_write_autoconf(sync_kconfig) && sync_kconfig) { + fprintf(stderr, + "\n*** Error during sync of the configuration.\n\n"); + return 1; + } } return 0; } - -/* - * 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/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index ce12bd555f..91d0a5c014 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -16,6 +16,69 @@ #include "lkc.h" +/* return true if 'path' exists, false otherwise */ +static bool is_present(const char *path) +{ + struct stat st; + + return !stat(path, &st); +} + +/* return true if 'path' exists and it is a directory, false otherwise */ +static bool is_dir(const char *path) +{ + struct stat st; + + if (stat(path, &st)) + return 0; + + return S_ISDIR(st.st_mode); +} + +/* + * Create the parent directory of the given path. + * + * For example, if 'include/config/auto.conf' is given, create 'include/config'. + */ +static int make_parent_dir(const char *path) +{ + char tmp[PATH_MAX + 1]; + char *p; + + strncpy(tmp, path, sizeof(tmp)); + tmp[sizeof(tmp) - 1] = 0; + + /* Remove the base name. Just return if nothing is left */ + p = strrchr(tmp, '/'); + if (!p) + return 0; + *(p + 1) = 0; + + /* Just in case it is an absolute path */ + p = tmp; + while (*p == '/') + p++; + + while ((p = strchr(p, '/'))) { + *p = 0; + + /* skip if the directory exists */ + if (!is_dir(tmp) && mkdir(tmp, 0755)) + return -1; + + *p = '/'; + while (*p == '/') + p++; + } + + return 0; +} + +struct conf_printer { + void (*print_symbol)(FILE *, struct symbol *, const char *, void *); + void (*print_comment)(FILE *, const char *, void *); +}; + static void conf_warning(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); @@ -23,9 +86,9 @@ static void conf_message(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); static const char *conf_filename; -static int conf_lineno, conf_warnings, conf_unsaved; +static int conf_lineno, conf_warnings; -const char conf_defname[] = "arch/$ARCH/defconfig"; +const char conf_defname[] = "arch/$(ARCH)/defconfig"; static void conf_warning(const char *fmt, ...) { @@ -38,16 +101,16 @@ static void conf_warning(const char *fmt, ...) conf_warnings++; } -static void conf_default_message_callback(const char *fmt, va_list ap) +static void conf_default_message_callback(const char *s) { printf("#\n# "); - vprintf(fmt, ap); + printf("%s", s); printf("\n#\n"); } -static void (*conf_message_callback) (const char *fmt, va_list ap) = +static void (*conf_message_callback)(const char *s) = conf_default_message_callback; -void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) +void conf_set_message_callback(void (*fn)(const char *s)) { conf_message_callback = fn; } @@ -55,10 +118,16 @@ void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) static void conf_message(const char *fmt, ...) { va_list ap; + char buf[4096]; + + if (!conf_message_callback) + return; va_start(ap, fmt); - if (conf_message_callback) - conf_message_callback(fmt, ap); + + vsnprintf(buf, sizeof(buf), fmt, ap); + conf_message_callback(buf); + va_end(ap); } const char *conf_get_configname(void) @@ -75,43 +144,16 @@ const char *conf_get_autoconfig_name(void) return name ? name : "include/config/auto.conf"; } -static char *conf_expand_value(const char *in) -{ - struct symbol *sym; - const char *src; - static char res_value[SYMBOL_MAXLENGTH]; - char *dst, name[SYMBOL_MAXLENGTH]; - - res_value[0] = 0; - dst = name; - while ((src = strchr(in, '$'))) { - strncat(res_value, in, src - in); - src++; - dst = name; - while (isalnum(*src) || *src == '_') - *dst++ = *src++; - *dst = 0; - sym = sym_lookup(name, 0); - sym_calc_value(sym); - strcat(res_value, sym_get_string_value(sym)); - in = src; - } - strcat(res_value, in); - - return res_value; -} - char *conf_get_default_confname(void) { - struct stat buf; static char fullname[PATH_MAX+1]; char *env, *name; - name = conf_expand_value(conf_defname); + name = expand_string(conf_defname); env = getenv(SRCTREE); if (env) { sprintf(fullname, "%s/%s", env, name); - if (!stat(fullname, &buf)) + if (is_present(fullname)) return fullname; } return name; @@ -172,7 +214,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) case S_HEX: done: if (sym_string_valid(sym, p)) { - sym->def[def].val = strdup(p); + sym->def[def].val = xstrdup(p); sym->flags |= def_flags; } else { if (def != S_DEF_AUTO) @@ -195,7 +237,7 @@ static int add_byte(int c, char **lineptr, size_t slen, size_t *n) if (new_size > *n) { new_size += LINE_GROWTH - 1; new_size *= 2; - nline = realloc(*lineptr, new_size); + nline = xrealloc(*lineptr, new_size); if (!nline) return -1; @@ -261,20 +303,18 @@ int conf_read_simple(const char *name, int def) if (in) goto load; sym_add_change_count(1); - if (!sym_defconfig_list) { - if (modules_sym) - sym_calc_value(modules_sym); + if (!sym_defconfig_list) return 1; - } for_all_defaults(sym_defconfig_list, prop) { if (expr_calc_value(prop->visible.expr) == no || prop->expr->type != E_SYMBOL) continue; - name = conf_expand_value(prop->expr->left.sym->name); + sym_calc_value(prop->expr->left.sym); + name = sym_get_string_value(prop->expr->left.sym); in = zconf_fopen(name); if (in) { - conf_message(_("using defaults found in %s"), + conf_message("using defaults found in %s", name); goto load; } @@ -287,7 +327,6 @@ load: conf_filename = name; conf_lineno = 0; conf_warnings = 0; - conf_unsaved = 0; def_flags = SYMBOL_DEF << def; for_all_symbols(i, sym) { @@ -372,7 +411,9 @@ load: continue; } else { if (line[0] != '\r' && line[0] != '\n') - conf_warning("unexpected data"); + conf_warning("unexpected data: %.*s", + (int)strcspn(line, "\r\n"), line); + continue; } setsym: @@ -398,25 +439,27 @@ setsym: } free(line); fclose(in); - - if (modules_sym) - sym_calc_value(modules_sym); return 0; } int conf_read(const char *name) { struct symbol *sym; + int conf_unsaved = 0; int i; sym_set_change_count(0); - if (conf_read_simple(name, S_DEF_USER)) + if (conf_read_simple(name, S_DEF_USER)) { + sym_calc_value(modules_sym); return 1; + } + + sym_calc_value(modules_sym); for_all_symbols(i, sym) { sym_calc_value(sym); - if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) + if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) continue; if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { /* check that calculated value agrees with saved value */ @@ -744,10 +787,9 @@ int conf_write(const char *name) dirname[0] = 0; if (name && name[0]) { - struct stat st; char *slash; - if (!stat(name, &st) && S_ISDIR(st.st_mode)) { + if (is_dir(name)) { strcpy(dirname, name); strcat(dirname, "/"); basename = conf_get_configname(); @@ -825,32 +867,66 @@ next: return 1; } - conf_message(_("configuration written to %s"), newname); + conf_message("configuration written to %s", newname); sym_set_change_count(0); return 0; } +/* write a dependency file as used by kbuild to track dependencies */ +static int conf_write_dep(const char *name) +{ + struct file *file; + FILE *out; + + if (!name) + name = ".kconfig.d"; + out = fopen("..config.tmp", "w"); + if (!out) + return 1; + fprintf(out, "deps_config := \\\n"); + for (file = file_list; file; file = file->next) { + if (file->next) + fprintf(out, "\t%s \\\n", file->name); + else + fprintf(out, "\t%s\n", file->name); + } + fprintf(out, "\n%s: \\\n" + "\t$(deps_config)\n\n", conf_get_autoconfig_name()); + + env_write_dep(out, conf_get_autoconfig_name()); + + fprintf(out, "\n$(deps_config): ;\n"); + fclose(out); + + if (make_parent_dir(name)) + return 1; + rename("..config.tmp", name); + return 0; +} + static int conf_split_config(void) { const char *name; char path[PATH_MAX+1]; char *s, *d, c; struct symbol *sym; - struct stat sb; int res, i, fd; name = conf_get_autoconfig_name(); conf_read_simple(name, S_DEF_AUTO); + sym_calc_value(modules_sym); + if (make_parent_dir("include/config/foo.h")) + return 1; if (chdir("include/config")) return 1; res = 0; for_all_symbols(i, sym) { sym_calc_value(sym); - if ((sym->flags & SYMBOL_AUTO) || !sym->name) + if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) continue; if (sym->flags & SYMBOL_WRITE) { if (sym->flags & SYMBOL_DEF_AUTO) { @@ -915,19 +991,12 @@ static int conf_split_config(void) res = 1; break; } - /* - * Create directory components, - * unless they exist already. - */ - d = path; - while ((d = strchr(d, '/'))) { - *d = 0; - if (stat(path, &sb) && mkdir(path, 0755)) { - res = 1; - goto out; - } - *d++ = '/'; + + if (make_parent_dir(path)) { + res = 1; + goto out; } + /* Try it again. */ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { @@ -944,16 +1013,20 @@ out: return res; } -int conf_write_autoconf(void) +int conf_write_autoconf(int overwrite) { struct symbol *sym; const char *name; + const char *autoconf_name = conf_get_autoconfig_name(); FILE *out, *tristate, *out_h; int i; + if (!overwrite && is_present(autoconf_name)) + return 0; + sym_clear_all_valid(); - file_write_dep("include/config/auto.conf.cmd"); + conf_write_dep("include/config/auto.conf.cmd"); if (conf_split_config()) return 1; @@ -1000,19 +1073,26 @@ int conf_write_autoconf(void) name = getenv("KCONFIG_AUTOHEADER"); if (!name) name = "include/generated/autoconf.h"; + if (make_parent_dir(name)) + return 1; if (rename(".tmpconfig.h", name)) return 1; + name = getenv("KCONFIG_TRISTATE"); if (!name) name = "include/config/tristate.conf"; + if (make_parent_dir(name)) + return 1; if (rename(".tmpconfig_tristate", name)) return 1; - name = conf_get_autoconfig_name(); + + if (make_parent_dir(autoconf_name)) + return 1; /* * This must be the last step, kbuild has a dependency on auto.conf * and this marks the successful completion of the previous steps. */ - if (rename(".tmpconfig", name)) + if (rename(".tmpconfig", autoconf_name)) return 1; return 0; @@ -1116,7 +1196,7 @@ void set_all_choice_values(struct symbol *csym) bool conf_set_all_new_symbols(enum conf_def_mode mode) { struct symbol *sym, *csym; - int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y + int i, cnt, pby, pty, ptm; /* pby: probability of bool = y * pty: probability of tristate = y * ptm: probability of tristate = m */ diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index d6626521f9..e1a39e9084 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -11,6 +11,9 @@ #define DEBUG_EXPR 0 +static int expr_eq(struct expr *e1, struct expr *e2); +static struct expr *expr_eliminate_yn(struct expr *e); + struct expr *expr_alloc_symbol(struct symbol *sym) { struct expr *e = xcalloc(1, sizeof(*e)); @@ -76,6 +79,10 @@ struct expr *expr_copy(const struct expr *org) e->left.expr = expr_copy(org->left.expr); break; case E_EQUAL: + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: e->left.sym = org->left.sym; e->right.sym = org->right.sym; @@ -87,7 +94,7 @@ struct expr *expr_copy(const struct expr *org) e->right.expr = expr_copy(org->right.expr); break; default: - printf("can't copy type %d\n", e->type); + fprintf(stderr, "can't copy type %d\n", e->type); free(e); e = NULL; break; @@ -106,8 +113,12 @@ void expr_free(struct expr *e) break; case E_NOT: expr_free(e->left.expr); - return; + break; case E_EQUAL: + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: break; case E_OR: @@ -116,7 +127,7 @@ void expr_free(struct expr *e) expr_free(e->right.expr); break; default: - printf("how to free type %d?\n", e->type); + fprintf(stderr, "how to free type %d?\n", e->type); break; } free(e); @@ -127,8 +138,18 @@ static int trans_count; #define e1 (*ep1) #define e2 (*ep2) +/* + * expr_eliminate_eq() helper. + * + * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does + * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared + * against all other leaves. Two equal leaves are both replaced with either 'y' + * or 'n' as appropriate for 'type', to be eliminated later. + */ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) { + /* Recurse down to leaves */ + if (e1->type == type) { __expr_eliminate_eq(type, &e1->left.expr, &e2); __expr_eliminate_eq(type, &e1->right.expr, &e2); @@ -139,12 +160,18 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e __expr_eliminate_eq(type, &e1, &e2->right.expr); return; } + + /* e1 and e2 are leaves. Compare them. */ + if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && e1->left.sym == e2->left.sym && (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) return; if (!expr_eq(e1, e2)) return; + + /* e1 and e2 are equal leaves. Prepare them for elimination. */ + trans_count++; expr_free(e1); expr_free(e2); switch (type) { @@ -161,6 +188,35 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e } } +/* + * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both. + * Example reductions: + * + * ep1: A && B -> ep1: y + * ep2: A && B && C -> ep2: C + * + * ep1: A || B -> ep1: n + * ep2: A || B || C -> ep2: C + * + * ep1: A && (B && FOO) -> ep1: FOO + * ep2: (BAR && B) && A -> ep2: BAR + * + * ep1: A && (B || C) -> ep1: y + * ep2: (C || B) && A -> ep2: y + * + * Comparisons are done between all operands at the same "level" of && or ||. + * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the + * following operands will be compared: + * + * - 'e1', 'e2 || e3', and 'e4 || e5', against each other + * - e2 against e3 + * - e4 against e5 + * + * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and + * '(e1 && e2) && e3' are both a single level. + * + * See __expr_eliminate_eq() as well. + */ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) { if (!e1 || !e2) @@ -186,7 +242,13 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) #undef e1 #undef e2 -int expr_eq(struct expr *e1, struct expr *e2) +/* + * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two + * &&/|| expressions are considered equal if every operand in one expression + * equals some operand in the other (operands do not need to appear in the same + * order), recursively. + */ +static int expr_eq(struct expr *e1, struct expr *e2) { int res, old_count; @@ -194,6 +256,10 @@ int expr_eq(struct expr *e1, struct expr *e2) return 0; switch (e1->type) { case E_EQUAL: + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; case E_SYMBOL: @@ -228,7 +294,18 @@ int expr_eq(struct expr *e1, struct expr *e2) return 0; } -struct expr *expr_eliminate_yn(struct expr *e) +/* + * Recursively performs the following simplifications in-place (as well as the + * corresponding simplifications with swapped operands): + * + * expr && n -> n + * expr && y -> expr + * expr || n -> expr + * expr || y -> y + * + * Returns the optimized expression. + */ +static struct expr *expr_eliminate_yn(struct expr *e) { struct expr *tmp; @@ -501,12 +578,21 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2) return NULL; } +/* + * expr_eliminate_dups() helper. + * + * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does + * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared + * against all other leaves to look for simplifications. + */ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) { #define e1 (*ep1) #define e2 (*ep2) struct expr *tmp; + /* Recurse down to leaves */ + if (e1->type == type) { expr_eliminate_dups1(type, &e1->left.expr, &e2); expr_eliminate_dups1(type, &e1->right.expr, &e2); @@ -517,6 +603,9 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr_eliminate_dups1(type, &e1, &e2->right.expr); return; } + + /* e1 and e2 are leaves. Compare and process them. */ + if (e1 == e2) return; @@ -553,62 +642,17 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct #undef e2 } -static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) -{ -#define e1 (*ep1) -#define e2 (*ep2) - struct expr *tmp, *tmp1, *tmp2; - - if (e1->type == type) { - expr_eliminate_dups2(type, &e1->left.expr, &e2); - expr_eliminate_dups2(type, &e1->right.expr, &e2); - return; - } - if (e2->type == type) { - expr_eliminate_dups2(type, &e1, &e2->left.expr); - expr_eliminate_dups2(type, &e1, &e2->right.expr); - } - if (e1 == e2) - return; - - switch (e1->type) { - case E_OR: - expr_eliminate_dups2(e1->type, &e1, &e1); - // (FOO || BAR) && (!FOO && !BAR) -> n - tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); - tmp2 = expr_copy(e2); - tmp = expr_extract_eq_and(&tmp1, &tmp2); - if (expr_is_yes(tmp1)) { - expr_free(e1); - e1 = expr_alloc_symbol(&symbol_no); - trans_count++; - } - expr_free(tmp2); - expr_free(tmp1); - expr_free(tmp); - break; - case E_AND: - expr_eliminate_dups2(e1->type, &e1, &e1); - // (FOO && BAR) || (!FOO || !BAR) -> y - tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); - tmp2 = expr_copy(e2); - tmp = expr_extract_eq_or(&tmp1, &tmp2); - if (expr_is_no(tmp1)) { - expr_free(e1); - e1 = expr_alloc_symbol(&symbol_yes); - trans_count++; - } - expr_free(tmp2); - expr_free(tmp1); - expr_free(tmp); - break; - default: - ; - } -#undef e1 -#undef e2 -} - +/* + * Rewrites 'e' in-place to remove ("join") duplicate and other redundant + * operands. + * + * Example simplifications: + * + * A || B || A -> A || B + * A && B && A=y -> A=y && B + * + * Returns the deduplicated expression. + */ struct expr *expr_eliminate_dups(struct expr *e) { int oldcount; @@ -621,11 +665,11 @@ struct expr *expr_eliminate_dups(struct expr *e) switch (e->type) { case E_OR: case E_AND: expr_eliminate_dups1(e->type, &e, &e); - expr_eliminate_dups2(e->type, &e, &e); default: ; } if (!trans_count) + /* No simplifications done in this pass. We're done */ break; e = expr_eliminate_yn(e); } @@ -633,6 +677,12 @@ struct expr *expr_eliminate_dups(struct expr *e) return e; } +/* + * Performs various simplifications involving logical operators and + * comparisons. + * + * Allocates and returns a new expression. + */ struct expr *expr_transform(struct expr *e) { struct expr *tmp; @@ -641,6 +691,10 @@ struct expr *expr_transform(struct expr *e) return NULL; switch (e->type) { case E_EQUAL: + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: case E_SYMBOL: case E_LIST: @@ -713,6 +767,22 @@ struct expr *expr_transform(struct expr *e) e = tmp; e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; break; + case E_LEQ: + case E_GEQ: + // !a<='x' -> a>'x' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = e->type == E_LEQ ? E_GTH : E_LTH; + break; + case E_LTH: + case E_GTH: + // !a<'x' -> a>='x' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = e->type == E_LTH ? E_GEQ : E_LEQ; + break; case E_OR: // !(a || b) -> !a && !b tmp = e->left.expr; @@ -783,6 +853,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym) case E_SYMBOL: return dep->left.sym == sym; case E_EQUAL: + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: return dep->left.sym == sym || dep->right.sym == sym; @@ -823,57 +897,20 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym) return false; } -struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) -{ - struct expr *tmp = NULL; - expr_extract_eq(E_AND, &tmp, ep1, ep2); - if (tmp) { - *ep1 = expr_eliminate_yn(*ep1); - *ep2 = expr_eliminate_yn(*ep2); - } - return tmp; -} - -struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) -{ - struct expr *tmp = NULL; - expr_extract_eq(E_OR, &tmp, ep1, ep2); - if (tmp) { - *ep1 = expr_eliminate_yn(*ep1); - *ep2 = expr_eliminate_yn(*ep2); - } - return tmp; -} - -void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) -{ -#define e1 (*ep1) -#define e2 (*ep2) - if (e1->type == type) { - expr_extract_eq(type, ep, &e1->left.expr, &e2); - expr_extract_eq(type, ep, &e1->right.expr, &e2); - return; - } - if (e2->type == type) { - expr_extract_eq(type, ep, ep1, &e2->left.expr); - expr_extract_eq(type, ep, ep1, &e2->right.expr); - return; - } - if (expr_eq(e1, e2)) { - *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; - expr_free(e2); - if (type == E_AND) { - e1 = expr_alloc_symbol(&symbol_yes); - e2 = expr_alloc_symbol(&symbol_yes); - } else if (type == E_OR) { - e1 = expr_alloc_symbol(&symbol_no); - e2 = expr_alloc_symbol(&symbol_no); - } - } -#undef e1 -#undef e2 -} - +/* + * Inserts explicit comparisons of type 'type' to symbol 'sym' into the + * expression 'e'. + * + * Examples transformations for type == E_UNEQUAL, sym == &symbol_no: + * + * A -> A!=n + * !A -> A=n + * A && B -> !(A=n || B=n) + * A || B -> !(A=n && B=n) + * A && (B || C) -> !(A=n || (B=n && C=n)) + * + * Allocates and returns a new expression. + */ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) { struct expr *e1, *e2; @@ -908,6 +945,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb case E_NOT: return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); case E_UNEQUAL: + case E_LTH: + case E_LEQ: + case E_GTH: + case E_GEQ: case E_EQUAL: if (type == E_EQUAL) { if (sym == &symbol_yes) @@ -935,10 +976,60 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb return NULL; } +enum string_value_kind { + k_string, + k_signed, + k_unsigned, + k_invalid +}; + +union string_value { + unsigned long long u; + signed long long s; +}; + +static enum string_value_kind expr_parse_string(const char *str, + enum symbol_type type, + union string_value *val) +{ + char *tail; + enum string_value_kind kind; + + errno = 0; + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + val->s = !strcmp(str, "n") ? 0 : + !strcmp(str, "m") ? 1 : + !strcmp(str, "y") ? 2 : -1; + return k_signed; + case S_INT: + val->s = strtoll(str, &tail, 10); + kind = k_signed; + break; + case S_HEX: + val->u = strtoull(str, &tail, 16); + kind = k_unsigned; + break; + case S_STRING: + case S_UNKNOWN: + val->s = strtoll(str, &tail, 0); + kind = k_signed; + break; + default: + return k_invalid; + } + return !errno && !*tail && tail > str && isxdigit(tail[-1]) + ? kind : k_string; +} + tristate expr_calc_value(struct expr *e) { tristate val1, val2; const char *str1, *str2; + enum string_value_kind k1 = k_string, k2 = k_string; + union string_value lval = {}, rval = {}; + int res; if (!e) return yes; @@ -959,31 +1050,70 @@ tristate expr_calc_value(struct expr *e) val1 = expr_calc_value(e->left.expr); return EXPR_NOT(val1); case E_EQUAL: - sym_calc_value(e->left.sym); - sym_calc_value(e->right.sym); - str1 = sym_get_string_value(e->left.sym); - str2 = sym_get_string_value(e->right.sym); - return !strcmp(str1, str2) ? yes : no; + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: - sym_calc_value(e->left.sym); - sym_calc_value(e->right.sym); - str1 = sym_get_string_value(e->left.sym); - str2 = sym_get_string_value(e->right.sym); - return !strcmp(str1, str2) ? no : yes; + break; default: printf("expr_calc_value: %d?\n", e->type); return no; } + + sym_calc_value(e->left.sym); + sym_calc_value(e->right.sym); + str1 = sym_get_string_value(e->left.sym); + str2 = sym_get_string_value(e->right.sym); + + if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) { + k1 = expr_parse_string(str1, e->left.sym->type, &lval); + k2 = expr_parse_string(str2, e->right.sym->type, &rval); + } + + if (k1 == k_string || k2 == k_string) + res = strcmp(str1, str2); + else if (k1 == k_invalid || k2 == k_invalid) { + if (e->type != E_EQUAL && e->type != E_UNEQUAL) { + printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2); + return no; + } + res = strcmp(str1, str2); + } else if (k1 == k_unsigned || k2 == k_unsigned) + res = (lval.u > rval.u) - (lval.u < rval.u); + else /* if (k1 == k_signed && k2 == k_signed) */ + res = (lval.s > rval.s) - (lval.s < rval.s); + + switch(e->type) { + case E_EQUAL: + return res ? no : yes; + case E_GEQ: + return res >= 0 ? yes : no; + case E_GTH: + return res > 0 ? yes : no; + case E_LEQ: + return res <= 0 ? yes : no; + case E_LTH: + return res < 0 ? yes : no; + case E_UNEQUAL: + return res ? yes : no; + default: + printf("expr_calc_value: relation %d?\n", e->type); + return no; + } } -int expr_compare_type(enum expr_type t1, enum expr_type t2) +static int expr_compare_type(enum expr_type t1, enum expr_type t2) { -#if 0 - return 1; -#else if (t1 == t2) return 0; switch (t1) { + case E_LEQ: + case E_LTH: + case E_GEQ: + case E_GTH: + if (t2 == E_EQUAL || t2 == E_UNEQUAL) + return 1; case E_EQUAL: case E_UNEQUAL: if (t2 == E_NOT) @@ -1005,52 +1135,11 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) } printf("[%dgt%d?]", t1, t2); return 0; -#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) +void expr_print(struct expr *e, + void (*fn)(void *, struct symbol *, const char *), + void *data, int prevtoken) { if (!e) { fn(data, NULL, "y"); @@ -1078,6 +1167,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * fn(data, NULL, "="); fn(data, e->right.sym, e->right.sym->name); break; + case E_LEQ: + case E_LTH: + if (e->left.sym->name) + fn(data, e->left.sym, e->left.sym->name); + else + fn(data, NULL, ""); + fn(data, NULL, e->type == E_LEQ ? "<=" : "<"); + fn(data, e->right.sym, e->right.sym->name); + break; + case E_GEQ: + case E_GTH: + if (e->left.sym->name) + fn(data, e->left.sym, e->left.sym->name); + else + fn(data, NULL, ""); + fn(data, NULL, e->type == E_GEQ ? ">=" : ">"); + fn(data, e->right.sym, e->right.sym->name); + break; case E_UNEQUAL: if (e->left.sym->name) fn(data, e->left.sym, e->left.sym->name); @@ -1166,3 +1273,33 @@ void expr_gstr_print(struct expr *e, struct gstr *gs) { expr_print(e, expr_print_gstr_helper, gs, E_NONE); } + +/* + * Transform the top level "||" tokens into newlines and prepend each + * line with a minus. This makes expressions much easier to read. + * Suitable for reverse dependency expressions. + */ +static void expr_print_revdep(struct expr *e, + void (*fn)(void *, struct symbol *, const char *), + void *data, tristate pr_type, const char **title) +{ + if (e->type == E_OR) { + expr_print_revdep(e->left.expr, fn, data, pr_type, title); + expr_print_revdep(e->right.expr, fn, data, pr_type, title); + } else if (expr_calc_value(e) == pr_type) { + if (*title) { + fn(data, NULL, *title); + *title = NULL; + } + + fn(data, NULL, " - "); + expr_print(e, fn, data, E_NONE); + fn(data, NULL, "\n"); + } +} + +void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, + tristate pr_type, const char *title) +{ + expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title); +} diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 412ea8a2ab..7c329e1790 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -29,7 +29,9 @@ typedef enum tristate { } tristate; enum expr_type { - E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE + E_NONE, E_OR, E_AND, E_NOT, + E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ, + E_LIST, E_SYMBOL, E_RANGE }; union expr_data { @@ -72,17 +74,61 @@ enum { S_DEF_COUNT }; +/* + * Represents a configuration symbol. + * + * Choices are represented as a special kind of symbol and have the + * SYMBOL_CHOICE bit set in 'flags'. + */ struct symbol { + /* The next symbol in the same bucket in the symbol hash table */ struct symbol *next; + + /* The name of the symbol, e.g. "FOO" for 'config FOO' */ char *name; + + /* S_BOOLEAN, S_TRISTATE, ... */ enum symbol_type type; + + /* + * The calculated value of the symbol. The SYMBOL_VALID bit is set in + * 'flags' when this is up to date. Note that this value might differ + * from the user value set in e.g. a .config file, due to visibility. + */ struct symbol_value curr; + + /* + * Values for the symbol provided from outside. def[S_DEF_USER] holds + * the .config value. + */ struct symbol_value def[S_DEF_COUNT]; + + /* + * An upper bound on the tristate value the user can set for the symbol + * if it is a boolean or tristate. Calculated from prompt dependencies, + * which also inherit dependencies from enclosing menus, choices, and + * ifs. If 'n', the user value will be ignored. + * + * Symbols lacking prompts always have visibility 'n'. + */ tristate visible; + + /* SYMBOL_* flags */ int flags; + + /* List of properties. See prop_type. */ struct property *prop; + + /* Dependencies from enclosing menus, choices, and ifs */ struct expr_value dir_dep; + + /* Reverse dependencies through being selected by other symbols */ struct expr_value rev_dep; + + /* + * "Weak" reverse dependencies through being implied by other symbols + */ + struct expr_value implied; }; #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) @@ -95,7 +141,7 @@ struct symbol { #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_CHANGED 0x0400 /* ? */ -#define SYMBOL_AUTO 0x1000 /* value from environment variable */ +#define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */ #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ #define SYMBOL_WARNED 0x8000 /* warning has been issued */ @@ -125,17 +171,20 @@ struct symbol { * config BAZ * int "BAZ Value" * range 1..255 + * + * Please, also check zconf.y:print_symbol() when modifying the + * list of property types! */ enum prop_type { P_UNKNOWN, P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ P_COMMENT, /* text associated with a comment */ - P_MENU, /* prompt associated with a menuconfig option */ + P_MENU, /* prompt associated with a menu or menuconfig symbol */ P_DEFAULT, /* default y */ P_CHOICE, /* choice value */ P_SELECT, /* select BAR */ + P_IMPLY, /* imply BAR */ P_RANGE, /* range 7..100 (for a symbol) */ - P_ENV, /* value from environment variable */ P_SYMBOL, /* where a symbol is defined */ }; @@ -162,22 +211,67 @@ struct property { for (st = sym->prop; st; st = st->next) \ if (st->text) +/* + * Represents a node in the menu tree, as seen in e.g. menuconfig (though used + * for all front ends). Each symbol, menu, etc. defined in the Kconfig files + * gets a node. A symbol defined in multiple locations gets one node at each + * location. + */ struct menu { + /* The next menu node at the same level */ struct menu *next; + + /* The parent menu node, corresponding to e.g. a menu or choice */ struct menu *parent; + + /* The first child menu node, for e.g. menus and choices */ struct menu *list; + + /* + * The symbol associated with the menu node. Choices are implemented as + * a special kind of symbol. NULL for menus, comments, and ifs. + */ struct symbol *sym; + + /* + * The prompt associated with the node. This holds the prompt for a + * symbol as well as the text for a menu or comment, along with the + * type (P_PROMPT, P_MENU, etc.) + */ struct property *prompt; + + /* + * 'visible if' dependencies. If more than one is given, they will be + * ANDed together. + */ struct expr *visibility; + + /* + * Ordinary dependencies from e.g. 'depends on' and 'if', ANDed + * together + */ struct expr *dep; + + /* MENU_* flags */ unsigned int flags; + + /* Any help text associated with the node */ char *help; + + /* The location where the menu node appears in the Kconfig files */ struct file *file; int lineno; + + /* For use by front ends that need to store auxiliary data */ void *data; }; +/* + * Set on a menu node when the corresponding symbol changes state in some way. + * Can be checked by front ends. + */ #define MENU_CHANGED 0x0001 + #define MENU_ROOT 0x0002 struct jump_key { @@ -205,24 +299,20 @@ 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(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); tristate expr_calc_value(struct expr *e); -struct expr *expr_eliminate_yn(struct expr *e); struct expr *expr_trans_bool(struct expr *e); struct expr *expr_eliminate_dups(struct expr *e); struct expr *expr_transform(struct expr *e); int expr_contains_symbol(struct expr *dep, struct symbol *sym); bool expr_depends_symbol(struct expr *dep, struct symbol *sym); -struct expr *expr_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 */ void expr_gstr_print(struct expr *e, struct gstr *gs); +void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, + tristate pr_type, const char *title); static inline int expr_is_yes(struct expr *e) { diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh new file mode 100755 index 0000000000..480ecd8b9f --- /dev/null +++ b/scripts/kconfig/gconf-cfg.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="gtk+-2.0 gmodule-2.0 libglade-2.0" + +if [ -z "$(command -v pkg-config)" ]; then + echo >&2 "*" + echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it." + echo >&2 "*" + exit 1 +fi + +if ! pkg-config --exists $PKG; then + echo >&2 "*" + echo >&2 "* Unable to find the GTK+ installation. Please make sure that" + echo >&2 "* the GTK+ 2.0 development package is correctly installed." + echo >&2 "* You need $PKG" + echo >&2 "*" + exit 1 +fi + +if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then + echo >&2 "*" + echo >&2 "* GTK+ is present but version >= 2.0.0 is required." + echo >&2 "*" + exit 1 +fi + +echo cflags=\"$(pkg-config --cflags $PKG)\" +echo libs=\"$(pkg-config --libs $PKG)\" diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index d0a35b21f3..36f578415c 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -101,8 +101,8 @@ const char *dbg_sym_flags(int val) strcat(buf, "write/"); if (val & SYMBOL_CHANGED) strcat(buf, "changed/"); - if (val & SYMBOL_AUTO) - strcat(buf, "auto/"); + if (val & SYMBOL_NO_WRITE) + strcat(buf, "no_write/"); buf[strlen(buf) - 1] = '\0'; @@ -137,7 +137,7 @@ void init_main_window(const gchar * glade_file) xml = glade_xml_new(glade_file, "window1", NULL); if (!xml) - g_error(_("GUI loading failed !\n")); + g_error("GUI loading failed !\n"); glade_xml_signal_autoconnect(xml); main_wnd = glade_xml_get_widget(xml, "window1"); @@ -169,14 +169,6 @@ void init_main_window(const gchar * glade_file) style = gtk_widget_get_style(main_wnd); widget = glade_xml_get_widget(xml, "toolbar1"); -#if 0 /* Use stock Gtk icons instead */ - replace_button_icon(xml, main_wnd->window, style, - "button1", (gchar **) xpm_back); - replace_button_icon(xml, main_wnd->window, style, - "button2", (gchar **) xpm_load); - replace_button_icon(xml, main_wnd->window, style, - "button3", (gchar **) xpm_save); -#endif replace_button_icon(xml, main_wnd->window, style, "button4", (gchar **) xpm_single_view); replace_button_icon(xml, main_wnd->window, style, @@ -184,22 +176,6 @@ void init_main_window(const gchar * glade_file) replace_button_icon(xml, main_wnd->window, style, "button6", (gchar **) xpm_tree_view); -#if 0 - switch (view_mode) { - case SINGLE_VIEW: - widget = glade_xml_get_widget(xml, "button4"); - g_signal_emit_by_name(widget, "clicked"); - break; - case SPLIT_VIEW: - widget = glade_xml_get_widget(xml, "button5"); - g_signal_emit_by_name(widget, "clicked"); - break; - case FULL_VIEW: - widget = glade_xml_get_widget(xml, "button6"); - g_signal_emit_by_name(widget, "clicked"); - break; - } -#endif txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", "foreground", "red", @@ -257,7 +233,7 @@ void init_left_tree(void) column = gtk_tree_view_column_new(); gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_title(column, _("Options")); + gtk_tree_view_column_set_title(column, "Options"); renderer = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), @@ -300,7 +276,7 @@ void init_right_tree(void) column = gtk_tree_view_column_new(); gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_title(column, _("Options")); + gtk_tree_view_column_set_title(column, "Options"); renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), @@ -329,7 +305,7 @@ void init_right_tree(void) renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(view, -1, - _("Name"), renderer, + "Name", renderer, "text", COL_NAME, "foreground-gdk", COL_COLOR, NULL); @@ -353,7 +329,7 @@ void init_right_tree(void) COL_COLOR, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(view, -1, - _("Value"), renderer, + "Value", renderer, "text", COL_VALUE, "editable", COL_EDIT, @@ -392,7 +368,7 @@ static void text_insert_help(struct menu *menu) { GtkTextBuffer *buffer; GtkTextIter start, end; - const char *prompt = _(menu_get_prompt(menu)); + const char *prompt = menu_get_prompt(menu); struct gstr help = str_new(); menu_get_ext_help(menu, &help); @@ -446,7 +422,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, if (!conf_get_changed()) return FALSE; - dialog = gtk_dialog_new_with_buttons(_("Warning !"), + dialog = gtk_dialog_new_with_buttons("Warning !", GTK_WINDOW(main_wnd), (GtkDialogFlags) (GTK_DIALOG_MODAL | @@ -460,7 +436,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL); - label = gtk_label_new(_("\nSave configuration ?\n")); + label = gtk_label_new("\nSave configuration ?\n"); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); gtk_widget_show(label); @@ -520,7 +496,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data) (user_data)); if (conf_read(fn)) - text_insert_msg(_("Error"), _("Unable to load configuration !")); + text_insert_msg("Error", "Unable to load configuration !"); else display_tree(&rootmenu); } @@ -529,7 +505,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *fs; - fs = gtk_file_selection_new(_("Load file...")); + fs = gtk_file_selection_new("Load file..."); g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), "clicked", G_CALLBACK(load_filename), (gpointer) fs); @@ -548,7 +524,8 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) { if (conf_write(NULL)) - text_insert_msg(_("Error"), _("Unable to save configuration !")); + text_insert_msg("Error", "Unable to save configuration !"); + conf_write_autoconf(0); } @@ -561,7 +538,7 @@ store_filename(GtkFileSelection * file_selector, gpointer user_data) (user_data)); if (conf_write(fn)) - text_insert_msg(_("Error"), _("Unable to save configuration !")); + text_insert_msg("Error", "Unable to save configuration !"); gtk_widget_destroy(GTK_WIDGET(user_data)); } @@ -570,7 +547,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *fs; - fs = gtk_file_selection_new(_("Save file as...")); + fs = gtk_file_selection_new("Save file as..."); g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), "clicked", G_CALLBACK(store_filename), (gpointer) fs); @@ -663,7 +640,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; - const gchar *intro_text = _( + const gchar *intro_text = "Welcome to gkc, the GTK+ graphical configuration tool\n" "For each option, a blank box indicates the feature is disabled, a\n" "check indicates it is enabled, and a dot indicates that it is to\n" @@ -678,7 +655,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) "option.\n" "\n" "Toggling Show Debug Info under the Options menu will show \n" - "the dependencies, which you can then match by examining other options."); + "the dependencies, which you can then match by examining other options."; dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, @@ -695,8 +672,8 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; const gchar *about_text = - _("gkc is copyright (c) 2002 Romain Lievin .\n" - "Based on the source code from Roman Zippel.\n"); + "gkc is copyright (c) 2002 Romain Lievin .\n" + "Based on the source code from Roman Zippel.\n"; dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, @@ -713,9 +690,9 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; const gchar *license_text = - _("gkc is released under the terms of the GNU GPL v2.\n" + "gkc is released under the terms of the GNU GPL v2.\n" "For more information, please see the source code or\n" - "visit http://www.fsf.org/licenses/licenses.html\n"); + "visit http://www.fsf.org/licenses/licenses.html\n"; dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, @@ -938,7 +915,7 @@ on_treeview2_button_press_event(GtkWidget * widget, current = menu; display_tree_part(); gtk_widget_set_sensitive(back_btn, TRUE); - } else if ((col == COL_OPTION)) { + } else if (col == COL_OPTION) { toggle_sym_value(menu); gtk_tree_view_expand_row(view, path, TRUE); } @@ -1073,7 +1050,7 @@ static gchar **fill_row(struct menu *menu) bzero(row, sizeof(row)); row[COL_OPTION] = - g_strdup_printf("%s %s", _(menu_get_prompt(menu)), + g_strdup_printf("%s %s", menu_get_prompt(menu), sym && !sym_has_value(sym) ? "(NEW)" : ""); if (opt_mode == OPT_ALL && !menu_is_visible(menu)) @@ -1126,7 +1103,7 @@ static gchar **fill_row(struct menu *menu) if (def_menu) row[COL_VALUE] = - g_strdup(_(menu_get_prompt(def_menu))); + g_strdup(menu_get_prompt(def_menu)); } if (sym->flags & SYMBOL_CHOICEVAL) row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); @@ -1471,10 +1448,6 @@ int main(int ac, char *av[]) char *env; gchar *glade_file; - bindtextdomain(PACKAGE, LOCALEDIR); - bind_textdomain_codeset(PACKAGE, "UTF-8"); - textdomain(PACKAGE); - /* GTK stuffs */ gtk_set_locale(); gtk_init(&ac, &av); @@ -1498,9 +1471,12 @@ int main(int ac, char *av[]) case 'a': //showAll = 1; break; + case 's': + conf_set_message_callback(NULL); + break; case 'h': case '?': - printf("%s \n", av[0]); + printf("%s [-s] \n", av[0]); exit(0); } name = av[2]; diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c new file mode 100644 index 0000000000..b3e0ea0ac7 --- /dev/null +++ b/scripts/kconfig/kconf_id.c @@ -0,0 +1,52 @@ + +static struct kconf_id kconf_id_array[] = { + { "mainmenu", T_MAINMENU, TF_COMMAND }, + { "menu", T_MENU, TF_COMMAND }, + { "endmenu", T_ENDMENU, TF_COMMAND }, + { "source", T_SOURCE, TF_COMMAND }, + { "choice", T_CHOICE, TF_COMMAND }, + { "endchoice", T_ENDCHOICE, TF_COMMAND }, + { "comment", T_COMMENT, TF_COMMAND }, + { "config", T_CONFIG, TF_COMMAND }, + { "menuconfig", T_MENUCONFIG, TF_COMMAND }, + { "help", T_HELP, TF_COMMAND }, + { "---help---", T_HELP, TF_COMMAND }, + { "if", T_IF, TF_COMMAND|TF_PARAM }, + { "endif", T_ENDIF, TF_COMMAND }, + { "depends", T_DEPENDS, TF_COMMAND }, + { "optional", T_OPTIONAL, TF_COMMAND }, + { "default", T_DEFAULT, TF_COMMAND, S_UNKNOWN }, + { "prompt", T_PROMPT, TF_COMMAND }, + { "tristate", T_TYPE, TF_COMMAND, S_TRISTATE }, + { "def_tristate", T_DEFAULT, TF_COMMAND, S_TRISTATE }, + { "bool", T_TYPE, TF_COMMAND, S_BOOLEAN }, + { "def_bool", T_DEFAULT, TF_COMMAND, S_BOOLEAN }, + { "int", T_TYPE, TF_COMMAND, S_INT }, + { "hex", T_TYPE, TF_COMMAND, S_HEX }, + { "string", T_TYPE, TF_COMMAND, S_STRING }, + { "select", T_SELECT, TF_COMMAND }, + { "imply", T_IMPLY, TF_COMMAND }, + { "range", T_RANGE, TF_COMMAND }, + { "visible", T_VISIBLE, TF_COMMAND }, + { "option", T_OPTION, TF_COMMAND }, + { "on", T_ON, TF_PARAM }, + { "modules", T_OPT_MODULES, TF_OPTION }, + { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, + { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, +}; + +#define KCONF_ID_ARRAY_SIZE (sizeof(kconf_id_array)/sizeof(struct kconf_id)) + +static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len) +{ + int i; + + for (i = 0; i < KCONF_ID_ARRAY_SIZE; i++) { + struct kconf_id *id = kconf_id_array+i; + int l = strlen(id->name); + + if (len == l && !memcmp(str, id->name, len)) + return id; + } + return NULL; +} diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c deleted file mode 100644 index 2858738b22..0000000000 --- a/scripts/kconfig/kxgettext.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Arnaldo Carvalho de Melo , 2005 - * - * Released under the terms of the GNU GPL v2.0 - */ - -#include -#include - -#include "lkc.h" - -static char *escape(const char* text, char *bf, int len) -{ - char *bfp = bf; - int multiline = strchr(text, '\n') != NULL; - int eol = 0; - int textlen = strlen(text); - - if ((textlen > 0) && (text[textlen-1] == '\n')) - eol = 1; - - *bfp++ = '"'; - --len; - - if (multiline) { - *bfp++ = '"'; - *bfp++ = '\n'; - *bfp++ = '"'; - len -= 3; - } - - while (*text != '\0' && len > 1) { - if (*text == '"') - *bfp++ = '\\'; - else if (*text == '\n') { - *bfp++ = '\\'; - *bfp++ = 'n'; - *bfp++ = '"'; - *bfp++ = '\n'; - *bfp++ = '"'; - len -= 5; - ++text; - goto next; - } - else if (*text == '\\') { - *bfp++ = '\\'; - len--; - } - *bfp++ = *text++; -next: - --len; - } - - if (multiline && eol) - bfp -= 3; - - *bfp++ = '"'; - *bfp = '\0'; - - return bf; -} - -struct file_line { - struct file_line *next; - const char *file; - int lineno; -}; - -static struct file_line *file_line__new(const char *file, int lineno) -{ - struct file_line *self = malloc(sizeof(*self)); - - if (self == NULL) - goto out; - - self->file = file; - self->lineno = lineno; - self->next = NULL; -out: - return self; -} - -struct message { - const char *msg; - const char *option; - struct message *next; - struct file_line *files; -}; - -static struct message *message__list; - -static struct message *message__new(const char *msg, char *option, - const char *file, int lineno) -{ - struct message *self = malloc(sizeof(*self)); - - if (self == NULL) - goto out; - - self->files = file_line__new(file, lineno); - if (self->files == NULL) - goto out_fail; - - self->msg = strdup(msg); - if (self->msg == NULL) - goto out_fail_msg; - - self->option = option; - self->next = NULL; -out: - return self; -out_fail_msg: - free(self->files); -out_fail: - free(self); - self = NULL; - goto out; -} - -static struct message *mesage__find(const char *msg) -{ - struct message *m = message__list; - - while (m != NULL) { - if (strcmp(m->msg, msg) == 0) - break; - m = m->next; - } - - return m; -} - -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); - - if (fl == NULL) - goto out; - - fl->next = self->files; - self->files = fl; - rc = 0; -out: - return rc; -} - -static int message__add(const char *msg, char *option, const char *file, - int lineno) -{ - int rc = 0; - char bf[16384]; - char *escaped = escape(msg, bf, sizeof(bf)); - struct message *m = mesage__find(escaped); - - if (m != NULL) - rc = message__add_file_line(m, file, lineno); - else { - m = message__new(escaped, option, file, lineno); - - if (m != NULL) { - m->next = message__list; - message__list = m; - } else - rc = -1; - } - return rc; -} - -static void menu_build_message_list(struct menu *menu) -{ - struct menu *child; - - message__add(menu_get_prompt(menu), NULL, - menu->file == NULL ? "Root Menu" : menu->file->name, - menu->lineno); - - if (menu->sym != NULL && menu_has_help(menu)) - message__add(menu_get_help(menu), menu->sym->name, - menu->file == NULL ? "Root Menu" : menu->file->name, - menu->lineno); - - for (child = menu->list; child != NULL; child = child->next) - if (child->prompt != NULL) - menu_build_message_list(child); -} - -static void message__print_file_lineno(struct message *self) -{ - struct file_line *fl = self->files; - - putchar('\n'); - if (self->option != NULL) - printf("# %s:00000\n", self->option); - - printf("#: %s:%d", fl->file, fl->lineno); - fl = fl->next; - - while (fl != NULL) { - printf(", %s:%d", fl->file, fl->lineno); - fl = fl->next; - } - - putchar('\n'); -} - -static void message__print_gettext_msgid_msgstr(struct message *self) -{ - message__print_file_lineno(self); - - printf("msgid %s\n" - "msgstr \"\"\n", self->msg); -} - -static void menu__xgettext(void) -{ - struct message *m = message__list; - - while (m != NULL) { - /* skip empty lines ("") */ - if (strlen(m->msg) > sizeof("\"\"")) - message__print_gettext_msgid_msgstr(m); - m = m->next; - } -} - -int main(int ac, char **av) -{ - conf_parse(av[1]); - - menu_build_message_list(menu_get_root_menu(NULL)); - menu__xgettext(); - return 0; -} diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h index 685d80e1bb..45cb237ab7 100644 --- a/scripts/kconfig/list.h +++ b/scripts/kconfig/list.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LIST_H #define LIST_H @@ -34,7 +35,7 @@ struct list_head { * 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. + * @member: the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) @@ -43,7 +44,7 @@ struct list_head { * 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. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ @@ -55,7 +56,7 @@ struct list_head { * @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. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index d5daa7af8b..9eb7c837cd 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -8,22 +8,11 @@ #include "expr.h" -#ifndef KBUILD_NO_NLS -# include -#else -static inline const char *gettext(const char *txt) { return txt; } -static inline void textdomain(const char *domainname) {} -static inline void bindtextdomain(const char *name, const char *dir) {} -static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; } -#endif - #ifdef __cplusplus extern "C" { #endif -#define P(name,type,arg) extern type name arg #include "lkc_proto.h" -#undef P #define SRCTREE "srctree" @@ -31,11 +20,6 @@ extern "C" { #define PACKAGE "linux" #endif -#define LOCALEDIR "/usr/share/locale" - -#define _(text) gettext(text) -#define N_(text) (text) - #ifndef CONFIG_ #define CONFIG_ "CONFIG_" #endif @@ -60,19 +44,16 @@ 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; + const char *name; int token; unsigned int flags; enum symbol_type stype; }; -extern int zconfdebug; - -int zconfparse(void); +extern int yylineno; void zconfdump(FILE *out); void zconf_starthelp(void); FILE *zconf_fopen(const char *name); @@ -90,11 +71,6 @@ void sym_add_change_count(int count); 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) { @@ -110,10 +86,8 @@ 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); @@ -123,9 +97,11 @@ void menu_set_type(int type); /* util.c */ struct file *file_lookup(const char *name); -int file_write_dep(const char *name); void *xmalloc(size_t size); void *xcalloc(size_t nmemb, size_t size); +void *xrealloc(void *p, size_t size); +char *xstrdup(const char *s); +char *xstrndup(const char *s, size_t n); struct gstr { size_t len; @@ -137,25 +113,18 @@ struct gstr { int max_width; }; struct gstr str_new(void); -struct gstr str_assign(const char *s); void str_free(struct gstr *gs); void str_append(struct gstr *gs, const char *s); void str_printf(struct gstr *gs, const char *fmt, ...); const char *str_get(struct gstr *gs); /* symbol.c */ -extern struct expr *sym_env_list; - -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); -struct property *sym_get_env_prop(struct symbol *sym); static inline tristate sym_get_tristate_value(struct symbol *sym) { diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index ecdb9659b6..86c267540c 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -1,57 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* confdata.c */ -P(conf_parse,void,(const char *name)); -P(conf_read,int,(const char *name)); -P(conf_read_simple,int,(const char *name, int)); -P(conf_write_defconfig,int,(const char *name)); -P(conf_write,int,(const char *name)); -P(conf_write_autoconf,int,(void)); -P(conf_get_changed,bool,(void)); -P(conf_set_changed_callback, void,(void (*fn)(void))); -P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); +void conf_parse(const char *name); +int conf_read(const char *name); +int conf_read_simple(const char *name, int); +int conf_write_defconfig(const char *name); +int conf_write(const char *name); +int conf_write_autoconf(int overwrite); +bool conf_get_changed(void); +void conf_set_changed_callback(void (*fn)(void)); +void conf_set_message_callback(void (*fn)(const char *s)); /* menu.c */ -P(rootmenu,struct 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)); +extern struct menu rootmenu; + +bool menu_is_empty(struct menu *menu); +bool menu_is_visible(struct menu *menu); +bool menu_has_prompt(struct menu *menu); +const char * menu_get_prompt(struct menu *menu); +struct menu * menu_get_root_menu(struct menu *menu); +struct menu * menu_get_parent_menu(struct menu *menu); +bool menu_has_help(struct menu *menu); +const char * menu_get_help(struct menu *menu); +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); +void menu_get_ext_help(struct menu *menu, struct gstr *help); /* symbol.c */ -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)); -P(sym_get_type,enum symbol_type,(struct symbol *sym)); -P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); -P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); -P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); -P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); -P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); -P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); -P(sym_is_changable,bool,(struct symbol *sym)); -P(sym_get_choice_prop,struct property *,(struct symbol *sym)); -P(sym_get_default_prop,struct property *,(struct symbol *sym)); -P(sym_get_string_value,const char *,(struct symbol *sym)); - -P(prop_get_type_name,const char *,(enum prop_type type)); +extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; + +struct symbol * sym_lookup(const char *name, int flags); +struct symbol * sym_find(const char *name); +const char * sym_escape_string_value(const char *in); +struct symbol ** sym_re_search(const char *pattern); +const char * sym_type_name(enum symbol_type type); +void sym_calc_value(struct symbol *sym); +enum symbol_type sym_get_type(struct symbol *sym); +bool sym_tristate_within_range(struct symbol *sym,tristate tri); +bool sym_set_tristate_value(struct symbol *sym,tristate tri); +tristate sym_toggle_tristate_value(struct symbol *sym); +bool sym_string_valid(struct symbol *sym, const char *newval); +bool sym_string_within_range(struct symbol *sym, const char *str); +bool sym_set_string_value(struct symbol *sym, const char *newval); +bool sym_is_changable(struct symbol *sym); +struct property * sym_get_choice_prop(struct symbol *sym); +const char * sym_get_string_value(struct symbol *sym); + +const char * prop_get_type_name(enum prop_type type); + +/* preprocess.c */ +enum variable_flavor { + VAR_SIMPLE, + VAR_RECURSIVE, + VAR_APPEND, +}; +void env_write_dep(FILE *f, const char *auto_conf_name); +void variable_add(const char *name, const char *value, + enum variable_flavor flavor); +void variable_all_del(void); +char *expand_string(const char *in); +char *expand_dollar(const char **str); +char *expand_one_token(const char **str); /* expr.c */ -P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); -P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)); +void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh deleted file mode 100755 index 5075ebf2d3..0000000000 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/sh -# Check ncurses compatibility - -# What library to link -ldflags() -{ - pkg-config --libs ncursesw 2>/dev/null && exit - pkg-config --libs ncurses 2>/dev/null && exit - for ext in so a dll.a dylib ; do - for lib in ncursesw ncurses curses ; do - $cc -print-file-name=lib${lib}.${ext} | grep -q / - if [ $? -eq 0 ]; then - echo "-l${lib}" - exit - fi - done - done - exit 1 -} - -# Where is ncurses.h? -ccflags() -{ - if pkg-config --cflags ncursesw 2>/dev/null; then - echo '-DCURSES_LOC="" -DNCURSES_WIDECHAR=1' - elif pkg-config --cflags ncurses 2>/dev/null; then - echo '-DCURSES_LOC=""' - elif [ -f /usr/include/ncursesw/curses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC=""' - echo ' -DNCURSES_WIDECHAR=1' - elif [ -f /usr/include/ncurses/ncurses.h ]; then - echo '-I/usr/include/ncurses -DCURSES_LOC=""' - elif [ -f /usr/include/ncurses/curses.h ]; then - echo '-I/usr/include/ncurses -DCURSES_LOC=""' - elif [ -f /usr/include/ncurses.h ]; then - echo '-DCURSES_LOC=""' - else - echo '-DCURSES_LOC=""' - fi -} - -# Temp file, try to clean up after us -tmp=.lxdialog.tmp -trap "rm -f $tmp" 0 1 2 3 15 - -# Check if we can link to ncurses -check() { - $cc -x c - -o $tmp 2>/dev/null <<'EOF' -#include CURSES_LOC -main() {} -EOF - if [ $? != 0 ]; then - echo " *** Unable to find the ncurses libraries or the" 1>&2 - echo " *** required header files." 1>&2 - echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 - echo " *** " 1>&2 - echo " *** Install ncurses (ncurses-devel) and try again." 1>&2 - echo " *** " 1>&2 - exit 1 - fi -} - -usage() { - printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n" -} - -if [ $# -eq 0 ]; then - usage - exit 1 -fi - -cc="" -case "$1" in - "-check") - shift - cc="$@" - check - ;; - "-ccflags") - ccflags - ;; - "-ldflags") - shift - cc="$@" - ldflags - ;; - "*") - usage - exit 1 - ;; -esac diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index 8d016faa28..2e96323ad1 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -103,8 +103,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) int x = width / 2 - 11; int y = height - 2; - print_button(dialog, gettext("Select"), y, x, selected == 0); - print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); + print_button(dialog, "Select", y, x, selected == 0); + print_button(dialog, " Help ", y, x + 14, selected == 1); wmove(dialog, y, x + 1 + 14 * selected); wrefresh(dialog); diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index fcffd5b41f..0b00be5aba 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h @@ -26,16 +26,10 @@ #include #include -#ifndef KBUILD_NO_NLS -# include -#else -# define gettext(Msgid) ((const char *) (Msgid)) -#endif - #ifdef __sun__ #define CURS_MACROS #endif -#include CURSES_LOC +#include /* * Colors in ncurses 1.9.9e do not work properly since foreground and diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index d58de1dc53..fe82ff6d74 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) int x = width / 2 - 11; int y = height - 2; - print_button(dialog, gettext(" Ok "), y, x, selected == 0); - print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); + print_button(dialog, " Ok ", y, x, selected == 0); + print_button(dialog, " Help ", y, x + 14, selected == 1); wmove(dialog, y, x + 1 + 14 * selected); wrefresh(dialog); diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 11ae9ad7ac..d70cab3613 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -157,11 +157,11 @@ static void print_buttons(WINDOW * win, int height, int width, int selected) 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); + print_button(win, "Select", y, x, selected == 0); + print_button(win, " Exit ", y, x + 12, selected == 1); + print_button(win, " Help ", y, x + 24, selected == 2); + print_button(win, " Save ", y, x + 36, selected == 3); + print_button(win, " Load ", y, x + 48, selected == 4); wmove(win, y, x + 1 + 12 * selected); wrefresh(win); diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 1773319b95..88d2818ed9 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -129,7 +129,7 @@ do_resize: print_title(dialog, title, width); - print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); + print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE); wnoutrefresh(dialog); getyx(dialog, cur_y, cur_x); /* Save cursor position */ diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c index 676fb2f824..cd1223c903 100644 --- a/scripts/kconfig/lxdialog/yesno.c +++ b/scripts/kconfig/lxdialog/yesno.c @@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) int x = width / 2 - 10; int y = height - 2; - print_button(dialog, gettext(" Yes "), y, x, selected == 0); - print_button(dialog, gettext(" No "), y, x + 13, selected == 1); + print_button(dialog, " Yes ", y, x, selected == 0); + print_button(dialog, " No ", y, x + 13, selected == 1); wmove(dialog, y, x + 1 + 13 * selected); wrefresh(dialog); diff --git a/scripts/kconfig/mconf-cfg.sh b/scripts/kconfig/mconf-cfg.sh new file mode 100755 index 0000000000..c812872d7f --- /dev/null +++ b/scripts/kconfig/mconf-cfg.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="ncursesw" +PKG2="ncurses" + +if [ -n "$(command -v pkg-config)" ]; then + if pkg-config --exists $PKG; then + echo cflags=\"$(pkg-config --cflags $PKG)\" + echo libs=\"$(pkg-config --libs $PKG)\" + exit 0 + fi + + if pkg-config --exists $PKG2; then + echo cflags=\"$(pkg-config --cflags $PKG2)\" + echo libs=\"$(pkg-config --libs $PKG2)\" + exit 0 + fi +fi + +# Check the default paths in case pkg-config is not installed. +# (Even if it is installed, some distributions such as openSUSE cannot +# find ncurses by pkg-config.) +if [ -f /usr/include/ncursesw/ncurses.h ]; then + echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\" + echo libs=\"-lncursesw\" + exit 0 +fi + +if [ -f /usr/include/ncurses/ncurses.h ]; then + echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\" + echo libs=\"-lncurses\" + exit 0 +fi + +if [ -f /usr/include/ncurses.h ]; then + echo cflags=\"-D_GNU_SOURCE\" + echo libs=\"-lncurses\" + exit 0 +fi + +echo >&2 "*" +echo >&2 "* Unable to find the ncurses package." +echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" +echo >&2 "* depending on your distribution)." +echo >&2 "*" +exit 1 diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 14cea7463a..143c05fec1 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -17,12 +17,11 @@ #include #include #include -#include #include "lkc.h" #include "lxdialog/dialog.h" -static const char mconf_readme[] = N_( +static const char mconf_readme[] = "Overview\n" "--------\n" "This interface lets you select features and parameters for the build.\n" @@ -171,37 +170,37 @@ static const char mconf_readme[] = N_( " blackbg => selects a color scheme with black background\n" " classic => theme with blue background. The classic look\n" " bluetitle => an LCD friendly version of classic. (default)\n" -"\n"), -menu_instructions[] = N_( +"\n", +menu_instructions[] = "Arrow keys navigate the menu. " " selects submenus ---> (or empty submenus ----). " "Highlighted letters are hotkeys. " "Pressing includes, excludes, modularizes features. " "Press to exit, for Help, for Search. " - "Legend: [*] built-in [ ] excluded module < > module capable"), -radiolist_instructions[] = N_( + "Legend: [*] built-in [ ] excluded module < > module capable", +radiolist_instructions[] = "Use the arrow keys to navigate this window or " "press the hotkey of the item you wish to select " "followed by the . " - "Press for additional information about this option."), -inputbox_instructions_int[] = N_( + "Press for additional information about this option.", +inputbox_instructions_int[] = "Please enter a decimal value. " "Fractions will not be accepted. " - "Use the key to move from the input field to the buttons below it."), -inputbox_instructions_hex[] = N_( + "Use the key to move from the input field to the buttons below it.", +inputbox_instructions_hex[] = "Please enter a hexadecimal value. " - "Use the key to move from the input field to the buttons below it."), -inputbox_instructions_string[] = N_( + "Use the key to move from the input field to the buttons below it.", +inputbox_instructions_string[] = "Please enter a string value. " - "Use the key to move from the input field to the buttons below it."), -setmod_text[] = N_( + "Use the key to move from the input field to the buttons below it.", +setmod_text[] = "This feature depends on another which has been configured as a module.\n" - "As a result, this feature will be built as a module."), -load_config_text[] = N_( + "As a result, this feature will be built as a module.", +load_config_text[] = "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_( + "last retrieved. Leave blank to abort.", +load_config_help[] = "\n" "For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" @@ -211,11 +210,11 @@ load_config_help[] = N_( "configuration.\n" "\n" "If you are uncertain, then you have probably never used alternate\n" - "configuration files. You should therefore leave this blank to abort.\n"), -save_config_text[] = N_( + "configuration files. You should therefore leave this blank to abort.\n", +save_config_text[] = "Enter a filename to which this configuration should be saved " - "as an alternate. Leave blank to abort."), -save_config_help[] = N_( + "as an alternate. Leave blank to abort.", +save_config_help[] = "\n" "For various reasons, one may wish to keep different configurations\n" "available on a single machine.\n" @@ -225,8 +224,8 @@ save_config_help[] = N_( "configuration options you have selected at that time.\n" "\n" "If you are uncertain what all this means then you should probably\n" - "leave this blank.\n"), -search_help[] = N_( + "leave this blank.\n", +search_help[] = "\n" "Search for symbols and display their relations.\n" "Regular expressions are allowed.\n" @@ -246,7 +245,7 @@ search_help[] = 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" + " this symbol (bool, tristate, string, ...)\n" "o The line 'Prompt:' shows the text used in the menu structure for\n" " this symbol\n" "o The 'Defined at' line tells at what file / line number the symbol\n" @@ -271,7 +270,7 @@ search_help[] = 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"); + "\n"; static int indent; static struct menu *current_menu; @@ -279,6 +278,7 @@ static int child_count; static int single_menu_mode; static int show_all_options; static int save_and_exit; +static int silent; static void conf(struct menu *menu, struct menu *active_menu); static void conf_choice(struct menu *menu); @@ -330,10 +330,10 @@ static void set_subtitle(void) list_for_each_entry(sp, &trail, entries) { if (sp->text) { if (pos) { - pos->next = xcalloc(sizeof(*pos), 1); + pos->next = xcalloc(1, sizeof(*pos)); pos = pos->next; } else { - subtitles = pos = xcalloc(sizeof(*pos), 1); + subtitles = pos = xcalloc(1, sizeof(*pos)); } pos->text = sp->text; } @@ -399,19 +399,19 @@ static void search_conf(void) struct subtitle_part stpart; title = str_new(); - str_printf( &title, _("Enter (sub)string or regexp to search for " - "(with or without \"%s\")"), CONFIG_); + str_printf( &title, "Enter (sub)string or regexp to search for " + "(with or without \"%s\")", CONFIG_); again: dialog_clear(); - dres = dialog_inputbox(_("Search Configuration Parameter"), + dres = dialog_inputbox("Search Configuration Parameter", str_get(&title), 10, 75, ""); switch (dres) { case 0: break; case 1: - show_helptext(_("Search Configuration"), search_help); + show_helptext("Search Configuration", search_help); goto again; default: str_free(&title); @@ -442,7 +442,7 @@ again: res = get_relations_str(sym_arr, &head); set_subtitle(); - dres = show_textbox_ext(_("Search Results"), (char *) + dres = show_textbox_ext("Search Results", (char *) str_get(&res), 0, 0, keys, &vscroll, &hscroll, &update_text, (void *) &data); @@ -490,7 +490,6 @@ static void build_conf(struct menu *menu) switch (prop->type) { case P_MENU: child_count++; - prompt = _(prompt); if (single_menu_mode) { item_make("%s%*c%s", menu->data ? "-->" : "++>", @@ -507,7 +506,7 @@ static void build_conf(struct menu *menu) case P_COMMENT: if (prompt) { child_count++; - item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt)); + item_make(" %*c*** %s ***", indent + 1, ' ', prompt); item_set_tag(':'); item_set_data(menu); } @@ -515,7 +514,7 @@ static void build_conf(struct menu *menu) default: if (prompt) { child_count++; - item_make("---%*c%s", indent + 1, ' ', _(prompt)); + item_make("---%*c%s", indent + 1, ' ', prompt); item_set_tag(':'); item_set_data(menu); } @@ -559,10 +558,10 @@ static void build_conf(struct menu *menu) item_set_data(menu); } - item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); + 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(" (%s)", menu_get_prompt(def_menu)); item_add_str(" --->"); if (def_menu->list) { indent += 2; @@ -574,7 +573,7 @@ static void build_conf(struct menu *menu) } } else { if (menu == current_menu) { - item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); + item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); item_set_tag(':'); item_set_data(menu); goto conf_childs; @@ -617,17 +616,17 @@ static void build_conf(struct menu *menu) tmp = indent - tmp + 4; if (tmp < 0) tmp = 0; - item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), + item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : _(" (NEW)")); + "" : " (NEW)"); item_set_tag('s'); item_set_data(menu); goto conf_childs; } } - item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), + item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : _(" (NEW)")); + "" : " (NEW)"); if (menu->prompt->type == P_MENU) { item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); return; @@ -664,8 +663,8 @@ static void conf(struct menu *menu, struct menu *active_menu) break; set_subtitle(); dialog_clear(); - res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), - _(menu_instructions), + res = dialog_menu(prompt ? prompt : "Main Menu", + menu_instructions, active_menu, &s_scroll); if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) break; @@ -707,7 +706,7 @@ static void conf(struct menu *menu, struct menu *active_menu) show_help(submenu); else { reset_subtitle(); - show_helptext(_("README"), _(mconf_readme)); + show_helptext("README", mconf_readme); } break; case 3: @@ -772,15 +771,14 @@ static void show_helptext(const char *title, const char *text) show_textbox(title, text, 0, 0); } -static void conf_message_callback(const char *fmt, va_list ap) +static void conf_message_callback(const char *s) { - char buf[PATH_MAX+1]; - - vsnprintf(buf, sizeof(buf), fmt, ap); - if (save_and_exit) - printf("%s", buf); - else - show_textbox(NULL, buf, 6, 60); + if (save_and_exit) { + if (!silent) + printf("%s", s); + } else { + show_textbox(NULL, s, 6, 60); + } } static void show_help(struct menu *menu) @@ -790,13 +788,13 @@ static void show_help(struct menu *menu) help.max_width = getmaxx(stdscr) - 10; menu_get_ext_help(menu, &help); - show_helptext(_(menu_get_prompt(menu)), str_get(&help)); + show_helptext(menu_get_prompt(menu), str_get(&help)); str_free(&help); } static void conf_choice(struct menu *menu) { - const char *prompt = _(menu_get_prompt(menu)); + const char *prompt = menu_get_prompt(menu); struct menu *child; struct symbol *active; @@ -811,9 +809,9 @@ static void conf_choice(struct menu *menu) if (!menu_is_visible(child)) continue; if (child->sym) - item_make("%s", _(menu_get_prompt(child))); + item_make("%s", menu_get_prompt(child)); else { - item_make("*** %s ***", _(menu_get_prompt(child))); + item_make("*** %s ***", menu_get_prompt(child)); item_set_tag(':'); } item_set_data(child); @@ -823,8 +821,8 @@ static void conf_choice(struct menu *menu) item_set_tag('X'); } dialog_clear(); - res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), - _(radiolist_instructions), + res = dialog_checklist(prompt ? prompt : "Main Menu", + radiolist_instructions, MENUBOX_HEIGTH_MIN, MENUBOX_WIDTH_MIN, CHECKLIST_HEIGTH_MIN); @@ -865,26 +863,26 @@ static void conf_string(struct menu *menu) switch (sym_get_type(menu->sym)) { case S_INT: - heading = _(inputbox_instructions_int); + heading = inputbox_instructions_int; break; case S_HEX: - heading = _(inputbox_instructions_hex); + heading = inputbox_instructions_hex; break; case S_STRING: - heading = _(inputbox_instructions_string); + heading = inputbox_instructions_string; break; default: - heading = _("Internal mconf error!"); + heading = "Internal mconf error!"; } dialog_clear(); - res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), + res = dialog_inputbox(prompt ? prompt : "Main Menu", heading, 10, 75, sym_get_string_value(menu->sym)); switch (res) { case 0: if (sym_set_string_value(menu->sym, dialog_input_result)) return; - show_textbox(NULL, _("You have made an invalid entry."), 5, 43); + show_textbox(NULL, "You have made an invalid entry.", 5, 43); break; case 1: show_help(menu); @@ -912,10 +910,10 @@ static void conf_load(void) sym_set_change_count(1); return; } - show_textbox(NULL, _("File does not exist!"), 5, 38); + show_textbox(NULL, "File does not exist!", 5, 38); break; case 1: - show_helptext(_("Load Alternate Configuration"), load_config_help); + show_helptext("Load Alternate Configuration", load_config_help); break; case KEY_ESC: return; @@ -938,10 +936,10 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); + show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); break; case 1: - show_helptext(_("Save Alternate Configuration"), save_config_help); + show_helptext("Save Alternate Configuration", save_config_help); break; case KEY_ESC: return; @@ -958,8 +956,8 @@ static int handle_exit(void) dialog_clear(); if (conf_get_changed()) res = dialog_yesno(NULL, - _("Do you wish to save your new configuration?\n" - "(Press to continue kernel configuration.)"), + "Do you wish to save your new configuration?\n" + "(Press to continue kernel configuration.)", 6, 60); else res = -1; @@ -969,24 +967,27 @@ static int handle_exit(void) switch (res) { case 0: if (conf_write(filename)) { - fprintf(stderr, _("\n\n" + fprintf(stderr, "\n\n" "Error while writing of the configuration.\n" "Your configuration changes were NOT saved." - "\n\n")); + "\n\n"); return 1; } + conf_write_autoconf(0); /* fall through */ case -1: - printf(_("\n\n" - "*** End of the configuration.\n" - "*** Execute 'make' to start the build or try 'make help'." - "\n\n")); + if (!silent) + 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 (!silent) + fprintf(stderr, "\n\n" + "Your configuration changes were NOT saved." + "\n\n"); if (res != KEY_ESC) res = 0; } @@ -1004,12 +1005,14 @@ int main(int ac, char **av) char *mode; int res; - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - signal(SIGINT, sig_handler); + if (ac > 1 && strcmp(av[1], "-s") == 0) { + silent = 1; + /* Silence conf_read() until the real callback is set up */ + conf_set_message_callback(NULL); + av++; + } conf_parse(av[1]); conf_read(NULL); @@ -1020,8 +1023,8 @@ int main(int ac, char **av) } 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")); + fprintf(stderr, "Your display is too small to run Menuconfig!\n"); + fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); return 1; } diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 584e0fc10d..4cf15d449c 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -62,13 +62,8 @@ void menu_add_entry(struct symbol *sym) menu_add_symbol(P_SYMBOL, sym, NULL); } -void menu_end_entry(void) -{ -} - struct menu *menu_add_menu(void) { - menu_end_entry(); last_entry_ptr = ¤t_entry->list; return current_menu = current_entry; } @@ -79,19 +74,23 @@ void menu_end_menu(void) current_menu = current_menu->parent; } -static struct expr *menu_check_dep(struct expr *e) +/* + * Rewrites 'm' to 'm' && MODULES, so that it evaluates to 'n' when running + * without modules + */ +static struct expr *rewrite_m(struct expr *e) { if (!e) return e; switch (e->type) { case E_NOT: - e->left.expr = menu_check_dep(e->left.expr); + e->left.expr = rewrite_m(e->left.expr); break; case E_OR: case E_AND: - e->left.expr = menu_check_dep(e->left.expr); - e->right.expr = menu_check_dep(e->right.expr); + e->left.expr = rewrite_m(e->left.expr); + e->right.expr = rewrite_m(e->right.expr); break; case E_SYMBOL: /* change 'm' into 'm' && MODULES */ @@ -106,7 +105,7 @@ static struct expr *menu_check_dep(struct expr *e) void menu_add_dep(struct expr *dep) { - current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); + current_entry->dep = expr_alloc_and(current_entry->dep, dep); } void menu_set_type(int type) @@ -125,13 +124,13 @@ void menu_set_type(int type) 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) +static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) { struct property *prop = prop_alloc(type, current_entry->sym); prop->menu = current_entry; prop->expr = expr; - prop->visible.expr = menu_check_dep(dep); + prop->visible.expr = dep; if (prompt) { if (isspace(*prompt)) { @@ -213,9 +212,7 @@ void menu_add_option(int token, char *arg) sym_defconfig_list = current_entry->sym; else if (sym_defconfig_list != current_entry->sym) zconf_error("trying to redefine defconfig symbol"); - break; - case T_OPT_ENV: - prop_add_env(arg); + sym_defconfig_list->flags |= SYMBOL_NO_WRITE; break; case T_OPT_ALLNOCONFIG_Y: current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; @@ -233,6 +230,8 @@ static void sym_check_prop(struct symbol *sym) { struct property *prop; struct symbol *sym2; + char *use; + for (prop = sym->prop; prop; prop = prop->next) { switch (prop->type) { case P_DEFAULT: @@ -250,20 +249,32 @@ static void sym_check_prop(struct symbol *sym) "'%s': number is invalid", sym->name); } + if (sym_is_choice(sym)) { + struct property *choice_prop = + sym_get_choice_prop(sym2); + + if (!choice_prop || + prop_get_symbol(choice_prop) != sym) + prop_warn(prop, + "choice default symbol '%s' is not contained in the choice", + sym2->name); + } break; case P_SELECT: + case P_IMPLY: + use = prop->type == P_SELECT ? "select" : "imply"; sym2 = prop_get_symbol(prop); if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) prop_warn(prop, - "config symbol '%s' uses select, but is " - "not boolean or tristate", sym->name); + "config symbol '%s' uses %s, but is " + "not bool or tristate", sym->name, use); else if (sym2->type != S_UNKNOWN && sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) prop_warn(prop, - "'%s' has wrong type. 'select' only " - "accept arguments of boolean and " - "tristate type", sym2->name); + "'%s' has wrong type. '%s' only " + "accept arguments of bool and " + "tristate type", sym2->name, use); break; case P_RANGE: if (sym->type != S_INT && sym->type != S_HEX) @@ -288,6 +299,11 @@ void menu_finalize(struct menu *parent) sym = parent->sym; if (parent->list) { + /* + * This menu node has children. We (recursively) process them + * and propagate parent dependencies before moving on. + */ + if (sym && sym_is_choice(sym)) { if (sym->type == S_UNKNOWN) { /* find the first choice value to find out choice type */ @@ -305,65 +321,169 @@ void menu_finalize(struct menu *parent) if (menu->sym && menu->sym->type == S_UNKNOWN) menu_set_type(sym->type); } + + /* + * Use the choice itself as the parent dependency of + * the contained items. This turns the mode of the + * choice into an upper bound on the visibility of the + * choice value symbols. + */ parentdep = expr_alloc_symbol(sym); } else if (parent->prompt) + /* Menu node for 'menu' */ parentdep = parent->prompt->visible.expr; else + /* Menu node for 'if' */ parentdep = parent->dep; + /* For each child menu node... */ for (menu = parent->list; menu; menu = menu->next) { - basedep = expr_transform(menu->dep); + /* + * Propagate parent dependencies to the child menu + * node, also rewriting and simplifying expressions + */ + basedep = rewrite_m(menu->dep); + basedep = expr_transform(basedep); basedep = expr_alloc_and(expr_copy(parentdep), basedep); basedep = expr_eliminate_dups(basedep); menu->dep = basedep; + if (menu->sym) + /* + * Note: For symbols, all prompts are included + * too in the symbol's own property list + */ prop = menu->sym->prop; else + /* + * For non-symbol menu nodes, we just need to + * handle the prompt + */ prop = menu->prompt; + + /* For each property... */ for (; prop; prop = prop->next) { if (prop->menu != menu) + /* + * Two possibilities: + * + * 1. The property lacks dependencies + * and so isn't location-specific, + * e.g. an 'option' + * + * 2. The property belongs to a symbol + * defined in multiple locations and + * is from some other location. It + * will be handled there in that + * case. + * + * Skip the property. + */ continue; - dep = expr_transform(prop->visible.expr); + + /* + * Propagate parent dependencies to the + * property's condition, rewriting and + * simplifying expressions at the same time + */ + dep = rewrite_m(prop->visible.expr); + dep = expr_transform(dep); dep = expr_alloc_and(expr_copy(basedep), dep); dep = expr_eliminate_dups(dep); if (menu->sym && menu->sym->type != S_TRISTATE) dep = expr_trans_bool(dep); prop->visible.expr = dep; + + /* + * Handle selects and implies, which modify the + * dependencies of the selected/implied symbol + */ if (prop->type == P_SELECT) { struct symbol *es = prop_get_symbol(prop); es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + } else if (prop->type == P_IMPLY) { + struct symbol *es = prop_get_symbol(prop); + es->implied.expr = expr_alloc_or(es->implied.expr, + expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); } } } + + if (sym && sym_is_choice(sym)) + expr_free(parentdep); + + /* + * Recursively process children in the same fashion before + * moving on + */ for (menu = parent->list; menu; menu = menu->next) menu_finalize(menu); } else if (sym) { + /* + * Automatic submenu creation. If sym is a symbol and A, B, C, + * ... are consecutive items (symbols, menus, ifs, etc.) that + * all depend on sym, then the following menu structure is + * created: + * + * sym + * +-A + * +-B + * +-C + * ... + * + * This also works recursively, giving the following structure + * if A is a symbol and B depends on A: + * + * sym + * +-A + * | +-B + * +-C + * ... + */ + basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_eliminate_dups(expr_transform(basedep)); + + /* Examine consecutive elements after sym */ last_menu = NULL; for (menu = parent->next; menu; menu = menu->next) { dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; if (!expr_contains_symbol(dep, sym)) + /* No dependency, quit */ break; if (expr_depends_symbol(dep, sym)) + /* Absolute dependency, put in submenu */ goto next; + + /* + * Also consider it a dependency on sym if our + * dependencies contain sym and are a "superset" of + * sym's dependencies, e.g. '(sym || Q) && R' when sym + * depends on R. + * + * Note that 'R' might be from an enclosing menu or if, + * making this a more common case than it might seem. + */ dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); dep = expr_eliminate_dups(expr_transform(dep)); dep2 = expr_copy(basedep); expr_eliminate_eq(&dep, &dep2); expr_free(dep); if (!expr_is_yes(dep2)) { + /* Not superset, quit */ expr_free(dep2); break; } + /* Superset, put in submenu */ expr_free(dep2); next: menu_finalize(menu); menu->parent = parent; last_menu = menu; } + expr_free(basedep); if (last_menu) { parent->list = parent->next; parent->next = last_menu->next; @@ -412,6 +532,35 @@ void menu_finalize(struct menu *parent) *ep = expr_alloc_one(E_LIST, NULL); (*ep)->right.sym = menu->sym; } + + /* + * This code serves two purposes: + * + * (1) Flattening 'if' blocks, which do not specify a submenu + * and only add dependencies. + * + * (Automatic submenu creation might still create a submenu + * from an 'if' before this code runs.) + * + * (2) "Undoing" any automatic submenus created earlier below + * promptless symbols. + * + * Before: + * + * A + * if ... (or promptless symbol) + * +-B + * +-C + * D + * + * After: + * + * A + * if ... (or promptless symbol) + * B + * C + * D + */ if (menu->list && (!menu->prompt || !menu->prompt->text)) { for (last_menu = menu->list; ; last_menu = last_menu->next) { last_menu->parent = parent; @@ -436,6 +585,15 @@ void menu_finalize(struct menu *parent) sym->flags |= SYMBOL_WARNED; } + /* + * For non-optional choices, add a reverse dependency (corresponding to + * a select) of ' && m'. This prevents the user from + * setting the choice mode to 'n' when the choice is visible. + * + * This would also work for non-choice symbols, but only non-optional + * choices clear SYMBOL_OPTIONAL as of writing. Choices are implemented + * as a type of symbol. + */ if (sym && !sym_is_optional(sym) && parent->prompt) { sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, expr_alloc_and(parent->prompt->visible.expr, @@ -477,7 +635,7 @@ bool menu_is_visible(struct menu *menu) if (menu->visibility) { if (expr_calc_value(menu->visibility) == no) - return no; + return false; } sym = menu->sym; @@ -550,7 +708,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop, struct menu *submenu[8], *menu, *location = NULL; struct jump_key *jump = NULL; - str_printf(r, _("Prompt: %s\n"), _(prop->text)); + str_printf(r, "Prompt: %s\n", prop->text); menu = prop->menu->parent; for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { bool accessible = menu_is_visible(menu); @@ -583,16 +741,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } if (i > 0) { - str_printf(r, _(" Location:\n")); + str_printf(r, " Location:\n"); for (j = 4; --i >= 0; j += 2) { menu = submenu[i]; - if (head && location && menu == location) + if (jump && menu == location) jump->offset = strlen(r->s); str_printf(r, "%*c-> %s", j, ' ', - _(menu_get_prompt(menu))); + menu_get_prompt(menu)); if (menu->sym) { str_printf(r, " (%s [=%s])", menu->sym->name ? - menu->sym->name : _(""), + menu->sym->name : "", sym_get_string_value(menu->sym)); } str_append(r, "\n"); @@ -612,13 +770,30 @@ static struct property *get_symbol_prop(struct symbol *sym) return prop; } +static void get_symbol_props_str(struct gstr *r, struct symbol *sym, + enum prop_type tok, const char *prefix) +{ + bool hit = false; + struct property *prop; + + for_all_properties(sym, prop, tok) { + if (!hit) { + str_append(r, prefix); + hit = true; + } else + str_printf(r, " && "); + expr_gstr_print(prop->expr, r); + } + if (hit) + str_append(r, "\n"); +} + /* * head is optional and may be NULL */ -void get_symbol_str(struct gstr *r, struct symbol *sym, +static void get_symbol_str(struct gstr *r, struct symbol *sym, struct list_head *head) { - bool hit; struct property *prop; if (sym && sym->name) { @@ -639,31 +814,29 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, prop = get_symbol_prop(sym); if (prop) { - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, + str_printf(r, " Defined at %s:%d\n", prop->menu->file->name, prop->menu->lineno); if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); + str_append(r, " Depends on: "); expr_gstr_print(prop->visible.expr, r); str_append(r, "\n"); } } - 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); - } - if (hit) - str_append(r, "\n"); + get_symbol_props_str(r, sym, P_SELECT, " Selects: "); if (sym->rev_dep.expr) { - str_append(r, _(" Selected by: ")); - expr_gstr_print(sym->rev_dep.expr, r); - str_append(r, "\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n"); } + + get_symbol_props_str(r, sym, P_IMPLY, " Implies: "); + if (sym->implied.expr) { + expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n"); + } + str_append(r, "\n\n"); } @@ -676,7 +849,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) for (i = 0; sym_arr && (sym = sym_arr[i]); i++) get_symbol_str(&res, sym, head); if (!i) - str_append(&res, _("No matches found.\n")); + str_append(&res, "No matches found.\n"); return res; } @@ -691,7 +864,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help) str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); help_text = menu_get_help(menu); } - str_printf(help, "%s\n", _(help_text)); + str_printf(help, "%s\n", help_text); if (sym) get_symbol_str(help, sym, NULL); } diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 81b0c61bb9..0ef9064996 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -32,13 +32,16 @@ usage() { echo " -m only merge the fragments, do not execute the make command" echo " -n use allnoconfig instead of alldefconfig" echo " -r list redundant entries when merging fragments" - echo " -O dir to put generated output files" + echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead." + echo + echo "Used prefix: '$CONFIG_PREFIX'. You can redefine it with \$CONFIG_ environment variable." } -MAKE=true +RUNMAKE=true ALLTARGET=alldefconfig WARNREDUN=false OUTPUT=. +CONFIG_PREFIX=${CONFIG_-CONFIG_} while true; do case $1 in @@ -48,7 +51,7 @@ while true; do continue ;; "-m") - MAKE=false + RUNMAKE=false shift continue ;; @@ -77,44 +80,66 @@ while true; do esac done +if [ "$#" -lt 1 ] ; then + usage + exit +fi + +if [ -z "$KCONFIG_CONFIG" ]; then + if [ "$OUTPUT" != . ]; then + KCONFIG_CONFIG=$(readlink -m -- "$OUTPUT/.config") + else + KCONFIG_CONFIG=.config + fi +fi + INITFILE=$1 shift; +if [ ! -r "$INITFILE" ]; then + echo "The base file '$INITFILE' does not exist. Exit." >&2 + exit 1 +fi + MERGE_LIST=$* -SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" +SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p" +SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p" + TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) echo "Using $INITFILE as base" cat $INITFILE > $TMP_FILE -# Merge files, printing warnings on overrided values +# Merge files, printing warnings on overridden values for MERGE_FILE in $MERGE_LIST ; do echo "Merging $MERGE_FILE" - CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) + if [ ! -r "$MERGE_FILE" ]; then + echo "The merge file '$MERGE_FILE' does not exist. Exit." >&2 + exit 1 + fi + CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE) for CFG in $CFG_LIST ; do - grep -q -w $CFG $TMP_FILE - if [ $? -eq 0 ] ; then - PREV_VAL=$(grep -w $CFG $TMP_FILE) - NEW_VAL=$(grep -w $CFG $MERGE_FILE) - if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then + grep -q -w $CFG $TMP_FILE || continue + PREV_VAL=$(grep -w $CFG $TMP_FILE) + NEW_VAL=$(grep -w $CFG $MERGE_FILE) + if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then echo Value of $CFG is redefined by fragment $MERGE_FILE: echo Previous value: $PREV_VAL echo New value: $NEW_VAL echo - elif [ "$WARNREDUN" = "true" ]; then + elif [ "$WARNREDUN" = "true" ]; then echo Value of $CFG is redundant by fragment $MERGE_FILE: - fi - sed -i "/$CFG[ =]/d" $TMP_FILE fi + sed -i "/$CFG[ =]/d" $TMP_FILE done cat $MERGE_FILE >> $TMP_FILE done -if [ "$MAKE" = "false" ]; then - cp $TMP_FILE $OUTPUT/.config +if [ "$RUNMAKE" = "false" ]; then + cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG" echo "#" - echo "# merged configuration written to $OUTPUT/.config (needs make)" + echo "# merged configuration written to $KCONFIG_CONFIG (needs make)" echo "#" clean_up exit @@ -135,10 +160,10 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET # Check all specified config values took (might have missed-dependency issues) -for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do +for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) - ACTUAL_VAL=$(grep -w -e "$CFG" $OUTPUT/.config) + ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG") if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then echo "Value requested for $CFG not in final .config" echo "Requested value: $REQUESTED_VAL" diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh new file mode 100644 index 0000000000..001559ef0a --- /dev/null +++ b/scripts/kconfig/nconf-cfg.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="ncursesw menuw panelw" +PKG2="ncurses menu panel" + +if [ -n "$(command -v pkg-config)" ]; then + if pkg-config --exists $PKG; then + echo cflags=\"$(pkg-config --cflags $PKG)\" + echo libs=\"$(pkg-config --libs $PKG)\" + exit 0 + fi + + if pkg-config --exists $PKG2; then + echo cflags=\"$(pkg-config --cflags $PKG2)\" + echo libs=\"$(pkg-config --libs $PKG2)\" + exit 0 + fi +fi + +# Check the default paths in case pkg-config is not installed. +# (Even if it is installed, some distributions such as openSUSE cannot +# find ncurses by pkg-config.) +if [ -f /usr/include/ncursesw/ncurses.h ]; then + echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\" + echo libs=\"-lncursesw -lmenuw -lpanelw\" + exit 0 +fi + +if [ -f /usr/include/ncurses/ncurses.h ]; then + echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\" + echo libs=\"-lncurses -lmenu -lpanel\" + exit 0 +fi + +if [ -f /usr/include/ncurses.h ]; then + echo cflags=\"-D_GNU_SOURCE\" + echo libs=\"-lncurses -lmenu -lpanel\" + exit 0 +fi + +echo >&2 "*" +echo >&2 "* Unable to find the ncurses package." +echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" +echo >&2 "* depending on your distribution)." +echo >&2 "*" +exit 1 diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 984489ef2b..1ef232ae5a 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -5,7 +5,9 @@ * Derived from menuconfig. * */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include @@ -13,7 +15,7 @@ #include "nconf.h" #include -static const char nconf_global_help[] = N_( +static const char nconf_global_help[] = "Help windows\n" "------------\n" "o Global help: Unless in a data entry window, pressing will give \n" @@ -128,8 +130,8 @@ static const char nconf_global_help[] = N_( "\n" "Note that this mode can eventually be a little more CPU expensive than\n" "the default mode, especially with a larger number of unfolded submenus.\n" -"\n"), -menu_no_f_instructions[] = N_( +"\n", +menu_no_f_instructions[] = "Legend: [*] built-in [ ] excluded module < > module capable.\n" "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" "\n" @@ -145,8 +147,8 @@ menu_no_f_instructions[] = N_( "You do not have function keys support.\n" "Press <1> instead of , <2> instead of , etc.\n" "For verbose global help use key <1>.\n" -"For help related to the current menu entry press or .\n"), -menu_instructions[] = N_( +"For help related to the current menu entry press or .\n", +menu_instructions[] = "Legend: [*] built-in [ ] excluded module < > module capable.\n" "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" "\n" @@ -161,30 +163,30 @@ menu_instructions[] = N_( "\n" "Pressing <1> may be used instead of , <2> instead of , etc.\n" "For verbose global help press .\n" -"For help related to the current menu entry press or .\n"), -radiolist_instructions[] = N_( +"For help related to the current menu entry press or .\n", +radiolist_instructions[] = "Press , , or to navigate a radiolist, select\n" "with .\n" "For help related to the current entry press or .\n" -"For global help press .\n"), -inputbox_instructions_int[] = N_( +"For global help press .\n", +inputbox_instructions_int[] = "Please enter a decimal value.\n" "Fractions will not be accepted.\n" -"Press to apply, to cancel."), -inputbox_instructions_hex[] = N_( +"Press to apply, to cancel.", +inputbox_instructions_hex[] = "Please enter a hexadecimal value.\n" -"Press to apply, to cancel."), -inputbox_instructions_string[] = N_( +"Press to apply, to cancel.", +inputbox_instructions_string[] = "Please enter a string value.\n" -"Press to apply, to cancel."), -setmod_text[] = N_( +"Press to apply, to cancel.", +setmod_text[] = "This feature depends on another feature which has been configured as a\n" -"module. As a result, the current feature will be built as a module too."), -load_config_text[] = N_( +"module. As a result, the current feature will be built as a module too.", +load_config_text[] = "Enter the name of the configuration file you wish to load.\n" "Accept the name shown to restore the configuration you last\n" -"retrieved. Leave empty to abort."), -load_config_help[] = N_( +"retrieved. Leave empty to abort.", +load_config_help[] = "For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" "\n" @@ -192,11 +194,11 @@ load_config_help[] = N_( "default one, entering its name here will allow you to load and modify\n" "that configuration.\n" "\n" -"Leave empty to abort.\n"), -save_config_text[] = N_( +"Leave empty to abort.\n", +save_config_text[] = "Enter a filename to which this configuration should be saved\n" -"as an alternate. Leave empty to abort."), -save_config_help[] = N_( +"as an alternate. Leave empty to abort.", +save_config_help[] = "For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" "\n" @@ -204,8 +206,8 @@ save_config_help[] = N_( "and use the current configuration as an alternate to whatever\n" "configuration options you have selected at that time.\n" "\n" -"Leave empty to abort.\n"), -search_help[] = N_( +"Leave empty to abort.\n", +search_help[] = "Search for symbols (configuration variable names CONFIG_*) and display\n" "their relations. Regular expressions are supported.\n" "Example: Search for \"^FOO\".\n" @@ -242,7 +244,7 @@ search_help[] = N_( "USB => find all symbols containing USB\n" "^USB => find all symbols starting with USB\n" "USB$ => find all symbols ending with USB\n" -"\n"); +"\n"; struct mitem { char str[256]; @@ -269,7 +271,7 @@ 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 const char *current_instructions = menu_instructions; static char *dialog_input_result; static int dialog_input_result_len; @@ -303,7 +305,7 @@ struct function_keys { }; static const int function_keys_num = 9; -struct function_keys function_keys[] = { +static struct function_keys function_keys[] = { { .key_str = "F1", .func = "Help", @@ -386,7 +388,7 @@ static void print_function_line(void) static void handle_f1(int *key, struct menu *current_item) { show_scroll_win(main_window, - _("Global help"), _(nconf_global_help)); + "Global help", nconf_global_help); return; } @@ -401,8 +403,8 @@ static void handle_f2(int *key, struct menu *current_item) static void handle_f3(int *key, struct menu *current_item) { show_scroll_win(main_window, - _("Short help"), - _(current_instructions)); + "Short help", + current_instructions); return; } @@ -410,7 +412,7 @@ static void handle_f3(int *key, struct menu *current_item) static void handle_f4(int *key, struct menu *current_item) { int res = btn_dialog(main_window, - _("Show all symbols?"), + "Show all symbols?", 2, " ", ""); @@ -506,7 +508,7 @@ static int get_mext_match(const char *match_str, match_f flag) index = (index + items_num) % items_num; while (true) { char *str = k_menu_items[index].str; - if (strcasestr(str, match_str) != 0) + if (strcasestr(str, match_str) != NULL) return index; if (flag == FIND_NEXT_MATCH_UP || flag == MATCH_TINKER_PATTERN_UP) @@ -651,8 +653,8 @@ static int do_exit(void) return 0; } res = btn_dialog(main_window, - _("Do you wish to save your new configuration?\n" - " to cancel and resume nconfig."), + "Do you wish to save your new configuration?\n" + " to cancel and resume nconfig.", 2, " ", ""); @@ -668,15 +670,16 @@ static int do_exit(void) if (res) btn_dialog( main_window, - _("Error during writing of configuration.\n" - "Your configuration changes were NOT saved."), + "Error during writing of configuration.\n" + "Your configuration changes were NOT saved.", 1, ""); + conf_write_autoconf(0); break; default: btn_dialog( main_window, - _("Your configuration changes were NOT saved."), + "Your configuration changes were NOT saved.", 1, ""); break; @@ -695,12 +698,12 @@ static void search_conf(void) int dres; title = str_new(); - str_printf( &title, _("Enter (sub)string or regexp to search for " - "(with or without \"%s\")"), CONFIG_); + str_printf( &title, "Enter (sub)string or regexp to search for " + "(with or without \"%s\")", CONFIG_); again: dres = dialog_inputbox(main_window, - _("Search Configuration Parameter"), + "Search Configuration Parameter", str_get(&title), "", &dialog_input_result, &dialog_input_result_len); switch (dres) { @@ -708,7 +711,7 @@ again: break; case 1: show_scroll_win(main_window, - _("Search Configuration"), search_help); + "Search Configuration", search_help); goto again; default: str_free(&title); @@ -724,7 +727,7 @@ again: res = get_relations_str(sym_arr, NULL); free(sym_arr); show_scroll_win(main_window, - _("Search Results"), str_get(&res)); + "Search Results", str_get(&res)); str_free(&res); str_free(&title); } @@ -752,7 +755,7 @@ static void build_conf(struct menu *menu) switch (ptype) { case P_MENU: child_count++; - prompt = _(prompt); + prompt = prompt; if (single_menu_mode) { item_make(menu, 'm', "%s%*c%s", @@ -773,7 +776,7 @@ static void build_conf(struct menu *menu) item_make(menu, ':', " %*c*** %s ***", indent + 1, ' ', - _(prompt)); + prompt); } break; default: @@ -781,7 +784,7 @@ static void build_conf(struct menu *menu) child_count++; item_make(menu, ':', "---%*c%s", indent + 1, ' ', - _(prompt)); + prompt); } } } else @@ -827,11 +830,11 @@ static void build_conf(struct menu *menu) } item_add_str("%*c%s", indent + 1, - ' ', _(menu_get_prompt(menu))); + ' ', menu_get_prompt(menu)); if (val == yes) { if (def_menu) { item_add_str(" (%s)", - _(menu_get_prompt(def_menu))); + menu_get_prompt(def_menu)); item_add_str(" --->"); if (def_menu->list) { indent += 2; @@ -845,7 +848,7 @@ static void build_conf(struct menu *menu) if (menu == current_menu) { item_make(menu, ':', "---%*c%s", indent + 1, - ' ', _(menu_get_prompt(menu))); + ' ', menu_get_prompt(menu)); goto conf_childs; } child_count++; @@ -892,17 +895,17 @@ static void build_conf(struct menu *menu) if (tmp < 0) tmp = 0; item_add_str("%*c%s%s", tmp, ' ', - _(menu_get_prompt(menu)), + menu_get_prompt(menu), (sym_has_value(sym) || !sym_is_changable(sym)) ? "" : - _(" (NEW)")); + " (NEW)"); goto conf_childs; } } item_add_str("%*c%s%s", indent + 1, ' ', - _(menu_get_prompt(menu)), + menu_get_prompt(menu), (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : _(" (NEW)")); + "" : " (NEW)"); if (menu->prompt && menu->prompt->type == P_MENU) { item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); return; @@ -1065,7 +1068,7 @@ static int do_match(int key, struct match_state *state, int *ans) static void conf(struct menu *menu) { - struct menu *submenu = 0; + struct menu *submenu = NULL; const char *prompt = menu_get_prompt(menu); struct symbol *sym; int res; @@ -1084,8 +1087,8 @@ static void conf(struct menu *menu) if (!child_count) break; - show_menu(prompt ? _(prompt) : _("Main Menu"), - _(menu_instructions), + show_menu(prompt ? prompt : "Main Menu", + menu_instructions, current_index, &last_top_row); keypad((menu_win(curses_menu)), TRUE); while (!global_exit) { @@ -1208,12 +1211,9 @@ static void conf(struct menu *menu) } } -static void conf_message_callback(const char *fmt, va_list ap) +static void conf_message_callback(const char *s) { - char buf[1024]; - - vsnprintf(buf, sizeof(buf), fmt, ap); - btn_dialog(main_window, buf, 1, ""); + btn_dialog(main_window, s, 1, ""); } static void show_help(struct menu *menu) @@ -1225,14 +1225,14 @@ static void show_help(struct menu *menu) help = str_new(); menu_get_ext_help(menu, &help); - show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); + show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help)); str_free(&help); } static void conf_choice(struct menu *menu) { - const char *prompt = _(menu_get_prompt(menu)); - struct menu *child = 0; + const char *prompt = menu_get_prompt(menu); + struct menu *child = NULL; struct symbol *active; int selected_index = 0; int last_top_row = 0; @@ -1254,13 +1254,13 @@ static void conf_choice(struct menu *menu) if (child->sym == sym_get_choice_value(menu->sym)) item_make(child, ':', " %s", - _(menu_get_prompt(child))); + menu_get_prompt(child)); else if (child->sym) item_make(child, ':', " %s", - _(menu_get_prompt(child))); + menu_get_prompt(child)); else item_make(child, ':', "*** %s ***", - _(menu_get_prompt(child))); + menu_get_prompt(child)); if (child->sym == active){ last_top_row = top_row(curses_menu); @@ -1268,8 +1268,8 @@ static void conf_choice(struct menu *menu) } i++; } - show_menu(prompt ? _(prompt) : _("Choice Menu"), - _(radiolist_instructions), + show_menu(prompt ? prompt : "Choice Menu", + radiolist_instructions, selected_index, &last_top_row); while (!global_exit) { @@ -1356,19 +1356,19 @@ static void conf_string(struct menu *menu) switch (sym_get_type(menu->sym)) { case S_INT: - heading = _(inputbox_instructions_int); + heading = inputbox_instructions_int; break; case S_HEX: - heading = _(inputbox_instructions_hex); + heading = inputbox_instructions_hex; break; case S_STRING: - heading = _(inputbox_instructions_string); + heading = inputbox_instructions_string; break; default: - heading = _("Internal nconf error!"); + heading = "Internal nconf error!"; } res = dialog_inputbox(main_window, - prompt ? _(prompt) : _("Main Menu"), + prompt ? prompt : "Main Menu", heading, sym_get_string_value(menu->sym), &dialog_input_result, @@ -1379,7 +1379,7 @@ static void conf_string(struct menu *menu) dialog_input_result)) return; btn_dialog(main_window, - _("You have made an invalid entry."), 0); + "You have made an invalid entry.", 0); break; case 1: show_help(menu); @@ -1408,11 +1408,11 @@ static void conf_load(void) sym_set_change_count(1); return; } - btn_dialog(main_window, _("File does not exist!"), 0); + btn_dialog(main_window, "File does not exist!", 0); break; case 1: show_scroll_win(main_window, - _("Load Alternate Configuration"), + "Load Alternate Configuration", load_config_help); break; case KEY_EXIT: @@ -1439,13 +1439,13 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - btn_dialog(main_window, _("Can't create file! " - "Probably a nonexistent directory."), + btn_dialog(main_window, "Can't create file! " + "Probably a nonexistent directory.", 1, ""); break; case 1: show_scroll_win(main_window, - _("Save Alternate Configuration"), + "Save Alternate Configuration", save_config_help); break; case KEY_EXIT: @@ -1454,7 +1454,7 @@ static void conf_save(void) } } -void setup_windows(void) +static void setup_windows(void) { int lines, columns; @@ -1478,10 +1478,11 @@ int main(int ac, char **av) int lines, columns; char *mode; - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - + if (ac > 1 && strcmp(av[1], "-s") == 0) { + /* Silence conf_read() until the real callback is set up */ + conf_set_message_callback(NULL); + av++; + } conf_parse(av[1]); conf_read(NULL); @@ -1534,8 +1535,8 @@ int main(int ac, char **av) /* check for KEY_FUNC(1) */ if (has_key(KEY_F(1)) == FALSE) { show_scroll_win(main_window, - _("Instructions"), - _(menu_no_f_instructions)); + "Instructions", + menu_no_f_instructions); } conf_set_message_callback(conf_message_callback); diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 8275f0e551..88874acfda 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -6,6 +6,7 @@ * */ #include "nconf.h" +#include "lkc.h" /* a list of all the different widgets we use */ attributes_t attributes[ATTR_MAX+1] = {0}; @@ -129,7 +130,7 @@ static void no_colors_theme(void) mkattrn(FUNCTION_TEXT, A_REVERSE); } -void set_colors() +void set_colors(void) { start_color(); use_default_colors(); @@ -192,7 +193,7 @@ const char *get_line(const char *text, int line_no) int lines = 0; if (!text) - return 0; + return NULL; for (i = 0; text[i] != '\0' && lines < line_no; i++) if (text[i] == '\n') @@ -364,15 +365,17 @@ int dialog_inputbox(WINDOW *main_window, WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; - int i, x, y; + int i, x, y, lines, columns, win_lines, win_cols; int res = -1; int cursor_position = strlen(init); int cursor_form_win; char *result = *resultp; + getmaxyx(stdscr, lines, columns); + if (strlen(init)+1 > *result_len) { *result_len = strlen(init)+1; - *resultp = result = realloc(result, *result_len); + *resultp = result = xrealloc(result, *result_len); } /* find the widest line of msg: */ @@ -386,14 +389,19 @@ int dialog_inputbox(WINDOW *main_window, if (title) prompt_width = max(prompt_width, strlen(title)); + win_lines = min(prompt_lines+6, lines-2); + win_cols = min(prompt_width+7, columns-2); + prompt_lines = max(win_lines-6, 0); + prompt_width = max(win_cols-7, 0); + /* place dialog in middle of screen */ - y = (getmaxy(stdscr)-(prompt_lines+4))/2; - x = (getmaxx(stdscr)-(prompt_width+4))/2; + y = (lines-win_lines)/2; + x = (columns-win_cols)/2; strncpy(result, init, *result_len); /* create the windows */ - win = newwin(prompt_lines+6, prompt_width+7, y, x); + win = newwin(win_lines, win_cols, 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); diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index 0d5261705e..2b9e19f603 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h @@ -14,8 +14,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -24,8 +23,6 @@ #include #include -#include "ncurses.h" - #define max(a, b) ({\ typeof(a) _a = a;\ typeof(b) _b = b;\ diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c new file mode 100644 index 0000000000..5ca2df790d --- /dev/null +++ b/scripts/kconfig/preprocess.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2018 Masahiro Yamada + +#include +#include +#include +#include +#include + +#include "list.h" + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +static char *expand_string_with_args(const char *in, int argc, char *argv[]); + +static void __attribute__((noreturn)) pperror(const char *format, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", current_file->name, yylineno); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fprintf(stderr, "\n"); + + exit(1); +} + +/* + * Environment variables + */ +static LIST_HEAD(env_list); + +struct env { + char *name; + char *value; + struct list_head node; +}; + +static void env_add(const char *name, const char *value) +{ + struct env *e; + + e = xmalloc(sizeof(*e)); + e->name = xstrdup(name); + e->value = xstrdup(value); + + list_add_tail(&e->node, &env_list); +} + +static void env_del(struct env *e) +{ + list_del(&e->node); + free(e->name); + free(e->value); + free(e); +} + +/* The returned pointer must be freed when done */ +static char *env_expand(const char *name) +{ + struct env *e; + const char *value; + + if (!*name) + return NULL; + + list_for_each_entry(e, &env_list, node) { + if (!strcmp(name, e->name)) + return xstrdup(e->value); + } + + value = getenv(name); + if (!value) + return NULL; + + /* + * We need to remember all referenced environment variables. + * They will be written out to include/config/auto.conf.cmd + */ + env_add(name, value); + + return xstrdup(value); +} + +void env_write_dep(FILE *f, const char *autoconfig_name) +{ + struct env *e, *tmp; + + list_for_each_entry_safe(e, tmp, &env_list, node) { + fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value); + fprintf(f, "%s: FORCE\n", autoconfig_name); + fprintf(f, "endif\n"); + env_del(e); + } +} + +/* + * Built-in functions + */ +struct function { + const char *name; + unsigned int min_args; + unsigned int max_args; + char *(*func)(int argc, char *argv[]); +}; + +static char *do_error_if(int argc, char *argv[]) +{ + if (!strcmp(argv[0], "y")) + pperror("%s", argv[1]); + + return NULL; +} + +static char *do_filename(int argc, char *argv[]) +{ + return xstrdup(current_file->name); +} + +static char *do_info(int argc, char *argv[]) +{ + printf("%s\n", argv[0]); + + return xstrdup(""); +} + +static char *do_lineno(int argc, char *argv[]) +{ + char buf[16]; + + sprintf(buf, "%d", yylineno); + + return xstrdup(buf); +} + +static char *do_shell(int argc, char *argv[]) +{ + FILE *p; + char buf[256]; + char *cmd; + size_t nread; + int i; + + cmd = argv[0]; + + p = popen(cmd, "r"); + if (!p) { + perror(cmd); + exit(1); + } + + nread = fread(buf, 1, sizeof(buf), p); + if (nread == sizeof(buf)) + nread--; + + /* remove trailing new lines */ + while (nread > 0 && buf[nread - 1] == '\n') + nread--; + + buf[nread] = 0; + + /* replace a new line with a space */ + for (i = 0; i < nread; i++) { + if (buf[i] == '\n') + buf[i] = ' '; + } + + if (pclose(p) == -1) { + perror(cmd); + exit(1); + } + + return xstrdup(buf); +} + +static char *do_warning_if(int argc, char *argv[]) +{ + if (!strcmp(argv[0], "y")) + fprintf(stderr, "%s:%d: %s\n", + current_file->name, yylineno, argv[1]); + + return xstrdup(""); +} + +static const struct function function_table[] = { + /* Name MIN MAX Function */ + { "error-if", 2, 2, do_error_if }, + { "filename", 0, 0, do_filename }, + { "info", 1, 1, do_info }, + { "lineno", 0, 0, do_lineno }, + { "shell", 1, 1, do_shell }, + { "warning-if", 2, 2, do_warning_if }, +}; + +#define FUNCTION_MAX_ARGS 16 + +static char *function_expand(const char *name, int argc, char *argv[]) +{ + const struct function *f; + int i; + + for (i = 0; i < ARRAY_SIZE(function_table); i++) { + f = &function_table[i]; + if (strcmp(f->name, name)) + continue; + + if (argc < f->min_args) + pperror("too few function arguments passed to '%s'", + name); + + if (argc > f->max_args) + pperror("too many function arguments passed to '%s'", + name); + + return f->func(argc, argv); + } + + return NULL; +} + +/* + * Variables (and user-defined functions) + */ +static LIST_HEAD(variable_list); + +struct variable { + char *name; + char *value; + enum variable_flavor flavor; + int exp_count; + struct list_head node; +}; + +static struct variable *variable_lookup(const char *name) +{ + struct variable *v; + + list_for_each_entry(v, &variable_list, node) { + if (!strcmp(name, v->name)) + return v; + } + + return NULL; +} + +static char *variable_expand(const char *name, int argc, char *argv[]) +{ + struct variable *v; + char *res; + + v = variable_lookup(name); + if (!v) + return NULL; + + if (argc == 0 && v->exp_count) + pperror("Recursive variable '%s' references itself (eventually)", + name); + + if (v->exp_count > 1000) + pperror("Too deep recursive expansion"); + + v->exp_count++; + + if (v->flavor == VAR_RECURSIVE) + res = expand_string_with_args(v->value, argc, argv); + else + res = xstrdup(v->value); + + v->exp_count--; + + return res; +} + +void variable_add(const char *name, const char *value, + enum variable_flavor flavor) +{ + struct variable *v; + char *new_value; + bool append = false; + + v = variable_lookup(name); + if (v) { + /* For defined variables, += inherits the existing flavor */ + if (flavor == VAR_APPEND) { + flavor = v->flavor; + append = true; + } else { + free(v->value); + } + } else { + /* For undefined variables, += assumes the recursive flavor */ + if (flavor == VAR_APPEND) + flavor = VAR_RECURSIVE; + + v = xmalloc(sizeof(*v)); + v->name = xstrdup(name); + v->exp_count = 0; + list_add_tail(&v->node, &variable_list); + } + + v->flavor = flavor; + + if (flavor == VAR_SIMPLE) + new_value = expand_string(value); + else + new_value = xstrdup(value); + + if (append) { + v->value = xrealloc(v->value, + strlen(v->value) + strlen(new_value) + 2); + strcat(v->value, " "); + strcat(v->value, new_value); + free(new_value); + } else { + v->value = new_value; + } +} + +static void variable_del(struct variable *v) +{ + list_del(&v->node); + free(v->name); + free(v->value); + free(v); +} + +void variable_all_del(void) +{ + struct variable *v, *tmp; + + list_for_each_entry_safe(v, tmp, &variable_list, node) + variable_del(v); +} + +/* + * Evaluate a clause with arguments. argc/argv are arguments from the upper + * function call. + * + * Returned string must be freed when done + */ +static char *eval_clause(const char *str, size_t len, int argc, char *argv[]) +{ + char *tmp, *name, *res, *endptr, *prev, *p; + int new_argc = 0; + char *new_argv[FUNCTION_MAX_ARGS]; + int nest = 0; + int i; + unsigned long n; + + tmp = xstrndup(str, len); + + /* + * If variable name is '1', '2', etc. It is generally an argument + * from a user-function call (i.e. local-scope variable). If not + * available, then look-up global-scope variables. + */ + n = strtoul(tmp, &endptr, 10); + if (!*endptr && n > 0 && n <= argc) { + res = xstrdup(argv[n - 1]); + goto free_tmp; + } + + prev = p = tmp; + + /* + * Split into tokens + * The function name and arguments are separated by a comma. + * For example, if the function call is like this: + * $(foo,$(x),$(y)) + * + * The input string for this helper should be: + * foo,$(x),$(y) + * + * and split into: + * new_argv[0] = 'foo' + * new_argv[1] = '$(x)' + * new_argv[2] = '$(y)' + */ + while (*p) { + if (nest == 0 && *p == ',') { + *p = 0; + if (new_argc >= FUNCTION_MAX_ARGS) + pperror("too many function arguments"); + new_argv[new_argc++] = prev; + prev = p + 1; + } else if (*p == '(') { + nest++; + } else if (*p == ')') { + nest--; + } + + p++; + } + new_argv[new_argc++] = prev; + + /* + * Shift arguments + * new_argv[0] represents a function name or a variable name. Put it + * into 'name', then shift the rest of the arguments. This simplifies + * 'const' handling. + */ + name = expand_string_with_args(new_argv[0], argc, argv); + new_argc--; + for (i = 0; i < new_argc; i++) + new_argv[i] = expand_string_with_args(new_argv[i + 1], + argc, argv); + + /* Search for variables */ + res = variable_expand(name, new_argc, new_argv); + if (res) + goto free; + + /* Look for built-in functions */ + res = function_expand(name, new_argc, new_argv); + if (res) + goto free; + + /* Last, try environment variable */ + if (new_argc == 0) { + res = env_expand(name); + if (res) + goto free; + } + + res = xstrdup(""); +free: + for (i = 0; i < new_argc; i++) + free(new_argv[i]); + free(name); +free_tmp: + free(tmp); + + return res; +} + +/* + * Expand a string that follows '$' + * + * For example, if the input string is + * ($(FOO)$($(BAR)))$(BAZ) + * this helper evaluates + * $($(FOO)$($(BAR))) + * and returns a new string containing the expansion (note that the string is + * recursively expanded), also advancing 'str' to point to the next character + * after the corresponding closing parenthesis, in this case, *str will be + * $(BAR) + */ +static char *expand_dollar_with_args(const char **str, int argc, char *argv[]) +{ + const char *p = *str; + const char *q; + int nest = 0; + + /* + * In Kconfig, variable/function references always start with "$(". + * Neither single-letter variables as in $A nor curly braces as in ${CC} + * are supported. '$' not followed by '(' loses its special meaning. + */ + if (*p != '(') { + *str = p; + return xstrdup("$"); + } + + p++; + q = p; + while (*q) { + if (*q == '(') { + nest++; + } else if (*q == ')') { + if (nest-- == 0) + break; + } + q++; + } + + if (!*q) + pperror("unterminated reference to '%s': missing ')'", p); + + /* Advance 'str' to after the expanded initial portion of the string */ + *str = q + 1; + + return eval_clause(p, q - p, argc, argv); +} + +char *expand_dollar(const char **str) +{ + return expand_dollar_with_args(str, 0, NULL); +} + +static char *__expand_string(const char **str, bool (*is_end)(char c), + int argc, char *argv[]) +{ + const char *in, *p; + char *expansion, *out; + size_t in_len, out_len; + + out = xmalloc(1); + *out = 0; + out_len = 1; + + p = in = *str; + + while (1) { + if (*p == '$') { + in_len = p - in; + p++; + expansion = expand_dollar_with_args(&p, argc, argv); + out_len += in_len + strlen(expansion); + out = xrealloc(out, out_len); + strncat(out, in, in_len); + strcat(out, expansion); + free(expansion); + in = p; + continue; + } + + if (is_end(*p)) + break; + + p++; + } + + in_len = p - in; + out_len += in_len; + out = xrealloc(out, out_len); + strncat(out, in, in_len); + + /* Advance 'str' to the end character */ + *str = p; + + return out; +} + +static bool is_end_of_str(char c) +{ + return !c; +} + +/* + * Expand variables and functions in the given string. Undefined variables + * expand to an empty string. + * The returned string must be freed when done. + */ +static char *expand_string_with_args(const char *in, int argc, char *argv[]) +{ + return __expand_string(&in, is_end_of_str, argc, argv); +} + +char *expand_string(const char *in) +{ + return expand_string_with_args(in, 0, NULL); +} + +static bool is_end_of_token(char c) +{ + /* Why are '.' and '/' valid characters for symbols? */ + return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/'); +} + +/* + * Expand variables in a token. The parsing stops when a token separater + * (in most cases, it is a whitespace) is encountered. 'str' is updated to + * point to the next character. + * + * The returned string must be freed when done. + */ +char *expand_one_token(const char **str) +{ + return __expand_string(str, is_end_of_token, 0, NULL); +} diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh new file mode 100755 index 0000000000..02ccc0ae10 --- /dev/null +++ b/scripts/kconfig/qconf-cfg.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="Qt5Core Qt5Gui Qt5Widgets" +PKG2="QtCore QtGui" + +if [ -z "$(command -v pkg-config)" ]; then + echo >&2 "*" + echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it." + echo >&2 "*" + exit 1 +fi + +if pkg-config --exists $PKG; then + echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\" + echo libs=\"$(pkg-config --libs $PKG)\" + echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\" + exit 0 +fi + +if pkg-config --exists $PKG2; then + echo cflags=\"$(pkg-config --cflags $PKG2)\" + echo libs=\"$(pkg-config --libs $PKG2)\" + echo moc=\"$(pkg-config --variable=moc_location QtCore)\" + exit 0 +fi + +echo >&2 "*" +echo >&2 "* Could not find Qt via pkg-config." +echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH" +echo >&2 "*" +exit 1 diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 9d3b04b076..ef4310f255 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1,32 +1,17 @@ /* * Copyright (C) 2002 Roman Zippel + * Copyright (C) 2015 Boris Barbulovski * Released under the terms of the GNU GPL v2.0. */ #include -#if QT_VERSION < 0x040000 -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif +#include +#include +#include #include #include @@ -49,24 +34,15 @@ #include "qconf.moc" #include "images.c" -#ifdef _ -# undef _ -# define _ qgettext -#endif static QApplication *configApp; static ConfigSettings *configSettings; -Q3Action *ConfigMainWindow::saveAction; +QAction *ConfigMainWindow::saveAction; static inline QString qgettext(const char* str) { - return QString::fromLocal8Bit(gettext(str)); -} - -static inline QString qgettext(const QString& str) -{ - return QString::fromLocal8Bit(gettext(str.latin1())); + return QString::fromLocal8Bit(str); } ConfigSettings::ConfigSettings() @@ -77,14 +53,22 @@ ConfigSettings::ConfigSettings() /** * Reads a list of integer values from the application settings. */ -Q3ValueList ConfigSettings::readSizes(const QString& key, bool *ok) +QList ConfigSettings::readSizes(const QString& key, bool *ok) { - Q3ValueList result; - QStringList entryList = readListEntry(key, ok); - QStringList::Iterator it; + QList result; + + if (contains(key)) + { + QStringList entryList = value(key).toStringList(); + QStringList::Iterator it; - for (it = entryList.begin(); it != entryList.end(); ++it) - result.push_back((*it).toInt()); + for (it = entryList.begin(); it != entryList.end(); ++it) + result.push_back((*it).toInt()); + + *ok = true; + } + else + *ok = false; return result; } @@ -92,14 +76,16 @@ Q3ValueList ConfigSettings::readSizes(const QString& key, bool *ok) /** * Writes a list of integer values to the application settings. */ -bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList& value) +bool ConfigSettings::writeSizes(const QString& key, const QList& value) { QStringList stringList; - Q3ValueList::ConstIterator it; + QList::ConstIterator it; for (it = value.begin(); it != value.end(); ++it) stringList.push_back(QString::number(*it)); - return writeEntry(key, stringList); + setValue(key, stringList); + + return true; } @@ -109,9 +95,6 @@ bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList& valu */ void ConfigItem::okRename(int col) { - Parent::okRename(col); - sym_set_string_value(menu->sym, text(dataColIdx).latin1()); - listView()->updateList(this); } /* @@ -135,7 +118,7 @@ void ConfigItem::updateMenu(void) sym = menu->sym; prop = menu->prompt; - prompt = _(menu_get_prompt(menu)); + prompt = qgettext(menu_get_prompt(menu)); if (prop) switch (prop->type) { case P_MENU: @@ -149,11 +132,11 @@ void ConfigItem::updateMenu(void) } else { if (sym) break; - setPixmap(promptColIdx, 0); + setPixmap(promptColIdx, QIcon()); } goto set_prompt; case P_COMMENT: - setPixmap(promptColIdx, 0); + setPixmap(promptColIdx, QIcon()); goto set_prompt; default: ; @@ -170,7 +153,7 @@ void ConfigItem::updateMenu(void) char ch; if (!sym_is_changable(sym) && list->optMode == normalOpt) { - setPixmap(promptColIdx, 0); + setPixmap(promptColIdx, QIcon()); setText(noColIdx, QString::null); setText(modColIdx, QString::null); setText(yesColIdx, QString::null); @@ -216,9 +199,6 @@ void ConfigItem::updateMenu(void) data = sym_get_string_value(sym); - int i = list->mapIdx(dataColIdx); - if (i >= 0) - setRenameEnabled(i, TRUE); setText(dataColIdx, data); if (type == S_STRING) prompt = QString("%1: %2").arg(prompt).arg(data); @@ -227,7 +207,7 @@ void ConfigItem::updateMenu(void) break; } if (!sym_has_value(sym) && visible) - prompt += _(" (NEW)"); + prompt += " (NEW)"; set_prompt: setText(promptColIdx, prompt); } @@ -250,18 +230,6 @@ void ConfigItem::testUpdateMenu(bool v) updateMenu(); } -void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) -{ - ConfigList* list = listView(); - - if (visible) { - if (isSelected() && !list->hasFocus() && list->mode == menuMode) - Parent::paintCell(p, list->inactivedColorGroup, column, width, align); - else - Parent::paintCell(p, cg, column, width, align); - } else - Parent::paintCell(p, list->disabledColorGroup, column, width, align); -} /* * construct a menu entry @@ -274,7 +242,7 @@ void ConfigItem::init(void) menu->data = this; if (list->mode != fullMode) - setOpen(TRUE); + setExpanded(true); sym_calc_value(menu->sym); } updateMenu(); @@ -299,7 +267,7 @@ ConfigItem::~ConfigItem(void) ConfigLineEdit::ConfigLineEdit(ConfigView* parent) : Parent(parent) { - connect(this, SIGNAL(lostFocus()), SLOT(hide())); + connect(this, SIGNAL(editingFinished()), SLOT(hide())); } void ConfigLineEdit::show(ConfigItem* i) @@ -320,7 +288,7 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e) break; case Qt::Key_Return: case Qt::Key_Enter: - sym_set_string_value(item->menu->sym, text().latin1()); + sym_set_string_value(item->menu->sym, text().toLatin1()); parent()->updateList(item); break; default: @@ -333,39 +301,39 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e) } ConfigList::ConfigList(ConfigView* p, const char *name) - : Parent(p, name), + : Parent(p), updateAll(false), symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), - showName(false), showRange(false), showData(false), optMode(normalOpt), + showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt), rootEntry(0), headerPopup(0) { int i; - setSorting(-1); - setRootIsDecorated(TRUE); - disabledColorGroup = palette().active(); - disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text()); - inactivedColorGroup = palette().active(); - inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight()); + setObjectName(name); + setSortingEnabled(false); + setRootIsDecorated(true); - connect(this, SIGNAL(selectionChanged(void)), + setVerticalScrollMode(ScrollPerPixel); + setHorizontalScrollMode(ScrollPerPixel); + + setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value"); + + connect(this, SIGNAL(itemSelectionChanged(void)), SLOT(updateSelection(void))); if (name) { configSettings->beginGroup(name); - showName = configSettings->readBoolEntry("/showName", false); - showRange = configSettings->readBoolEntry("/showRange", false); - showData = configSettings->readBoolEntry("/showData", false); - optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false); + showName = configSettings->value("/showName", false).toBool(); + showRange = configSettings->value("/showRange", false).toBool(); + showData = configSettings->value("/showData", false).toBool(); + optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt(); configSettings->endGroup(); connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); } - for (i = 0; i < colNr; i++) - colMap[i] = colRevMap[i] = -1; - addColumn(promptColIdx, _("Option")); + addColumn(promptColIdx); reinit(); } @@ -390,26 +358,26 @@ void ConfigList::reinit(void) removeColumn(nameColIdx); if (showName) - addColumn(nameColIdx, _("Name")); + addColumn(nameColIdx); if (showRange) { - addColumn(noColIdx, "N"); - addColumn(modColIdx, "M"); - addColumn(yesColIdx, "Y"); + addColumn(noColIdx); + addColumn(modColIdx); + addColumn(yesColIdx); } if (showData) - addColumn(dataColIdx, _("Value")); + addColumn(dataColIdx); updateListAll(); } void ConfigList::saveSettings(void) { - if (name()) { - configSettings->beginGroup(name()); - configSettings->writeEntry("/showName", showName); - configSettings->writeEntry("/showRange", showRange); - configSettings->writeEntry("/showData", showData); - configSettings->writeEntry("/optionMode", (int)optMode); + if (!objectName().isEmpty()) { + configSettings->beginGroup(objectName()); + configSettings->setValue("/showName", showName); + configSettings->setValue("/showRange", showRange); + configSettings->setValue("/showData", showData); + configSettings->setValue("/optionMode", (int)optMode); configSettings->endGroup(); } } @@ -431,7 +399,10 @@ void ConfigList::updateSelection(void) struct menu *menu; enum prop_type type; - ConfigItem* item = (ConfigItem*)selectedItem(); + if (selectedItems().count() == 0) + return; + + ConfigItem* item = (ConfigItem*)selectedItems().first(); if (!item) return; @@ -451,21 +422,23 @@ void ConfigList::updateList(ConfigItem* item) if (!rootEntry) { if (mode != listMode) goto update; - Q3ListViewItemIterator it(this); + QTreeWidgetItemIterator it(this); ConfigItem* item; - for (; it.current(); ++it) { - item = (ConfigItem*)it.current(); + while (*it) { + item = (ConfigItem*)(*it); if (!item->menu) continue; item->testUpdateMenu(menu_is_visible(item->menu)); + + ++it; } return; } if (rootEntry != &rootmenu && (mode == singleMode || (mode == symbolMode && rootEntry->parent != &rootmenu))) { - item = firstChild(); + item = (ConfigItem *)topLevelItem(0); if (!item) item = new ConfigItem(this, 0, true); last = item; @@ -479,12 +452,14 @@ void ConfigList::updateList(ConfigItem* item) item->testUpdateMenu(true); updateMenuList(item, rootEntry); - triggerUpdate(); + update(); + resizeColumnToContents(0); return; } update: updateMenuList(this, rootEntry); - triggerUpdate(); + update(); + resizeColumnToContents(0); } void ConfigList::setValue(ConfigItem* item, tristate val) @@ -506,7 +481,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val) if (!sym_set_tristate_value(sym, val)) return; if (oldval == no && item->menu->list) - item->setOpen(TRUE); + item->setExpanded(true); parent()->updateList(item); break; } @@ -524,7 +499,7 @@ void ConfigList::changeValue(ConfigItem* item) sym = menu->sym; if (!sym) { if (item->menu->list) - item->setOpen(!item->isOpen()); + item->setExpanded(!item->isExpanded()); return; } @@ -536,9 +511,9 @@ void ConfigList::changeValue(ConfigItem* item) newexpr = sym_toggle_tristate_value(sym); if (item->menu->list) { if (oldexpr == newexpr) - item->setOpen(!item->isOpen()); + item->setExpanded(!item->isExpanded()); else if (oldexpr == no) - item->setOpen(TRUE); + item->setExpanded(true); } if (oldexpr != newexpr) parent()->updateList(item); @@ -546,10 +521,7 @@ void ConfigList::changeValue(ConfigItem* item) case S_INT: case S_HEX: case S_STRING: - if (colMap[dataColIdx] >= 0) - item->startRename(colMap[dataColIdx]); - else - parent()->lineEdit->show(item); + parent()->lineEdit->show(item); break; } } @@ -566,8 +538,10 @@ void ConfigList::setRootMenu(struct menu *menu) updateMenuList(this, 0); rootEntry = menu; updateListAll(); - setSelected(currentItem(), hasFocus()); - ensureItemVisible(currentItem()); + if (currentItem()) { + currentItem()->setSelected(hasFocus()); + scrollToItem(currentItem()); + } } void ConfigList::setParentMenu(void) @@ -580,13 +554,16 @@ void ConfigList::setParentMenu(void) return; setRootMenu(menu_get_parent_menu(rootEntry->parent)); - Q3ListViewItemIterator it(this); - for (; (item = (ConfigItem*)it.current()); it++) { + QTreeWidgetItemIterator it(this); + while (*it) { + item = (ConfigItem *)(*it); if (item->menu == oldroot) { setCurrentItem(item); - ensureItemVisible(item); + scrollToItem(item); break; } + + ++it; } } @@ -597,8 +574,7 @@ void ConfigList::setParentMenu(void) * parent: either the menu list widget or a menu entry widget * menu: entry to be updated */ -template -void ConfigList::updateMenuList(P* parent, struct menu* menu) +void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) { struct menu* child; ConfigItem* item; @@ -607,8 +583,11 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) enum prop_type type; if (!menu) { - while ((item = parent->firstChild())) - delete item; + while (parent->childCount() > 0) + { + delete parent->takeChild(0); + } + return; } @@ -660,9 +639,74 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) } } +void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu) +{ + struct menu* child; + ConfigItem* item; + ConfigItem* last; + bool visible; + enum prop_type type; + + if (!menu) { + while (parent->topLevelItemCount() > 0) + { + delete parent->takeTopLevelItem(0); + } + + return; + } + + last = (ConfigItem*)parent->topLevelItem(0); + if (last && !last->goParent) + last = 0; + for (child = menu->list; child; child = child->next) { + item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0); + type = child->prompt ? child->prompt->type : P_UNKNOWN; + + switch (mode) { + case menuMode: + if (!(child->flags & MENU_ROOT)) + goto hide; + break; + case symbolMode: + if (child->flags & MENU_ROOT) + goto hide; + break; + default: + break; + } + + visible = menu_is_visible(child); + if (!menuSkip(child)) { + if (!child->sym && !child->list && !child->prompt) + continue; + if (!item || item->menu != child) + item = new ConfigItem(parent, last, child, visible); + else + item->testUpdateMenu(visible); + + if (mode == fullMode || mode == menuMode || type != P_MENU) + updateMenuList(item, child); + else + updateMenuList(item, 0); + last = item; + continue; + } + hide: + if (item && item->menu == child) { + last = (ConfigItem*)parent->topLevelItem(0); + if (last == item) + last = 0; + else while (last->nextSibling() != item) + last = last->nextSibling(); + delete item; + } + } +} + void ConfigList::keyPressEvent(QKeyEvent* ev) { - Q3ListViewItem* i = currentItem(); + QTreeWidgetItem* i = currentItem(); ConfigItem* item; struct menu *menu; enum prop_type type; @@ -714,20 +758,20 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) ev->accept(); } -void ConfigList::contentsMousePressEvent(QMouseEvent* e) +void ConfigList::mousePressEvent(QMouseEvent* e) { //QPoint p(contentsToViewport(e->pos())); //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); - Parent::contentsMousePressEvent(e); + Parent::mousePressEvent(e); } -void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) +void ConfigList::mouseReleaseEvent(QMouseEvent* e) { - QPoint p(contentsToViewport(e->pos())); + QPoint p = e->pos(); ConfigItem* item = (ConfigItem*)itemAt(p); struct menu *menu; enum prop_type ptype; - const QPixmap* pm; + QIcon icon; int idx, x; if (!item) @@ -735,14 +779,13 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) menu = item->menu; x = header()->offset() + p.x(); - idx = colRevMap[header()->sectionAt(x)]; + idx = header()->logicalIndexAt(x); switch (idx) { case promptColIdx: - pm = item->pixmap(promptColIdx); - if (pm) { - int off = header()->sectionPos(0) + itemMargin() + - treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0)); - if (x >= off && x < off + pm->width()) { + icon = item->pixmap(promptColIdx); + if (!icon.isNull()) { + int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly. + if (x >= off && x < off + icon.availableSizes().first().width()) { if (item->goParent) { emit parentSelected(); break; @@ -773,19 +816,19 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) skip: //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); - Parent::contentsMouseReleaseEvent(e); + Parent::mouseReleaseEvent(e); } -void ConfigList::contentsMouseMoveEvent(QMouseEvent* e) +void ConfigList::mouseMoveEvent(QMouseEvent* e) { //QPoint p(contentsToViewport(e->pos())); //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); - Parent::contentsMouseMoveEvent(e); + Parent::mouseMoveEvent(e); } -void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) +void ConfigList::mouseDoubleClickEvent(QMouseEvent* e) { - QPoint p(contentsToViewport(e->pos())); + QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport). ConfigItem* item = (ConfigItem*)itemAt(p); struct menu *menu; enum prop_type ptype; @@ -807,7 +850,7 @@ void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) skip: //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y()); - Parent::contentsMouseDoubleClickEvent(e); + Parent::mouseDoubleClickEvent(e); } void ConfigList::focusInEvent(QFocusEvent *e) @@ -818,7 +861,7 @@ void ConfigList::focusInEvent(QFocusEvent *e) ConfigItem* item = (ConfigItem *)currentItem(); if (item) { - setSelected(item, TRUE); + item->setSelected(true); menu = item->menu; } emit gotFocus(menu); @@ -828,33 +871,33 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) { if (e->y() <= header()->geometry().bottom()) { if (!headerPopup) { - Q3Action *action; + QAction *action; - headerPopup = new Q3PopupMenu(this); - action = new Q3Action(NULL, _("Show Name"), 0, this); - action->setToggleAction(TRUE); + headerPopup = new QMenu(this); + action = new QAction("Show Name", this); + action->setCheckable(true); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowName(bool))); connect(parent(), SIGNAL(showNameChanged(bool)), action, SLOT(setOn(bool))); - action->setOn(showName); - action->addTo(headerPopup); - action = new Q3Action(NULL, _("Show Range"), 0, this); - action->setToggleAction(TRUE); + action->setChecked(showName); + headerPopup->addAction(action); + action = new QAction("Show Range", this); + action->setCheckable(true); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowRange(bool))); connect(parent(), SIGNAL(showRangeChanged(bool)), action, SLOT(setOn(bool))); - action->setOn(showRange); - action->addTo(headerPopup); - action = new Q3Action(NULL, _("Show Data"), 0, this); - action->setToggleAction(TRUE); + action->setChecked(showRange); + headerPopup->addAction(action); + action = new QAction("Show Data", this); + action->setCheckable(true); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowData(bool))); connect(parent(), SIGNAL(showDataChanged(bool)), action, SLOT(setOn(bool))); - action->setOn(showData); - action->addTo(headerPopup); + action->setChecked(showData); + headerPopup->addAction(action); } headerPopup->exec(e->globalPos()); e->accept(); @@ -868,11 +911,17 @@ QAction *ConfigView::showAllAction; QAction *ConfigView::showPromptAction; ConfigView::ConfigView(QWidget* parent, const char *name) - : Parent(parent, name) + : Parent(parent) { - list = new ConfigList(this, name); + setObjectName(name); + QVBoxLayout *verticalLayout = new QVBoxLayout(this); + verticalLayout->setContentsMargins(0, 0, 0, 0); + + list = new ConfigList(this); + verticalLayout->addWidget(list); lineEdit = new ConfigLineEdit(this); lineEdit->hide(); + verticalLayout->addWidget(lineEdit); this->nextView = viewList; viewList = this; @@ -931,10 +980,13 @@ void ConfigView::setShowData(bool b) void ConfigList::setAllOpen(bool open) { - Q3ListViewItemIterator it(this); + QTreeWidgetItemIterator it(this); - for (; it.current(); it++) - it.current()->setOpen(open); + while (*it) { + (*it)->setExpanded(open); + + ++it; + } } void ConfigView::updateList(ConfigItem* item) @@ -954,11 +1006,14 @@ void ConfigView::updateListAll(void) } ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) - : Parent(parent, name), sym(0), _menu(0) + : Parent(parent), sym(0), _menu(0) { - if (name) { - configSettings->beginGroup(name); - _showDebug = configSettings->readBoolEntry("/showDebug", false); + setObjectName(name); + + + if (!objectName().isEmpty()) { + configSettings->beginGroup(objectName()); + setShowDebug(configSettings->value("/showDebug", false).toBool()); configSettings->endGroup(); connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); } @@ -966,9 +1021,9 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) void ConfigInfoView::saveSettings(void) { - if (name()) { - configSettings->beginGroup(name()); - configSettings->writeEntry("/showDebug", showDebug()); + if (!objectName().isEmpty()) { + configSettings->beginGroup(objectName()); + configSettings->setValue("/showDebug", showDebug()); configSettings->endGroup(); } } @@ -1022,7 +1077,7 @@ void ConfigInfoView::menuInfo(void) if (sym) { if (_menu->prompt) { head += ""; - head += print_filter(_(_menu->prompt->text)); + head += print_filter(_menu->prompt->text); head += ""; if (sym->name) { head += " ("; @@ -1053,7 +1108,7 @@ void ConfigInfoView::menuInfo(void) str_free(&help_gstr); } else if (_menu->prompt) { head += ""; - head += print_filter(_(_menu->prompt->text)); + head += print_filter(_menu->prompt->text); head += "

"; if (showDebug()) { if (_menu->prompt->visible.expr) { @@ -1088,13 +1143,12 @@ QString ConfigInfoView::debug_info(struct symbol *sym) case P_PROMPT: case P_MENU: debug += QString().sprintf("prompt: ", prop->menu); - debug += print_filter(_(prop->text)); + debug += print_filter(prop->text); debug += "
"; break; case P_DEFAULT: case P_SELECT: case P_RANGE: - case P_ENV: debug += prop_get_type_name(prop->type); debug += ": "; expr_print(prop->expr, expr_print_help, &debug, E_NONE); @@ -1127,8 +1181,8 @@ QString ConfigInfoView::print_filter(const QString &str) { QRegExp re("[<>&\"\\n]"); QString res = str; - for (int i = 0; (i = res.find(re, i)) >= 0;) { - switch (res[i].latin1()) { + for (int i = 0; (i = res.indexOf(re, i)) >= 0;) { + switch (res[i].toLatin1()) { case '<': res.replace(i, 1, "<"); i += 4; @@ -1167,37 +1221,42 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *text += str2; } -Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) +QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos) { - Q3PopupMenu* popup = Parent::createPopupMenu(pos); - Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup); - action->setToggleAction(TRUE); + QMenu* popup = Parent::createStandardContextMenu(pos); + QAction* action = new QAction("Show Debug Info", popup); + action->setCheckable(true); connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); - action->setOn(showDebug()); - popup->insertSeparator(); - action->addTo(popup); + action->setChecked(showDebug()); + popup->addSeparator(); + popup->addAction(action); return popup; } -void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e) +void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e) { - Parent::contentsContextMenuEvent(e); + Parent::contextMenuEvent(e); } ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name) - : Parent(parent, name), result(NULL) -{ - setCaption("Search Config"); - - QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6); - QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6); - layout2->addWidget(new QLabel(_("Find:"), this)); + : Parent(parent), result(NULL) +{ + setObjectName(name); + setWindowTitle("Search Config"); + + QVBoxLayout* layout1 = new QVBoxLayout(this); + layout1->setContentsMargins(11, 11, 11, 11); + layout1->setSpacing(6); + QHBoxLayout* layout2 = new QHBoxLayout(0); + layout2->setContentsMargins(0, 0, 0, 0); + layout2->setSpacing(6); + layout2->addWidget(new QLabel("Find:", this)); editField = new QLineEdit(this); connect(editField, SIGNAL(returnPressed()), SLOT(search())); layout2->addWidget(editField); - searchButton = new QPushButton(_("Search"), this); - searchButton->setAutoDefault(FALSE); + searchButton = new QPushButton("Search", this); + searchButton->setAutoDefault(false); connect(searchButton, SIGNAL(clicked()), SLOT(search())); layout2->addWidget(searchButton); layout1->addLayout(layout2); @@ -1215,19 +1274,19 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam layout1->addWidget(split); if (name) { - int x, y, width, height; + QVariant x, y; + int width, height; bool ok; configSettings->beginGroup(name); - width = configSettings->readNumEntry("/window width", parent->width() / 2); - height = configSettings->readNumEntry("/window height", parent->height() / 2); + width = configSettings->value("/window width", parent->width() / 2).toInt(); + height = configSettings->value("/window height", parent->height() / 2).toInt(); resize(width, height); - x = configSettings->readNumEntry("/window x", 0, &ok); - if (ok) - y = configSettings->readNumEntry("/window y", 0, &ok); - if (ok) - move(x, y); - Q3ValueList sizes = configSettings->readSizes("/split", &ok); + x = configSettings->value("/window x"); + y = configSettings->value("/window y"); + if ((x.isValid())&&(y.isValid())) + move(x.toInt(), y.toInt()); + QList sizes = configSettings->readSizes("/split", &ok); if (ok) split->setSizes(sizes); configSettings->endGroup(); @@ -1237,12 +1296,12 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam void ConfigSearchWindow::saveSettings(void) { - if (name()) { - configSettings->beginGroup(name()); - configSettings->writeEntry("/window x", pos().x()); - configSettings->writeEntry("/window y", pos().y()); - configSettings->writeEntry("/window width", size().width()); - configSettings->writeEntry("/window height", size().height()); + if (!objectName().isEmpty()) { + configSettings->beginGroup(objectName()); + configSettings->setValue("/window x", pos().x()); + configSettings->setValue("/window y", pos().y()); + configSettings->setValue("/window width", size().width()); + configSettings->setValue("/window height", size().height()); configSettings->writeSizes("/split", split->sizes()); configSettings->endGroup(); } @@ -1258,7 +1317,7 @@ void ConfigSearchWindow::search(void) list->list->clear(); info->clear(); - result = sym_re_search(editField->text().latin1()); + result = sym_re_search(editField->text().toLatin1()); if (!result) return; for (p = result; *p; p++) { @@ -1275,29 +1334,25 @@ ConfigMainWindow::ConfigMainWindow(void) : searchWindow(0) { QMenuBar* menu; - bool ok; - int x, y, width, height; + bool ok = true; + QVariant x, y; + int width, height; char title[256]; QDesktopWidget *d = configApp->desktop(); snprintf(title, sizeof(title), "%s%s", rootmenu.prompt->text, -#if QT_VERSION < 0x040000 - " (Qt3)" -#else "" -#endif ); - setCaption(title); + setWindowTitle(title); - width = configSettings->readNumEntry("/window width", d->width() - 64); - height = configSettings->readNumEntry("/window height", d->height() - 64); + width = configSettings->value("/window width", d->width() - 64).toInt(); + height = configSettings->value("/window height", d->height() - 64).toInt(); resize(width, height); - x = configSettings->readNumEntry("/window x", 0, &ok); - if (ok) - y = configSettings->readNumEntry("/window y", 0, &ok); - if (ok) - move(x, y); + x = configSettings->value("/window x"); + y = configSettings->value("/window y"); + if ((x.isValid())&&(y.isValid())) + move(x.toInt(), y.toInt()); split1 = new QSplitter(this); split1->setOrientation(Qt::Horizontal); @@ -1314,127 +1369,116 @@ ConfigMainWindow::ConfigMainWindow(void) configList = configView->list; helpText = new ConfigInfoView(split2, "help"); - helpText->setTextFormat(Qt::RichText); setTabOrder(configList, helpText); configList->setFocus(); menu = menuBar(); - toolBar = new Q3ToolBar("Tools", this); - - backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this); - connect(backAction, SIGNAL(activated()), SLOT(goBack())); - backAction->setEnabled(FALSE); - Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this); - connect(quitAction, SIGNAL(activated()), SLOT(close())); - Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this); - connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); - saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this); - connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); + toolBar = new QToolBar("Tools", this); + addToolBar(toolBar); + + backAction = new QAction(QPixmap(xpm_back), "Back", this); + connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack())); + backAction->setEnabled(false); + QAction *quitAction = new QAction("&Quit", this); + quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); + connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); + QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); + loadAction->setShortcut(Qt::CTRL + Qt::Key_L); + connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); + saveAction = new QAction(QPixmap(xpm_save), "&Save", this); + saveAction->setShortcut(Qt::CTRL + Qt::Key_S); + connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig())); conf_set_changed_callback(conf_changed); // Set saveAction's initial state conf_changed(); - Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this); - connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); - Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this); - connect(searchAction, SIGNAL(activated()), SLOT(searchConfig())); - Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this); - connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); - Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this); - connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); - Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this); - connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); - - Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this); - showNameAction->setToggleAction(TRUE); + QAction *saveAsAction = new QAction("Save &As...", this); + connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs())); + QAction *searchAction = new QAction("&Find", this); + searchAction->setShortcut(Qt::CTRL + Qt::Key_F); + connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig())); + singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); + singleViewAction->setCheckable(true); + connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView())); + splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); + splitViewAction->setCheckable(true); + connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView())); + fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); + fullViewAction->setCheckable(true); + connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView())); + + QAction *showNameAction = new QAction("Show Name", this); + showNameAction->setCheckable(true); connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); - connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool))); - showNameAction->setOn(configView->showName()); - Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this); - showRangeAction->setToggleAction(TRUE); + showNameAction->setChecked(configView->showName()); + QAction *showRangeAction = new QAction("Show Range", this); + showRangeAction->setCheckable(true); connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); - connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool))); - showRangeAction->setOn(configList->showRange); - Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this); - showDataAction->setToggleAction(TRUE); + QAction *showDataAction = new QAction("Show Data", this); + showDataAction->setCheckable(true); connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); - connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); - showDataAction->setOn(configList->showData); QActionGroup *optGroup = new QActionGroup(this); - optGroup->setExclusive(TRUE); - connect(optGroup, SIGNAL(selected(QAction *)), configView, + optGroup->setExclusive(true); + connect(optGroup, SIGNAL(triggered(QAction*)), configView, SLOT(setOptionMode(QAction *))); - connect(optGroup, SIGNAL(selected(QAction *)), menuView, + connect(optGroup, SIGNAL(triggered(QAction *)), menuView, SLOT(setOptionMode(QAction *))); -#if QT_VERSION >= 0x040000 - configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup); - configView->showAllAction = new QAction(_("Show All Options"), optGroup); - configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup); -#else - configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup); - configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup); - configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup); -#endif - configView->showNormalAction->setToggleAction(TRUE); - configView->showNormalAction->setOn(configList->optMode == normalOpt); - configView->showAllAction->setToggleAction(TRUE); - configView->showAllAction->setOn(configList->optMode == allOpt); - configView->showPromptAction->setToggleAction(TRUE); - configView->showPromptAction->setOn(configList->optMode == promptOpt); - - Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this); - showDebugAction->setToggleAction(TRUE); + configView->showNormalAction = new QAction("Show Normal Options", optGroup); + configView->showAllAction = new QAction("Show All Options", optGroup); + configView->showPromptAction = new QAction("Show Prompt Options", optGroup); + configView->showNormalAction->setCheckable(true); + configView->showAllAction->setCheckable(true); + configView->showPromptAction->setCheckable(true); + + QAction *showDebugAction = new QAction("Show Debug Info", this); + showDebugAction->setCheckable(true); connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); - connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool))); - showDebugAction->setOn(helpText->showDebug()); + showDebugAction->setChecked(helpText->showDebug()); - Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this); - connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); - Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this); - connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); + QAction *showIntroAction = new QAction("Introduction", this); + connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro())); + QAction *showAboutAction = new QAction("About", this); + connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout())); // init tool bar - backAction->addTo(toolBar); + toolBar->addAction(backAction); toolBar->addSeparator(); - loadAction->addTo(toolBar); - saveAction->addTo(toolBar); + toolBar->addAction(loadAction); + toolBar->addAction(saveAction); toolBar->addSeparator(); - singleViewAction->addTo(toolBar); - splitViewAction->addTo(toolBar); - fullViewAction->addTo(toolBar); + toolBar->addAction(singleViewAction); + toolBar->addAction(splitViewAction); + toolBar->addAction(fullViewAction); // create config menu - Q3PopupMenu* config = new Q3PopupMenu(this); - menu->insertItem(_("&File"), config); - loadAction->addTo(config); - saveAction->addTo(config); - saveAsAction->addTo(config); - config->insertSeparator(); - quitAction->addTo(config); + QMenu* config = menu->addMenu("&File"); + config->addAction(loadAction); + config->addAction(saveAction); + config->addAction(saveAsAction); + config->addSeparator(); + config->addAction(quitAction); // create edit menu - Q3PopupMenu* editMenu = new Q3PopupMenu(this); - menu->insertItem(_("&Edit"), editMenu); - searchAction->addTo(editMenu); + QMenu* editMenu = menu->addMenu("&Edit"); + editMenu->addAction(searchAction); // create options menu - Q3PopupMenu* optionMenu = new Q3PopupMenu(this); - menu->insertItem(_("&Option"), optionMenu); - showNameAction->addTo(optionMenu); - showRangeAction->addTo(optionMenu); - showDataAction->addTo(optionMenu); - optionMenu->insertSeparator(); - optGroup->addTo(optionMenu); - optionMenu->insertSeparator(); + QMenu* optionMenu = menu->addMenu("&Option"); + optionMenu->addAction(showNameAction); + optionMenu->addAction(showRangeAction); + optionMenu->addAction(showDataAction); + optionMenu->addSeparator(); + optionMenu->addActions(optGroup->actions()); + optionMenu->addSeparator(); + optionMenu->addAction(showDebugAction); // create help menu - Q3PopupMenu* helpMenu = new Q3PopupMenu(this); - menu->insertSeparator(); - menu->insertItem(_("&Help"), helpMenu); - showIntroAction->addTo(helpMenu); - showAboutAction->addTo(helpMenu); + menu->addSeparator(); + QMenu* helpMenu = menu->addMenu("&Help"); + helpMenu->addAction(showIntroAction); + helpMenu->addAction(showAboutAction); connect(configList, SIGNAL(menuChanged(struct menu *)), helpText, SLOT(setInfo(struct menu *))); @@ -1456,7 +1500,7 @@ ConfigMainWindow::ConfigMainWindow(void) connect(helpText, SIGNAL(menuSelected(struct menu *)), SLOT(setMenuLink(struct menu *))); - QString listMode = configSettings->readEntry("/listMode", "symbol"); + QString listMode = configSettings->value("/listMode", "symbol").toString(); if (listMode == "single") showSingleView(); else if (listMode == "full") @@ -1465,7 +1509,7 @@ ConfigMainWindow::ConfigMainWindow(void) showSplitView(); // UI setup done, restore splitter positions - Q3ValueList sizes = configSettings->readSizes("/split1", &ok); + QList sizes = configSettings->readSizes("/split1", &ok); if (ok) split1->setSizes(sizes); @@ -1476,26 +1520,28 @@ ConfigMainWindow::ConfigMainWindow(void) void ConfigMainWindow::loadConfig(void) { - QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this); + QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname()); if (s.isNull()) return; if (conf_read(QFile::encodeName(s))) - QMessageBox::information(this, "qconf", _("Unable to load configuration!")); + QMessageBox::information(this, "qconf", "Unable to load configuration!"); ConfigView::updateListAll(); } bool ConfigMainWindow::saveConfig(void) { if (conf_write(NULL)) { - QMessageBox::information(this, "qconf", _("Unable to save configuration!")); + QMessageBox::information(this, "qconf", "Unable to save configuration!"); return false; } + conf_write_autoconf(0); + return true; } void ConfigMainWindow::saveConfigAs(void) { - QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this); + QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname()); if (s.isNull()) return; saveConfig(); @@ -1512,9 +1558,9 @@ void ConfigMainWindow::changeMenu(struct menu *menu) { configList->setRootMenu(menu); if (configList->rootEntry->parent == &rootmenu) - backAction->setEnabled(FALSE); + backAction->setEnabled(false); else - backAction->setEnabled(TRUE); + backAction->setEnabled(true); } void ConfigMainWindow::setMenuLink(struct menu *menu) @@ -1546,8 +1592,8 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) return; item = menuList->findConfigItem(parent); if (item) { - menuList->setSelected(item, TRUE); - menuList->ensureItemVisible(item); + item->setSelected(true); + menuList->scrollToItem(item); } list->setRootMenu(parent); } @@ -1562,8 +1608,8 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) if (list) { item = list->findConfigItem(menu); if (item) { - list->setSelected(item, TRUE); - list->ensureItemVisible(item); + item->setSelected(true); + list->scrollToItem(item); list->setFocus(); } } @@ -1577,15 +1623,21 @@ void ConfigMainWindow::listFocusChanged(void) void ConfigMainWindow::goBack(void) { - ConfigItem* item; + ConfigItem* item, *oldSelection; configList->setParentMenu(); if (configList->rootEntry == &rootmenu) - backAction->setEnabled(FALSE); - item = (ConfigItem*)menuList->selectedItem(); + backAction->setEnabled(false); + + if (menuList->selectedItems().count() == 0) + return; + + item = (ConfigItem*)menuList->selectedItems().first(); + oldSelection = item; while (item) { if (item->menu == configList->rootEntry) { - menuList->setSelected(item, TRUE); + oldSelection->setSelected(false); + item->setSelected(true); break; } item = (ConfigItem*)item->parent(); @@ -1594,6 +1646,13 @@ void ConfigMainWindow::goBack(void) void ConfigMainWindow::showSingleView(void) { + singleViewAction->setEnabled(false); + singleViewAction->setChecked(true); + splitViewAction->setEnabled(true); + splitViewAction->setChecked(false); + fullViewAction->setEnabled(true); + fullViewAction->setChecked(false); + menuView->hide(); menuList->setRootMenu(0); configList->mode = singleMode; @@ -1601,28 +1660,41 @@ void ConfigMainWindow::showSingleView(void) configList->updateListAll(); else configList->setRootMenu(&rootmenu); - configList->setAllOpen(TRUE); configList->setFocus(); } void ConfigMainWindow::showSplitView(void) { + singleViewAction->setEnabled(true); + singleViewAction->setChecked(false); + splitViewAction->setEnabled(false); + splitViewAction->setChecked(true); + fullViewAction->setEnabled(true); + fullViewAction->setChecked(false); + configList->mode = symbolMode; if (configList->rootEntry == &rootmenu) configList->updateListAll(); else configList->setRootMenu(&rootmenu); - configList->setAllOpen(TRUE); + configList->setAllOpen(true); configApp->processEvents(); menuList->mode = menuMode; menuList->setRootMenu(&rootmenu); - menuList->setAllOpen(TRUE); + menuList->setAllOpen(true); menuView->show(); menuList->setFocus(); } void ConfigMainWindow::showFullView(void) { + singleViewAction->setEnabled(true); + singleViewAction->setChecked(false); + splitViewAction->setEnabled(true); + splitViewAction->setChecked(false); + fullViewAction->setEnabled(false); + fullViewAction->setChecked(true); + menuView->hide(); menuList->setRootMenu(0); configList->mode = fullMode; @@ -1630,7 +1702,6 @@ void ConfigMainWindow::showFullView(void) configList->updateListAll(); else configList->setRootMenu(&rootmenu); - configList->setAllOpen(FALSE); configList->setFocus(); } @@ -1644,11 +1715,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) e->accept(); return; } - QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning, + QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); - mb.setButtonText(QMessageBox::Yes, _("&Save Changes")); - mb.setButtonText(QMessageBox::No, _("&Discard Changes")); - mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit")); + mb.setButtonText(QMessageBox::Yes, "&Save Changes"); + mb.setButtonText(QMessageBox::No, "&Discard Changes"); + mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); switch (mb.exec()) { case QMessageBox::Yes: if (saveConfig()) @@ -1667,7 +1738,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) void ConfigMainWindow::showIntro(void) { - static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n" + static const QString str = "Welcome to the qconf graphical configuration tool.\n\n" "For each option, a blank box indicates the feature is disabled, a check\n" "indicates it is enabled, and a dot indicates that it is to be compiled\n" "as a module. Clicking on the box will cycle through the three states.\n\n" @@ -1677,25 +1748,26 @@ void ConfigMainWindow::showIntro(void) "options must be enabled to support the option you are interested in, you can\n" "still view the help of a grayed-out option.\n\n" "Toggling Show Debug Info under the Options menu will show the dependencies,\n" - "which you can then match by examining other options.\n\n"); + "which you can then match by examining other options.\n\n"; QMessageBox::information(this, "qconf", str); } void ConfigMainWindow::showAbout(void) { - static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel .\n\n" - "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"); + static const QString str = "qconf is Copyright (C) 2002 Roman Zippel .\n" + "Copyright (C) 2015 Boris Barbulovski .\n\n" + "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"; QMessageBox::information(this, "qconf", str); } void ConfigMainWindow::saveSettings(void) { - configSettings->writeEntry("/window x", pos().x()); - configSettings->writeEntry("/window y", pos().y()); - configSettings->writeEntry("/window width", size().width()); - configSettings->writeEntry("/window height", size().height()); + configSettings->setValue("/window x", pos().x()); + configSettings->setValue("/window y", pos().y()); + configSettings->setValue("/window width", size().width()); + configSettings->setValue("/window height", size().height()); QString entry; switch(configList->mode) { @@ -1714,7 +1786,7 @@ void ConfigMainWindow::saveSettings(void) default: break; } - configSettings->writeEntry("/listMode", entry); + configSettings->setValue("/listMode", entry); configSettings->writeSizes("/split1", split1->sizes()); configSettings->writeSizes("/split2", split2->sizes()); @@ -1746,7 +1818,7 @@ static const char *progname; static void usage(void) { - printf(_("%s \n"), progname); + printf("%s [-s] \n", progname); exit(0); } @@ -1755,13 +1827,13 @@ int main(int ac, char** av) ConfigMainWindow* v; const char *name; - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - progname = av[0]; configApp = new QApplication(ac, av); if (ac > 1 && av[1][0] == '-') { switch (av[1][1]) { + case 's': + conf_set_message_callback(NULL); + break; case 'h': case '?': usage(); @@ -1782,7 +1854,6 @@ int main(int ac, char** av) v = new ConfigMainWindow(); //zconfdump(stdout); - configApp->setMainWidget(v); configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); v->show(); @@ -1790,6 +1861,8 @@ int main(int ac, char** av) configSettings->endGroup(); delete configSettings; + delete v; + delete configApp; return 0; } diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index bde0c6b6f9..a40036d1b0 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -3,26 +3,18 @@ * Released under the terms of the GNU GPL v2.0. */ -#if QT_VERSION < 0x040000 -#include -#else -#include -#endif +#include +#include +#include +#include #include - -#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 +#include +#include +#include +#include +#include +#include +#include "expr.h" class ConfigView; class ConfigList; @@ -33,8 +25,8 @@ class ConfigMainWindow; class ConfigSettings : public QSettings { public: ConfigSettings(); - Q3ValueList readSizes(const QString& key, bool *ok); - bool writeSizes(const QString& key, const Q3ValueList& value); + QList readSizes(const QString& key, bool *ok); + bool writeSizes(const QString& key, const QList& value); }; enum colIdx { @@ -47,9 +39,9 @@ enum optionMode { normalOpt = 0, allOpt, promptOpt }; -class ConfigList : public Q3ListView { +class ConfigList : public QTreeWidget { Q_OBJECT - typedef class Q3ListView Parent; + typedef class QTreeWidget Parent; public: ConfigList(ConfigView* p, const char *name = 0); void reinit(void); @@ -61,10 +53,10 @@ public: protected: void keyPressEvent(QKeyEvent *e); - void contentsMousePressEvent(QMouseEvent *e); - void contentsMouseReleaseEvent(QMouseEvent *e); - void contentsMouseMoveEvent(QMouseEvent *e); - void contentsMouseDoubleClickEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseDoubleClickEvent(QMouseEvent *e); void focusInEvent(QFocusEvent *e); void contextMenuEvent(QContextMenuEvent *e); @@ -95,32 +87,23 @@ public: } ConfigItem* firstChild() const { - return (ConfigItem *)Parent::firstChild(); - } - int mapIdx(colIdx idx) - { - return colMap[idx]; + return (ConfigItem *)children().first(); } - void addColumn(colIdx idx, const QString& label) + void addColumn(colIdx idx) { - colMap[idx] = Parent::addColumn(label); - colRevMap[colMap[idx]] = idx; + showColumn(idx); } void removeColumn(colIdx idx) { - int col = colMap[idx]; - if (col >= 0) { - Parent::removeColumn(col); - colRevMap[col] = colMap[idx] = -1; - } + hideColumn(idx); } void setAllOpen(bool open); void setParentMenu(void); bool menuSkip(struct menu *); - template - void updateMenuList(P*, struct menu*); + void updateMenuList(ConfigItem *parent, struct menu*); + void updateMenuList(ConfigList *parent, struct menu*); bool updateAll; @@ -132,30 +115,26 @@ public: enum listMode mode; enum optionMode optMode; struct menu *rootEntry; - QColorGroup disabledColorGroup; - QColorGroup inactivedColorGroup; - Q3PopupMenu* headerPopup; - -private: - int colMap[colNr]; - int colRevMap[colNr]; + QPalette disabledColorGroup; + QPalette inactivedColorGroup; + QMenu* headerPopup; }; -class ConfigItem : public Q3ListViewItem { - typedef class Q3ListViewItem Parent; +class ConfigItem : public QTreeWidgetItem { + typedef class QTreeWidgetItem Parent; public: - ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v) - : Parent(parent, after), menu(m), visible(v), goParent(false) + ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v) + : Parent(parent, after), nextItem(0), 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) + : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false) { init(); } - ConfigItem(Q3ListView *parent, ConfigItem *after, bool v) - : Parent(parent, after), menu(0), visible(v), goParent(true) + ConfigItem(ConfigList *parent, ConfigItem *after, bool v) + : Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true) { init(); } @@ -166,33 +145,43 @@ public: void testUpdateMenu(bool v); ConfigList* listView() const { - return (ConfigList*)Parent::listView(); + return (ConfigList*)Parent::treeWidget(); } ConfigItem* firstChild() const { - return (ConfigItem *)Parent::firstChild(); + return (ConfigItem *)Parent::child(0); } - ConfigItem* nextSibling() const + ConfigItem* nextSibling() { - return (ConfigItem *)Parent::nextSibling(); + ConfigItem *ret = NULL; + ConfigItem *_parent = (ConfigItem *)parent(); + + if(_parent) { + ret = (ConfigItem *)_parent->child(_parent->indexOfChild(this)+1); + } else { + QTreeWidget *_treeWidget = treeWidget(); + ret = (ConfigItem *)_treeWidget->topLevelItem(_treeWidget->indexOfTopLevelItem(this)+1); + } + + return ret; } void setText(colIdx idx, const QString& text) { - Parent::setText(listView()->mapIdx(idx), text); + Parent::setText(idx, text); } QString text(colIdx idx) const { - return Parent::text(listView()->mapIdx(idx)); + return Parent::text(idx); } - void setPixmap(colIdx idx, const QPixmap& pm) + void setPixmap(colIdx idx, const QIcon &icon) { - Parent::setPixmap(listView()->mapIdx(idx), pm); + Parent::setIcon(idx, icon); } - const QPixmap* pixmap(colIdx idx) const + const QIcon pixmap(colIdx idx) const { - return Parent::pixmap(listView()->mapIdx(idx)); + return icon(idx); } - void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align); + // TODO: Implement paintCell ConfigItem* nextItem; struct menu *menu; @@ -216,9 +205,9 @@ public: ConfigItem *item; }; -class ConfigView : public Q3VBox { +class ConfigView : public QWidget { Q_OBJECT - typedef class Q3VBox Parent; + typedef class QWidget Parent; public: ConfigView(QWidget* parent, const char *name = 0); ~ConfigView(void); @@ -249,9 +238,9 @@ public: static QAction *showPromptAction; }; -class ConfigInfoView : public Q3TextBrowser { +class ConfigInfoView : public QTextBrowser { Q_OBJECT - typedef class Q3TextBrowser Parent; + typedef class QTextBrowser Parent; public: ConfigInfoView(QWidget* parent, const char *name = 0); bool showDebug(void) const { return _showDebug; } @@ -271,8 +260,8 @@ protected: 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); + QMenu *createStandardContextMenu(const QPoint & pos); + void contextMenuEvent(QContextMenuEvent *e); struct symbol *sym; struct menu *_menu; @@ -299,10 +288,10 @@ protected: struct symbol **result; }; -class ConfigMainWindow : public Q3MainWindow { +class ConfigMainWindow : public QMainWindow { Q_OBJECT - static Q3Action *saveAction; + static QAction *saveAction; static void conf_changed(void); public: ConfigMainWindow(void); @@ -331,8 +320,11 @@ protected: ConfigView *configView; ConfigList *configList; ConfigInfoView *helpText; - Q3ToolBar *toolBar; - Q3Action *backAction; - QSplitter* split1; - QSplitter* split2; + QToolBar *toolBar; + QAction *backAction; + QAction *singleViewAction; + QAction *splitViewAction; + QAction *fullViewAction; + QSplitter *split1; + QSplitter *split2; }; diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 9cb8522d8d..4686531e2f 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # Copyright 2005-2009 - Steven Rostedt # Licensed under the terms of the GNU GPL License version 2 @@ -42,6 +42,7 @@ # mv config_strip .config # make oldconfig # +use warnings; use strict; use Getopt::Long; @@ -137,7 +138,7 @@ my $ksource = ($ARGV[0] ? $ARGV[0] : '.'); my $kconfig = $ARGV[1]; my $lsmod_file = $ENV{'LSMOD'}; -my @makefiles = `find $ksource -name Makefile 2>/dev/null`; +my @makefiles = `find $ksource -name Makefile -or -name Kbuild 2>/dev/null`; chomp @makefiles; my %depends; @@ -164,10 +165,10 @@ sub read_kconfig { my $last_source = ""; # Check for any environment variables used - while ($source =~ /\$(\w+)/ && $last_source ne $source) { + while ($source =~ /\$\((\w+)\)/ && $last_source ne $source) { my $env = $1; $last_source = $source; - $source =~ s/\$$env/$ENV{$env}/; + $source =~ s/\$\($env\)/$ENV{$env}/; } open(my $kinfile, '<', $source) || die "Can't open $kconfig"; @@ -188,7 +189,7 @@ sub read_kconfig { $cont = 0; # collect any Kconfig sources - if (/^source\s*"(.*)"/) { + if (/^source\s+"?([^"]+)/) { my $kconfig = $1; # prevent reading twice. if (!defined($read_kconfigs{$kconfig})) { @@ -237,7 +238,7 @@ sub read_kconfig { } # configs without prompts must be selected - } elsif ($state ne "NONE" && /^\s*tristate\s\S/) { + } elsif ($state ne "NONE" && /^\s*(tristate\s+\S|prompt\b)/) { # note if the config has a prompt $prompts{$config} = 1; @@ -256,8 +257,8 @@ sub read_kconfig { $iflevel-- if ($iflevel); - # stop on "help" - } elsif (/^\s*help\s*$/) { + # stop on "help" and keywords that end a menu entry + } elsif (/^\s*(---)?help(---)?\s*$/ || /^(comment|choice|menu)\b/) { $state = "NONE"; } } @@ -454,7 +455,7 @@ sub parse_config_depends $p =~ s/^[^$valid]*[$valid]+//; # We only need to process if the depend config is a module - if (!defined($orig_configs{$conf}) || !$orig_configs{conf} eq "m") { + if (!defined($orig_configs{$conf}) || $orig_configs{$conf} eq "y") { next; } @@ -610,6 +611,40 @@ foreach my $line (@config_file) { next; } + if (/CONFIG_MODULE_SIG_KEY="(.+)"/) { + my $orig_cert = $1; + my $default_cert = "certs/signing_key.pem"; + + # Check that the logic in this script still matches the one in Kconfig + if (!defined($depends{"MODULE_SIG_KEY"}) || + $depends{"MODULE_SIG_KEY"} !~ /"\Q$default_cert\E"/) { + print STDERR "WARNING: MODULE_SIG_KEY assertion failure, ", + "update needed to ", __FILE__, " line ", __LINE__, "\n"; + print; + } elsif ($orig_cert ne $default_cert && ! -f $orig_cert) { + print STDERR "Module signature verification enabled but ", + "module signing key \"$orig_cert\" not found. Resetting ", + "signing key to default value.\n"; + print "CONFIG_MODULE_SIG_KEY=\"$default_cert\"\n"; + } else { + print; + } + next; + } + + if (/CONFIG_SYSTEM_TRUSTED_KEYS="(.+)"/) { + my $orig_keys = $1; + + if (! -f $orig_keys) { + print STDERR "System keyring enabled but keys \"$orig_keys\" ", + "not found. Resetting keys to default value.\n"; + print "CONFIG_SYSTEM_TRUSTED_KEYS=\"\"\n"; + } else { + print; + } + next; + } + if (/^(CONFIG.*)=(m|y)/) { if (defined($configs{$1})) { if ($localyesconfig) { diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 7caabdb51c..703b9b899e 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -33,33 +33,6 @@ struct symbol *sym_defconfig_list; struct symbol *modules_sym; tristate modules_val; -struct expr *sym_env_list; - -static void sym_add_default(struct symbol *sym, const char *def) -{ - struct property *prop = prop_alloc(P_DEFAULT, sym); - - prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); -} - -void sym_init(void) -{ - struct symbol *sym; - struct utsname uts; - static bool inited = false; - - if (inited) - return; - inited = true; - - uname(&uts); - - sym = sym_lookup("UNAME_RELEASE", 0); - sym->type = S_STRING; - sym->flags |= SYMBOL_AUTO; - sym_add_default(sym, uts.release); -} - enum symbol_type sym_get_type(struct symbol *sym) { enum symbol_type type = sym->type; @@ -77,7 +50,7 @@ const char *sym_type_name(enum symbol_type type) { switch (type) { case S_BOOLEAN: - return "boolean"; + return "bool"; case S_TRISTATE: return "tristate"; case S_INT: @@ -103,16 +76,7 @@ struct property *sym_get_choice_prop(struct symbol *sym) return NULL; } -struct property *sym_get_env_prop(struct symbol *sym) -{ - struct property *prop; - - for_all_properties(sym, prop, P_ENV) - return prop; - return NULL; -} - -struct property *sym_get_default_prop(struct symbol *sym) +static struct property *sym_get_default_prop(struct symbol *sym) { struct property *prop; @@ -183,18 +147,52 @@ static void sym_validate_range(struct symbol *sym) sprintf(str, "%lld", val2); else sprintf(str, "0x%llx", val2); - sym->curr.val = strdup(str); + sym->curr.val = xstrdup(str); +} + +static void sym_set_changed(struct symbol *sym) +{ + struct property *prop; + + sym->flags |= SYMBOL_CHANGED; + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu) + prop->menu->flags |= MENU_CHANGED; + } +} + +static void sym_set_all_changed(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) + sym_set_changed(sym); } static void sym_calc_visibility(struct symbol *sym) { struct property *prop; + struct symbol *choice_sym = NULL; tristate tri; /* any prompt visible? */ tri = no; + + if (sym_is_choice_value(sym)) + choice_sym = prop_get_symbol(sym_get_choice_prop(sym)); + for_all_prompts(sym, prop) { prop->visible.tri = expr_calc_value(prop->visible.expr); + /* + * Tristate choice_values with visibility 'mod' are + * not visible if the corresponding choice's value is + * 'yes'. + */ + if (choice_sym && sym->type == S_TRISTATE && + prop->visible.tri == mod && choice_sym->curr.tri == yes) + prop->visible.tri = no; + tri = EXPR_OR(tri, prop->visible.tri); } if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) @@ -209,7 +207,7 @@ static void sym_calc_visibility(struct symbol *sym) tri = yes; if (sym->dir_dep.expr) tri = expr_calc_value(sym->dir_dep.expr); - if (tri == mod) + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) tri = yes; if (sym->dir_dep.tri != tri) { sym->dir_dep.tri = tri; @@ -224,6 +222,15 @@ static void sym_calc_visibility(struct symbol *sym) sym->rev_dep.tri = tri; sym_set_changed(sym); } + tri = no; + if (sym->implied.expr && sym->dir_dep.tri != no) + tri = expr_calc_value(sym->implied.expr); + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) + tri = yes; + if (sym->implied.tri != tri) { + sym->implied.tri = tri; + sym_set_changed(sym); + } } /* @@ -290,6 +297,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym) return def_sym; } +static void sym_warn_unmet_dep(struct symbol *sym) +{ + struct gstr gs = str_new(); + + str_printf(&gs, + "\nWARNING: unmet direct dependencies detected for %s\n", + sym->name); + str_printf(&gs, + " Depends on [%c]: ", + sym->dir_dep.tri == mod ? 'm' : 'n'); + expr_gstr_print(sym->dir_dep.expr, &gs); + str_printf(&gs, "\n"); + + expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes, + " Selected by [y]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod, + " Selected by [m]:\n"); + + fputs(str_get(&gs), stderr); +} + void sym_calc_value(struct symbol *sym) { struct symbol_value newval, oldval; @@ -328,11 +356,13 @@ void sym_calc_value(struct symbol *sym) sym->curr.tri = no; return; } - if (!sym_is_choice_value(sym)) - sym->flags &= ~SYMBOL_WRITE; + sym->flags &= ~SYMBOL_WRITE; sym_calc_visibility(sym); + if (sym->visible != no) + sym->flags |= SYMBOL_WRITE; + /* set default if recursively called */ sym->curr = newval; @@ -347,7 +377,6 @@ void sym_calc_value(struct symbol *sym) /* if the symbol is visible use the user value * if available, otherwise try the default value */ - sym->flags |= SYMBOL_WRITE; if (sym_has_value(sym)) { newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, sym->visible); @@ -359,38 +388,31 @@ void sym_calc_value(struct symbol *sym) if (!sym_is_choice(sym)) { prop = sym_get_default_prop(sym); if (prop) { - sym->flags |= SYMBOL_WRITE; newval.tri = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); + if (newval.tri != no) + sym->flags |= SYMBOL_WRITE; + } + if (sym->implied.tri != no) { + sym->flags |= SYMBOL_WRITE; + newval.tri = EXPR_OR(newval.tri, sym->implied.tri); } } calc_newval: - if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { - struct expr *e; - e = expr_simplify_unmet_dep(sym->rev_dep.expr, - sym->dir_dep.expr); - fprintf(stderr, "warning: ("); - expr_fprint(e, stderr); - fprintf(stderr, ") selects %s which has unmet direct dependencies (", - sym->name); - expr_fprint(sym->dir_dep.expr, stderr); - fprintf(stderr, ")\n"); - expr_free(e); - } + if (sym->dir_dep.tri < sym->rev_dep.tri) + sym_warn_unmet_dep(sym); newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } - if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) + if (newval.tri == mod && + (sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes)) newval.tri = yes; break; case S_STRING: case S_HEX: case S_INT: - if (sym->visible != no) { - sym->flags |= SYMBOL_WRITE; - if (sym_has_value(sym)) { - newval.val = sym->def[S_DEF_USER].val; - break; - } + if (sym->visible != no && sym_has_value(sym)) { + newval.val = sym->def[S_DEF_USER].val; + break; } prop = sym_get_default_prop(sym); if (prop) { @@ -432,7 +454,7 @@ void sym_calc_value(struct symbol *sym) } } - if (sym->flags & SYMBOL_AUTO) + if (sym->flags & SYMBOL_NO_WRITE) sym->flags &= ~SYMBOL_WRITE; if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) @@ -447,28 +469,7 @@ void sym_clear_all_valid(void) for_all_symbols(i, sym) sym->flags &= ~SYMBOL_VALID; sym_add_change_count(1); - if (modules_sym) - sym_calc_value(modules_sym); -} - -void sym_set_changed(struct symbol *sym) -{ - struct property *prop; - - sym->flags |= SYMBOL_CHANGED; - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu) - prop->menu->flags |= MENU_CHANGED; - } -} - -void sym_set_all_changed(void) -{ - struct symbol *sym; - int i; - - for_all_symbols(i, sym) - sym_set_changed(sym); + sym_calc_value(modules_sym); } bool sym_tristate_within_range(struct symbol *sym, tristate val) @@ -485,6 +486,8 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) return false; if (sym->visible <= sym->rev_dep.tri) return false; + if (sym->implied.tri == yes && val == mod) + return false; if (sym_is_choice_value(sym) && sym->visible == yes) return val == yes; return val >= sym->rev_dep.tri && val <= sym->visible; @@ -737,6 +740,10 @@ const char *sym_get_string_default(struct symbol *sym) if (sym->type == S_BOOLEAN && val == mod) val = yes; + /* adjust the default value if this symbol is implied by another */ + if (val < sym->implied.tri) + val = sym->implied.tri; + switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: @@ -818,7 +825,7 @@ struct symbol *sym_lookup(const char *name, int flags) : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) return symbol; } - new_name = strdup(name); + new_name = xstrdup(name); } else { new_name = NULL; hash = 0; @@ -863,55 +870,6 @@ struct symbol *sym_find(const char *name) return symbol; } -/* - * Expand symbol's names embedded in the string given in argument. Symbols' - * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to - * the empty string. - */ -const char *sym_expand_string_value(const char *in) -{ - const char *src; - char *res; - size_t reslen; - - reslen = strlen(in) + 1; - res = xmalloc(reslen); - res[0] = '\0'; - - while ((src = strchr(in, '$'))) { - char *p, name[SYMBOL_MAXLENGTH]; - const char *symval = ""; - struct symbol *sym; - size_t newlen; - - strncat(res, in, src - in); - src++; - - p = name; - while (isalnum(*src) || *src == '_') - *p++ = *src++; - *p = '\0'; - - sym = sym_find(name); - if (sym != NULL) { - sym_calc_value(sym); - symval = sym_get_string_value(sym); - } - - newlen = strlen(res) + strlen(symval) + strlen(src) + 1; - if (newlen > reslen) { - reslen = newlen; - res = realloc(res, reslen); - } - - strcat(res, symval); - in = src; - } - strcat(res, in); - - return res; -} - const char *sym_escape_string_value(const char *in) { const char *p; @@ -1028,7 +986,7 @@ struct symbol **sym_re_search(const char *pattern) } if (sym_match_arr) { qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp); - sym_arr = malloc((cnt+1) * sizeof(struct symbol)); + sym_arr = malloc((cnt+1) * sizeof(struct symbol *)); if (!sym_arr) goto sym_re_search_free; for (i = 0; i < cnt; i++) @@ -1053,7 +1011,7 @@ static struct dep_stack { struct dep_stack *prev, *next; struct symbol *sym; struct property *prop; - struct expr *expr; + struct expr **expr; } *check_top; static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) @@ -1117,35 +1075,52 @@ static void sym_check_print_recursive(struct symbol *last_sym) if (stack->sym == last_sym) fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", prop->file->name, prop->lineno); - if (stack->expr) { - fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", - prop->file->name, prop->lineno, + + if (sym_is_choice(sym)) { + fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", + menu->file->name, menu->lineno, sym->name ? sym->name : "", - prop_get_type_name(prop->type), next_sym->name ? next_sym->name : ""); - } else if (stack->prop) { + } else if (sym_is_choice_value(sym)) { + fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "", + next_sym->name ? next_sym->name : ""); + } else if (stack->expr == &sym->dir_dep.expr) { fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", prop->file->name, prop->lineno, sym->name ? sym->name : "", next_sym->name ? next_sym->name : ""); - } else if (sym_is_choice(sym)) { - fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", - menu->file->name, menu->lineno, + } else if (stack->expr == &sym->rev_dep.expr) { + fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", + prop->file->name, prop->lineno, sym->name ? sym->name : "", next_sym->name ? next_sym->name : ""); - } else if (sym_is_choice_value(sym)) { - fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", - menu->file->name, menu->lineno, + } else if (stack->expr == &sym->implied.expr) { + fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n", + prop->file->name, prop->lineno, sym->name ? sym->name : "", next_sym->name ? next_sym->name : ""); + } else if (stack->expr) { + fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "", + prop_get_type_name(prop->type), + next_sym->name ? next_sym->name : ""); } else { - fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", + fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n", prop->file->name, prop->lineno, sym->name ? sym->name : "", + prop_get_type_name(prop->type), next_sym->name ? next_sym->name : ""); } } + fprintf(stderr, + "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n" + "subsection \"Kconfig recursive dependency limitations\"\n" + "\n"); + if (check_top == &cv_stack) dep_stack_remove(); } @@ -1166,6 +1141,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e) case E_NOT: return sym_check_expr_deps(e->left.expr); case E_EQUAL: + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: sym = sym_check_deps(e->left.sym); if (sym) @@ -1176,7 +1155,7 @@ static struct symbol *sym_check_expr_deps(struct expr *e) default: break; } - printf("Oops! How to check %d?\n", e->type); + fprintf(stderr, "Oops! How to check %d?\n", e->type); return NULL; } @@ -1189,12 +1168,26 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) dep_stack_insert(&stack, sym); + stack.expr = &sym->dir_dep.expr; + sym2 = sym_check_expr_deps(sym->dir_dep.expr); + if (sym2) + goto out; + + stack.expr = &sym->rev_dep.expr; sym2 = sym_check_expr_deps(sym->rev_dep.expr); if (sym2) goto out; + stack.expr = &sym->implied.expr; + sym2 = sym_check_expr_deps(sym->implied.expr); + if (sym2) + goto out; + + stack.expr = NULL; + for (prop = sym->prop; prop; prop = prop->next) { - if (prop->type == P_CHOICE || prop->type == P_SELECT) + if (prop->type == P_CHOICE || prop->type == P_SELECT || + prop->type == P_IMPLY) continue; stack.prop = prop; sym2 = sym_check_expr_deps(prop->visible.expr); @@ -1202,7 +1195,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) break; if (prop->type != P_DEFAULT || sym_is_choice(sym)) continue; - stack.expr = prop->expr; + stack.expr = &prop->expr; sym2 = sym_check_expr_deps(prop->expr); if (sym2) break; @@ -1280,9 +1273,6 @@ struct symbol *sym_check_deps(struct symbol *sym) sym->flags &= ~SYMBOL_CHECK; } - if (sym2 && sym2 == sym) - sym2 = NULL; - return sym2; } @@ -1321,8 +1311,6 @@ const char *prop_get_type_name(enum prop_type type) switch (type) { case P_PROMPT: return "prompt"; - case P_ENV: - return "env"; case P_COMMENT: return "comment"; case P_MENU: @@ -1333,6 +1321,8 @@ const char *prop_get_type_name(enum prop_type type) return "choice"; case P_SELECT: return "select"; + case P_IMPLY: + return "imply"; case P_RANGE: return "range"; case P_SYMBOL: @@ -1342,32 +1332,3 @@ const char *prop_get_type_name(enum prop_type type) } return "unknown"; } - -static void prop_add_env(const char *env) -{ - struct symbol *sym, *sym2; - struct property *prop; - char *p; - - sym = current_entry->sym; - sym->flags |= SYMBOL_AUTO; - for_all_properties(sym, prop, P_ENV) { - sym2 = prop_get_symbol(prop); - if (strcmp(sym2->name, env)) - menu_warn(current_entry, "redefining environment symbol from %s", - sym2->name); - return; - } - - prop = prop_alloc(P_ENV, sym); - prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); - - sym_env_list = expr_alloc_one(E_LIST, sym_env_list); - sym_env_list->right.sym = sym; - - p = getenv(env); - if (p) - sym_add_default(sym, p); - else - menu_warn(current_entry, "environment variable %s undefined", env); -} diff --git a/scripts/kconfig/tests/auto_submenu/Kconfig b/scripts/kconfig/tests/auto_submenu/Kconfig new file mode 100644 index 0000000000..c17bf2caa7 --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/Kconfig @@ -0,0 +1,50 @@ +config A + bool "A" + default y + +config A0 + bool "A0" + depends on A + default y + help + This depends on A, so should be a submenu of A. + +config A0_0 + bool "A1_0" + depends on A0 + help + Submenus are created recursively. + This should be a submenu of A0. + +config A1 + bool "A1" + depends on A + default y + help + This should line up with A0. + +choice + prompt "choice" + depends on A1 + help + Choice should become a submenu as well. + +config A1_0 + bool "A1_0" + +config A1_1 + bool "A1_1" + +endchoice + +config B + bool "B" + help + This is independent of A. + +config C + bool "C" + depends on A + help + This depends on A, but not a consecutive item, so can/should not + be a submenu. diff --git a/scripts/kconfig/tests/auto_submenu/__init__.py b/scripts/kconfig/tests/auto_submenu/__init__.py new file mode 100644 index 0000000000..32e79b85fa --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/__init__.py @@ -0,0 +1,12 @@ +""" +Create submenu for symbols that depend on the preceding one. + +If a symbols has dependency on the preceding symbol, the menu entry +should become the submenu of the preceding one, and displayed with +deeper indentation. +""" + + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stdout_contains('expected_stdout') diff --git a/scripts/kconfig/tests/auto_submenu/expected_stdout b/scripts/kconfig/tests/auto_submenu/expected_stdout new file mode 100644 index 0000000000..bf5236f39a --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/expected_stdout @@ -0,0 +1,10 @@ +A (A) [Y/n/?] (NEW) + A0 (A0) [Y/n/?] (NEW) + A1_0 (A0_0) [N/y/?] (NEW) + A1 (A1) [Y/n/?] (NEW) + choice + > 1. A1_0 (A1_0) (NEW) + 2. A1_1 (A1_1) (NEW) + choice[1-2?]: +B (B) [N/y/?] (NEW) +C (C) [N/y/?] (NEW) diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig new file mode 100644 index 0000000000..cc60e9ce2c --- /dev/null +++ b/scripts/kconfig/tests/choice/Kconfig @@ -0,0 +1,54 @@ +config MODULES + bool "Enable loadable module support" + option modules + default y + +choice + prompt "boolean choice" + default BOOL_CHOICE1 + +config BOOL_CHOICE0 + bool "choice 0" + +config BOOL_CHOICE1 + bool "choice 1" + +endchoice + +choice + prompt "optional boolean choice" + optional + default OPT_BOOL_CHOICE1 + +config OPT_BOOL_CHOICE0 + bool "choice 0" + +config OPT_BOOL_CHOICE1 + bool "choice 1" + +endchoice + +choice + prompt "tristate choice" + default TRI_CHOICE1 + +config TRI_CHOICE0 + tristate "choice 0" + +config TRI_CHOICE1 + tristate "choice 1" + +endchoice + +choice + prompt "optional tristate choice" + optional + default OPT_TRI_CHOICE1 + +config OPT_TRI_CHOICE0 + tristate "choice 0" + +config OPT_TRI_CHOICE1 + tristate "choice 1" + +endchoice diff --git a/scripts/kconfig/tests/choice/__init__.py b/scripts/kconfig/tests/choice/__init__.py new file mode 100644 index 0000000000..9edcc52621 --- /dev/null +++ b/scripts/kconfig/tests/choice/__init__.py @@ -0,0 +1,40 @@ +""" +Basic choice tests. + +The handling of 'choice' is a bit complicated part in Kconfig. + +The behavior of 'y' choice is intuitive. If choice values are tristate, +the choice can be 'm' where each value can be enabled independently. +Also, if a choice is marked as 'optional', the whole choice can be +invisible. +""" + + +def test_oldask0(conf): + assert conf.oldaskconfig() == 0 + assert conf.stdout_contains('oldask0_expected_stdout') + + +def test_oldask1(conf): + assert conf.oldaskconfig('oldask1_config') == 0 + assert conf.stdout_contains('oldask1_expected_stdout') + + +def test_allyes(conf): + assert conf.allyesconfig() == 0 + assert conf.config_contains('allyes_expected_config') + + +def test_allmod(conf): + assert conf.allmodconfig() == 0 + assert conf.config_contains('allmod_expected_config') + + +def test_allno(conf): + assert conf.allnoconfig() == 0 + assert conf.config_contains('allno_expected_config') + + +def test_alldef(conf): + assert conf.alldefconfig() == 0 + assert conf.config_contains('alldef_expected_config') diff --git a/scripts/kconfig/tests/choice/alldef_expected_config b/scripts/kconfig/tests/choice/alldef_expected_config new file mode 100644 index 0000000000..7a754bf4be --- /dev/null +++ b/scripts/kconfig/tests/choice/alldef_expected_config @@ -0,0 +1,5 @@ +CONFIG_MODULES=y +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_TRI_CHOICE0 is not set +# CONFIG_TRI_CHOICE1 is not set diff --git a/scripts/kconfig/tests/choice/allmod_expected_config b/scripts/kconfig/tests/choice/allmod_expected_config new file mode 100644 index 0000000000..f1f5dcdb79 --- /dev/null +++ b/scripts/kconfig/tests/choice/allmod_expected_config @@ -0,0 +1,9 @@ +CONFIG_MODULES=y +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_OPT_BOOL_CHOICE0 is not set +CONFIG_OPT_BOOL_CHOICE1=y +CONFIG_TRI_CHOICE0=m +CONFIG_TRI_CHOICE1=m +CONFIG_OPT_TRI_CHOICE0=m +CONFIG_OPT_TRI_CHOICE1=m diff --git a/scripts/kconfig/tests/choice/allno_expected_config b/scripts/kconfig/tests/choice/allno_expected_config new file mode 100644 index 0000000000..b88ee7a431 --- /dev/null +++ b/scripts/kconfig/tests/choice/allno_expected_config @@ -0,0 +1,5 @@ +# CONFIG_MODULES is not set +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_TRI_CHOICE0 is not set +CONFIG_TRI_CHOICE1=y diff --git a/scripts/kconfig/tests/choice/allyes_expected_config b/scripts/kconfig/tests/choice/allyes_expected_config new file mode 100644 index 0000000000..e5a062a115 --- /dev/null +++ b/scripts/kconfig/tests/choice/allyes_expected_config @@ -0,0 +1,9 @@ +CONFIG_MODULES=y +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_OPT_BOOL_CHOICE0 is not set +CONFIG_OPT_BOOL_CHOICE1=y +# CONFIG_TRI_CHOICE0 is not set +CONFIG_TRI_CHOICE1=y +# CONFIG_OPT_TRI_CHOICE0 is not set +CONFIG_OPT_TRI_CHOICE1=y diff --git a/scripts/kconfig/tests/choice/oldask0_expected_stdout b/scripts/kconfig/tests/choice/oldask0_expected_stdout new file mode 100644 index 0000000000..b251bba969 --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask0_expected_stdout @@ -0,0 +1,10 @@ +Enable loadable module support (MODULES) [Y/n/?] (NEW) +boolean choice + 1. choice 0 (BOOL_CHOICE0) (NEW) +> 2. choice 1 (BOOL_CHOICE1) (NEW) +choice[1-2?]: +optional boolean choice [N/y/?] (NEW) +tristate choice [M/y/?] (NEW) + choice 0 (TRI_CHOICE0) [N/m/?] (NEW) + choice 1 (TRI_CHOICE1) [N/m/?] (NEW) +optional tristate choice [N/m/y/?] (NEW) diff --git a/scripts/kconfig/tests/choice/oldask1_config b/scripts/kconfig/tests/choice/oldask1_config new file mode 100644 index 0000000000..b67bfe3c64 --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask1_config @@ -0,0 +1,2 @@ +# CONFIG_MODULES is not set +CONFIG_OPT_BOOL_CHOICE0=y diff --git a/scripts/kconfig/tests/choice/oldask1_expected_stdout b/scripts/kconfig/tests/choice/oldask1_expected_stdout new file mode 100644 index 0000000000..c2125e9bf9 --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask1_expected_stdout @@ -0,0 +1,15 @@ +Enable loadable module support (MODULES) [N/y/?] +boolean choice + 1. choice 0 (BOOL_CHOICE0) (NEW) +> 2. choice 1 (BOOL_CHOICE1) (NEW) +choice[1-2?]: +optional boolean choice [Y/n/?] (NEW) +optional boolean choice +> 1. choice 0 (OPT_BOOL_CHOICE0) + 2. choice 1 (OPT_BOOL_CHOICE1) (NEW) +choice[1-2?]: +tristate choice + 1. choice 0 (TRI_CHOICE0) (NEW) +> 2. choice 1 (TRI_CHOICE1) (NEW) +choice[1-2?]: +optional tristate choice [N/y/?] diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig new file mode 100644 index 0000000000..11ac25c260 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig @@ -0,0 +1,19 @@ +config MODULES + def_bool y + option modules + +config DEP + tristate + default m + +choice + prompt "Tristate Choice" + +config CHOICE0 + tristate "Choice 0" + +config CHOICE1 + tristate "Choice 1" + depends on DEP + +endchoice diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py new file mode 100644 index 0000000000..f8d728c7b1 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py @@ -0,0 +1,15 @@ +""" +Hide tristate choice values with mod dependency in y choice. + +If tristate choice values depend on symbols set to 'm', they should be +hidden when the choice containing them is changed from 'm' to 'y' +(i.e. exclusive choice). + +Related Linux commit: fa64e5f6a35efd5e77d639125d973077ca506074 +""" + + +def test(conf): + assert conf.oldaskconfig('config', 'y') == 0 + assert conf.config_contains('expected_config') + assert conf.stdout_contains('expected_stdout') diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/config b/scripts/kconfig/tests/choice_value_with_m_dep/config new file mode 100644 index 0000000000..3a126b7a25 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/config @@ -0,0 +1,2 @@ +CONFIG_CHOICE0=m +CONFIG_CHOICE1=m diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_config b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config new file mode 100644 index 0000000000..4d07b44954 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config @@ -0,0 +1,3 @@ +CONFIG_MODULES=y +CONFIG_DEP=m +CONFIG_CHOICE0=y diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout new file mode 100644 index 0000000000..2b50ab65c8 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout @@ -0,0 +1,4 @@ +Tristate Choice [M/y/?] y +Tristate Choice +> 1. Choice 0 (CHOICE0) +choice[1]: 1 diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py new file mode 100644 index 0000000000..0345ef6e32 --- /dev/null +++ b/scripts/kconfig/tests/conftest.py @@ -0,0 +1,291 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2018 Masahiro Yamada +# + +""" +Kconfig unit testing framework. + +This provides fixture functions commonly used from test files. +""" + +import os +import pytest +import shutil +import subprocess +import tempfile + +CONF_PATH = os.path.abspath(os.path.join('scripts', 'kconfig', 'conf')) + + +class Conf: + """Kconfig runner and result checker. + + This class provides methods to run text-based interface of Kconfig + (scripts/kconfig/conf) and retrieve the resulted configuration, + stdout, and stderr. It also provides methods to compare those + results with expectations. + """ + + def __init__(self, request): + """Create a new Conf instance. + + request: object to introspect the requesting test module + """ + # the directory of the test being run + self._test_dir = os.path.dirname(str(request.fspath)) + + # runners + def _run_conf(self, mode, dot_config=None, out_file='.config', + interactive=False, in_keys=None, extra_env={}): + """Run text-based Kconfig executable and save the result. + + mode: input mode option (--oldaskconfig, --defconfig= etc.) + dot_config: .config file to use for configuration base + out_file: file name to contain the output config data + interactive: flag to specify the interactive mode + in_keys: key inputs for interactive modes + extra_env: additional environments + returncode: exit status of the Kconfig executable + """ + command = [CONF_PATH, mode, 'Kconfig'] + + # Override 'srctree' environment to make the test as the top directory + extra_env['srctree'] = self._test_dir + + # Run Kconfig in a temporary directory. + # This directory is automatically removed when done. + with tempfile.TemporaryDirectory() as temp_dir: + + # if .config is given, copy it to the working directory + if dot_config: + shutil.copyfile(os.path.join(self._test_dir, dot_config), + os.path.join(temp_dir, '.config')) + + ps = subprocess.Popen(command, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=temp_dir, + env=dict(os.environ, **extra_env)) + + # If input key sequence is given, feed it to stdin. + if in_keys: + ps.stdin.write(in_keys.encode('utf-8')) + + while ps.poll() is None: + # For interactive modes such as oldaskconfig, oldconfig, + # send 'Enter' key until the program finishes. + if interactive: + ps.stdin.write(b'\n') + + self.retcode = ps.returncode + self.stdout = ps.stdout.read().decode() + self.stderr = ps.stderr.read().decode() + + # Retrieve the resulted config data only when .config is supposed + # to exist. If the command fails, the .config does not exist. + # 'listnewconfig' does not produce .config in the first place. + if self.retcode == 0 and out_file: + with open(os.path.join(temp_dir, out_file)) as f: + self.config = f.read() + else: + self.config = None + + # Logging: + # Pytest captures the following information by default. In failure + # of tests, the captured log will be displayed. This will be useful to + # figure out what has happened. + + print("[command]\n{}\n".format(' '.join(command))) + + print("[retcode]\n{}\n".format(self.retcode)) + + print("[stdout]") + print(self.stdout) + + print("[stderr]") + print(self.stderr) + + if self.config is not None: + print("[output for '{}']".format(out_file)) + print(self.config) + + return self.retcode + + def oldaskconfig(self, dot_config=None, in_keys=None): + """Run oldaskconfig. + + dot_config: .config file to use for configuration base (optional) + in_key: key inputs (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--oldaskconfig', dot_config=dot_config, + interactive=True, in_keys=in_keys) + + def oldconfig(self, dot_config=None, in_keys=None): + """Run oldconfig. + + dot_config: .config file to use for configuration base (optional) + in_key: key inputs (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--oldconfig', dot_config=dot_config, + interactive=True, in_keys=in_keys) + + def olddefconfig(self, dot_config=None): + """Run olddefconfig. + + dot_config: .config file to use for configuration base (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--olddefconfig', dot_config=dot_config) + + def defconfig(self, defconfig): + """Run defconfig. + + defconfig: defconfig file for input + returncode: exit status of the Kconfig executable + """ + defconfig_path = os.path.join(self._test_dir, defconfig) + return self._run_conf('--defconfig={}'.format(defconfig_path)) + + def _allconfig(self, mode, all_config): + if all_config: + all_config_path = os.path.join(self._test_dir, all_config) + extra_env = {'KCONFIG_ALLCONFIG': all_config_path} + else: + extra_env = {} + + return self._run_conf('--{}config'.format(mode), extra_env=extra_env) + + def allyesconfig(self, all_config=None): + """Run allyesconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('allyes', all_config) + + def allmodconfig(self, all_config=None): + """Run allmodconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('allmod', all_config) + + def allnoconfig(self, all_config=None): + """Run allnoconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('allno', all_config) + + def alldefconfig(self, all_config=None): + """Run alldefconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('alldef', all_config) + + def randconfig(self, all_config=None): + """Run randconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('rand', all_config) + + def savedefconfig(self, dot_config): + """Run savedefconfig. + + dot_config: .config file for input + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--savedefconfig', out_file='defconfig') + + def listnewconfig(self, dot_config=None): + """Run listnewconfig. + + dot_config: .config file to use for configuration base (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--listnewconfig', dot_config=dot_config, + out_file=None) + + # checkers + def _read_and_compare(self, compare, expected): + """Compare the result with expectation. + + compare: function to compare the result with expectation + expected: file that contains the expected data + """ + with open(os.path.join(self._test_dir, expected)) as f: + expected_data = f.read() + return compare(self, expected_data) + + def _contains(self, attr, expected): + return self._read_and_compare( + lambda s, e: getattr(s, attr).find(e) >= 0, + expected) + + def _matches(self, attr, expected): + return self._read_and_compare(lambda s, e: getattr(s, attr) == e, + expected) + + def config_contains(self, expected): + """Check if resulted configuration contains expected data. + + expected: file that contains the expected data + returncode: True if result contains the expected data, False otherwise + """ + return self._contains('config', expected) + + def config_matches(self, expected): + """Check if resulted configuration exactly matches expected data. + + expected: file that contains the expected data + returncode: True if result matches the expected data, False otherwise + """ + return self._matches('config', expected) + + def stdout_contains(self, expected): + """Check if resulted stdout contains expected data. + + expected: file that contains the expected data + returncode: True if result contains the expected data, False otherwise + """ + return self._contains('stdout', expected) + + def stdout_matches(self, expected): + """Check if resulted stdout exactly matches expected data. + + expected: file that contains the expected data + returncode: True if result matches the expected data, False otherwise + """ + return self._matches('stdout', expected) + + def stderr_contains(self, expected): + """Check if resulted stderr contains expected data. + + expected: file that contains the expected data + returncode: True if result contains the expected data, False otherwise + """ + return self._contains('stderr', expected) + + def stderr_matches(self, expected): + """Check if resulted stderr exactly matches expected data. + + expected: file that contains the expected data + returncode: True if result matches the expected data, False otherwise + """ + return self._matches('stderr', expected) + + +@pytest.fixture(scope="module") +def conf(request): + """Create a Conf instance and provide it to test functions.""" + return Conf(request) diff --git a/scripts/kconfig/tests/err_recursive_dep/Kconfig b/scripts/kconfig/tests/err_recursive_dep/Kconfig new file mode 100644 index 0000000000..ebdb3ffd87 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_dep/Kconfig @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 + +# depends on itself + +config A + bool "A" + depends on A + +# select itself + +config B + bool + select B + +# depends on each other + +config C1 + bool "C1" + depends on C2 + +config C2 + bool "C2" + depends on C1 + +# depends on and select + +config D1 + bool "D1" + depends on D2 + select D2 + +config D2 + bool + +# depends on and imply + +config E1 + bool "E1" + depends on E2 + imply E2 + +config E2 + bool "E2" + +# property + +config F1 + bool "F1" + default F2 + +config F2 + bool "F2" + depends on F1 + +# menu + +menu "menu depending on its content" + depends on G + +config G + bool "G" + +endmenu diff --git a/scripts/kconfig/tests/err_recursive_dep/__init__.py b/scripts/kconfig/tests/err_recursive_dep/__init__.py new file mode 100644 index 0000000000..5f3821b43c --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_dep/__init__.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Detect recursive dependency error. + +Recursive dependency should be treated as an error. +""" + +def test(conf): + assert conf.oldaskconfig() == 1 + assert conf.stderr_contains('expected_stderr') diff --git a/scripts/kconfig/tests/err_recursive_dep/expected_stderr b/scripts/kconfig/tests/err_recursive_dep/expected_stderr new file mode 100644 index 0000000000..84679b1046 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_dep/expected_stderr @@ -0,0 +1,38 @@ +Kconfig:11:error: recursive dependency detected! +Kconfig:11: symbol B is selected by B +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:5:error: recursive dependency detected! +Kconfig:5: symbol A depends on A +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:17:error: recursive dependency detected! +Kconfig:17: symbol C1 depends on C2 +Kconfig:21: symbol C2 depends on C1 +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:32:error: recursive dependency detected! +Kconfig:32: symbol D2 is selected by D1 +Kconfig:27: symbol D1 depends on D2 +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:37:error: recursive dependency detected! +Kconfig:37: symbol E1 depends on E2 +Kconfig:42: symbol E2 is implied by E1 +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:60:error: recursive dependency detected! +Kconfig:60: symbol G depends on G +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:51:error: recursive dependency detected! +Kconfig:51: symbol F2 depends on F1 +Kconfig:49: symbol F1 default value contains F2 +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig b/scripts/kconfig/tests/err_recursive_inc/Kconfig new file mode 100644 index 0000000000..0e4c8750ab --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig @@ -0,0 +1 @@ +source "Kconfig.inc1" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 new file mode 100644 index 0000000000..00e408d653 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 @@ -0,0 +1,4 @@ + + + +source "Kconfig.inc2" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 new file mode 100644 index 0000000000..349ea2db15 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 @@ -0,0 +1,3 @@ + + +source "Kconfig.inc3" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 new file mode 100644 index 0000000000..0e4c8750ab --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 @@ -0,0 +1 @@ +source "Kconfig.inc1" diff --git a/scripts/kconfig/tests/err_recursive_inc/__init__.py b/scripts/kconfig/tests/err_recursive_inc/__init__.py new file mode 100644 index 0000000000..0e4c839c54 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/__init__.py @@ -0,0 +1,10 @@ +""" +Detect recursive inclusion error. + +If recursive inclusion is detected, it should fail with error messages. +""" + + +def test(conf): + assert conf.oldaskconfig() != 0 + assert conf.stderr_contains('expected_stderr') diff --git a/scripts/kconfig/tests/err_recursive_inc/expected_stderr b/scripts/kconfig/tests/err_recursive_inc/expected_stderr new file mode 100644 index 0000000000..6b582eee21 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/expected_stderr @@ -0,0 +1,6 @@ +Recursive inclusion detected. +Inclusion path: + current file : Kconfig.inc1 + included from: Kconfig.inc3:1 + included from: Kconfig.inc2:3 + included from: Kconfig.inc1:4 diff --git a/scripts/kconfig/tests/inter_choice/Kconfig b/scripts/kconfig/tests/inter_choice/Kconfig new file mode 100644 index 0000000000..e44449f075 --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/Kconfig @@ -0,0 +1,23 @@ +config MODULES + def_bool y + option modules + +choice + prompt "Choice" + +config CHOICE_VAL0 + tristate "Choice 0" + +config CHOIVE_VAL1 + tristate "Choice 1" + +endchoice + +choice + prompt "Another choice" + depends on CHOICE_VAL0 + +config DUMMY + bool "dummy" + +endchoice diff --git a/scripts/kconfig/tests/inter_choice/__init__.py b/scripts/kconfig/tests/inter_choice/__init__.py new file mode 100644 index 0000000000..5c7fc365ed --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/__init__.py @@ -0,0 +1,14 @@ +""" +Do not affect user-assigned choice value by another choice. + +Handling of state flags for choices is complecated. In old days, +the defconfig result of a choice could be affected by another choice +if those choices interact by 'depends on', 'select', etc. + +Related Linux commit: fbe98bb9ed3dae23e320c6b113e35f129538d14a +""" + + +def test(conf): + assert conf.defconfig('defconfig') == 0 + assert conf.config_contains('expected_config') diff --git a/scripts/kconfig/tests/inter_choice/defconfig b/scripts/kconfig/tests/inter_choice/defconfig new file mode 100644 index 0000000000..162c4148e2 --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/defconfig @@ -0,0 +1 @@ +CONFIG_CHOICE_VAL0=y diff --git a/scripts/kconfig/tests/inter_choice/expected_config b/scripts/kconfig/tests/inter_choice/expected_config new file mode 100644 index 0000000000..5dceefb054 --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/expected_config @@ -0,0 +1,4 @@ +CONFIG_MODULES=y +CONFIG_CHOICE_VAL0=y +# CONFIG_CHOIVE_VAL1 is not set +CONFIG_DUMMY=y diff --git a/scripts/kconfig/tests/new_choice_with_dep/Kconfig b/scripts/kconfig/tests/new_choice_with_dep/Kconfig new file mode 100644 index 0000000000..53ef1b86e7 --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/Kconfig @@ -0,0 +1,37 @@ +config A + bool "A" + help + This is a new symbol. + +choice + prompt "Choice ?" + depends on A + help + "depends on A" has been newly added. + +config CHOICE_B + bool "Choice B" + +config CHOICE_C + bool "Choice C" + help + This is a new symbol, so should be asked. + +endchoice + +choice + prompt "Choice2 ?" + +config CHOICE_D + bool "Choice D" + +config CHOICE_E + bool "Choice E" + +config CHOICE_F + bool "Choice F" + depends on A + help + This is a new symbol, so should be asked. + +endchoice diff --git a/scripts/kconfig/tests/new_choice_with_dep/__init__.py b/scripts/kconfig/tests/new_choice_with_dep/__init__.py new file mode 100644 index 0000000000..f0e0ead0f3 --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/__init__.py @@ -0,0 +1,14 @@ +""" +Ask new choice values when they become visible. + +If new choice values are added with new dependency, and they become +visible during user configuration, oldconfig should recognize them +as (NEW), and ask the user for choice. + +Related Linux commit: 5d09598d488f081e3be23f885ed65cbbe2d073b5 +""" + + +def test(conf): + assert conf.oldconfig('config', 'y') == 0 + assert conf.stdout_contains('expected_stdout') diff --git a/scripts/kconfig/tests/new_choice_with_dep/config b/scripts/kconfig/tests/new_choice_with_dep/config new file mode 100644 index 0000000000..47ef95d567 --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/config @@ -0,0 +1,3 @@ +CONFIG_CHOICE_B=y +# CONFIG_CHOICE_D is not set +CONFIG_CHOICE_E=y diff --git a/scripts/kconfig/tests/new_choice_with_dep/expected_stdout b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout new file mode 100644 index 0000000000..74dc0bcb22 --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout @@ -0,0 +1,10 @@ +A (A) [N/y/?] (NEW) y + Choice ? + > 1. Choice B (CHOICE_B) + 2. Choice C (CHOICE_C) (NEW) + choice[1-2?]: +Choice2 ? + 1. Choice D (CHOICE_D) +> 2. Choice E (CHOICE_E) + 3. Choice F (CHOICE_F) (NEW) +choice[1-3?]: diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig new file mode 100644 index 0000000000..c00b8fe54f --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig @@ -0,0 +1,14 @@ +config A + bool "A" + +choice + prompt "Choice ?" + depends on A + +config CHOICE_B + bool "Choice B" + +config CHOICE_C + bool "Choice C" + +endchoice diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py new file mode 100644 index 0000000000..207261b0fe --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py @@ -0,0 +1,19 @@ +""" +Do not write choice values to .config if the dependency is unmet. + +"# CONFIG_... is not set" should not be written into the .config file +for symbols with unmet dependency. + +This was not working correctly for choice values because choice needs +a bit different symbol computation. + +This checks that no unneeded "# COFIG_... is not set" is contained in +the .config file. + +Related Linux commit: cb67ab2cd2b8abd9650292c986c79901e3073a59 +""" + + +def test(conf): + assert conf.oldaskconfig('config', 'n') == 0 + assert conf.config_matches('expected_config') diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/config b/scripts/kconfig/tests/no_write_if_dep_unmet/config new file mode 100644 index 0000000000..abd280e2f6 --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/config @@ -0,0 +1 @@ +CONFIG_A=y diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config new file mode 100644 index 0000000000..473228810c --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config @@ -0,0 +1,5 @@ +# +# Automatically generated file; DO NOT EDIT. +# Main menu +# +# CONFIG_A is not set diff --git a/scripts/kconfig/tests/preprocess/builtin_func/Kconfig b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig new file mode 100644 index 0000000000..baa3288279 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 + +# 'info' prints the argument to stdout. +$(info,hello world 0) + +# 'warning-if', if the first argument is y, sends the second argument to stderr, +# and the message is prefixed with the current file name and line number. +$(warning-if,y,hello world 1) + +# 'error-if' is similar, but it terminates the parsing immediately. +# The following is just no-op since the first argument is not y. +$(error-if,n,this should not be printed) + +# Shorthand +warning = $(warning-if,y,$(1)) + +# 'shell' executes a command, and returns its stdout. +$(warning,$(shell,echo hello world 3)) + +# Every newline in the output is replaced with a space, +# but any trailing newlines are deleted. +$(warning,$(shell,printf 'hello\nworld\n\n4\n\n\n')) + +# 'filename' is expanded to the currently parsed file name, +# 'lineno' to the line number. +$(warning,filename=$(filename)) +$(warning,lineno=$(lineno)) diff --git a/scripts/kconfig/tests/preprocess/builtin_func/__init__.py b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py new file mode 100644 index 0000000000..2e53ba08fc --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Built-in function tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stdout_contains('expected_stdout') + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr new file mode 100644 index 0000000000..33ea9ca384 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr @@ -0,0 +1,5 @@ +Kconfig:8: hello world 1 +Kconfig:18: hello world 3 +Kconfig:22: hello world 4 +Kconfig:26: filename=Kconfig +Kconfig:27: lineno=27 diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout new file mode 100644 index 0000000000..82de3a7e97 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout @@ -0,0 +1 @@ +hello world 0 diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig new file mode 100644 index 0000000000..6838997c23 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +X = $(Y) +Y = $(X) +$(info $(X)) diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py new file mode 100644 index 0000000000..419bda3e07 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Detect circular variable expansion. + +If a recursively expanded variable references itself (eventually), +it should fail with an error message. +""" + +def test(conf): + assert conf.oldaskconfig() != 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr new file mode 100644 index 0000000000..cde68fa989 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr @@ -0,0 +1 @@ +Kconfig:5: Recursive variable 'X' references itself (eventually) diff --git a/scripts/kconfig/tests/preprocess/escape/Kconfig b/scripts/kconfig/tests/preprocess/escape/Kconfig new file mode 100644 index 0000000000..4e3f444455 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/Kconfig @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# You can not pass commas directly to a function since they are treated as +# delimiters. You can use the following trick to do so. +comma := , +$(warning,hello$(comma) world) + +# Like Make, single quotes, double quotes, spaces are treated verbatim. +# The following prints the text as-is. +$(warning, ' " '" ' ''' "'") + +# Unlike Make, '$' has special meaning only when it is followed by '('. +# No need to escape '$' itself. +$(warning,$) +$(warning,$$) +$ := 1 +$(warning,$($)) + +# You need a trick to escape '$' followed by '(' +# The following should print "$(X)". It should not be expanded further. +dollar := $ +$(warning,$(dollar)(X)) + +# You need a trick to treat unbalanced parentheses. +# The following should print "(". +left_paren := ( +$(warning,$(left_paren)) + +# A simple expanded should not be expanded multiple times. +# The following should print "$(X)". It should not be expanded further. +Y := $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(X)" as well. +Y = $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(". +# It should not be emit "unterminated reference" error. +unterminated := $(dollar)( +$(warning,$(unterminated)) diff --git a/scripts/kconfig/tests/preprocess/escape/__init__.py b/scripts/kconfig/tests/preprocess/escape/__init__.py new file mode 100644 index 0000000000..7ee8e747f5 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Escape sequence tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/escape/expected_stderr b/scripts/kconfig/tests/preprocess/escape/expected_stderr new file mode 100644 index 0000000000..1c00957dda --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/expected_stderr @@ -0,0 +1,10 @@ +Kconfig:9: hello, world +Kconfig:13: ' " '" ' ''' "'" +Kconfig:17: $ +Kconfig:18: $$ +Kconfig:20: 1 +Kconfig:25: $(X) +Kconfig:30: ( +Kconfig:35: $(X) +Kconfig:39: $(X) +Kconfig:44: $( diff --git a/scripts/kconfig/tests/preprocess/variable/Kconfig b/scripts/kconfig/tests/preprocess/variable/Kconfig new file mode 100644 index 0000000000..9ce2f95cbd --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/Kconfig @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# Simply expanded variable. +X := 1 +SIMPLE := $(X) +X := 2 +$(warning,SIMPLE = $(SIMPLE)) + +# Recursively expanded variable. +X := 1 +RECURSIVE = $(X) +X := 2 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Append something to a simply expanded variable. +Y := 3 +SIMPLE += $(Y) +Y := 4 +$(warning,SIMPLE = $(SIMPLE)) + +# Append something to a recursively expanded variable. +Y := 3 +RECURSIVE += $(Y) +Y := 4 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Use += operator to an undefined variable. +# This works as a recursively expanded variable. +Y := 3 +UNDEFINED_VARIABLE += $(Y) +Y := 4 +$(warning,UNDEFINED_VARIABLE = $(UNDEFINED_VARIABLE)) + +# You can use variable references for the lefthand side of assignment statement. +X := A +Y := B +$(X)$(Y) := 5 +$(warning,AB = $(AB)) + +# User-defined function. +greeting = $(1), my name is $(2). +$(warning,$(greeting,Hello,John)) + +# The number of arguments is not checked for user-defined functions. +# If some arguments are optional, it is useful to pass fewer parameters. +# $(2) will be blank in this case. +$(warning,$(greeting,Hello)) + +# Unreferenced parameters are just ignored. +$(warning,$(greeting,Hello,John,ignored,ignored)) diff --git a/scripts/kconfig/tests/preprocess/variable/__init__.py b/scripts/kconfig/tests/preprocess/variable/__init__.py new file mode 100644 index 0000000000..e88b1708d6 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Variable and user-defined function tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/variable/expected_stderr b/scripts/kconfig/tests/preprocess/variable/expected_stderr new file mode 100644 index 0000000000..a4841c3fdf --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/expected_stderr @@ -0,0 +1,9 @@ +Kconfig:10: SIMPLE = 1 +Kconfig:16: RECURSIVE = 2 +Kconfig:22: SIMPLE = 1 3 +Kconfig:28: RECURSIVE = 2 4 +Kconfig:35: UNDEFINED_VARIABLE = 4 +Kconfig:41: AB = 5 +Kconfig:45: Hello, my name is John. +Kconfig:50: Hello, my name is . +Kconfig:53: Hello, my name is John. diff --git a/scripts/kconfig/tests/pytest.ini b/scripts/kconfig/tests/pytest.ini new file mode 100644 index 0000000000..85d7ce8e44 --- /dev/null +++ b/scripts/kconfig/tests/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +addopts = --verbose + +# Pytest requires that test files have unique names, because pytest imports +# them as top-level modules. It is silly to prefix or suffix a test file with +# the directory name that contains it. Use __init__.py for all test files. +python_files = __init__.py diff --git a/scripts/kconfig/tests/rand_nested_choice/Kconfig b/scripts/kconfig/tests/rand_nested_choice/Kconfig new file mode 100644 index 0000000000..c591d51292 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/Kconfig @@ -0,0 +1,33 @@ +choice + prompt "choice" + +config A + bool "A" + +config B + bool "B" + +if B +choice + prompt "sub choice" + +config C + bool "C" + +config D + bool "D" + +if D +choice + prompt "subsub choice" + +config E + bool "E" + +endchoice +endif # D + +endchoice +endif # B + +endchoice diff --git a/scripts/kconfig/tests/rand_nested_choice/__init__.py b/scripts/kconfig/tests/rand_nested_choice/__init__.py new file mode 100644 index 0000000000..e729a4e852 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/__init__.py @@ -0,0 +1,16 @@ +""" +Set random values recursively in nested choices. + +Kconfig can create a choice-in-choice structure by using 'if' statement. +randconfig should correctly set random choice values. + +Related Linux commit: 3b9a19e08960e5cdad5253998637653e592a3c29 +""" + + +def test(conf): + for i in range(20): + assert conf.randconfig() == 0 + assert (conf.config_contains('expected_stdout0') or + conf.config_contains('expected_stdout1') or + conf.config_contains('expected_stdout2')) diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 new file mode 100644 index 0000000000..05450f3d4e --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 @@ -0,0 +1,2 @@ +CONFIG_A=y +# CONFIG_B is not set diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 new file mode 100644 index 0000000000..37ab295841 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 @@ -0,0 +1,4 @@ +# CONFIG_A is not set +CONFIG_B=y +CONFIG_C=y +# CONFIG_D is not set diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 new file mode 100644 index 0000000000..849ff47e98 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 @@ -0,0 +1,5 @@ +# CONFIG_A is not set +CONFIG_B=y +# CONFIG_C is not set +CONFIG_D=y +CONFIG_E=y diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index 94f9c83e32..d999683bb2 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -14,69 +14,21 @@ struct file *file_lookup(const char *name) { struct file *file; - const char *file_name = sym_expand_string_value(name); for (file = file_list; file; file = file->next) { if (!strcmp(name, file->name)) { - free((void *)file_name); return file; } } file = xmalloc(sizeof(*file)); memset(file, 0, sizeof(*file)); - file->name = file_name; + file->name = xstrdup(name); file->next = file_list; file_list = file; return file; } -/* write a dependency file as used by kbuild to track dependencies */ -int file_write_dep(const char *name) -{ - struct symbol *sym, *env_sym; - struct expr *e; - struct file *file; - FILE *out; - - if (!name) - name = ".kconfig.d"; - out = fopen("..config.tmp", "w"); - if (!out) - return 1; - fprintf(out, "deps_config := \\\n"); - for (file = file_list; file; file = file->next) { - if (file->next) - fprintf(out, "\t%s \\\n", file->name); - else - fprintf(out, "\t%s\n", file->name); - } - fprintf(out, "\n%s: \\\n" - "\t$(deps_config)\n\n", conf_get_autoconfig_name()); - - expr_list_for_each_sym(sym_env_list, e, sym) { - struct property *prop; - const char *value; - - prop = sym_get_env_prop(sym); - env_sym = prop_get_symbol(prop); - if (!env_sym) - continue; - value = getenv(env_sym->name); - if (!value) - value = ""; - fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); - fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); - fprintf(out, "endif\n"); - } - - fprintf(out, "\n$(deps_config): ;\n"); - fclose(out); - rename("..config.tmp", name); - return 0; -} - - /* Allocate initial growable string */ struct gstr str_new(void) { @@ -88,16 +40,6 @@ struct gstr str_new(void) return gs; } -/* Allocate and assign growable string */ -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; -} - /* Free storage for growable string */ void str_free(struct gstr *gs) { @@ -114,7 +56,7 @@ void str_append(struct gstr *gs, const char *s) if (s) { l = strlen(gs->s) + strlen(s) + 1; if (l > gs->len) { - gs->s = realloc(gs->s, l); + gs->s = xrealloc(gs->s, l); gs->len = l; } strcat(gs->s, s); @@ -155,3 +97,34 @@ void *xcalloc(size_t nmemb, size_t size) fprintf(stderr, "Out of memory.\n"); exit(1); } + +void *xrealloc(void *p, size_t size) +{ + p = realloc(p, size); + if (p) + return p; + fprintf(stderr, "Out of memory.\n"); + exit(1); +} + +char *xstrdup(const char *s) +{ + char *p; + + p = strdup(s); + if (p) + return p; + fprintf(stderr, "Out of memory.\n"); + exit(1); +} + +char *xstrndup(const char *s, size_t n) +{ + char *p; + + p = strndup(s, n); + if (p) + return p; + fprintf(stderr, "Out of memory.\n"); + exit(1); +} diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf deleted file mode 100644 index b6ac02d604..0000000000 --- a/scripts/kconfig/zconf.gperf +++ /dev/null @@ -1,48 +0,0 @@ -%language=ANSI-C -%define hash-function-name kconf_id_hash -%define lookup-function-name kconf_id_lookup -%define string-pool-name kconf_id_strings -%compare-strncmp -%enum -%pic -%struct-type - -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 -endmenu, T_ENDMENU, TF_COMMAND -source, T_SOURCE, TF_COMMAND -choice, T_CHOICE, TF_COMMAND -endchoice, T_ENDCHOICE, TF_COMMAND -comment, T_COMMENT, TF_COMMAND -config, T_CONFIG, TF_COMMAND -menuconfig, T_MENUCONFIG, TF_COMMAND -help, T_HELP, TF_COMMAND -if, T_IF, TF_COMMAND|TF_PARAM -endif, T_ENDIF, TF_COMMAND -depends, T_DEPENDS, TF_COMMAND -optional, T_OPTIONAL, TF_COMMAND -default, T_DEFAULT, TF_COMMAND, S_UNKNOWN -prompt, T_PROMPT, TF_COMMAND -tristate, T_TYPE, TF_COMMAND, S_TRISTATE -def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE -bool, T_TYPE, TF_COMMAND, S_BOOLEAN -boolean, T_TYPE, TF_COMMAND, S_BOOLEAN -def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN -int, T_TYPE, TF_COMMAND, S_INT -hex, T_TYPE, TF_COMMAND, S_HEX -string, T_TYPE, TF_COMMAND, S_STRING -select, T_SELECT, TF_COMMAND -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/scripts/kconfig/zconf.hash.c b/scripts/kconfig/zconf.hash.c new file mode 100644 index 0000000000..c77a8eff1e --- /dev/null +++ b/scripts/kconfig/zconf.hash.c @@ -0,0 +1,289 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -t --output-file scripts/kconfig/zconf.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/kconfig/zconf.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 10 "scripts/kconfig/zconf.gperf" +struct kconf_id; + +static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); +/* maximum key range = 71, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +kconf_id_hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 5, 25, 25, + 0, 0, 0, 5, 0, 0, 73, 73, 5, 0, + 10, 5, 45, 73, 20, 20, 0, 15, 15, 73, + 20, 5, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct kconf_id_strings_t + { + char kconf_id_strings_str2[sizeof("if")]; + char kconf_id_strings_str3[sizeof("int")]; + char kconf_id_strings_str5[sizeof("endif")]; + char kconf_id_strings_str7[sizeof("default")]; + char kconf_id_strings_str8[sizeof("tristate")]; + char kconf_id_strings_str9[sizeof("endchoice")]; + char kconf_id_strings_str12[sizeof("def_tristate")]; + char kconf_id_strings_str13[sizeof("def_bool")]; + char kconf_id_strings_str14[sizeof("defconfig_list")]; + char kconf_id_strings_str17[sizeof("on")]; + char kconf_id_strings_str18[sizeof("optional")]; + char kconf_id_strings_str21[sizeof("option")]; + char kconf_id_strings_str22[sizeof("endmenu")]; + char kconf_id_strings_str23[sizeof("mainmenu")]; + char kconf_id_strings_str25[sizeof("menuconfig")]; + char kconf_id_strings_str27[sizeof("modules")]; + char kconf_id_strings_str28[sizeof("allnoconfig_y")]; + char kconf_id_strings_str29[sizeof("menu")]; + char kconf_id_strings_str31[sizeof("select")]; + char kconf_id_strings_str32[sizeof("comment")]; + char kconf_id_strings_str33[sizeof("env")]; + char kconf_id_strings_str35[sizeof("range")]; + char kconf_id_strings_str36[sizeof("choice")]; + char kconf_id_strings_str39[sizeof("bool")]; + char kconf_id_strings_str41[sizeof("source")]; + char kconf_id_strings_str42[sizeof("visible")]; + char kconf_id_strings_str43[sizeof("hex")]; + char kconf_id_strings_str46[sizeof("config")]; + char kconf_id_strings_str47[sizeof("boolean")]; + char kconf_id_strings_str51[sizeof("string")]; + char kconf_id_strings_str54[sizeof("help")]; + char kconf_id_strings_str56[sizeof("prompt")]; + char kconf_id_strings_str72[sizeof("depends")]; + }; +static const struct kconf_id_strings_t kconf_id_strings_contents = + { + "if", + "int", + "endif", + "default", + "tristate", + "endchoice", + "def_tristate", + "def_bool", + "defconfig_list", + "on", + "optional", + "option", + "endmenu", + "mainmenu", + "menuconfig", + "modules", + "allnoconfig_y", + "menu", + "select", + "comment", + "env", + "range", + "choice", + "bool", + "source", + "visible", + "hex", + "config", + "boolean", + "string", + "help", + "prompt", + "depends" + }; +#define kconf_id_strings ((const char *) &kconf_id_strings_contents) +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct kconf_id * +kconf_id_lookup (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 33, + MIN_WORD_LENGTH = 2, + MAX_WORD_LENGTH = 14, + MIN_HASH_VALUE = 2, + MAX_HASH_VALUE = 72 + }; + + static const struct kconf_id wordlist[] = + { + {-1}, {-1}, +#line 25 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM}, +#line 36 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT}, + {-1}, +#line 26 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, + {-1}, +#line 29 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, +#line 31 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE}, +#line 20 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, + {-1}, {-1}, +#line 32 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE}, +#line 35 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, +#line 45 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION}, + {-1}, {-1}, +#line 43 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_ON, TF_PARAM}, +#line 28 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND}, + {-1}, {-1}, +#line 42 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_OPTION, TF_COMMAND}, +#line 17 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND}, +#line 15 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_MAINMENU, TF_COMMAND}, + {-1}, +#line 23 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25, T_MENUCONFIG, TF_COMMAND}, + {-1}, +#line 44 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, +#line 47 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPT_ALLNOCONFIG_Y,TF_OPTION}, +#line 16 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, + {-1}, +#line 39 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND}, +#line 21 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, +#line 46 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ENV, TF_OPTION}, + {-1}, +#line 40 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_RANGE, TF_COMMAND}, +#line 19 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_CHOICE, TF_COMMAND}, + {-1}, {-1}, +#line 33 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, +#line 18 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND}, +#line 41 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_VISIBLE, TF_COMMAND}, +#line 37 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_TYPE, TF_COMMAND, S_HEX}, + {-1}, {-1}, +#line 22 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_CONFIG, TF_COMMAND}, +#line 34 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, {-1}, {-1}, +#line 38 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_TYPE, TF_COMMAND, S_STRING}, + {-1}, {-1}, +#line 24 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str54, T_HELP, TF_COMMAND}, + {-1}, +#line 30 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str56, T_PROMPT, TF_COMMAND}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 27 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str72, T_DEPENDS, TF_COMMAND} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = kconf_id_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = wordlist[key].name; + if (o >= 0) + { + register const char *s = o + kconf_id_strings; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[key]; + } + } + } + return 0; +} +#line 48 "scripts/kconfig/zconf.gperf" + diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped deleted file mode 100644 index c77a8eff1e..0000000000 --- a/scripts/kconfig/zconf.hash.c_shipped +++ /dev/null @@ -1,289 +0,0 @@ -/* ANSI-C code produced by gperf version 3.0.4 */ -/* Command-line: gperf -t --output-file scripts/kconfig/zconf.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/kconfig/zconf.gperf */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." -#endif - -#line 10 "scripts/kconfig/zconf.gperf" -struct kconf_id; - -static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); -/* maximum key range = 71, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -kconf_id_hash (register const char *str, register unsigned int len) -{ - static const unsigned char asso_values[] = - { - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 5, 25, 25, - 0, 0, 0, 5, 0, 0, 73, 73, 5, 0, - 10, 5, 45, 73, 20, 20, 0, 15, 15, 73, - 20, 5, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73 - }; - register int hval = len; - - switch (hval) - { - default: - hval += asso_values[(unsigned char)str[2]]; - /*FALLTHROUGH*/ - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval + asso_values[(unsigned char)str[len - 1]]; -} - -struct kconf_id_strings_t - { - char kconf_id_strings_str2[sizeof("if")]; - char kconf_id_strings_str3[sizeof("int")]; - char kconf_id_strings_str5[sizeof("endif")]; - char kconf_id_strings_str7[sizeof("default")]; - char kconf_id_strings_str8[sizeof("tristate")]; - char kconf_id_strings_str9[sizeof("endchoice")]; - char kconf_id_strings_str12[sizeof("def_tristate")]; - char kconf_id_strings_str13[sizeof("def_bool")]; - char kconf_id_strings_str14[sizeof("defconfig_list")]; - char kconf_id_strings_str17[sizeof("on")]; - char kconf_id_strings_str18[sizeof("optional")]; - char kconf_id_strings_str21[sizeof("option")]; - char kconf_id_strings_str22[sizeof("endmenu")]; - char kconf_id_strings_str23[sizeof("mainmenu")]; - char kconf_id_strings_str25[sizeof("menuconfig")]; - char kconf_id_strings_str27[sizeof("modules")]; - char kconf_id_strings_str28[sizeof("allnoconfig_y")]; - char kconf_id_strings_str29[sizeof("menu")]; - char kconf_id_strings_str31[sizeof("select")]; - char kconf_id_strings_str32[sizeof("comment")]; - char kconf_id_strings_str33[sizeof("env")]; - char kconf_id_strings_str35[sizeof("range")]; - char kconf_id_strings_str36[sizeof("choice")]; - char kconf_id_strings_str39[sizeof("bool")]; - char kconf_id_strings_str41[sizeof("source")]; - char kconf_id_strings_str42[sizeof("visible")]; - char kconf_id_strings_str43[sizeof("hex")]; - char kconf_id_strings_str46[sizeof("config")]; - char kconf_id_strings_str47[sizeof("boolean")]; - char kconf_id_strings_str51[sizeof("string")]; - char kconf_id_strings_str54[sizeof("help")]; - char kconf_id_strings_str56[sizeof("prompt")]; - char kconf_id_strings_str72[sizeof("depends")]; - }; -static const struct kconf_id_strings_t kconf_id_strings_contents = - { - "if", - "int", - "endif", - "default", - "tristate", - "endchoice", - "def_tristate", - "def_bool", - "defconfig_list", - "on", - "optional", - "option", - "endmenu", - "mainmenu", - "menuconfig", - "modules", - "allnoconfig_y", - "menu", - "select", - "comment", - "env", - "range", - "choice", - "bool", - "source", - "visible", - "hex", - "config", - "boolean", - "string", - "help", - "prompt", - "depends" - }; -#define kconf_id_strings ((const char *) &kconf_id_strings_contents) -#ifdef __GNUC__ -__inline -#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif -const struct kconf_id * -kconf_id_lookup (register const char *str, register unsigned int len) -{ - enum - { - TOTAL_KEYWORDS = 33, - MIN_WORD_LENGTH = 2, - MAX_WORD_LENGTH = 14, - MIN_HASH_VALUE = 2, - MAX_HASH_VALUE = 72 - }; - - static const struct kconf_id wordlist[] = - { - {-1}, {-1}, -#line 25 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM}, -#line 36 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT}, - {-1}, -#line 26 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, - {-1}, -#line 29 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, -#line 31 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE}, -#line 20 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, - {-1}, {-1}, -#line 32 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE}, -#line 35 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, -#line 45 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION}, - {-1}, {-1}, -#line 43 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_ON, TF_PARAM}, -#line 28 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND}, - {-1}, {-1}, -#line 42 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_OPTION, TF_COMMAND}, -#line 17 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND}, -#line 15 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_MAINMENU, TF_COMMAND}, - {-1}, -#line 23 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25, T_MENUCONFIG, TF_COMMAND}, - {-1}, -#line 44 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, -#line 47 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPT_ALLNOCONFIG_Y,TF_OPTION}, -#line 16 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, - {-1}, -#line 39 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND}, -#line 21 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, -#line 46 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ENV, TF_OPTION}, - {-1}, -#line 40 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_RANGE, TF_COMMAND}, -#line 19 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_CHOICE, TF_COMMAND}, - {-1}, {-1}, -#line 33 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {-1}, -#line 18 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND}, -#line 41 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_VISIBLE, TF_COMMAND}, -#line 37 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_TYPE, TF_COMMAND, S_HEX}, - {-1}, {-1}, -#line 22 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_CONFIG, TF_COMMAND}, -#line 34 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {-1}, {-1}, {-1}, -#line 38 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_TYPE, TF_COMMAND, S_STRING}, - {-1}, {-1}, -#line 24 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str54, T_HELP, TF_COMMAND}, - {-1}, -#line 30 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str56, T_PROMPT, TF_COMMAND}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 27 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str72, T_DEPENDS, TF_COMMAND} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = kconf_id_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register int o = wordlist[key].name; - if (o >= 0) - { - register const char *s = o + kconf_id_strings; - - if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') - return &wordlist[key]; - } - } - } - return 0; -} -#line 48 "scripts/kconfig/zconf.gperf" - diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 6c62d93b4f..25bd2b89fe 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -1,13 +1,13 @@ %option nostdinit noyywrap never-interactive full ecs -%option 8bit nodefault perf-report perf-report -%option noinput -%x COMMAND HELP STRING PARAM +%option 8bit nodefault yylineno +%x COMMAND HELP STRING PARAM ASSIGN_VAL %{ /* * Copyright (C) 2002 Roman Zippel * Released under the terms of the GNU GPL v2.0. */ +#include #include #include #include @@ -35,6 +35,8 @@ struct buffer *current_buf; static int last_ts, first_ts; +static char *expand_token(const char *in, size_t n); +static void append_expanded_string(const char *in); static void zconf_endhelp(void); static void zconf_endfile(void); @@ -52,7 +54,7 @@ static void append_string(const char *str, int size) if (new_size > text_asize) { new_size += START_STRSIZE - 1; new_size &= -START_STRSIZE; - text = realloc(text, new_size); + text = xrealloc(text, new_size); text_asize = new_size; } memcpy(text + text_size, str, size); @@ -66,9 +68,16 @@ static void alloc_string(const char *str, int size) memcpy(text, str, size); text[size] = 0; } + +static void warn_ignored_character(char chr) +{ + fprintf(stderr, + "%s:%d:warning: ignoring unsupported character '%c'\n", + zconf_curname(), zconf_lineno(), chr); +} %} -n [A-Za-z0-9_] +n [A-Za-z0-9_-] %% int str = 0; @@ -76,7 +85,6 @@ n [A-Za-z0-9_] [ \t]*#.*\n | [ \t]*\n { - current_file->lineno++; return T_EOL; } [ \t]*#.* @@ -95,25 +103,45 @@ n [A-Za-z0-9_] { {n}+ { const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); - BEGIN(PARAM); current_pos.file = current_file; - current_pos.lineno = current_file->lineno; + current_pos.lineno = yylineno; if (id && id->flags & TF_COMMAND) { - zconflval.id = id; + BEGIN(PARAM); + yylval.id = id; return id->token; } alloc_string(yytext, yyleng); - zconflval.string = text; - return T_WORD; + yylval.string = text; + return T_VARIABLE; } - . + ({n}|$)+ { + /* this token includes at least one '$' */ + yylval.string = expand_token(yytext, yyleng); + if (strlen(yylval.string)) + return T_VARIABLE; + free(yylval.string); + } + "=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; } + ":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; } + "+=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; } + [[:blank:]]+ + . warn_ignored_character(*yytext); \n { BEGIN(INITIAL); - current_file->lineno++; return T_EOL; } } +{ + [^[:blank:]\n]+.* { + alloc_string(yytext, yyleng); + yylval.string = text; + return T_ASSIGN_VAL; + } + \n { BEGIN(INITIAL); return T_EOL; } + . +} + { "&&" return T_AND; "||" return T_OR; @@ -122,43 +150,55 @@ n [A-Za-z0-9_] "!" return T_NOT; "=" return T_EQUAL; "!=" return T_UNEQUAL; + "<=" return T_LESS_EQUAL; + ">=" return T_GREATER_EQUAL; + "<" return T_LESS; + ">" return T_GREATER; \"|\' { str = yytext[0]; new_string(); BEGIN(STRING); } - \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; - --- /* ignore */ - ({n}|[-/.])+ { + \n BEGIN(INITIAL); return T_EOL; + ({n}|[/.])+ { const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); if (id && id->flags & TF_PARAM) { - zconflval.id = id; + yylval.id = id; return id->token; } alloc_string(yytext, yyleng); - zconflval.string = text; + yylval.string = text; return T_WORD; } + ({n}|[/.$])+ { + /* this token includes at least one '$' */ + yylval.string = expand_token(yytext, yyleng); + if (strlen(yylval.string)) + return T_WORD; + free(yylval.string); + } #.* /* comment */ - \\\n current_file->lineno++; - . + \\\n ; + [[:blank:]]+ + . warn_ignored_character(*yytext); <> { BEGIN(INITIAL); } } { - [^'"\\\n]+/\n { + "$".* append_expanded_string(yytext); + [^$'"\\\n]+/\n { append_string(yytext, yyleng); - zconflval.string = text; + yylval.string = text; return T_WORD_QUOTE; } - [^'"\\\n]+ { + [^$'"\\\n]+ { append_string(yytext, yyleng); } \\.?/\n { append_string(yytext + 1, yyleng - 1); - zconflval.string = text; + yylval.string = text; return T_WORD_QUOTE; } \\.? { @@ -167,14 +207,15 @@ n [A-Za-z0-9_] \'|\" { if (str == yytext[0]) { BEGIN(PARAM); - zconflval.string = text; + yylval.string = text; return T_WORD_QUOTE; } else append_string(yytext, 1); } \n { - printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); - current_file->lineno++; + fprintf(stderr, + "%s:%d:warning: multi-line strings not supported\n", + zconf_curname(), zconf_lineno()); BEGIN(INITIAL); return T_EOL; } @@ -207,12 +248,10 @@ n [A-Za-z0-9_] } } [ \t]*\n/[^ \t\n] { - current_file->lineno++; zconf_endhelp(); return T_HELPTEXT; } [ \t]*\n { - current_file->lineno++; append_string("\n", 1); } [^ \t\n].* { @@ -241,6 +280,58 @@ n [A-Za-z0-9_] } %% +static char *expand_token(const char *in, size_t n) +{ + char *out; + int c; + char c2; + const char *rest, *end; + + new_string(); + append_string(in, n); + + /* get the whole line because we do not know the end of token. */ + while ((c = input()) != EOF) { + if (c == '\n') { + unput(c); + break; + } + c2 = c; + append_string(&c2, 1); + } + + rest = text; + out = expand_one_token(&rest); + + /* push back unused characters to the input stream */ + end = rest + strlen(rest); + while (end > rest) + unput(*--end); + + free(text); + + return out; +} + +static void append_expanded_string(const char *str) +{ + const char *end; + char *res; + + str++; + + res = expand_dollar(&str); + + /* push back unused characters to the input stream */ + end = str + strlen(str); + while (end > str) + unput(*--end); + + append_string(res, strlen(res)); + + free(res); +} + void zconf_starthelp(void) { new_string(); @@ -250,7 +341,7 @@ void zconf_starthelp(void) static void zconf_endhelp(void) { - zconflval.string = text; + yylval.string = text; BEGIN(INITIAL); } @@ -283,7 +374,7 @@ void zconf_initscan(const char *name) { yyin = zconf_fopen(name); if (!yyin) { - printf("can't find file %s\n", name); + fprintf(stderr, "can't find file %s\n", name); exit(1); } @@ -291,7 +382,7 @@ void zconf_initscan(const char *name) memset(current_buf, 0, sizeof(*current_buf)); current_file = file_lookup(name); - current_file->lineno = 1; + yylineno = 1; } void zconf_nextfile(const char *name) @@ -304,35 +395,34 @@ void zconf_nextfile(const char *name) current_buf->state = YY_CURRENT_BUFFER; yyin = zconf_fopen(file->name); if (!yyin) { - printf("%s:%d: can't open file \"%s\"\n", - zconf_curname(), zconf_lineno(), file->name); + fprintf(stderr, "%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->name); exit(1); } yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); buf->parent = current_buf; current_buf = buf; - for (iter = current_file->parent; iter; iter = iter->parent ) { - if (!strcmp(current_file->name,iter->name) ) { - printf("%s:%d: recursive inclusion detected. " - "Inclusion path:\n current file : '%s'\n", - zconf_curname(), zconf_lineno(), - zconf_curname()); - iter = current_file->parent; - while (iter && \ - strcmp(iter->name,current_file->name)) { - printf(" included from: '%s:%d'\n", - iter->name, iter->lineno-1); + current_file->lineno = yylineno; + file->parent = current_file; + + for (iter = current_file; iter; iter = iter->parent) { + if (!strcmp(iter->name, file->name)) { + fprintf(stderr, + "Recursive inclusion detected.\n" + "Inclusion path:\n" + " current file : %s\n", file->name); + iter = file; + do { iter = iter->parent; - } - if (iter) - printf(" included from: '%s:%d'\n", - iter->name, iter->lineno+1); + fprintf(stderr, " included from: %s:%d\n", + iter->name, iter->lineno - 1); + } while (strcmp(iter->name, file->name)); exit(1); } } - file->lineno = 1; - file->parent = current_file; + + yylineno = 1; current_file = file; } @@ -341,6 +431,8 @@ static void zconf_endfile(void) struct buffer *parent; current_file = current_file->parent; + if (current_file) + yylineno = current_file->lineno; parent = current_buf->parent; if (parent) { diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 0f683cfa53..22fceb264c 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -20,10 +20,10 @@ int cdebug = PRINTD; -extern int zconflex(void); +int yylex(void); +static void yyerror(const char *err); static void zconfprint(const char *err, ...); static void zconf_error(const char *err, ...); -static void zconferror(const char *err); static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); struct symbol *symbol_hash[SYMBOL_HASHSIZE]; @@ -41,6 +41,7 @@ static struct menu *current_menu, *current_entry; struct expr *expr; struct menu *menu; const struct kconf_id *id; + enum variable_flavor flavor; } %token T_MAINMENU @@ -62,6 +63,7 @@ static struct menu *current_menu, *current_entry; %token T_TYPE %token T_DEFAULT %token T_SELECT +%token T_IMPLY %token T_RANGE %token T_VISIBLE %token T_OPTION @@ -69,23 +71,32 @@ static struct menu *current_menu, *current_entry; %token T_WORD %token T_WORD_QUOTE %token T_UNEQUAL +%token T_LESS +%token T_LESS_EQUAL +%token T_GREATER +%token T_GREATER_EQUAL %token T_CLOSE_PAREN %token T_OPEN_PAREN %token T_EOL +%token T_VARIABLE +%token T_ASSIGN +%token T_ASSIGN_VAL %left T_OR %left T_AND %left T_EQUAL T_UNEQUAL +%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL %nonassoc T_NOT %type prompt +%type nonconst_symbol %type symbol %type expr %type if_expr %type end %type option_name %type if_entry menu_entry choice_entry -%type symbol_option_arg word_opt +%type symbol_option_arg word_opt assign_val %destructor { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -95,8 +106,8 @@ static struct menu *current_menu, *current_entry; } if_entry menu_entry choice_entry %{ -/* Include zconf.hash.c here so it can see the token constants. */ -#include "zconf.hash.c" +/* Include kconf_id.c here so it can see the token constants. */ +#include "kconf_id.c" %} %% @@ -104,6 +115,13 @@ input: nl start | start; start: mainmenu_stmt stmt_list | stmt_list; +/* mainmenu entry */ + +mainmenu_stmt: T_MAINMENU prompt T_EOL +{ + menu_add_prompt(P_MENU, $2, NULL); +}; + stmt_list: /* empty */ | stmt_list common_stmt @@ -113,13 +131,13 @@ stmt_list: | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } | stmt_list option_name error T_EOL { - zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); + zconf_error("unexpected option \"%s\"", $2->name); } | stmt_list error T_EOL { zconf_error("invalid statement"); } ; option_name: - T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE + T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE ; common_stmt: @@ -129,6 +147,7 @@ common_stmt: | config_stmt | menuconfig_stmt | source_stmt + | assignment_stmt ; option_error: @@ -139,26 +158,23 @@ option_error: /* config/menuconfig entry */ -config_entry_start: T_CONFIG T_WORD T_EOL +config_entry_start: T_CONFIG nonconst_symbol T_EOL { - struct symbol *sym = sym_lookup($2, 0); - sym->flags |= SYMBOL_OPTIONAL; - menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); + $2->flags |= SYMBOL_OPTIONAL; + menu_add_entry($2); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name); }; config_stmt: config_entry_start config_option_list { - menu_end_entry(); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); }; -menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL +menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL { - struct symbol *sym = sym_lookup($2, 0); - sym->flags |= SYMBOL_OPTIONAL; - menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); + $2->flags |= SYMBOL_OPTIONAL; + menu_add_entry($2); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name); }; menuconfig_stmt: menuconfig_entry_start config_option_list @@ -167,7 +183,6 @@ menuconfig_stmt: menuconfig_entry_start config_option_list current_entry->prompt->type = P_MENU; else zconfprint("warning: menuconfig statement without prompt"); - menu_end_entry(); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); }; @@ -205,12 +220,18 @@ config_option: T_DEFAULT expr if_expr T_EOL $1->stype); }; -config_option: T_SELECT T_WORD if_expr T_EOL +config_option: T_SELECT nonconst_symbol if_expr T_EOL { - menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + menu_add_symbol(P_SELECT, $2, $3); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); }; +config_option: T_IMPLY nonconst_symbol if_expr T_EOL +{ + menu_add_symbol(P_IMPLY, $2, $3); + printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); +}; + config_option: T_RANGE symbol symbol if_expr T_EOL { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); @@ -225,8 +246,10 @@ symbol_option_list: | symbol_option_list T_WORD symbol_option_arg { const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); - if (id && id->flags & TF_OPTION) + if (id && id->flags & TF_OPTION) { menu_add_option(id->token, $3); + free($3); + } else zconfprint("warning: ignoring unknown option %s", $2); free($2); @@ -242,9 +265,10 @@ symbol_option_arg: choice: T_CHOICE word_opt T_EOL { struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); - sym->flags |= SYMBOL_AUTO; + sym->flags |= SYMBOL_NO_WRITE; menu_add_entry(sym); menu_add_expr(P_CHOICE, NULL, NULL); + free($2); printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); }; @@ -296,10 +320,10 @@ choice_option: T_OPTIONAL T_EOL printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); }; -choice_option: T_DEFAULT T_WORD if_expr T_EOL +choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL { if ($1->stype == S_UNKNOWN) { - menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); + menu_add_symbol(P_DEFAULT, $2, $3); printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); } else @@ -313,7 +337,7 @@ choice_block: /* if entry */ -if_entry: T_IF expr nl +if_entry: T_IF expr T_EOL { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); menu_add_entry(NULL); @@ -339,13 +363,6 @@ 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 @@ -382,6 +399,7 @@ source_stmt: T_SOURCE prompt T_EOL { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); zconf_nextfile($2); + free($2); }; /* comment entry */ @@ -394,9 +412,7 @@ comment: T_COMMENT prompt T_EOL }; comment_stmt: comment depends_list -{ - menu_end_entry(); -}; +; /* help option */ @@ -408,6 +424,17 @@ help_start: T_HELP T_EOL help: help_start T_HELPTEXT { + if (current_entry->help) { + free(current_entry->help); + zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used", + current_entry->sym->name ?: ""); + } + + /* Is the help text empty or all whitespace? */ + if ($2[strspn($2, " \f\n\r\t\v")] == '\0') + zconfprint("warning: '%s' defined with blank help text", + current_entry->sym->name ?: ""); + current_entry->help = $2; }; @@ -467,6 +494,10 @@ if_expr: /* empty */ { $$ = NULL; } ; expr: symbol { $$ = expr_alloc_symbol($1); } + | symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); } + | symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); } + | symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); } + | symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); } | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } @@ -475,13 +506,25 @@ expr: symbol { $$ = expr_alloc_symbol($1); } | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } ; -symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } +/* For symbol definitions, selects, etc., where quotes are not accepted */ +nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }; + +symbol: nonconst_symbol | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } ; word_opt: /* empty */ { $$ = NULL; } | T_WORD +/* assignment statement */ + +assignment_stmt: T_VARIABLE T_ASSIGN assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } + +assign_val: + /* empty */ { $$ = xstrdup(""); }; + | T_ASSIGN_VAL +; + %% void conf_parse(const char *name) @@ -491,27 +534,31 @@ void conf_parse(const char *name) zconf_initscan(name); - sym_init(); _menu_init(); - rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); if (getenv("ZCONF_DEBUG")) - zconfdebug = 1; - zconfparse(); - if (zconfnerrs) + yydebug = 1; + yyparse(); + + /* Variables are expanded in the parse phase. We can free them here. */ + variable_all_del(); + + if (yynerrs) exit(1); if (!modules_sym) modules_sym = sym_find( "n" ); - rootmenu.prompt->text = _(rootmenu.prompt->text); - rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); + if (!menu_has_prompt(&rootmenu)) { + current_entry = &rootmenu; + menu_add_prompt(P_MENU, "Main menu", NULL); + } menu_finalize(&rootmenu); for_all_symbols(i, sym) { if (sym_check_deps(sym)) - zconfnerrs++; + yynerrs++; } - if (zconfnerrs) + if (yynerrs) exit(1); sym_set_change_count(1); } @@ -535,17 +582,17 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok { if (id->token != endtoken) { zconf_error("unexpected '%s' within %s block", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); - zconfnerrs++; + id->name, zconf_tokenname(starttoken)); + yynerrs++; return false; } if (current_menu->file != current_file) { zconf_error("'%s' in different file than '%s'", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); + id->name, zconf_tokenname(starttoken)); fprintf(stderr, "%s:%d: location of the '%s'\n", current_menu->file->name, current_menu->lineno, zconf_tokenname(starttoken)); - zconfnerrs++; + yynerrs++; return false; } return true; @@ -566,7 +613,7 @@ static void zconf_error(const char *err, ...) { va_list ap; - zconfnerrs++; + yynerrs++; fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); va_start(ap, err); vfprintf(stderr, err, ap); @@ -574,7 +621,7 @@ static void zconf_error(const char *err, ...) fprintf(stderr, "\n"); } -static void zconferror(const char *err) +static void yyerror(const char *err) { fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); } @@ -607,7 +654,7 @@ static void print_symbol(FILE *out, struct menu *menu) fprintf(out, "\nconfig %s\n", sym->name); switch (sym->type) { case S_BOOLEAN: - fputs(" boolean\n", out); + fputs(" bool\n", out); break; case S_TRISTATE: fputs(" tristate\n", out); @@ -655,6 +702,11 @@ static void print_symbol(FILE *out, struct menu *menu) expr_fprint(prop->expr, out); fputc('\n', out); break; + case P_IMPLY: + fputs( " imply ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; case P_RANGE: fputs( " range ", out); expr_fprint(prop->expr, out); @@ -665,6 +717,10 @@ static void print_symbol(FILE *out, struct menu *menu) print_quoted_string(out, prop->text); fputc('\n', out); break; + case P_SYMBOL: + fputs( " symbol ", out); + fprintf(out, "%s\n", prop->sym->name); + break; default: fprintf(out, " unknown prop %d!\n", prop->type); break; @@ -731,3 +787,4 @@ void zconfdump(FILE *out) #include "expr.c" #include "symbol.c" #include "menu.c" +#include "preprocess.c" -- cgit v1.2.3