Skip to contentSkip to conversation

intro

PATCH New Konrad Eisele 3 participants 13 messages Nov 17, 2011 – Nov 18, 2011 Kbuild

lore
Share & tools
lore
#0 lore raw

cover intro

Appended are 2 patches:

[PATCH 1/2] Add a configuration subtree and an execution command to kconfig:
[PATCH 2/2] Example of how to define a subtree using kconfig tag "subsource":
(maybe too big to be sent to the list)

The aim of patch-1 is to make it possible to have configuration subtrees. This makes it possible to have a structure like this:

buildroot-kconfigs
+ linux-kconfigs
+ busybox-kconfigs
+ uclibc-kconfigs
+ crosstools-kconfigs

Where all configuration appear in one xconfig screen. Currently I have focues on qconfig only, I think however adding support for gconfig and mconfig is possible easily. The subtree feature is enabled with the -s option to qconfig: "qconfig -s <kconf>"

The other feature that patch-1 adds is a config-entry type "execute: It is like a string, however when doubleclicking (trying to edit) in qconfig (only in qconfig currently) then the string is executed using "system(<str>)". The goal is to be able to execute "make" from inside the gui, without having to exit.

patch-2 demonstrates the new "subsource" kconfig tag by adding a busybox1.19.x
kconfig subtree into buildroots config. (Note again that only "make xconfig" has
the subsource tag enabled, it is enabled by calling qconfig with the option "-s",
mconfig and gconfig whould be simple to add.)
package/busybox/busybox-1.19.x.in is generated by flattening the busybox Kconfigsnippets using support/kconfig/flatten.pl added by patch-1.
In case patch-2 is too big to be transmitted her is a link to it:
ftp://gaisler.com/gaisler.com/linux/patches/0002-Example-of-how-to-define-a-subtree-using-kconfig-tag.patch

#1 lore raw

PATCH 1/2 Add a configuration subtree and an execution command to kconfig:

New kconfig command "subsource":
subsource "<kconfig>" "<cwd>" "<.config>" "<title>" <internal_prefix> <.config_prefix> Allocates <kconfig> as a configuration subtree using <.config> as the configuration file to save and load from. <cwd> is the directory path to switch to for "source" to work, "<title>" is the Menu tile of the subtree, <internal_prefix> is a internal prefix, and <.config_prefix> is the prefix to append/remove when saving/loading <.config>.

New kconfig config-type "execute":
Type "execute" is similar to "string". However instead of editing, the string is executed using call to "system(<string>)" i.e.:
config EXECUTE_BUILD
execute "title"
default "make CFLAGS=\"\" build"
help
Execute "make build"

An utility function
char *resolve_vars(const char *n, struct conf_level *l)
has been added in util.c that takes a string and replaces $(...) parts with a symbol value i.e.:

config TARGET
string "Specify target"
default "all"
help

config EXECUTE_BUILD

	execute "title"
	default "make CFLAGS=\"\" $(TARGET)"
	help
	  Execute "make"
---
 Makefile                    |    2 +-
 support/kconfig/conf.c      |    8 ++-
 support/kconfig/confdata.c  |  103 ++++++++++++++++++++++++++++++++-----------
 support/kconfig/expr.h      |   15 ++++++-
 support/kconfig/flatten.pl  |   27 +++++++++++
 support/kconfig/gconf.c     |    2 +
 support/kconfig/lkc.h       |    1 +
 support/kconfig/lkc_proto.h |    5 ++
 support/kconfig/mconf.c     |    1 +
 support/kconfig/menu.c      |    5 +-
 support/kconfig/qconf.cc    |   24 ++++++++++
 support/kconfig/qconf.h     |    1 +
 support/kconfig/symbol.c    |   54 ++++++++++++++++++++---
 support/kconfig/util.c      |   45 +++++++++++++++++++
 support/kconfig/zconf.l     |   50 ++++++++++++++++++++-
 support/kconfig/zconf.y     |   26 ++++++++++-
 16 files changed, 326 insertions(+), 43 deletions(-)
 create mode 100644 support/kconfig/flatten.pl
Makefile +1 -1
index df2f859..50c5cf0 100644
@@ -523,7 +523,7 @@ COMMON_CONFIG_ENV = \
 
 xconfig: $(BUILD_DIR)/buildroot-config/qconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
-	@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
+	@$(COMMON_CONFIG_ENV) $< -s $(CONFIG_CONFIG_IN)
 
 gconfig: $(BUILD_DIR)/buildroot-config/gconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
support/kconfig/conf.c +5 -3
index 652e079..0dbe229 100644
@@ -117,6 +117,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
 	switch (type) {
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		printf("%s\n", def);
 		return 1;
@@ -394,6 +395,7 @@ static void conf(struct menu *menu)
 	switch (sym->type) {
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		conf_string(menu);
 		break;
@@ -542,7 +544,7 @@ int main(int ac, char **av)
 	case randconfig:
 		name = getenv("KCONFIG_ALLCONFIG");
 		if (name && !stat(name, &tmpstat)) {
-			conf_read_simple(name, S_DEF_USER);
+			conf_read_simple_level(name, S_DEF_USER, 0);
 			break;
 		}
 		switch (input_mode) {
@@ -554,9 +556,9 @@ int main(int ac, char **av)
 		default: break;
 		}
 		if (!stat(name, &tmpstat))
-			conf_read_simple(name, S_DEF_USER);
+			conf_read_simple_level(name, S_DEF_USER, 0);
 		else if (!stat("all.config", &tmpstat))
-			conf_read_simple("all.config", S_DEF_USER);
+			conf_read_simple_level("all.config", S_DEF_USER, 0);
 		break;
 	default:
 		break;
support/kconfig/confdata.c +77 -26

258 lines not on this page · raw message

support/kconfig/expr.h +14 -1
index 3d238db..286bb5e 100644
@@ -15,6 +15,16 @@ extern "C" {
 #include <stdbool.h>
 #endif
 
+struct conf_level {
+        struct conf_level *n, *parent;
+        char *sym_prefix;
+	char *conf, *conf_prefix, *cwd;
+	struct symbol *modules_sym;
+};
+extern struct conf_level *conf_levels;
+extern struct conf_level *current_conf_level;
+extern int dosubsource;
+
 struct file {
 	struct file *next;
 	struct file *parent;
@@ -62,7 +72,7 @@ struct symbol_value {
 };
 
 enum symbol_type {
-	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_EXECUTE, S_OTHER
 };
 
 /* enum values are used as index to symbol.def[] */
@@ -77,6 +87,7 @@ enum {
 struct symbol {
 	struct symbol *next;
 	char *name;
+	struct conf_level *level;
 	enum symbol_type type;
 	struct symbol_value curr;
 	struct symbol_value def[S_DEF_COUNT];
@@ -88,6 +99,7 @@ struct symbol {
 };
 
 #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
+#define for_all_symbols_level(i, sym, l) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->level == l && sym->type != S_OTHER)
 
 #define SYMBOL_CONST      0x0001  /* symbol is const */
 #define SYMBOL_CHECK      0x0008  /* used during dependency checking */
@@ -171,6 +183,7 @@ struct menu {
 	struct file *file;
 	int lineno;
 	void *data;
+	struct conf_level *level;
 };
 
 #define MENU_CHANGED		0x0001
support/kconfig/flatten.pl new file +27 -0
new file mode 100644
index 0000000..1ae82e5
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+flatten($ARGV[0]);
+
+sub readfile {
+    my ($in) = @_;
+    usage(\*STDOUT) if (length($in) == 0) ;
+    open IN, "$in" or die "Reading \"$in\":".$!;
+    local $/ = undef;
+    $m = <IN>;
+    close IN;
+    return $m;
+}
+
+sub flatten {
+    my ($f) = @_;
+    foreach my $l (split("\n",readfile($f))) {
+	if ($l =~ /^\s*source/) {
+	    print ("# -> $l\n");
+	    my $nf = substr($l,length($&));
+	    $nf =~ s/"//g;
+	    flatten($nf);
+	} else {
+	    print ("$l\n");
+	}
+    }
+}
support/kconfig/gconf.c +2 -0
index f9daf98..409977b 100644
@@ -869,6 +869,7 @@ static void change_sym_value(struct menu *menu, gint col)
 	case S_INT:
 	case S_HEX:
 	case S_STRING:
+	case S_EXECUTE:
 	default:
 		break;
 	}
@@ -1205,6 +1206,7 @@ static gchar **fill_row(struct menu *menu)
 		break;
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		def = sym_get_string_value(sym);
 		row[COL_VALUE] = g_strdup(def);
support/kconfig/lkc.h +1 -0
index e899066..f22dc87 100644
@@ -78,6 +78,7 @@ void zconf_starthelp(void);
 FILE *zconf_fopen(const char *name);
 void zconf_initscan(const char *name);
 void zconf_nextfile(const char *name);
+void zconf_nextconf(const char *name, char *subdir, char *subconf, char *title, char *subprefix, char *confprefix);	
 int zconf_lineno(void);
 const char *zconf_curname(void);
 
support/kconfig/lkc_proto.h +5 -0
index 17342fe..334fdfc 100644
@@ -29,7 +29,9 @@ P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
 P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
 
 P(sym_lookup,struct symbol *,(const char *name, int flags));
+P(sym_lookup_level,struct symbol *,(const char *name, int flags,struct conf_level *l));
 P(sym_find,struct symbol *,(const char *name));
+P(sym_find_level,struct symbol *,(const char *name,struct conf_level *l));
 P(sym_expand_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));
@@ -51,3 +53,6 @@ P(prop_get_type_name,const char *,(enum prop_type type));
 /* 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));
+
+/* util.c */
+P(resolve_vars,char*,(const char *n, struct conf_level *l));
support/kconfig/mconf.c +1 -0
index 3ed8a25..5bd3c10 100644
@@ -714,6 +714,7 @@ static void conf_string(struct menu *menu)
 		case S_HEX:
 			heading = _(inputbox_instructions_hex);
 			break;
+		case S_EXECUTE:
 		case S_STRING:
 			heading = _(inputbox_instructions_string);
 			break;
support/kconfig/menu.c +3 -2
index d49f8b8..1629613 100644
@@ -54,7 +54,8 @@ void menu_add_entry(struct symbol *sym)
 	menu->parent = current_menu;
 	menu->file = current_file;
 	menu->lineno = zconf_lineno();
-
+	menu->level = current_conf_level;
+	
 	*last_entry_ptr = menu;
 	last_entry_ptr = &menu->next;
 	current_entry = menu;
@@ -216,7 +217,7 @@ static void sym_check_prop(struct symbol *sym)
 	for (prop = sym->prop; prop; prop = prop->next) {
 		switch (prop->type) {
 		case P_DEFAULT:
-			if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+			if ((sym->type == S_STRING || sym->type == S_EXECUTE || sym->type == S_INT || sym->type == S_HEX) &&
 			    prop->expr->type != E_SYMBOL)
 				prop_warn(prop,
 				    "default for config symbol '%s'"
support/kconfig/qconf.cc +24 -0
index 06dd2e3..2a74a24 100644
@@ -296,6 +296,24 @@ ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
 	connect(this, SIGNAL(lostFocus()), SLOT(hide()));
 }
 
+void ConfigLineEdit::execute(ConfigItem* i)
+{
+	struct symbol *sym;
+	item = i;
+	sym = item->menu->sym;
+	if (sym
+	    && sym_get_string_value(sym)
+	    && sym_get_type(sym) == S_EXECUTE) {
+		const char *cmd = sym_get_string_value(sym);
+		char *rcmd = resolve_vars(cmd, sym->level);
+		conf_write(NULL);
+		if (rcmd) {
+			system(rcmd);
+			free(rcmd);
+		}
+	} 
+}
+
 void ConfigLineEdit::show(ConfigItem* i)
 {
 	item = i;
@@ -537,6 +555,9 @@ void ConfigList::changeValue(ConfigItem* item)
 		if (oldexpr != newexpr)
 			parent()->updateList(item);
 		break;
+	case S_EXECUTE:
+		parent()->lineEdit->execute(item);
+		break;
 	case S_INT:
 	case S_HEX:
 	case S_STRING:
@@ -1754,6 +1775,9 @@ int main(int ac, char** av)
 	configApp = new QApplication(ac, av);
 	if (ac > 1 && av[1][0] == '-') {
 		switch (av[1][1]) {
+		case 's':
+			dosubsource = 1;
+			break;
 		case 'h':
 		case '?':
 			usage();
support/kconfig/qconf.h +1 -0
index 91677d9..1537671 100644
@@ -209,6 +209,7 @@ public:
 		return (ConfigView*)Parent::parent();
 	}
 	void show(ConfigItem *i);
+	void execute(ConfigItem *i);
 	void keyPressEvent(QKeyEvent *e);
 
 public:
support/kconfig/symbol.c +48 -6

157 lines not on this page · raw message

support/kconfig/util.c +45 -0

48 lines not on this page · raw message

support/kconfig/zconf.l +49 -1

77 lines not on this page · raw message

support/kconfig/zconf.y +23 -3
index 0717a32..de7c498 100644
@@ -20,7 +20,8 @@
 #define DEBUG_PARSE	0x0002
 
 int cdebug = PRINTD;
-
+int dosubsource = 0;
+ 
 extern int zconflex(void);
 static void zconfprint(const char *err, ...);
 static void zconf_error(const char *err, ...);
@@ -30,6 +31,8 @@ static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
 struct symbol *symbol_hash[SYMBOL_HASHSIZE];
 
 static struct menu *current_menu, *current_entry;
+struct conf_level *current_conf_level = 0;
+struct conf_level *conf_levels = 0;
 
 #define YYDEBUG 0
 #if YYDEBUG
@@ -52,6 +55,7 @@ static struct menu *current_menu, *current_entry;
 %token <id>T_MENU
 %token <id>T_ENDMENU
 %token <id>T_SOURCE
+%token <id>T_SUBSOURCE
 %token <id>T_CHOICE
 %token <id>T_ENDCHOICE
 %token <id>T_COMMENT
@@ -107,7 +111,7 @@ static struct menu *current_menu, *current_entry;
 %%
 input: nl start | start;
 
-start: mainmenu_stmt stmt_list | stmt_list;
+start: stmt_list;
 
 stmt_list:
 	  /* empty */
@@ -130,10 +134,12 @@ option_name:
 common_stmt:
 	  T_EOL
 	| if_stmt
+	| mainmenu_stmt 
 	| comment_stmt
 	| config_stmt
 	| menuconfig_stmt
 	| source_stmt
+	| subsource_stmt
 ;
 
 option_error:
@@ -389,6 +395,15 @@ source_stmt: T_SOURCE prompt T_EOL
 	zconf_nextfile($2);
 };
 
+/* subsource $2:"sub-kconfig" $3:"sub-chdir" $4:"sub-.config" $5:"Title" $6:"subdomainprefix" $7:"confprefix" */
+subsource_stmt: T_SUBSOURCE prompt prompt prompt prompt T_WORD word_opt T_EOL
+{
+	if (dosubsource) {
+		printd(DEBUG_PARSE, "%s:%d:subsource %s\n", zconf_curname(), zconf_lineno(), $2);
+		zconf_nextconf($2, $3, $4, $5, $6, $7);
+	}
+}
+
 /* comment entry */
 
 comment: T_COMMENT prompt T_EOL
@@ -522,8 +537,10 @@ void conf_parse(const char *name)
 
 	menu_finalize(&rootmenu);
 	for_all_symbols(i, sym) {
-		if (sym_check_deps(sym))
+		if (sym_check_deps(sym)) {
+			fprintf(stderr, "Cannot check dependencies for %s\n", sym->name ? sym->name : "<null>");
 			zconfnerrs++;
+		}
         }
 	if (zconfnerrs)
 		exit(1);
@@ -631,6 +648,9 @@ static void print_symbol(FILE *out, struct menu *menu)
 	case S_STRING:
 		fputs("  string\n", out);
 		break;
+	case S_EXECUTE:
+		fputs("  execute\n", out);
+		break;
 	case S_INT:
 		fputs("  integer\n", out);
 		break;
Signature · 1 line
1.6.4.1
#2 lore raw

PATCH 1/2 Add a configuration subtree and an execution command to kconfig:

In reply to Konrad Eisele

New kconfig command "subsource":
subsource "<kconfig>" "<cwd>" "<.config>" "<title>" <internal_prefix> <.config_prefix> Allocates <kconfig> as a configuration subtree using <.config> as the configuration file to save and load from. <cwd> is the directory path to switch to for "source" to work, "<title>" is the Menu tile of the subtree, <internal_prefix> is a internal prefix, and <.config_prefix> is the prefix to append/remove when saving/loading <.config>.

New kconfig config-type "execute":
Type "execute" is similar to "string". However instead of editing, the string is executed using call to "system(<string>)" i.e.:
config EXECUTE_BUILD
execute "title"
default "make CFLAGS=\"\" build"
help
Execute "make build"

An utility function
char *resolve_vars(const char *n, struct conf_level *l)
has been added in util.c that takes a string and replaces $(...) parts with a symbol value i.e.:

config TARGET
string "Specify target"
default "all"
help

config EXECUTE_BUILD

	execute "title"
	default "make CFLAGS=\"\" $(TARGET)"
	help
	  Execute "make"
---
 Makefile                    |    2 +-
 support/kconfig/conf.c      |    8 ++-
 support/kconfig/confdata.c  |  103 ++++++++++++++++++++++++++++++++-----------
 support/kconfig/expr.h      |   15 ++++++-
 support/kconfig/flatten.pl  |   27 +++++++++++
 support/kconfig/gconf.c     |    2 +
 support/kconfig/lkc.h       |    1 +
 support/kconfig/lkc_proto.h |    5 ++
 support/kconfig/mconf.c     |    1 +
 support/kconfig/menu.c      |    5 +-
 support/kconfig/qconf.cc    |   24 ++++++++++
 support/kconfig/qconf.h     |    1 +
 support/kconfig/symbol.c    |   54 ++++++++++++++++++++---
 support/kconfig/util.c      |   45 +++++++++++++++++++
 support/kconfig/zconf.l     |   50 ++++++++++++++++++++-
 support/kconfig/zconf.y     |   26 ++++++++++-
 16 files changed, 326 insertions(+), 43 deletions(-)
 create mode 100644 support/kconfig/flatten.pl
Makefile +1 -1
index df2f859..50c5cf0 100644
@@ -523,7 +523,7 @@ COMMON_CONFIG_ENV = \
 
 xconfig: $(BUILD_DIR)/buildroot-config/qconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
-	@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
+	@$(COMMON_CONFIG_ENV) $< -s $(CONFIG_CONFIG_IN)
 
 gconfig: $(BUILD_DIR)/buildroot-config/gconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
support/kconfig/conf.c +5 -3
index 652e079..0dbe229 100644
@@ -117,6 +117,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
 	switch (type) {
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		printf("%s\n", def);
 		return 1;
@@ -394,6 +395,7 @@ static void conf(struct menu *menu)
 	switch (sym->type) {
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		conf_string(menu);
 		break;
@@ -542,7 +544,7 @@ int main(int ac, char **av)
 	case randconfig:
 		name = getenv("KCONFIG_ALLCONFIG");
 		if (name && !stat(name, &tmpstat)) {
-			conf_read_simple(name, S_DEF_USER);
+			conf_read_simple_level(name, S_DEF_USER, 0);
 			break;
 		}
 		switch (input_mode) {
@@ -554,9 +556,9 @@ int main(int ac, char **av)
 		default: break;
 		}
 		if (!stat(name, &tmpstat))
-			conf_read_simple(name, S_DEF_USER);
+			conf_read_simple_level(name, S_DEF_USER, 0);
 		else if (!stat("all.config", &tmpstat))
-			conf_read_simple("all.config", S_DEF_USER);
+			conf_read_simple_level("all.config", S_DEF_USER, 0);
 		break;
 	default:
 		break;
support/kconfig/confdata.c +77 -26

258 lines not on this page · raw message

support/kconfig/expr.h +14 -1
index 3d238db..286bb5e 100644
@@ -15,6 +15,16 @@ extern "C" {
 #include <stdbool.h>
 #endif
 
+struct conf_level {
+        struct conf_level *n, *parent;
+        char *sym_prefix;
+	char *conf, *conf_prefix, *cwd;
+	struct symbol *modules_sym;
+};
+extern struct conf_level *conf_levels;
+extern struct conf_level *current_conf_level;
+extern int dosubsource;
+
 struct file {
 	struct file *next;
 	struct file *parent;
@@ -62,7 +72,7 @@ struct symbol_value {
 };
 
 enum symbol_type {
-	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_EXECUTE, S_OTHER
 };
 
 /* enum values are used as index to symbol.def[] */
@@ -77,6 +87,7 @@ enum {
 struct symbol {
 	struct symbol *next;
 	char *name;
+	struct conf_level *level;
 	enum symbol_type type;
 	struct symbol_value curr;
 	struct symbol_value def[S_DEF_COUNT];
@@ -88,6 +99,7 @@ struct symbol {
 };
 
 #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
+#define for_all_symbols_level(i, sym, l) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->level == l && sym->type != S_OTHER)
 
 #define SYMBOL_CONST      0x0001  /* symbol is const */
 #define SYMBOL_CHECK      0x0008  /* used during dependency checking */
@@ -171,6 +183,7 @@ struct menu {
 	struct file *file;
 	int lineno;
 	void *data;
+	struct conf_level *level;
 };
 
 #define MENU_CHANGED		0x0001
support/kconfig/flatten.pl new file +27 -0
new file mode 100644
index 0000000..1ae82e5
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+flatten($ARGV[0]);
+
+sub readfile {
+    my ($in) = @_;
+    usage(\*STDOUT) if (length($in) == 0) ;
+    open IN, "$in" or die "Reading \"$in\":".$!;
+    local $/ = undef;
+    $m = <IN>;
+    close IN;
+    return $m;
+}
+
+sub flatten {
+    my ($f) = @_;
+    foreach my $l (split("\n",readfile($f))) {
+	if ($l =~ /^\s*source/) {
+	    print ("# -> $l\n");
+	    my $nf = substr($l,length($&));
+	    $nf =~ s/"//g;
+	    flatten($nf);
+	} else {
+	    print ("$l\n");
+	}
+    }
+}
support/kconfig/gconf.c +2 -0
index f9daf98..409977b 100644
@@ -869,6 +869,7 @@ static void change_sym_value(struct menu *menu, gint col)
 	case S_INT:
 	case S_HEX:
 	case S_STRING:
+	case S_EXECUTE:
 	default:
 		break;
 	}
@@ -1205,6 +1206,7 @@ static gchar **fill_row(struct menu *menu)
 		break;
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		def = sym_get_string_value(sym);
 		row[COL_VALUE] = g_strdup(def);
support/kconfig/lkc.h +1 -0
index e899066..f22dc87 100644
@@ -78,6 +78,7 @@ void zconf_starthelp(void);
 FILE *zconf_fopen(const char *name);
 void zconf_initscan(const char *name);
 void zconf_nextfile(const char *name);
+void zconf_nextconf(const char *name, char *subdir, char *subconf, char *title, char *subprefix, char *confprefix);	
 int zconf_lineno(void);
 const char *zconf_curname(void);
 
support/kconfig/lkc_proto.h +5 -0
index 17342fe..334fdfc 100644
@@ -29,7 +29,9 @@ P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
 P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
 
 P(sym_lookup,struct symbol *,(const char *name, int flags));
+P(sym_lookup_level,struct symbol *,(const char *name, int flags,struct conf_level *l));
 P(sym_find,struct symbol *,(const char *name));
+P(sym_find_level,struct symbol *,(const char *name,struct conf_level *l));
 P(sym_expand_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));
@@ -51,3 +53,6 @@ P(prop_get_type_name,const char *,(enum prop_type type));
 /* 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));
+
+/* util.c */
+P(resolve_vars,char*,(const char *n, struct conf_level *l));
support/kconfig/mconf.c +1 -0
index 3ed8a25..5bd3c10 100644
@@ -714,6 +714,7 @@ static void conf_string(struct menu *menu)
 		case S_HEX:
 			heading = _(inputbox_instructions_hex);
 			break;
+		case S_EXECUTE:
 		case S_STRING:
 			heading = _(inputbox_instructions_string);
 			break;
support/kconfig/menu.c +3 -2
index d49f8b8..1629613 100644
@@ -54,7 +54,8 @@ void menu_add_entry(struct symbol *sym)
 	menu->parent = current_menu;
 	menu->file = current_file;
 	menu->lineno = zconf_lineno();
-
+	menu->level = current_conf_level;
+	
 	*last_entry_ptr = menu;
 	last_entry_ptr = &menu->next;
 	current_entry = menu;
@@ -216,7 +217,7 @@ static void sym_check_prop(struct symbol *sym)
 	for (prop = sym->prop; prop; prop = prop->next) {
 		switch (prop->type) {
 		case P_DEFAULT:
-			if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+			if ((sym->type == S_STRING || sym->type == S_EXECUTE || sym->type == S_INT || sym->type == S_HEX) &&
 			    prop->expr->type != E_SYMBOL)
 				prop_warn(prop,
 				    "default for config symbol '%s'"
support/kconfig/qconf.cc +24 -0
index 06dd2e3..2a74a24 100644
@@ -296,6 +296,24 @@ ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
 	connect(this, SIGNAL(lostFocus()), SLOT(hide()));
 }
 
+void ConfigLineEdit::execute(ConfigItem* i)
+{
+	struct symbol *sym;
+	item = i;
+	sym = item->menu->sym;
+	if (sym
+	    && sym_get_string_value(sym)
+	    && sym_get_type(sym) == S_EXECUTE) {
+		const char *cmd = sym_get_string_value(sym);
+		char *rcmd = resolve_vars(cmd, sym->level);
+		conf_write(NULL);
+		if (rcmd) {
+			system(rcmd);
+			free(rcmd);
+		}
+	} 
+}
+
 void ConfigLineEdit::show(ConfigItem* i)
 {
 	item = i;
@@ -537,6 +555,9 @@ void ConfigList::changeValue(ConfigItem* item)
 		if (oldexpr != newexpr)
 			parent()->updateList(item);
 		break;
+	case S_EXECUTE:
+		parent()->lineEdit->execute(item);
+		break;
 	case S_INT:
 	case S_HEX:
 	case S_STRING:
@@ -1754,6 +1775,9 @@ int main(int ac, char** av)
 	configApp = new QApplication(ac, av);
 	if (ac > 1 && av[1][0] == '-') {
 		switch (av[1][1]) {
+		case 's':
+			dosubsource = 1;
+			break;
 		case 'h':
 		case '?':
 			usage();
support/kconfig/qconf.h +1 -0
index 91677d9..1537671 100644
@@ -209,6 +209,7 @@ public:
 		return (ConfigView*)Parent::parent();
 	}
 	void show(ConfigItem *i);
+	void execute(ConfigItem *i);
 	void keyPressEvent(QKeyEvent *e);
 
 public:
support/kconfig/symbol.c +48 -6

157 lines not on this page · raw message

support/kconfig/util.c +45 -0

48 lines not on this page · raw message

support/kconfig/zconf.l +49 -1

77 lines not on this page · raw message

support/kconfig/zconf.y +23 -3
index 0717a32..de7c498 100644
@@ -20,7 +20,8 @@
 #define DEBUG_PARSE	0x0002
 
 int cdebug = PRINTD;
-
+int dosubsource = 0;
+ 
 extern int zconflex(void);
 static void zconfprint(const char *err, ...);
 static void zconf_error(const char *err, ...);
@@ -30,6 +31,8 @@ static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
 struct symbol *symbol_hash[SYMBOL_HASHSIZE];
 
 static struct menu *current_menu, *current_entry;
+struct conf_level *current_conf_level = 0;
+struct conf_level *conf_levels = 0;
 
 #define YYDEBUG 0
 #if YYDEBUG
@@ -52,6 +55,7 @@ static struct menu *current_menu, *current_entry;
 %token <id>T_MENU
 %token <id>T_ENDMENU
 %token <id>T_SOURCE
+%token <id>T_SUBSOURCE
 %token <id>T_CHOICE
 %token <id>T_ENDCHOICE
 %token <id>T_COMMENT
@@ -107,7 +111,7 @@ static struct menu *current_menu, *current_entry;
 %%
 input: nl start | start;
 
-start: mainmenu_stmt stmt_list | stmt_list;
+start: stmt_list;
 
 stmt_list:
 	  /* empty */
@@ -130,10 +134,12 @@ option_name:
 common_stmt:
 	  T_EOL
 	| if_stmt
+	| mainmenu_stmt 
 	| comment_stmt
 	| config_stmt
 	| menuconfig_stmt
 	| source_stmt
+	| subsource_stmt
 ;
 
 option_error:
@@ -389,6 +395,15 @@ source_stmt: T_SOURCE prompt T_EOL
 	zconf_nextfile($2);
 };
 
+/* subsource $2:"sub-kconfig" $3:"sub-chdir" $4:"sub-.config" $5:"Title" $6:"subdomainprefix" $7:"confprefix" */
+subsource_stmt: T_SUBSOURCE prompt prompt prompt prompt T_WORD word_opt T_EOL
+{
+	if (dosubsource) {
+		printd(DEBUG_PARSE, "%s:%d:subsource %s\n", zconf_curname(), zconf_lineno(), $2);
+		zconf_nextconf($2, $3, $4, $5, $6, $7);
+	}
+}
+
 /* comment entry */
 
 comment: T_COMMENT prompt T_EOL
@@ -522,8 +537,10 @@ void conf_parse(const char *name)
 
 	menu_finalize(&rootmenu);
 	for_all_symbols(i, sym) {
-		if (sym_check_deps(sym))
+		if (sym_check_deps(sym)) {
+			fprintf(stderr, "Cannot check dependencies for %s\n", sym->name ? sym->name : "<null>");
 			zconfnerrs++;
+		}
         }
 	if (zconfnerrs)
 		exit(1);
@@ -631,6 +648,9 @@ static void print_symbol(FILE *out, struct menu *menu)
 	case S_STRING:
 		fputs("  string\n", out);
 		break;
+	case S_EXECUTE:
+		fputs("  execute\n", out);
+		break;
 	case S_INT:
 		fputs("  integer\n", out);
 		break;
Signature · 1 line
1.6.4.1
#3 lore raw

PATCH 1/2 Add a configuration subtree and an execution command to kconfig:

Hi,

Quoted 48 lines · Konrad Eisele

New kconfig command "subsource":
subsource "<kconfig>" "<cwd>" "<.config>" "<title>" ?<internal_prefix> <.config_prefix> Allocates <kconfig> as a configuration subtree using <.config> as the configuration file to save and load from. <cwd> is the directory path to switch to for "source" to work, "<title>" is the Menu tile of the subtree, <internal_prefix> is a internal prefix, and <.config_prefix> is the prefix to append/remove when saving/loading <.config>.

New kconfig config-type "execute":
Type "execute" is similar to "string". However instead of editing, the string is executed using call to "system(<string>)" i.e.:
config EXECUTE_BUILD
? ? ? ?execute "title"
? ? ? ?default "make CFLAGS=\"\" build"
? ? ? ?help
? ? ? ? ?Execute "make build"

An utility function
char *resolve_vars(const char *n, struct conf_level *l)
has been added in util.c that takes a string and replaces $(...) parts with a symbol value i.e.:

config TARGET
? ? ? ?string "Specify target"
? ? ? ?default "all"
? ? ? ? ? ? ? ?help

config EXECUTE_BUILD
? ? ? ?execute "title"
? ? ? ?default "make CFLAGS=\"\" $(TARGET)"
? ? ? ?help
? ? ? ? ?Execute "make"
---

?Makefile ? ? ? ? ? ? ? ? ? ?| ? ?2 +-
?support/kconfig/conf.c ? ? ?| ? ?8 ++-
?support/kconfig/confdata.c ?| ?103 ++++++++++++++++++++++++++++++++-----------
?support/kconfig/expr.h ? ? ?| ? 15 ++++++-
?support/kconfig/flatten.pl ?| ? 27 +++++++++++
?support/kconfig/gconf.c ? ? | ? ?2 +
?support/kconfig/lkc.h ? ? ? | ? ?1 +
?support/kconfig/lkc_proto.h | ? ?5 ++
?support/kconfig/mconf.c ? ? | ? ?1 +
?support/kconfig/menu.c ? ? ?| ? ?5 +-
?support/kconfig/qconf.cc ? ?| ? 24 ++++++++++
?support/kconfig/qconf.h ? ? | ? ?1 +
?support/kconfig/symbol.c ? ?| ? 54 ++++++++++++++++++++---
?support/kconfig/util.c ? ? ?| ? 45 +++++++++++++++++++
?support/kconfig/zconf.l ? ? | ? 50 ++++++++++++++++++++-
?support/kconfig/zconf.y ? ? | ? 26 ++++++++++-
Quoted 3 lines

?16 files changed, 326 insertions(+), 43 deletions(-) ?create mode 100644 support/kconfig/flatten.pl

I'm unfamiliar with the internals of kconfig, so I can't really comment on the contents of the patch.
However, I think you should split up your patch in more pieces. For example, the addition of the new execute type is independent from the subsource command, and could therefore be in a separate patch. This makes it easier to understand and review your changes.

Some comments below though.

Quoted 75 lines
Makefile +0 -0
index df2f859..50c5cf0 100644
@@ -523,7 +523,7 @@ COMMON_CONFIG_ENV = \
 

?xconfig: $(BUILD_DIR)/buildroot-config/qconf outputmakefile ? ? ? ?@mkdir -p $(BUILD_DIR)/buildroot-config
- ? ? ? @$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
+ ? ? ? @$(COMMON_CONFIG_ENV) $< -s $(CONFIG_CONFIG_IN)

?gconfig: $(BUILD_DIR)/buildroot-config/gconf outputmakefile ? ? ? ?@mkdir -p $(BUILD_DIR)/buildroot-config

support/kconfig/conf.c +0 -0
index 652e079..0dbe229 100644
@@ -117,6 +117,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
 ? ? ? ?switch (type) {

? ? ? ?case S_INT:
? ? ? ?case S_HEX:
+ ? ? ? case S_EXECUTE:
? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?printf("%s\n", def);
? ? ? ? ? ? ? ?return 1;

support/kconfig/conf.c +0 -0
@@ -394,6 +395,7 @@ static void conf(struct menu *menu)
 ? ? ? ?switch (sym->type) {

? ? ? ?case S_INT:
? ? ? ?case S_HEX:
+ ? ? ? case S_EXECUTE:
? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?conf_string(menu);
? ? ? ? ? ? ? ?break;

support/kconfig/conf.c +0 -0
@@ -542,7 +544,7 @@ int main(int ac, char **av)

? ? ? ?case randconfig:
? ? ? ? ? ? ? ?name = getenv("KCONFIG_ALLCONFIG");
? ? ? ? ? ? ? ?if (name && !stat(name, &tmpstat)) {
- ? ? ? ? ? ? ? ? ? ? ? conf_read_simple(name, S_DEF_USER);
+ ? ? ? ? ? ? ? ? ? ? ? conf_read_simple_level(name, S_DEF_USER, 0); ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?switch (input_mode) {

support/kconfig/conf.c +2 -2
@@ -554,9 +556,9 @@ int main(int ac, char **av)
 ? ? ? ? ? ? ? ?default: break;
 ? ? ? ? ? ? ? ?}
 ? ? ? ? ? ? ? ?if (!stat(name, &tmpstat))
- ? ? ? ? ? ? ? ? ? ? ? conf_read_simple(name, S_DEF_USER);
+ ? ? ? ? ? ? ? ? ? ? ? conf_read_simple_level(name, S_DEF_USER, 0);
 ? ? ? ? ? ? ? ?else if (!stat("all.config", &tmpstat))
- ? ? ? ? ? ? ? ? ? ? ? conf_read_simple("all.config", S_DEF_USER);
+ ? ? ? ? ? ? ? ? ? ? ? conf_read_simple_level("all.config", S_DEF_USER, 0);
 ? ? ? ? ? ? ? ?break;

? ? ? ?default:
? ? ? ? ? ? ? ?break;

support/kconfig/confdata.c +2 -2
index c9f13ee..def8ec4 100644
@@ -178,11 +178,11 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
 ? ? ? ?return 0;
 ?}
 
-int conf_read_simple(const char *name, int def)
+int conf_read_simple_level(const char *name, int def, struct conf_level *l)
 ?{
 ? ? ? ?FILE *in = NULL;
 ? ? ? ?char line[1024];
- ? ? ? char *p, *p2;
+ ? ? ? char *p, *p2, *lp;
 ? ? ? ?struct symbol *sym;
 ? ? ? ?int i, def_flags;
 
@@ -219,13 +219,14 @@ int conf_read_simple(const char *name, int def)
 ? ? ? ? ? ? ? ?return 1;
 
Quoted 2 lines

?load:
+

Extra whitespace without added value IMO.

Quoted 266 lines

? ? ? ?conf_filename = name;
? ? ? ?conf_lineno = 0;
? ? ? ?conf_warnings = 0;
? ? ? ?conf_unsaved = 0;

? ? ? ?def_flags = SYMBOL_DEF << def;
- ? ? ? for_all_symbols(i, sym) {
+ ? ? ? for_all_symbols_level(i, sym, l) {
? ? ? ? ? ? ? ?sym->flags |= SYMBOL_CHANGED;
? ? ? ? ? ? ? ?sym->flags &= ~(def_flags|SYMBOL_VALID); ? ? ? ? ? ? ? ?if (sym_is_choice(sym))

support/kconfig/confdata.c +0 -0
@@ -233,6 +234,7 @@ load:
 ? ? ? ? ? ? ? ?switch (sym->type) {

? ? ? ? ? ? ? ?case S_INT:
? ? ? ? ? ? ? ?case S_HEX:
+ ? ? ? ? ? ? ? case S_EXECUTE:
? ? ? ? ? ? ? ?case S_STRING:
? ? ? ? ? ? ? ? ? ? ? ?if (sym->def[def].val) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(sym->def[def].val);

support/kconfig/confdata.c +21 -9
@@ -246,7 +248,7 @@ load:
 ? ? ? ? ? ? ? ?conf_lineno++;
 ? ? ? ? ? ? ? ?sym = NULL;
 ? ? ? ? ? ? ? ?if (line[0] == '#') {
- ? ? ? ? ? ? ? ? ? ? ? if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
+ ? ? ? ? ? ? ? ? ? ? ? if (memcmp(line + 2, l ? l->conf_prefix : CONFIG_, strlen(l ? l->conf_prefix : CONFIG_)))
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?continue;
 ? ? ? ? ? ? ? ? ? ? ? ?p = strchr(line + 2, ' ');
 ? ? ? ? ? ? ? ? ? ? ? ?if (!p)
@@ -254,14 +256,20 @@ load:
 ? ? ? ? ? ? ? ? ? ? ? ?*p++ = 0;
 ? ? ? ? ? ? ? ? ? ? ? ?if (strncmp(p, "is not set", 10))
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?continue;
+ ? ? ? ? ? ? ? ? ? ? ? lp = line + 2;
+ ? ? ? ? ? ? ? ? ? ? ? if (l
+ ? ? ? ? ? ? ? ? ? ? ? ? ? && l->conf_prefix
+ ? ? ? ? ? ? ? ? ? ? ? ? ? && strstr(lp, l->conf_prefix) == lp) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lp += strlen(l->conf_prefix);
+ ? ? ? ? ? ? ? ? ? ? ? }
 ? ? ? ? ? ? ? ? ? ? ? ?if (def == S_DEF_USER) {
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_find(line + 2);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_find_level(lp, l);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (!sym) {
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sym_add_change_count(1);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?goto setsym;
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
 ? ? ? ? ? ? ? ? ? ? ? ?} else {
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_lookup(line + 2, 0);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_lookup_level(lp, 0, l);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (sym->type == S_UNKNOWN)
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sym->type = S_BOOLEAN;
 ? ? ? ? ? ? ? ? ? ? ? ?}
@@ -288,14 +296,20 @@ load:
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (*p2 == '\r')
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*p2 = 0;
 ? ? ? ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ? ? ? ? lp = line;
+ ? ? ? ? ? ? ? ? ? ? ? if (l
+ ? ? ? ? ? ? ? ? ? ? ? ? ? && l->conf_prefix
+ ? ? ? ? ? ? ? ? ? ? ? ? ? && strstr(lp, l->conf_prefix) == lp) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lp += strlen(l->conf_prefix);
+ ? ? ? ? ? ? ? ? ? ? ? }
 ? ? ? ? ? ? ? ? ? ? ? ?if (def == S_DEF_USER) {
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_find(line);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_find_level(lp, l);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (!sym) {
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sym_add_change_count(1);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?goto setsym;
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
 ? ? ? ? ? ? ? ? ? ? ? ?} else {
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_lookup(line, 0);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym = sym_lookup_level(line, 0, l);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (sym->type == S_UNKNOWN)
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sym->type = S_OTHER;
 ? ? ? ? ? ? ? ? ? ? ? ?}
@@ -337,7 +351,7 @@ setsym:
 ? ? ? ?return 0;
 ?}
 
-int conf_read(const char *name)
+int conf_read_level(const char *name, struct conf_level *l)
 ?{
 ? ? ? ?struct symbol *sym, *choice_sym;
 ? ? ? ?struct property *prop;
@@ -346,10 +360,10 @@ int conf_read(const char *name)
 
 ? ? ? ?sym_set_change_count(0);
 
- ? ? ? if (conf_read_simple(name, S_DEF_USER))
+ ? ? ? if (conf_read_simple_level(name, S_DEF_USER, l))
 ? ? ? ? ? ? ? ?return 1;
 
- ? ? ? for_all_symbols(i, sym) {
+ ? ? ? for_all_symbols_level(i, sym, l) {
 ? ? ? ? ? ? ? ?sym_calc_value(sym);
 ? ? ? ? ? ? ? ?if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
 ? ? ? ? ? ? ? ? ? ? ? ?goto sym_ok;
@@ -386,7 +400,7 @@ int conf_read(const char *name)
 ? ? ? ? ? ? ? ?sym->flags &= flags | ~SYMBOL_DEF_USER;
 ? ? ? ?}
 
- ? ? ? for_all_symbols(i, sym) {
+ ? ? ? for_all_symbols_level(i, sym, l) {
 ? ? ? ? ? ? ? ?if (sym_has_value(sym) && !sym_is_choice_value(sym)) {

? ? ? ? ? ? ? ? ? ? ? ?/* Reset values of generates values, so they'll appear ? ? ? ? ? ? ? ? ? ? ? ? * as new, if they should become visible, but that

support/kconfig/confdata.c +1 -0
@@ -396,6 +410,7 @@ int conf_read(const char *name)
 ? ? ? ? ? ? ? ? ? ? ? ?if (sym->visible == no && !conf_unsaved)
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sym->flags &= ~SYMBOL_DEF_USER;
 ? ? ? ? ? ? ? ? ? ? ? ?switch (sym->type) {
+ ? ? ? ? ? ? ? ? ? ? ? case S_EXECUTE:

? ? ? ? ? ? ? ? ? ? ? ?case S_STRING:
? ? ? ? ? ? ? ? ? ? ? ?case S_INT:
? ? ? ? ? ? ? ? ? ? ? ?case S_HEX:

support/kconfig/confdata.c +17 -0
@@ -416,15 +431,32 @@ int conf_read(const char *name)
 ? ? ? ?return 0;
 ?}
 
+int conf_read(const char *name) {
+ ? ? ? int r = conf_read_level(name, 0);
+ ? ? ? if (!r && !name) {
+ ? ? ? ? ? ? ? struct conf_level *l = conf_levels;
+ ? ? ? ? ? ? ? while (l) {
+ ? ? ? ? ? ? ? ? ? ? ? char *n = resolve_vars(l->conf, l->parent);
+ ? ? ? ? ? ? ? ? ? ? ? if (n) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (r = conf_read_level(n, l))
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? free(n);
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? l = l->n;
+ ? ? ? ? ? ? ? }
+ ? ? ? }
+ ? ? ? return r;
+}
+

?/* Write a S_STRING */

support/kconfig/confdata.c +1 -1
-static void conf_write_string(bool headerfile, const char *name,
+static void conf_write_string(bool headerfile, const char *prefix, const char *name,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *str, FILE *out) ?{
? ? ? ?int l;
? ? ? ?if (headerfile)
- ? ? ? ? ? ? ? fprintf(out, "#define %s \"", name);
+ ? ? ? ? ? ? ? fprintf(out, "#define %s%s \"", prefix, name); ? ? ? ?else
- ? ? ? ? ? ? ? fprintf(out, "%s=\"", name);
+ ? ? ? ? ? ? ? fprintf(out, "%s%s=\"", prefix, name);

? ? ? ?while (1) {
? ? ? ? ? ? ? ?l = strcspn(str, "\"\\");

support/kconfig/confdata.c +2 -0
@@ -439,6 +471,8 @@ static void conf_write_string(bool headerfile, const char *name,
 ? ? ? ?fputs("\"\n", out);
 ?}
 
+#define CONFPREFIX(sym) ((sym && sym->level && sym->level->conf_prefix) ? sym->level->conf_prefix : "")
+
 ?static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
 ?{
 ? ? ? ?const char *str;
@@ -449,24 +483,24 @@ static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
 ? ? ? ? ? ? ? ?switch (sym_get_tristate_value(sym)) {

? ? ? ? ? ? ? ?case no:
? ? ? ? ? ? ? ? ? ? ? ?if (write_no)
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fprintf(out, "# %s is not set\n",
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym->name);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fprintf(out, "# %s%s is not set\n",
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CONFPREFIX(sym), sym->name);
? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case mod:
- ? ? ? ? ? ? ? ? ? ? ? fprintf(out, "%s=m\n", sym->name);
+ ? ? ? ? ? ? ? ? ? ? ? fprintf(out, "%s%s=m\n", CONFPREFIX(sym), sym->name);
? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case yes:
- ? ? ? ? ? ? ? ? ? ? ? fprintf(out, "%s=y\n", sym->name);
+ ? ? ? ? ? ? ? ? ? ? ? fprintf(out, "%s%s=y\n", CONFPREFIX(sym), sym->name);
? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?break;
? ? ? ?case S_STRING:
- ? ? ? ? ? ? ? conf_write_string(false, sym->name, sym_get_string_value(sym), out);
+ ? ? ? ? ? ? ? conf_write_string(false, CONFPREFIX(sym), sym->name, sym_get_string_value(sym), out); ? ? ? ? ? ? ? ?break;
? ? ? ?case S_HEX:
? ? ? ?case S_INT:
? ? ? ? ? ? ? ?str = sym_get_string_value(sym);
- ? ? ? ? ? ? ? fprintf(out, "%s=%s\n", sym->name, str);
+ ? ? ? ? ? ? ? fprintf(out, "%s%s=%s\n", CONFPREFIX(sym), sym->name, str);
? ? ? ? ? ? ? ?break;
? ? ? ?case S_OTHER:
? ? ? ?case S_UNKNOWN:

support/kconfig/confdata.c +2 -2
@@ -551,7 +585,7 @@ next_menu:
 ? ? ? ?return 0;
 ?}
 
-int conf_write(const char *name)
+int conf_write_level(const char *name, struct conf_level *l)
 ?{
 ? ? ? ?FILE *out;
 ? ? ? ?struct symbol *sym;
@@ -621,7 +655,7 @@ int conf_write(const char *name)
 ? ? ? ?while (menu) {
 ? ? ? ? ? ? ? ?sym = menu->sym;
 ? ? ? ? ? ? ? ?if (!sym) {
- ? ? ? ? ? ? ? ? ? ? ? if (!menu_is_visible(menu))
+ ? ? ? ? ? ? ? ? ? ? ? if (!menu_is_visible(menu) || menu->level != l)
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?goto next;
 ? ? ? ? ? ? ? ? ? ? ? ?str = menu_get_prompt(menu);

? ? ? ? ? ? ? ? ? ? ? ?fprintf(out, "\n"

support/kconfig/confdata.c +0 -0
@@ -634,7 +668,8 @@ int conf_write(const char *name)
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?goto next;
 ? ? ? ? ? ? ? ? ? ? ? ?sym->flags &= ~SYMBOL_WRITE;

? ? ? ? ? ? ? ? ? ? ? ?/* Write config symbol to file */
- ? ? ? ? ? ? ? ? ? ? ? conf_write_symbol(sym, out, true);
+ ? ? ? ? ? ? ? ? ? ? ? if (sym->level == l)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? conf_write_symbol(sym, out, true); ? ? ? ? ? ? ? ?}

?next:

support/kconfig/confdata.c +17 -1
@@ -668,6 +703,22 @@ next:
 ? ? ? ?return 0;
 ?}
 
+int conf_write(const char *name) {
+ ? ? ? int r = conf_write_level(name, 0);
+ ? ? ? if (!r && !name) {
+ ? ? ? ? ? ? ? struct conf_level *l = conf_levels;
+ ? ? ? ? ? ? ? while (l) {
+ ? ? ? ? ? ? ? ? ? ? ? char *n = resolve_vars(l->conf, l->parent);
+ ? ? ? ? ? ? ? ? ? ? ? if (r = conf_write_level(n, l))
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? l = l->n;
+ ? ? ? ? ? ? ? ? ? ? ? if (n)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? free(n);
+ ? ? ? ? ? ? ? }
+ ? ? ? }
+ ? ? ? return r;
+}
+
 ?static int conf_split_config(void)
 ?{
 ? ? ? ?const char *name;
@@ -679,7 +730,7 @@ static int conf_split_config(void)
 ? ? ? ?int res, i, fd;
 
 ? ? ? ?name = conf_get_autoconfig_name();
- ? ? ? conf_read_simple(name, S_DEF_AUTO);
+ ? ? ? conf_read_simple_level(name, S_DEF_AUTO, 0);
 
 ? ? ? ?opwd = malloc(256);
 ? ? ? ?_name = strdup(name);
@@ -889,7 +940,7 @@ int conf_write_autoconf(void)
 ? ? ? ? ? ? ? ? ? ? ? ?}
 ? ? ? ? ? ? ? ? ? ? ? ?break;

? ? ? ? ? ? ? ?case S_STRING:
- ? ? ? ? ? ? ? ? ? ? ? conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
+ ? ? ? ? ? ? ? ? ? ? ? conf_write_string(true, CONFPREFIX(sym), sym->name, sym_get_string_value(sym), out_h); ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case S_HEX:
? ? ? ? ? ? ? ? ? ? ? ?str = sym_get_string_value(sym);

support/kconfig/expr.h +0 -0
index 3d238db..286bb5e 100644
@@ -15,6 +15,16 @@ extern "C" {

?#include <stdbool.h>
?#endif

support/kconfig/expr.h

Quoted 6 lines
support/kconfig/expr.h +6 -0
+struct conf_level {
+ ? ? ? ?struct conf_level *n, *parent;
+ ? ? ? ?char *sym_prefix;
+ ? ? ? char *conf, *conf_prefix, *cwd;
+ ? ? ? struct symbol *modules_sym;
+};

I don't really like the fact that multiple fields are listed on one line here. IMO this makes it more difficult to see the contents of the structure.

Quoted 350 lines
support/kconfig/expr.h +4 -0
+extern struct conf_level *conf_levels;
+extern struct conf_level *current_conf_level;
+extern int dosubsource;
+

?struct file {
? ? ? ?struct file *next;
? ? ? ?struct file *parent;

support/kconfig/expr.h +1 -1
@@ -62,7 +72,7 @@ struct symbol_value {
 ?};
 
 ?enum symbol_type {
- ? ? ? S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+ ? ? ? S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_EXECUTE, S_OTHER
 ?};
 

?/* enum values are used as index to symbol.def[] */

support/kconfig/expr.h +2 -0
@@ -77,6 +87,7 @@ enum {
 ?struct symbol {
 ? ? ? ?struct symbol *next;
 ? ? ? ?char *name;
+ ? ? ? struct conf_level *level;
 ? ? ? ?enum symbol_type type;
 ? ? ? ?struct symbol_value curr;
 ? ? ? ?struct symbol_value def[S_DEF_COUNT];
@@ -88,6 +99,7 @@ struct symbol {
 ?};
 
 ?#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
+#define for_all_symbols_level(i, sym, l) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->level == l && sym->type != S_OTHER)
 

?#define SYMBOL_CONST ? ? ?0x0001 ?/* symbol is const */ ?#define SYMBOL_CHECK ? ? ?0x0008 ?/* used during dependency checking */

support/kconfig/expr.h +1 -0
@@ -171,6 +183,7 @@ struct menu {
 ? ? ? ?struct file *file;
 ? ? ? ?int lineno;
 ? ? ? ?void *data;
+ ? ? ? struct conf_level *level;
 ?};
 

?#define MENU_CHANGED ? ? ? ? ? 0x0001

support/kconfig/flatten.pl new file +27 -0
new file mode 100644
index 0000000..1ae82e5
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+flatten($ARGV[0]);
+
+sub readfile {
+ ? ?my ($in) = @_;
+ ? ?usage(\*STDOUT) if (length($in) == 0) ;
+ ? ?open IN, "$in" or die "Reading \"$in\":".$!;
+ ? ?local $/ = undef;
+ ? ?$m = <IN>;
+ ? ?close IN;
+ ? ?return $m;
+}
+
+sub flatten {
+ ? ?my ($f) = @_;
+ ? ?foreach my $l (split("\n",readfile($f))) {
+ ? ? ? if ($l =~ /^\s*source/) {
+ ? ? ? ? ? print ("# -> $l\n");
+ ? ? ? ? ? my $nf = substr($l,length($&));
+ ? ? ? ? ? $nf =~ s/"//g;
+ ? ? ? ? ? flatten($nf);
+ ? ? ? } else {
+ ? ? ? ? ? print ("$l\n");
+ ? ? ? }
+ ? ?}
+}
support/kconfig/gconf.c +0 -0
index f9daf98..409977b 100644
@@ -869,6 +869,7 @@ static void change_sym_value(struct menu *menu, gint col)

? ? ? ?case S_INT:
? ? ? ?case S_HEX:
? ? ? ?case S_STRING:
+ ? ? ? case S_EXECUTE:
? ? ? ?default:
? ? ? ? ? ? ? ?break;
? ? ? ?}

support/kconfig/gconf.c +0 -0
@@ -1205,6 +1206,7 @@ static gchar **fill_row(struct menu *menu)
 ? ? ? ? ? ? ? ?break;

? ? ? ?case S_INT:
? ? ? ?case S_HEX:
+ ? ? ? case S_EXECUTE:
? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?def = sym_get_string_value(sym);
? ? ? ? ? ? ? ?row[COL_VALUE] = g_strdup(def);

support/kconfig/lkc.h +1 -0
index e899066..f22dc87 100644
@@ -78,6 +78,7 @@ void zconf_starthelp(void);
 ?FILE *zconf_fopen(const char *name);
 ?void zconf_initscan(const char *name);
 ?void zconf_nextfile(const char *name);
+void zconf_nextconf(const char *name, char *subdir, char *subconf, char *title, char *subprefix, char *confprefix);
 ?int zconf_lineno(void);
 ?const char *zconf_curname(void);
 
support/kconfig/lkc_proto.h +2 -0
index 17342fe..334fdfc 100644
@@ -29,7 +29,9 @@ P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
 ?P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
 
 ?P(sym_lookup,struct symbol *,(const char *name, int flags));
+P(sym_lookup_level,struct symbol *,(const char *name, int flags,struct conf_level *l));
 ?P(sym_find,struct symbol *,(const char *name));
+P(sym_find_level,struct symbol *,(const char *name,struct conf_level *l));
 ?P(sym_expand_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));
@@ -51,3 +53,6 @@ P(prop_get_type_name,const char *,(enum prop_type type));

?/* 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));

support/kconfig/lkc_proto.h +3 -0
+
+/* util.c */
+P(resolve_vars,char*,(const char *n, struct conf_level *l));
support/kconfig/mconf.c +0 -0
index 3ed8a25..5bd3c10 100644
@@ -714,6 +714,7 @@ static void conf_string(struct menu *menu)

? ? ? ? ? ? ? ?case S_HEX:
? ? ? ? ? ? ? ? ? ? ? ?heading = _(inputbox_instructions_hex); ? ? ? ? ? ? ? ? ? ? ? ?break;
+ ? ? ? ? ? ? ? case S_EXECUTE:
? ? ? ? ? ? ? ?case S_STRING:
? ? ? ? ? ? ? ? ? ? ? ?heading = _(inputbox_instructions_string); ? ? ? ? ? ? ? ? ? ? ? ?break;

support/kconfig/menu.c +2 -1
index d49f8b8..1629613 100644
@@ -54,7 +54,8 @@ void menu_add_entry(struct symbol *sym)
 ? ? ? ?menu->parent = current_menu;
 ? ? ? ?menu->file = current_file;
 ? ? ? ?menu->lineno = zconf_lineno();
-
+ ? ? ? menu->level = current_conf_level;
+
 ? ? ? ?*last_entry_ptr = menu;
 ? ? ? ?last_entry_ptr = &menu->next;
 ? ? ? ?current_entry = menu;
@@ -216,7 +217,7 @@ static void sym_check_prop(struct symbol *sym)
 ? ? ? ?for (prop = sym->prop; prop; prop = prop->next) {
 ? ? ? ? ? ? ? ?switch (prop->type) {

? ? ? ? ? ? ? ?case P_DEFAULT:

- ? ? ? ? ? ? ? ? ? ? ? if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+ ? ? ? ? ? ? ? ? ? ? ? if ((sym->type == S_STRING || sym->type == S_EXECUTE || sym->type == S_INT || sym->type == S_HEX) &&

? ? ? ? ? ? ? ? ? ? ? ? ? ?prop->expr->type != E_SYMBOL) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?prop_warn(prop,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"default for config symbol '%s'"

support/kconfig/qconf.cc +21 -0
index 06dd2e3..2a74a24 100644
@@ -296,6 +296,24 @@ ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
 ? ? ? ?connect(this, SIGNAL(lostFocus()), SLOT(hide()));
 ?}
 
+void ConfigLineEdit::execute(ConfigItem* i)
+{
+ ? ? ? struct symbol *sym;
+ ? ? ? item = i;
+ ? ? ? sym = item->menu->sym;
+ ? ? ? if (sym
+ ? ? ? ? ? && sym_get_string_value(sym)
+ ? ? ? ? ? && sym_get_type(sym) == S_EXECUTE) {
+ ? ? ? ? ? ? ? const char *cmd = sym_get_string_value(sym);
+ ? ? ? ? ? ? ? char *rcmd = resolve_vars(cmd, sym->level);
+ ? ? ? ? ? ? ? conf_write(NULL);
+ ? ? ? ? ? ? ? if (rcmd) {
+ ? ? ? ? ? ? ? ? ? ? ? system(rcmd);
+ ? ? ? ? ? ? ? ? ? ? ? free(rcmd);
+ ? ? ? ? ? ? ? }
+ ? ? ? }
+}
+
 ?void ConfigLineEdit::show(ConfigItem* i)
 ?{
 ? ? ? ?item = i;
@@ -537,6 +555,9 @@ void ConfigList::changeValue(ConfigItem* item)
 ? ? ? ? ? ? ? ?if (oldexpr != newexpr)
 ? ? ? ? ? ? ? ? ? ? ? ?parent()->updateList(item);
 ? ? ? ? ? ? ? ?break;
+ ? ? ? case S_EXECUTE:
+ ? ? ? ? ? ? ? parent()->lineEdit->execute(item);
+ ? ? ? ? ? ? ? break;

? ? ? ?case S_INT:
? ? ? ?case S_HEX:
? ? ? ?case S_STRING:

support/kconfig/qconf.cc +3 -0
@@ -1754,6 +1775,9 @@ int main(int ac, char** av)
 ? ? ? ?configApp = new QApplication(ac, av);
 ? ? ? ?if (ac > 1 && av[1][0] == '-') {
 ? ? ? ? ? ? ? ?switch (av[1][1]) {
+ ? ? ? ? ? ? ? case 's':
+ ? ? ? ? ? ? ? ? ? ? ? dosubsource = 1;
+ ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ?case 'h':
? ? ? ? ? ? ? ?case '?':
? ? ? ? ? ? ? ? ? ? ? ?usage();

support/kconfig/qconf.h +1 -0
index 91677d9..1537671 100644
@@ -209,6 +209,7 @@ public:
 ? ? ? ? ? ? ? ?return (ConfigView*)Parent::parent();
 ? ? ? ?}
 ? ? ? ?void show(ConfigItem *i);
+ ? ? ? void execute(ConfigItem *i);
 ? ? ? ?void keyPressEvent(QKeyEvent *e);
 

?public:

support/kconfig/symbol.c +7 -0
index a796c95..9574e6e 100644
@@ -33,6 +33,13 @@ struct symbol symbol_yes = {
 ?struct symbol *sym_defconfig_list;
 ?struct symbol *modules_sym;
 ?tristate modules_val;
+struct symbol *modules_sym_level(struct symbol *sym) {
+ ? ? ? if (sym->level) {
+ ? ? ? ? ? ? ? return sym->level->modules_sym;
+ ? ? ? } else {
+ ? ? ? ? ? ? ? return modules_sym;
+ ? ? ? }
+}
 
 ?struct expr *sym_env_list;
 
@@ -85,6 +92,8 @@ const char *sym_type_name(enum symbol_type type)
 ? ? ? ? ? ? ? ?return "integer";

? ? ? ?case S_HEX:
? ? ? ? ? ? ? ?return "hex";
+ ? ? ? case S_EXECUTE:
+ ? ? ? ? ? ? ? return "execute";
? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?return "string";
? ? ? ?case S_UNKNOWN:

support/kconfig/symbol.c +0 -0
@@ -301,6 +310,7 @@ void sym_calc_value(struct symbol *sym)
 ? ? ? ?switch (sym->type) {

? ? ? ?case S_INT:
? ? ? ?case S_HEX:
+ ? ? ? case S_EXECUTE:
? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?newval = symbol_empty.curr;
? ? ? ? ? ? ? ?break;

support/kconfig/symbol.c +1 -0
@@ -367,6 +377,7 @@ void sym_calc_value(struct symbol *sym)
 ? ? ? ? ? ? ? ?if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
 ? ? ? ? ? ? ? ? ? ? ? ?newval.tri = yes;
 ? ? ? ? ? ? ? ?break;
+ ? ? ? case S_EXECUTE:

? ? ? ?case S_STRING:
? ? ? ?case S_HEX:
? ? ? ?case S_INT:

support/kconfig/symbol.c +10 -2
@@ -398,9 +409,9 @@ void sym_calc_value(struct symbol *sym)
 
 ? ? ? ?if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
 ? ? ? ? ? ? ? ?sym_set_changed(sym);
- ? ? ? ? ? ? ? if (modules_sym == sym) {
+ ? ? ? ? ? ? ? if (modules_sym_level(sym) == sym) {
 ? ? ? ? ? ? ? ? ? ? ? ?sym_set_all_changed();
- ? ? ? ? ? ? ? ? ? ? ? modules_val = modules_sym->curr.tri;
+ ? ? ? ? ? ? ? ? ? ? ? modules_val = modules_sym_level(sym)->curr.tri;
 ? ? ? ? ? ? ? ?}
 ? ? ? ?}
 
@@ -424,6 +435,7 @@ void sym_calc_value(struct symbol *sym)
 ?void sym_clear_all_valid(void)
 ?{
 ? ? ? ?struct symbol *sym;
+ ? ? ? struct conf_level *l;
 ? ? ? ?int i;
 
 ? ? ? ?for_all_symbols(i, sym)
@@ -431,6 +443,12 @@ void sym_clear_all_valid(void)
 ? ? ? ?sym_add_change_count(1);
 ? ? ? ?if (modules_sym)
 ? ? ? ? ? ? ? ?sym_calc_value(modules_sym);
+ ? ? ? l = conf_levels;
+ ? ? ? while (l) {
+ ? ? ? ? ? ? ? if (l->modules_sym)
+ ? ? ? ? ? ? ? ? ? ? ? sym_calc_value(l->modules_sym);
+ ? ? ? ? ? ? ? l = l->n;
+ ? ? ? }
 ?}
 
 ?void sym_set_changed(struct symbol *sym)
@@ -536,6 +554,7 @@ bool sym_string_valid(struct symbol *sym, const char *str)
 ? ? ? ?signed char ch;
 
 ? ? ? ?switch (sym->type) {
+ ? ? ? case S_EXECUTE:

? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?return true;
? ? ? ?case S_INT:

support/kconfig/symbol.c +1 -0
@@ -580,6 +599,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
 ? ? ? ?int val;
 
 ? ? ? ?switch (sym->type) {
+ ? ? ? case S_EXECUTE:

? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?return sym_string_valid(sym, str);
? ? ? ?case S_INT:

support/kconfig/symbol.c +1 -1
@@ -680,7 +700,7 @@ const char *sym_get_string_default(struct symbol *sym)
 ? ? ? ?tristate val;
 
 ? ? ? ?sym_calc_visibility(sym);
- ? ? ? sym_calc_value(modules_sym);
+ ? ? ? sym_calc_value(modules_sym_level(sym));
 ? ? ? ?val = symbol_no.curr.tri;
 ? ? ? ?str = symbol_empty.curr.val;
 
@@ -712,7 +732,7 @@ const char *sym_get_string_default(struct symbol *sym)
 

? ? ? ?/* transpose mod to yes if modules are not enabled */
? ? ? ?if (val == mod)
- ? ? ? ? ? ? ? if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
+ ? ? ? ? ? ? ? if (!sym_is_choice_value(sym) && modules_sym_level(sym)->curr.tri == no) ? ? ? ? ? ? ? ? ? ? ? ?val = yes;

? ? ? ?/* transpose mod to yes if type is bool */

support/kconfig/symbol.c +0 -0
@@ -730,6 +750,7 @@ const char *sym_get_string_default(struct symbol *sym)

? ? ? ?case S_INT:
? ? ? ?case S_HEX:
? ? ? ? ? ? ? ?return str;
+ ? ? ? case S_EXECUTE:
? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?return str;
? ? ? ?case S_OTHER:

support/kconfig/symbol.c +1 -1
@@ -793,7 +814,7 @@ struct symbol *sym_lookup(const char *name, int flags)
 ? ? ? ? ? ? ? ?hash = strhash(name) % SYMBOL_HASHSIZE;
 
 ? ? ? ? ? ? ? ?for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
- ? ? ? ? ? ? ? ? ? ? ? if (symbol->name &&
+ ? ? ? ? ? ? ? ? ? ? ? if (symbol->name && symbol->level == current_conf_level &&

? ? ? ? ? ? ? ? ? ? ? ? ? ?!strcmp(symbol->name, name) &&
? ? ? ? ? ? ? ? ? ? ? ? ? ?(flags ? symbol->flags & flags
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))

support/kconfig/symbol.c struct symbol *sym_lookup(const char *name, int flags) · line 835

Quoted 6 lines
support/kconfig/symbol.c +2 -1
@@ -810,13 +831,23 @@ struct symbol *sym_lookup(const char *name, int flags)
 ? ? ? ?symbol->name = new_name;
 ? ? ? ?symbol->type = S_UNKNOWN;
 ? ? ? ?symbol->flags |= flags;
-
+ ? ? ? symbol->level = current_conf_level;
+

Is this extra blank line really needed? The same in several other places in this patch...

support/kconfig/symbol.c struct symbol *sym_lookup(const char *name, int flags) · line 844

Quoted 9 lines
support/kconfig/symbol.c +3 -0
 ? ? ? ?symbol->next = symbol_hash[hash];
 ? ? ? ?symbol_hash[hash] = symbol;
 
 ? ? ? ?return symbol;
 ?}
 
+struct symbol *sym_lookup_level(const char *name, int flags, struct conf_level *l)
+{
+ ? ? ? struct conf_level *ol = current_conf_level; struct symbol *sym;

I don't really like multiple declarations on one line. Why don't you put each declaration on a line of its own?

Quoted 18 lines
support/kconfig/symbol.c +6 -0
+ ? ? ? current_conf_level = l;
+ ? ? ? sym = sym_lookup(name, flags);
+ ? ? ? current_conf_level = ol;
+ ? ? ? return sym;
+}
+
 ?struct symbol *sym_find(const char *name)
 ?{
 ? ? ? ?struct symbol *symbol = NULL;
@@ -836,6 +867,7 @@ struct symbol *sym_find(const char *name)
 
 ? ? ? ?for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {

? ? ? ? ? ? ? ?if (symbol->name &&
+ ? ? ? ? ? ? ? ? ? symbol->level == current_conf_level && ? ? ? ? ? ? ? ? ? ?!strcmp(symbol->name, name) && ? ? ? ? ? ? ? ? ? ?!(symbol->flags & SYMBOL_CONST)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;

support/kconfig/symbol.c const char *sym_expand_string_value(const char *in) · line 930

Quoted 6 lines
support/kconfig/symbol.c +3 -0
@@ -893,6 +925,16 @@ const char *sym_expand_string_value(const char *in)
 ? ? ? ?return res;
 ?}
 
+struct symbol *sym_find_level(const char *name, struct conf_level *l)
+{
+ ? ? ? struct conf_level *ol = current_conf_level; struct symbol *sym;

Idem: multiple declarations.

Quoted 15 lines
support/kconfig/symbol.c +7 -0
+ ? ? ? current_conf_level = l;
+ ? ? ? sym = sym_find(name);
+ ? ? ? current_conf_level = ol;
+ ? ? ? return sym;
+}
+
+
 ?struct symbol **sym_re_search(const char *pattern)
 ?{
 ? ? ? ?struct symbol *sym, **sym_arr = NULL;
support/kconfig/util.c +0 -0
index 8a5efaa..e0dc21d 100644

support/kconfig/util.c const char *str_get(struct gstr *gs) · line 266

Quoted 4 lines
support/kconfig/util.c +1 -0
@@ -263,3 +263,48 @@ const char *str_get(struct gstr *gs)
 ? ? ? ?return gs->s;
 ?}
 
+#define APPEND_STR(r,a,l) if (l) {int rl=r?strlen(r):0; r = realloc(r,rl+l+1); memcpy(r+rl,a,l);r[rl+l] = 0;}

I would suggest to put this on multiple lines, splitted with \
Moreover, I think you should consider using a do {} while (0) statement here. See http://kernelnewbies.org/FAQ/DoWhile0

support/kconfig/util.c const char *str_get(struct gstr *gs)

Quoted 3 lines
support/kconfig/util.c +3 -0
+
+char *resolve_vars(const char *n, struct conf_level *l) {
+ ? ? ? char *r = 0, *var = 0; const char *val = 0; int nl = strlen(n); int i,j;

This is a really long declaration list as well...

Quoted 100 lines
support/kconfig/util.c +41 -0
+ ? ? ? struct symbol *sym;
+ ? ? ? struct conf_level *o = current_conf_level;
+ ? ? ? current_conf_level = l;
+
+ ? ? ? for (i = 0, j = 0; i < nl; i++) {
+ ? ? ? ? ? ? ? if (n[i] == '$' && n[i+1] == '(') {
+ ? ? ? ? ? ? ? ? ? ? ? APPEND_STR(r,&n[j],i-j);
+ ? ? ? ? ? ? ? ? ? ? ? for (i+=2, j = i; i < nl; i++) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (n[i] == ')') {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? if (i < nl && i > j) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? var = malloc(i-j+1);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? memcpy(var, &n[j], i-j);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? var[i-j] = 0;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((sym = sym_lookup(var, 0))) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (sym_get_type(sym) == S_STRING) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sym_calc_value(sym);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? val ?= sym_get_string_value(sym);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (val) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? APPEND_STR(r,val,strlen(val));
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
+
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? free(var);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? j=i+1;
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? }
+ ? ? ? }
+ ? ? ? APPEND_STR(r,&n[j],i-j);
+ ? ? ? current_conf_level = o;
+ ? ? ? return r;
+error_out:
+ ? ? ? if (r)
+ ? ? ? ? ? ? ? free(r);
+ ? ? ? if (var)
+ ? ? ? ? ? ? ? free(var);
+ ? ? ? return 0;
+}
support/kconfig/zconf.l +31 -0
index 3dbaec1..0f9d201 100644
@@ -30,6 +30,7 @@ static int text_size, text_asize;
 ?struct buffer {
 ? ? ? ? struct buffer *parent;
 ? ? ? ? YY_BUFFER_STATE state;
+ ? ? ? ?struct conf_level *level;
 ?};
 
 ?struct buffer *current_buf;
@@ -312,6 +313,7 @@ void zconf_nextfile(const char *name)
 ? ? ? ?}
 ? ? ? ?yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
 ? ? ? ?buf->parent = current_buf;
+ ? ? ? buf->level = current_conf_level;
 ? ? ? ?current_buf = buf;
 
 ? ? ? ?if (file->flags & FILE_BUSY) {
@@ -331,6 +333,35 @@ void zconf_nextfile(const char *name)
 ? ? ? ?current_file = file;
 ?}
 
+void zconf_nextconf(const char *name, char *subdir, char *subconf, char *title, char *subprefix, char *confprefix)
+{
+ ? ? ? struct conf_level **lp, *l;
+ ? ? ? l = malloc(sizeof(struct conf_level));
+ ? ? ? memset(l,0,sizeof(*l));
+ ? ? ? l->conf = subconf;
+ ? ? ? l->sym_prefix = subprefix;
+ ? ? ? l->conf_prefix = confprefix;
+ ? ? ? l->parent = current_conf_level;
+ ? ? ? for (lp = &conf_levels; *lp; lp = &(*lp)->n) ;
+ ? ? ? *lp = l;
+ ? ? ? current_conf_level = l;
+
+ ? ? ? zconf_nextfile(name);
+
+ ? ? ? /* allocate per conf module-sym */
+ ? ? ? l->modules_sym = sym_lookup(NULL, 0);
+ ? ? ? l->modules_sym->type = S_BOOLEAN;
+ ? ? ? l->modules_sym->flags |= SYMBOL_AUTO;
+ ? ? ? l->cwd = getcwd(0,0);
+ ? ? ? chdir(subdir);
+
+ ? ? ? /* open new menue */
+ ? ? ? menu_add_entry(NULL);
+ ? ? ? menu_add_prompt(P_MENU, title, NULL);
+ ? ? ? menu_add_menu();
+
+}
+
 ?static void zconf_endfile(void)
 ?{
 ? ? ? ?struct buffer *parent;
@@ -340,10 +371,27 @@ static void zconf_endfile(void)
 ? ? ? ?current_file = current_file->parent;
 

support/kconfig/zconf.l static void zconf_endfile(void) · line 381

Quoted 10 lines
support/kconfig/zconf.l +5 -1
 ? ? ? ?parent = current_buf->parent;
+
 ? ? ? ?if (parent) {
- ? ? ? ? ? ? ? fclose(yyin);
+ ? ? ? ? ? ? ? ?fclose(yyin);
 ? ? ? ? ? ? ? ?yy_delete_buffer(YY_CURRENT_BUFFER);
 ? ? ? ? ? ? ? ?yy_switch_to_buffer(parent->state);
+
+ ? ? ? ? ? ? ? if (current_buf->level && (parent->level != current_buf->level)) {
+ ? ? ? ? ? ? ? ? ? ? ? /* close menue */

typo: menu

Quoted 101 lines
support/kconfig/zconf.l +13 -0
+ ? ? ? ? ? ? ? ? ? ? ? menu_end_menu();
+ ? ? ? ? ? ? ? ? ? ? ? /* restore cwd */
+ ? ? ? ? ? ? ? ? ? ? ? chdir(current_buf->level->cwd);
+
+ ? ? ? ? ? ? ? ? ? ? ? if (current_conf_level && !current_conf_level->modules_sym->prop) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct property *prop;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? prop = prop_alloc(P_DEFAULT, current_conf_level->modules_sym);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
+ ? ? ? ? ? ? ? ? ? ? ? }
+
+ ? ? ? ? ? ? ? ? ? ? ? /* switch to previous conf */
+ ? ? ? ? ? ? ? ? ? ? ? current_conf_level = parent->level;
+ ? ? ? ? ? ? ? }
 ? ? ? ?}
 ? ? ? ?free(current_buf);
 ? ? ? ?current_buf = parent;
support/kconfig/zconf.y +0 -0
index 0717a32..de7c498 100644
@@ -20,7 +20,8 @@

?#define DEBUG_PARSE ? ?0x0002

?int cdebug = PRINTD;

support/kconfig/zconf.y +2 -1
-
+int dosubsource = 0;
+

?extern int zconflex(void);
?static void zconfprint(const char *err, ...);
?static void zconf_error(const char *err, ...);

support/kconfig/zconf.y +2 -0
@@ -30,6 +31,8 @@ static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
 ?struct symbol *symbol_hash[SYMBOL_HASHSIZE];
 
 ?static struct menu *current_menu, *current_entry;
+struct conf_level *current_conf_level = 0;
+struct conf_level *conf_levels = 0;
 

?#define YYDEBUG 0
?#if YYDEBUG

support/kconfig/zconf.y +0 -0
@@ -52,6 +55,7 @@ static struct menu *current_menu, *current_entry;

?%token <id>T_MENU
?%token <id>T_ENDMENU
?%token <id>T_SOURCE
+%token <id>T_SUBSOURCE
?%token <id>T_CHOICE
?%token <id>T_ENDCHOICE
?%token <id>T_COMMENT

support/kconfig/zconf.y +0 -0
@@ -107,7 +111,7 @@ static struct menu *current_menu, *current_entry;

?%%
?input: nl start | start;

support/kconfig/zconf.y +1 -1
-start: mainmenu_stmt stmt_list | stmt_list;
+start: stmt_list;

?stmt_list:
? ? ? ? ?/* empty */

support/kconfig/zconf.y +0 -0
@@ -130,10 +134,12 @@ option_name:

?common_stmt:
? ? ? ? ?T_EOL
? ? ? ?| if_stmt
+ ? ? ? | mainmenu_stmt

? ? ? ?| comment_stmt
? ? ? ?| config_stmt
? ? ? ?| menuconfig_stmt
? ? ? ?| source_stmt

+ ? ? ? | subsource_stmt
?;

?option_error:

support/kconfig/zconf.y +9 -0
@@ -389,6 +395,15 @@ source_stmt: T_SOURCE prompt T_EOL
 ? ? ? ?zconf_nextfile($2);
 ?};
 
+/* subsource $2:"sub-kconfig" $3:"sub-chdir" $4:"sub-.config" $5:"Title" $6:"subdomainprefix" $7:"confprefix" */
+subsource_stmt: T_SUBSOURCE prompt prompt prompt prompt T_WORD word_opt T_EOL
+{
+ ? ? ? if (dosubsource) {
+ ? ? ? ? ? ? ? printd(DEBUG_PARSE, "%s:%d:subsource %s\n", zconf_curname(), zconf_lineno(), $2);
+ ? ? ? ? ? ? ? zconf_nextconf($2, $3, $4, $5, $6, $7);
+ ? ? ? }
+}
+

?/* comment entry */

?comment: T_COMMENT prompt T_EOL

support/kconfig/zconf.y +3 -1
@@ -522,8 +537,10 @@ void conf_parse(const char *name)
 
 ? ? ? ?menu_finalize(&rootmenu);
 ? ? ? ?for_all_symbols(i, sym) {
- ? ? ? ? ? ? ? if (sym_check_deps(sym))
+ ? ? ? ? ? ? ? if (sym_check_deps(sym)) {
+ ? ? ? ? ? ? ? ? ? ? ? fprintf(stderr, "Cannot check dependencies for %s\n", sym->name ? sym->name : "<null>");
 ? ? ? ? ? ? ? ? ? ? ? ?zconfnerrs++;
+ ? ? ? ? ? ? ? }
 ? ? ? ? }
 ? ? ? ?if (zconfnerrs)
 ? ? ? ? ? ? ? ?exit(1);
@@ -631,6 +648,9 @@ static void print_symbol(FILE *out, struct menu *menu)

? ? ? ?case S_STRING:
? ? ? ? ? ? ? ?fputs(" ?string\n", out);
? ? ? ? ? ? ? ?break;

Quoted 9 lines

+ ? ? ? case S_EXECUTE:
+ ? ? ? ? ? ? ? fputs(" ?execute\n", out);
+ ? ? ? ? ? ? ? break;
? ? ? ?case S_INT:
? ? ? ? ? ? ? ?fputs(" ?integer\n", out);
? ? ? ? ? ? ? ?break;
--
1.6.4.1

Best regards,
Thomas

#4 lore raw

PATCH 1/1 kconfig: Add a configuration subtree command to kconfig

New kconfig command "subsource":
subsource "<kconfig>" "<cwd>" "<.config>" "<title>" <internal_prefix> <.config_prefix> Allocates <kconfig> as a configuration subtree using <.config> as the configuration file to save and load from. <cwd> is the directory path to switch to for "source" to work, "<title>" is the Menu tile of the subtree, <internal_prefix> is a internal prefix, and <.config_prefix> is the prefix to append/remove when saving/loading <.config>.

---
 Makefile                             |    8 +-
 support/kconfig/conf.c               |    6 +-
 support/kconfig/confdata.c           |  100 +++-
 support/kconfig/expr.h               |   15 +
 support/kconfig/gconf.c              |    3 +
 support/kconfig/lex.zconf.c_shipped  |   74 ++-
 support/kconfig/lkc.h                |    1 +
 support/kconfig/lkc_proto.h          |    5 +
 support/kconfig/mconf.c              |   13 +-
 support/kconfig/menu.c               |    3 +-
 support/kconfig/nconf.c              |   13 +-
 support/kconfig/qconf.cc             |    3 +
 support/kconfig/symbol.c             |   50 ++-
 support/kconfig/util.c               |   55 ++
 support/kconfig/zconf.gperf          |    1 +
 support/kconfig/zconf.hash.c_shipped |  145 +++---
 support/kconfig/zconf.l              |   50 ++-
 support/kconfig/zconf.tab.c_shipped  |  969 ++++++++++++++++++----------------
 support/kconfig/zconf.y              |   23 +-
 19 files changed, 946 insertions(+), 591 deletions(-)
Makefile +4 -4
index df2f859..972f43d 100644
@@ -523,19 +523,19 @@ COMMON_CONFIG_ENV = \
 
 xconfig: $(BUILD_DIR)/buildroot-config/qconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
-	@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
+	@$(COMMON_CONFIG_ENV) $< -s $(CONFIG_CONFIG_IN)
 
 gconfig: $(BUILD_DIR)/buildroot-config/gconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
-	@$(COMMON_CONFIG_ENV) srctree=$(TOPDIR) $< $(CONFIG_CONFIG_IN)
+	@$(COMMON_CONFIG_ENV) srctree=$(TOPDIR) $< -s $(CONFIG_CONFIG_IN)
 
 menuconfig: $(BUILD_DIR)/buildroot-config/mconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
-	@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
+	@$(COMMON_CONFIG_ENV) $< -s $(CONFIG_CONFIG_IN)
 
 nconfig: $(BUILD_DIR)/buildroot-config/nconf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
-	@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
+	@$(COMMON_CONFIG_ENV) $< -s $(CONFIG_CONFIG_IN)
 
 config: $(BUILD_DIR)/buildroot-config/conf outputmakefile
 	@mkdir -p $(BUILD_DIR)/buildroot-config
support/kconfig/conf.c +3 -3
index 652e079..692f779 100644
@@ -542,7 +542,7 @@ int main(int ac, char **av)
 	case randconfig:
 		name = getenv("KCONFIG_ALLCONFIG");
 		if (name && !stat(name, &tmpstat)) {
-			conf_read_simple(name, S_DEF_USER);
+			conf_read_simple_level(name, S_DEF_USER, 0);
 			break;
 		}
 		switch (input_mode) {
@@ -554,9 +554,9 @@ int main(int ac, char **av)
 		default: break;
 		}
 		if (!stat(name, &tmpstat))
-			conf_read_simple(name, S_DEF_USER);
+			conf_read_simple_level(name, S_DEF_USER, 0);
 		else if (!stat("all.config", &tmpstat))
-			conf_read_simple("all.config", S_DEF_USER);
+			conf_read_simple_level("all.config", S_DEF_USER, 0);
 		break;
 	default:
 		break;
support/kconfig/confdata.c +74 -26

237 lines not on this page · raw message

support/kconfig/expr.h +15 -0
index 3d238db..b2d8b4a 100644
@@ -15,6 +15,18 @@ extern "C" {
 #include <stdbool.h>
 #endif
 
+struct conf_level {
+        struct conf_level *n, *parent;
+        char *sym_prefix;
+	char *conf;
+	char *conf_prefix;
+	char *cwd;
+	struct symbol *modules_sym;
+};
+extern struct conf_level *conf_levels;
+extern struct conf_level *current_conf_level;
+extern int dosubsource;
+
 struct file {
 	struct file *next;
 	struct file *parent;
@@ -77,6 +89,7 @@ enum {
 struct symbol {
 	struct symbol *next;
 	char *name;
+	struct conf_level *level;
 	enum symbol_type type;
 	struct symbol_value curr;
 	struct symbol_value def[S_DEF_COUNT];
@@ -88,6 +101,7 @@ struct symbol {
 };
 
 #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
+#define for_all_symbols_level(i, sym, l) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->level == l && sym->type != S_OTHER)
 
 #define SYMBOL_CONST      0x0001  /* symbol is const */
 #define SYMBOL_CHECK      0x0008  /* used during dependency checking */
@@ -171,6 +185,7 @@ struct menu {
 	struct file *file;
 	int lineno;
 	void *data;
+	struct conf_level *level;
 };
 
 #define MENU_CHANGED		0x0001
support/kconfig/gconf.c +3 -0
index f9daf98..1c3cb81 100644
@@ -1530,6 +1530,9 @@ int main(int ac, char *av[])
 	/* Conf stuffs */
 	if (ac > 1 && av[1][0] == '-') {
 		switch (av[1][1]) {
+		case 's':
+			dosubsource = 1;
+			break;
 		case 'a':
 			//showAll = 1;
 			break;
support/kconfig/lex.zconf.c_shipped +54 -20

143 lines not on this page · raw message

support/kconfig/lkc.h +1 -0
index e899066..f22dc87 100644
@@ -78,6 +78,7 @@ void zconf_starthelp(void);
 FILE *zconf_fopen(const char *name);
 void zconf_initscan(const char *name);
 void zconf_nextfile(const char *name);
+void zconf_nextconf(const char *name, char *subdir, char *subconf, char *title, char *subprefix, char *confprefix);	
 int zconf_lineno(void);
 const char *zconf_curname(void);
 
support/kconfig/lkc_proto.h +5 -0
index 17342fe..334fdfc 100644
@@ -29,7 +29,9 @@ P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
 P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
 
 P(sym_lookup,struct symbol *,(const char *name, int flags));
+P(sym_lookup_level,struct symbol *,(const char *name, int flags,struct conf_level *l));
 P(sym_find,struct symbol *,(const char *name));
+P(sym_find_level,struct symbol *,(const char *name,struct conf_level *l));
 P(sym_expand_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));
@@ -51,3 +53,6 @@ P(prop_get_type_name,const char *,(enum prop_type type));
 /* 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));
+
+/* util.c */
+P(resolve_vars,char*,(const char *n, struct conf_level *l));
support/kconfig/mconf.c +12 -1
index 3ed8a25..6711085 100644
@@ -798,12 +798,23 @@ int main(int ac, char **av)
 	int saved_x, saved_y;
 	char *mode;
 	int res;
+	const char *name;
 
 	setlocale(LC_ALL, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 
-	conf_parse(av[1]);
+	if (ac > 1 && av[1][0] == '-') {
+		switch (av[1][1]) {
+		case 's':
+			dosubsource = 1;
+			break;
+		}
+		name = av[2];
+	} else
+		name = av[1];
+
+	conf_parse(name);
 	conf_read(NULL);
 
 	mode = getenv("MENUCONFIG_MODE");
support/kconfig/menu.c +2 -1
index d49f8b8..1ffaeac 100644
@@ -54,7 +54,8 @@ void menu_add_entry(struct symbol *sym)
 	menu->parent = current_menu;
 	menu->file = current_file;
 	menu->lineno = zconf_lineno();
-
+	menu->level = current_conf_level;
+	
 	*last_entry_ptr = menu;
 	last_entry_ptr = &menu->next;
 	current_entry = menu;
support/kconfig/nconf.c +12 -1
index db56377..ca1b055 100644
@@ -1486,12 +1486,23 @@ void setup_windows(void)
 int main(int ac, char **av)
 {
 	char *mode;
+	const char *name;
 
 	setlocale(LC_ALL, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 
-	conf_parse(av[1]);
+	if (ac > 1 && av[1][0] == '-') {
+		switch (av[1][1]) {
+		case 's':
+			dosubsource = 1;
+			break;
+		}
+		name = av[2];
+	} else
+		name = av[1];
+
+	conf_parse(name);
 	conf_read(NULL);
 
 	mode = getenv("NCONFIG_MODE");
support/kconfig/qconf.cc +3 -0
index 06dd2e3..0760f4f 100644
@@ -1754,6 +1754,9 @@ int main(int ac, char** av)
 	configApp = new QApplication(ac, av);
 	if (ac > 1 && av[1][0] == '-') {
 		switch (av[1][1]) {
+		case 's':
+			dosubsource = 1;
+			break;
 		case 'h':
 		case '?':
 			usage();
support/kconfig/symbol.c +44 -6

117 lines not on this page · raw message

support/kconfig/util.c +55 -0

58 lines not on this page · raw message

support/kconfig/zconf.gperf +1 -0
index c9e690e..88228c6 100644
@@ -16,6 +16,7 @@ mainmenu,	T_MAINMENU,	TF_COMMAND
 menu,		T_MENU,		TF_COMMAND
 endmenu,	T_ENDMENU,	TF_COMMAND
 source,		T_SOURCE,	TF_COMMAND
+subsource,	T_SUBSOURCE,	TF_COMMAND
 choice,		T_CHOICE,	TF_COMMAND
 endchoice,	T_ENDCHOICE,	TF_COMMAND
 comment,	T_COMMENT,	TF_COMMAND
support/kconfig/zconf.hash.c_shipped +74 -71

243 lines not on this page · raw message

support/kconfig/zconf.l +49 -1

77 lines not on this page · raw message

support/kconfig/zconf.tab.c_shipped +515 -454

1,651 lines not on this page · raw message

support/kconfig/zconf.y +20 -3
index 0717a32..a3ca573 100644
@@ -20,7 +20,8 @@
 #define DEBUG_PARSE	0x0002
 
 int cdebug = PRINTD;
-
+int dosubsource = 0;
+ 
 extern int zconflex(void);
 static void zconfprint(const char *err, ...);
 static void zconf_error(const char *err, ...);
@@ -30,6 +31,8 @@ static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
 struct symbol *symbol_hash[SYMBOL_HASHSIZE];
 
 static struct menu *current_menu, *current_entry;
+struct conf_level *current_conf_level = 0;
+struct conf_level *conf_levels = 0;
 
 #define YYDEBUG 0
 #if YYDEBUG
@@ -52,6 +55,7 @@ static struct menu *current_menu, *current_entry;
 %token <id>T_MENU
 %token <id>T_ENDMENU
 %token <id>T_SOURCE
+%token <id>T_SUBSOURCE
 %token <id>T_CHOICE
 %token <id>T_ENDCHOICE
 %token <id>T_COMMENT
@@ -107,7 +111,7 @@ static struct menu *current_menu, *current_entry;
 %%
 input: nl start | start;
 
-start: mainmenu_stmt stmt_list | stmt_list;
+start: stmt_list;
 
 stmt_list:
 	  /* empty */
@@ -130,10 +134,12 @@ option_name:
 common_stmt:
 	  T_EOL
 	| if_stmt
+	| mainmenu_stmt 
 	| comment_stmt
 	| config_stmt
 	| menuconfig_stmt
 	| source_stmt
+	| subsource_stmt
 ;
 
 option_error:
@@ -389,6 +395,15 @@ source_stmt: T_SOURCE prompt T_EOL
 	zconf_nextfile($2);
 };
 
+/* subsource $2:"sub-kconfig" $3:"sub-chdir" $4:"sub-.config" $5:"Title" $6:"subdomainprefix" $7:"confprefix" */
+subsource_stmt: T_SUBSOURCE prompt prompt prompt prompt T_WORD word_opt T_EOL
+{
+	if (dosubsource) {
+		printd(DEBUG_PARSE, "%s:%d:subsource %s\n", zconf_curname(), zconf_lineno(), $2);
+		zconf_nextconf($2, $3, $4, $5, $6, $7);
+	}
+}
+
 /* comment entry */
 
 comment: T_COMMENT prompt T_EOL
@@ -522,8 +537,10 @@ void conf_parse(const char *name)
 
 	menu_finalize(&rootmenu);
 	for_all_symbols(i, sym) {
-		if (sym_check_deps(sym))
+		if (sym_check_deps(sym)) {
+			fprintf(stderr, "Cannot check dependencies for %s\n", sym->name ? sym->name : "<null>");
 			zconfnerrs++;
+		}
         }
 	if (zconfnerrs)
 		exit(1);
Signature · 1 line
1.6.4.1
#5 lore raw

PATCH 1/1 kconfig: Add a configuration subtree command to kconfig

Quoted 21 lines · Konrad Eisele

New kconfig command "subsource":
subsource "<kconfig>" "<cwd>" "<.config>" "<title>" <internal_prefix> <.config_prefix> Allocates <kconfig> as a configuration subtree using <.config> as the configuration file to save and load from. <cwd> is the directory path to switch to for "source" to work, "<title>" is the Menu tile of the subtree, <internal_prefix> is a internal prefix, and <.config_prefix> is the prefix to append/remove when saving/loading <.config>.

---
 Makefile                             |    8 +-
 support/kconfig/conf.c               |    6 +-
 support/kconfig/confdata.c           |  100 +++-
 support/kconfig/expr.h               |   15 +
 support/kconfig/gconf.c              |    3 +
 support/kconfig/lex.zconf.c_shipped  |   74 ++-
 support/kconfig/lkc.h                |    1 +
 support/kconfig/lkc_proto.h          |    5 +
 support/kconfig/mconf.c              |   13 +-
 support/kconfig/menu.c               |    3 +-
 support/kconfig/nconf.c              |   13 +-
 support/kconfig/qconf.cc             |    3 +
Quoted 9 lines
 support/kconfig/symbol.c             |   50 ++-
 support/kconfig/util.c               |   55 ++
 support/kconfig/zconf.gperf          |    1 +
 support/kconfig/zconf.hash.c_shipped |  145 +++---
 support/kconfig/zconf.l              |   50 ++-
 support/kconfig/zconf.tab.c_shipped  |  969 ++++++++++++++++++----------------
 support/kconfig/zconf.y              |   23 +-
 19 files changed, 946 insertions(+), 591 deletions(-)

This time the patch is only for the "subsource" tag. I implemented "-s" switch (that enables the "subsource" tag) for mconf, nconf, gconf and qconf.
To test you might want to flatten the Kconfig scripts of for instance busybox, use the script below.

If you create a flattened version in package/busybox/busybox-1.19.x.in you can add i.e.:
subsource "package/busybox/busybox-1.19.x.in" "package/busybox/" "package/busybox/busybox-1.19.x.config" "Busybox 1.19.x configuration" BUSYBOX_ CONFIG_ To get busybox Kconfig as a subtree. (Or you can add the original Kconfig directory hirarchy of course...).

------ flatten.pl -------

#!/usr/bin/perl

flatten($ARGV[0]);

sub readfile {
    my ($in) = @_;
    usage(\*STDOUT) if (length($in) == 0) ;
    open IN, "$in" or die "Reading \"$in\":".$!;
    local $/ = undef;
    $m = <IN>;
    close IN;
    return $m;
}
sub flatten {
    my ($f) = @_;
    foreach my $l (split("\n",readfile($f))) {
	if ($l =~ /^\s*source/) {
	    print ("# -> $l\n");
	    my $nf = substr($l,length($&));
	    $nf =~ s/"//g;
	    flatten($nf);
	} else {
	    print ("$l\n");
	}
    }
}
#6 lore raw

PATCH 1/1 kconfig: Add "execute" config-type

In reply to Thomas De Schampheleire

New kconfig config-type "execute":
Type "execute" is similar to "string". However instead of editing, the string is executed using call to "system(<string>)" i.e.:
config EXECUTE_BUILD
execute "title"
default "make CFLAGS=\"\" build"
help
Execute "make build"

---
 support/kconfig/conf.c               |    2 +
 support/kconfig/confdata.c           |    6 +
 support/kconfig/expr.h               |    2 +-
 support/kconfig/gconf.c              |    7 +-
 support/kconfig/lkc_proto.h          |    1 +
 support/kconfig/mconf.c              |    3 +
 support/kconfig/menu.c               |    2 +-
 support/kconfig/nconf.c              |    3 +
 support/kconfig/qconf.cc             |   13 ++-
 support/kconfig/qconf.h              |    1 +
 support/kconfig/symbol.c             |    7 ++
 support/kconfig/util.c               |   24 +++++
 support/kconfig/zconf.gperf          |    1 +
 support/kconfig/zconf.hash.c_shipped |  190 +++++++++++++++++-----------------
 support/kconfig/zconf.tab.c_shipped  |    3 +
 support/kconfig/zconf.y              |    3 +
 16 files changed, 170 insertions(+), 98 deletions(-)
support/kconfig/conf.c +2 -0
index 692f779..e6986f2 100644
@@ -120,6 +120,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
 	case S_STRING:
 		printf("%s\n", def);
 		return 1;
+	case S_EXECUTE:
 	default:
 		;
 	}
@@ -394,6 +395,7 @@ static void conf(struct menu *menu)
 	switch (sym->type) {
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		conf_string(menu);
 		break;
support/kconfig/confdata.c +6 -0
index 3fb4f09..d558e84 100644
@@ -147,6 +147,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
 			sym->type = S_STRING;
 			goto done;
 		}
+	case S_EXECUTE:
 	case S_STRING:
 		if (*p++ != '"')
 			break;
@@ -233,6 +234,7 @@ load:
 		switch (sym->type) {
 		case S_INT:
 		case S_HEX:
+		case S_EXECUTE:
 		case S_STRING:
 			if (sym->def[def].val)
 				free(sym->def[def].val);
@@ -408,6 +410,7 @@ int conf_read_level(const char *name, struct conf_level *l)
 			if (sym->visible == no && !conf_unsaved)
 				sym->flags &= ~SYMBOL_DEF_USER;
 			switch (sym->type) {
+			case S_EXECUTE:
 			case S_STRING:
 			case S_INT:
 			case S_HEX:
@@ -491,6 +494,7 @@ static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
 			break;
 		}
 		break;
+	case S_EXECUTE:
 	case S_STRING:
 		conf_write_string(false, CONFPREFIX(sym), sym->name, sym_get_string_value(sym), out);
 		break;
@@ -762,6 +766,7 @@ static int conf_split_config(void)
 					    sym->def[S_DEF_AUTO].tri)
 						continue;
 					break;
+				case S_EXECUTE:
 				case S_STRING:
 				case S_HEX:
 				case S_INT:
@@ -936,6 +941,7 @@ int conf_write_autoconf(void)
 				break;
 			}
 			break;
+		case S_EXECUTE:
 		case S_STRING:
 			conf_write_string(true, CONFPREFIX(sym), sym->name, sym_get_string_value(sym), out_h);
 			break;
support/kconfig/expr.h +1 -1
index b2d8b4a..1a7fcf2 100644
@@ -74,7 +74,7 @@ struct symbol_value {
 };
 
 enum symbol_type {
-	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_EXECUTE, S_OTHER
 };
 
 /* enum values are used as index to symbol.def[] */
support/kconfig/gconf.c +5 -2
index 1c3cb81..d44ec15 100644
@@ -968,8 +968,10 @@ on_treeview2_button_press_event(GtkWidget * widget,
 	if (event->type == GDK_2BUTTON_PRESS) {
 		enum prop_type ptype;
 		ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
-
-		if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
+		if (menu->sym && (sym_get_type(menu->sym) == S_EXECUTE) &&
+		    (col == COL_OPTION || col == COL_VALUE || col == COL_NAME)) {
+			execute_sym(menu->sym, 0);
+		} if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
 			// goes down into menu
 			current = menu;
 			display_tree_part();
@@ -1205,6 +1207,7 @@ static gchar **fill_row(struct menu *menu)
 		break;
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		def = sym_get_string_value(sym);
 		row[COL_VALUE] = g_strdup(def);
support/kconfig/lkc_proto.h +1 -0
index 334fdfc..276001f 100644
@@ -56,3 +56,4 @@ P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const cha
 
 /* util.c */
 P(resolve_vars,char*,(const char *n, struct conf_level *l));
+P(execute_sym,void,(struct symbol *sym, int isterm));
support/kconfig/mconf.c +3 -0
index 6711085..5720179 100644
@@ -714,6 +714,9 @@ static void conf_string(struct menu *menu)
 		case S_HEX:
 			heading = _(inputbox_instructions_hex);
 			break;
+		case S_EXECUTE:
+			execute_sym(menu->sym, 1);
+			return;
 		case S_STRING:
 			heading = _(inputbox_instructions_string);
 			break;
support/kconfig/menu.c +1 -1
index 1ffaeac..1629613 100644
@@ -217,7 +217,7 @@ static void sym_check_prop(struct symbol *sym)
 	for (prop = sym->prop; prop; prop = prop->next) {
 		switch (prop->type) {
 		case P_DEFAULT:
-			if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+			if ((sym->type == S_STRING || sym->type == S_EXECUTE || sym->type == S_INT || sym->type == S_HEX) &&
 			    prop->expr->type != E_SYMBOL)
 				prop_warn(prop,
 				    "default for config symbol '%s'"
support/kconfig/nconf.c +3 -0
index ca1b055..b6dcb19 100644
@@ -1373,6 +1373,9 @@ static void conf_string(struct menu *menu)
 		case S_HEX:
 			heading = _(inputbox_instructions_hex);
 			break;
+		case S_EXECUTE:
+			execute_sym(menu->sym, 1);
+			return;
 		case S_STRING:
 			heading = _(inputbox_instructions_string);
 			break;
support/kconfig/qconf.cc +12 -1
index 0760f4f..8c0d7c5 100644
@@ -296,6 +296,14 @@ ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
 	connect(this, SIGNAL(lostFocus()), SLOT(hide()));
 }
 
+void ConfigLineEdit::execute(ConfigItem* i)
+{
+	struct symbol *sym;
+	item = i;
+	sym = item->menu->sym;
+	execute_sym(sym, 0);
+}
+
 void ConfigLineEdit::show(ConfigItem* i)
 {
 	item = i;
@@ -537,7 +545,10 @@ void ConfigList::changeValue(ConfigItem* item)
 		if (oldexpr != newexpr)
 			parent()->updateList(item);
 		break;
-	case S_INT:
+	case S_EXECUTE:
+		parent()->lineEdit->execute(item);
+		break;
+ 	case S_INT:
 	case S_HEX:
 	case S_STRING:
 		if (colMap[dataColIdx] >= 0)
support/kconfig/qconf.h +1 -0
index 91677d9..1537671 100644
@@ -209,6 +209,7 @@ public:
 		return (ConfigView*)Parent::parent();
 	}
 	void show(ConfigItem *i);
+	void execute(ConfigItem *i);
 	void keyPressEvent(QKeyEvent *e);
 
 public:
support/kconfig/symbol.c +7 -0
index 941152e..b7d6c09 100644
@@ -92,6 +92,8 @@ const char *sym_type_name(enum symbol_type type)
 		return "integer";
 	case S_HEX:
 		return "hex";
+	case S_EXECUTE:
+		return "execute";
 	case S_STRING:
 		return "string";
 	case S_UNKNOWN:
@@ -308,6 +310,7 @@ void sym_calc_value(struct symbol *sym)
 	switch (sym->type) {
 	case S_INT:
 	case S_HEX:
+	case S_EXECUTE:
 	case S_STRING:
 		newval = symbol_empty.curr;
 		break;
@@ -374,6 +377,7 @@ void sym_calc_value(struct symbol *sym)
 		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
 			newval.tri = yes;
 		break;
+	case S_EXECUTE:
 	case S_STRING:
 	case S_HEX:
 	case S_INT:
@@ -550,6 +554,7 @@ bool sym_string_valid(struct symbol *sym, const char *str)
 	signed char ch;
 
 	switch (sym->type) {
+	case S_EXECUTE:
 	case S_STRING:
 		return true;
 	case S_INT:
@@ -594,6 +599,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
 	int val;
 
 	switch (sym->type) {
+	case S_EXECUTE:
 	case S_STRING:
 		return sym_string_valid(sym, str);
 	case S_INT:
@@ -744,6 +750,7 @@ const char *sym_get_string_default(struct symbol *sym)
 	case S_INT:
 	case S_HEX:
 		return str;
+	case S_EXECUTE:
 	case S_STRING:
 		return str;
 	case S_OTHER:
support/kconfig/util.c +24 -0
index cb8df5f..b970c7e 100644
@@ -318,3 +318,27 @@ error_out:
 		free(var);
 	return 0;
 }
+
+void execute_sym(struct symbol *sym, int isterm) 
+{
+	if (sym
+	    && sym_get_string_value(sym)
+	    && sym_get_type(sym) == S_EXECUTE) {
+		const char *cmd = sym_get_string_value(sym);
+		char *rcmd = resolve_vars(cmd, sym->level);
+		if (rcmd) {
+			if (isterm) {
+				char *tcmd;
+				tcmd = malloc(strlen(rcmd) + 32);
+				tcmd[0] = 0;
+				strcat(tcmd, "xterm -e ");
+				strcat(tcmd, rcmd);
+				free(rcmd);
+				rcmd = tcmd;
+			}
+			conf_write(NULL);
+			system(rcmd);
+			free(rcmd);
+		}
+	}
+}
support/kconfig/zconf.gperf +1 -0
index 88228c6..3a624d3 100644
@@ -37,6 +37,7 @@ 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
+execute,	T_TYPE,		TF_COMMAND, S_EXECUTE
 select,		T_SELECT,	TF_COMMAND
 range,		T_RANGE,	TF_COMMAND
 visible,	T_VISIBLE,	TF_COMMAND
support/kconfig/zconf.hash.c_shipped +97 -93

267 lines not on this page · raw message

support/kconfig/zconf.tab.c_shipped +3 -0
index 347c5a5..e5be5fb 100644
@@ -2447,6 +2447,9 @@ static void print_symbol(FILE *out, struct menu *menu)
 	case S_STRING:
 		fputs("  string\n", out);
 		break;
+	case S_EXECUTE:
+		fputs("  execute\n", out);
+		break;
 	case S_INT:
 		fputs("  integer\n", out);
 		break;
support/kconfig/zconf.y +3 -0
index a3ca573..de7c498 100644
@@ -648,6 +648,9 @@ static void print_symbol(FILE *out, struct menu *menu)
 	case S_STRING:
 		fputs("  string\n", out);
 		break;
+	case S_EXECUTE:
+		fputs("  execute\n", out);
+		break;
 	case S_INT:
 		fputs("  integer\n", out);
 		break;
Signature · 1 line
1.6.4.1
#7 lore raw

PATCH 2/2 Example of how to define a subtree using kconfig tag "subsource": package/busybox/busybox-1.19.x.in is a flattend version of busybox-1.19.3's kconfig scripts (all-in-one). package/busybox/Config.in adds this Kconfig as a subtree to the main configuration tree: subsource "package/busybox/busybox-1.19.x.in" "package/busybox/" "package/busybox/busybox-1.19.x.config" "Busybox 1.19.x configuration" BUSYBOX_ CONFIG_ package/busybox/busybox-1.19.x.config is used as the .config for this subtree. config BR2_BUSYBOX_VERSION_1_19_X has to be selected for the subtree to show up.

In reply to Konrad Eisele
---
 package/busybox/Config.in         |   11 +
 package/busybox/busybox-1.19.x.in | 8003 +++++++++++++++++++++++++++++++++++++
 2 files changed, 8014 insertions(+), 0 deletions(-)
 create mode 100644 package/busybox/busybox-1.19.x.in
package/busybox/Config.in +11 -0
index 4176020..a97d3dd 100644
@@ -36,6 +36,7 @@ choice
 
 endchoice
 
+
 config BR2_BUSYBOX_VERSION
 	string
 	default "1.16.2"	if BR2_BUSYBOX_VERSION_1_16_X
@@ -71,3 +72,13 @@ if !BR2_PACKAGE_BUSYBOX # kconfig doesn't support else
 config BR2_PACKAGE_BUSYBOX_SHOW_OTHERS
        default y
 endif
+
+if BR2_BUSYBOX_VERSION_1_19_X
+
+menu "Busybox 1.19.x configuration"
+
+subsource "package/busybox/busybox-1.19.x.in" "package/busybox/" "package/busybox/busybox-1.19.x.config" "Busybox 1.19.x configuration"  BUSYBOX_ CONFIG_
+
+endmenu
+
+endif
package/busybox/busybox-1.19.x.in new file +8003 -0

2,980 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.6.4.1

Part of the diff is not shown here. View the raw message.

#8 lore raw

cover intro

In reply to Konrad Eisele

Hoi,

I'm not very enthousiastic about either of these two features.

Quoted 9 lines · On Thursday 17 November 2011 14:18:07 Konrad Eisele wrote:

The aim of patch-1 is to make it possible to have configuration subtrees. This makes it possible to have a structure like this:

buildroot-kconfigs
+ linux-kconfigs
+ busybox-kconfigs
+ uclibc-kconfigs
+ crosstools-kconfigs

Quoted 3 lines

Where all configuration appear in one xconfig screen. Currently I have focues on qconfig only, I think however adding support for gconfig and mconfig is possible easily. The subtree feature is enabled with the -s option to qconfig: "qconfig -s <kconf>"

- The subtree that has to be included depends on your buildroot configuration. So you have to include all possible linux, busybox, uclibc, ... configs and protect them with IFs. I can hardly imagine that Kconfig can deal with such huge configurations.

- I don't like the size explosion of the buildroot tree that we would see if all these configs are included.

- The packages which have kconfigs are the ones that are most likely to need board-specific modifications, which may define additional config options. This means that copying the config tree into buildroot isn't going to cut it.

- Running configs for these things is a bit of an expert step. In particular because the configs have to be post-processed by buildroot and because you have to save them explicitly afterwards in a place different from the output directory. I think that part should be smoothed out first. Until then, I consider it a good thing that the normal user runs 'make xconfig' while the expert user runs 'make {,linux-,busybox-}menuconfig'.

- I don't know what it will look like visually because the patch failed to compile for me (current_conf_level is undefined), but I wonder if there is a significant advantage compared to just menus. At least in menuconfig it wouldn't really make a difference.

Quoted 5 lines

The other feature that patch-1 adds is a config-entry type "execute: It is like a string, however when doubleclicking (trying to edit) in qconfig (only in qconfig currently) then the string is executed using "system(<str>)". The goal is to be able to execute "make" from inside the gui, without having to exit.

Here I simply don't see the benefit. Whatever needs to be executed there
can just be done with the normal make after the config finishes. If people want to push a button to run make, give them Eclipse with a buildroot plugin :-)

Regards,
Arnout

Signature · 6 lines
Arnout Vandecappelle                               arnout at mind be
Senior Embedded Software Architect                 +32-16-286540
Essensium/Mind                                     http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium                BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  31BB CF53 8660 6F88 345D  54CC A836 5879 20D7 CF43
#9 lore raw

cover intro

I just sent a new patch
[PATCH 1/1] kconfig: Add a configuration subtree command to kconfig that splits the execute and subtree patch. The "subsource" tag is activated by "-s" option to mconfig,qconfig, nconfig and gconfig now.

Quoted 3 lines · Arnout Vandecappelle

Hoi,

I'm not very enthousiastic about either of these two features.

subtrees are for convenience only. Still everything can be done the way it is now.

Quoted 11 lines · On Thursday 17 November 2011 14:18:07 Konrad Eisele wrote:
Quoted 9 lines

The aim of patch-1 is to make it possible to have configuration subtrees. This makes it possible to have a structure like this:

buildroot-kconfigs
+ linux-kconfigs
+ busybox-kconfigs
+ uclibc-kconfigs
+ crosstools-kconfigs

Quoted 8 lines
Quoted 3 lines

Where all configuration appear in one xconfig screen. Currently I have focues on qconfig only, I think however adding support for gconfig and mconfig is possible easily. The subtree feature is enabled with the -s option to qconfig: "qconfig -s <kconf>"

- The subtree that has to be included depends on your buildroot configuration. So you have to include all possible linux, busybox, uclibc, ... configs and protect them with IFs. I can hardly imagine that Kconfig can deal with such huge configurations.

I have added rudiment support so that you can specify
subsource "kconfig.in" "path" "$(var)/config" ...
where "$(var) is substituted by the symbol-value of "var". I did it only for the ".config" entry of "subsource" but it acn be done
for "kconfig.in" element as well, i.e. you could
subsource "linux-$(lversion)/arch/$(arch)/kconfig.in" "path" "$(var)/config" ... The function to use is resolve_vars() in support/kconfig/util.c of the patch.

Quoted 3 lines

- I don't like the size explosion of the buildroot tree that we would see if all these configs are included.

You could define a subtree that point to the kconfig root of the package _after_ download and install. Then you can add a check weather a subtree exists by adding support/kconfig/zconf.y:

/* subsource $2:"sub-kconfig" $3:"sub-chdir" $4:"sub-.config" $5:"Title" $6:"subdomainprefix" $7:"confprefix" */
subsource_stmt: T_SUBSOURCE prompt prompt prompt prompt T_WORD word_opt T_EOL

{
	if (dosubsource) {
+                FILE *f = zconf_fopen($2);
+                if (f) {
+                fclose(f);
		printd(DEBUG_PARSE, "%s:%d:subsource %s\n", zconf_curname(), zconf_lineno(), $2);
		zconf_nextconf($2, $3, $4, $5, $6, $7);
+                }
	}
}

If the subtree doesnt exists the statement is ignored...

Quoted 11 lines

- The packages which have kconfigs are the ones that are most likely to need board-specific modifications, which may define additional config options. This means that copying the config tree into buildroot isn't going to cut it.

- Running configs for these things is a bit of an expert step. In particular because the configs have to be post-processed by buildroot and because you have to save them explicitly afterwards in a place different from the output directory. I think that part should be smoothed out first. Until then, I consider it a good thing that the normal user runs 'make xconfig' while the expert user runs 'make {,linux-,busybox-}menuconfig'.

Can still be done.

Quoted 5 lines

- I don't know what it will look like visually because the patch failed to compile for me (current_conf_level is undefined), but I wonder if there is a significant advantage compared to just menus. At least in menuconfig it wouldn't really make a difference.

please try the patch I sent a hour ago to the list.
[PATCH 1/1] kconfig: Add a configuration subtree command to kconfig It also includes the bison, flex, gperf outputs. it is diffed against master of one hour ago...

Quoted 8 lines
Quoted 7 lines

The other feature that patch-1 adds is a config-entry type "execute: It is like a string, however when doubleclicking (trying to edit) in qconfig (only in qconfig currently) then the string is executed using "system(<str>)". The goal is to be able to execute "make" from inside the gui, without having to exit.

Quoted 4 lines

Here I simply don't see the benefit. Whatever needs to be executed there
can just be done with the normal make after the config finishes. If people want to push a button to run make, give them Eclipse with a buildroot plugin :-)

Still, you have to exit. Running it with a press on a button is more intuitive... -- Konrad

Quoted 6 lines

Regards,
Arnout

#10 lore raw

cover intro

In reply to Arnout Vandecappelle
Quoted 49 lines · Arnout Vandecappelle

?Hoi,

?I'm not very enthousiastic about either of these two features.

Quoted 9 lines · On Thursday 17 November 2011 14:18:07 Konrad Eisele wrote:

The aim of patch-1 is to make it possible to have configuration subtrees. This makes it possible to have a structure like this:

buildroot-kconfigs
+ linux-kconfigs
+ busybox-kconfigs
+ uclibc-kconfigs
+ crosstools-kconfigs

Quoted 3 lines

Where all configuration appear in one xconfig screen. Currently I have focues on qconfig only, I think however adding support for gconfig and mconfig is possible easily. The subtree feature is enabled with the -s option to qconfig: "qconfig -s <kconf>"

- The subtree that has to be included depends on your buildroot configuration. So you have to include all possible linux, busybox, uclibc, ... configs and protect them with IFs. ?I can hardly imagine that Kconfig can deal with such huge configurations.

- I don't like the size explosion of the buildroot tree that we would see if all these configs are included.

- The packages which have kconfigs are the ones that are most likely to need board-specific modifications, which may define additional config options. ?This means that copying the config tree into buildroot isn't going to cut it.

- Running configs for these things is a bit of an expert step. ?In particular because the configs have to be post-processed by buildroot and because you have to save them explicitly afterwards in a place different from the output directory. ?I think that part should be smoothed out first. ?Until then, I consider it a good thing that the normal user runs 'make xconfig' while the expert user runs 'make {,linux-,busybox-}menuconfig'.

- I don't know what it will look like visually because the patch failed to compile for me (current_conf_level is undefined), but I wonder if there is a significant advantage compared to just menus. ?At least in menuconfig it wouldn't really make a difference.

Quoted 5 lines

The other feature that patch-1 adds is a config-entry type "execute: It is like a string, however when doubleclicking (trying to edit) in qconfig (only in qconfig currently) then the string is executed using "system(<str>)". The goal is to be able to execute "make" from inside the gui, without having to exit.

Quoted 5 lines

?Here I simply don't see the benefit. ?Whatever needs to be executed there can just be done with the normal make after the config finishes. ?If people want to push a button to run make, give them Eclipse with a buildroot plugin :-)

In fact, similar features (e.g. including one menuconfig into another) were discussed in the context of crosstool-ng integration into buildroot. See the thread "Report from the Buildroot Developer Day" and Yann's comments on it.

Best regards,
Thomas

#11 lore raw

cover intro

Quoted 56 lines · Thomas De Schampheleire
Quoted 49 lines · Arnout Vandecappelle

Hoi,

I'm not very enthousiastic about either of these two features.

Quoted 9 lines · On Thursday 17 November 2011 14:18:07 Konrad Eisele wrote:

The aim of patch-1 is to make it possible to have configuration subtrees. This makes it possible to have a structure like this:

buildroot-kconfigs
+ linux-kconfigs
+ busybox-kconfigs
+ uclibc-kconfigs
+ crosstools-kconfigs

Quoted 3 lines

Where all configuration appear in one xconfig screen. Currently I have focues on qconfig only, I think however adding support for gconfig and mconfig is possible easily. The subtree feature is enabled with the -s option to qconfig: "qconfig -s <kconf>"

- The subtree that has to be included depends on your buildroot configuration. So you have to include all possible linux, busybox, uclibc, ... configs and protect them with IFs. I can hardly imagine that Kconfig can deal with such huge configurations.

- I don't like the size explosion of the buildroot tree that we would see if all these configs are included.

- The packages which have kconfigs are the ones that are most likely to need board-specific modifications, which may define additional config options. This means that copying the config tree into buildroot isn't going to cut it.

- Running configs for these things is a bit of an expert step. In particular because the configs have to be post-processed by buildroot and because you have to save them explicitly afterwards in a place different from the output directory. I think that part should be smoothed out first. Until then, I consider it a good thing that the normal user runs 'make xconfig' while the expert user runs 'make {,linux-,busybox-}menuconfig'.

- I don't know what it will look like visually because the patch failed to compile for me (current_conf_level is undefined), but I wonder if there is a significant advantage compared to just menus. At least in menuconfig it wouldn't really make a difference.

Quoted 5 lines

The other feature that patch-1 adds is a config-entry type "execute: It is like a string, however when doubleclicking (trying to edit) in qconfig (only in qconfig currently) then the string is executed using "system(<str>)". The goal is to be able to execute "make" from inside the gui, without having to exit.

Quoted 5 lines

Here I simply don't see the benefit. Whatever needs to be executed there
can just be done with the normal make after the config finishes. If people want to push a button to run make, give them Eclipse with a buildroot plugin :-)

Quoted 4 lines

In fact, similar features (e.g. including one menuconfig into another) were discussed in the context of crosstool-ng integration into buildroot. See the thread "Report from the Buildroot Developer Day" and Yann's comments on it.

Maybe there is some interest in it then.
I have created a split patch as requested, splitting subtree and execution tag. I sent it to the buildroot list. The patch is called:
[PATCH 1/1] kconfig: Add a configuration subtree command to kconfig
hope you got it.

Quoted 6 lines

Best regards,
Thomas

#12 lore raw

cover intro

In reply to Thomas De Schampheleire
Quoted 56 lines · Thomas De Schampheleire
Quoted 49 lines · Arnout Vandecappelle

Hoi,

I'm not very enthousiastic about either of these two features.

Quoted 9 lines · On Thursday 17 November 2011 14:18:07 Konrad Eisele wrote:

The aim of patch-1 is to make it possible to have configuration subtrees. This makes it possible to have a structure like this:

buildroot-kconfigs
+ linux-kconfigs
+ busybox-kconfigs
+ uclibc-kconfigs
+ crosstools-kconfigs

Quoted 3 lines

Where all configuration appear in one xconfig screen. Currently I have focues on qconfig only, I think however adding support for gconfig and mconfig is possible easily. The subtree feature is enabled with the -s option to qconfig: "qconfig -s <kconf>"

- The subtree that has to be included depends on your buildroot configuration. So you have to include all possible linux, busybox, uclibc, ... configs and protect them with IFs. I can hardly imagine that Kconfig can deal with such huge configurations.

- I don't like the size explosion of the buildroot tree that we would see if all these configs are included.

- The packages which have kconfigs are the ones that are most likely to need board-specific modifications, which may define additional config options. This means that copying the config tree into buildroot isn't going to cut it.

- Running configs for these things is a bit of an expert step. In particular because the configs have to be post-processed by buildroot and because you have to save them explicitly afterwards in a place different from the output directory. I think that part should be smoothed out first. Until then, I consider it a good thing that the normal user runs 'make xconfig' while the expert user runs 'make {,linux-,busybox-}menuconfig'.

- I don't know what it will look like visually because the patch failed to compile for me (current_conf_level is undefined), but I wonder if there is a significant advantage compared to just menus. At least in menuconfig it wouldn't really make a difference.

Quoted 5 lines

The other feature that patch-1 adds is a config-entry type "execute: It is like a string, however when doubleclicking (trying to edit) in qconfig (only in qconfig currently) then the string is executed using "system(<str>)". The goal is to be able to execute "make" from inside the gui, without having to exit.

Quoted 5 lines

Here I simply don't see the benefit. Whatever needs to be executed there
can just be done with the normal make after the config finishes. If people want to push a button to run make, give them Eclipse with a buildroot plugin :-)

Quoted 5 lines

In fact, similar features (e.g. including one menuconfig into another) were discussed in the context of crosstool-ng integration into buildroot. See the thread "Report from the Buildroot Developer Day" and Yann's comments on it.

I read the thread and:

Quoted 5 lines

There are two ways to do a better integration:

1) Include the crosstool-NG menuconfig entries into the buildroot menuconfig. This will be difficule for two reasons:
- namespace clashing [1]

with "subsource" there is not namespace clashing.

Quoted 1 line

- maintenance when a newer crosstool-NG version gets integrated

The newest crosstools kconfig gets added always. As written in a previous mal you can make a "subsource" to the kconfig _after_ download and install. It not present the "subsource" is ignored.

Quoted 5 lines

Best regards,
Thomas