diff options
Diffstat (limited to 'support/kconfig/mconf.c')
| -rw-r--r-- | support/kconfig/mconf.c | 269 | 
1 files changed, 185 insertions, 84 deletions
diff --git a/support/kconfig/mconf.c b/support/kconfig/mconf.c index 3ed8a2530..fa61759aa 100644 --- a/support/kconfig/mconf.c +++ b/support/kconfig/mconf.c @@ -15,10 +15,10 @@  #include <stdarg.h>  #include <stdlib.h>  #include <string.h> +#include <signal.h>  #include <unistd.h>  #include <locale.h> -#define LKC_DIRECT_LINK  #include "lkc.h"  #include "lxdialog/dialog.h" @@ -105,10 +105,10 @@ static const char mconf_readme[] = N_(  "Text Box    (Help Window)\n"  "--------\n"  "o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n" -"   keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n" -"   who are familiar with less and lynx.\n" +"   keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for \n" +"   those who are familiar with less and lynx.\n"  "\n" -"o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n" +"o  Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n"  "\n"  "\n"  "Alternate Configuration Files\n" @@ -236,16 +236,19 @@ search_help[] = N_(  	"Result:\n"  	"-----------------------------------------------------------------\n"  	"Symbol: FOO [=m]\n" +	"Type  : tristate\n"  	"Prompt: Foo bus is used to drive the bar HW\n" -	"Defined at drivers/pci/Kconfig:47\n" -	"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" -	"Location:\n" -	"  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" -	"    -> PCI support (PCI [=y])\n" -	"      -> PCI access mode (<choice> [=y])\n" -	"Selects: LIBCRC32\n" -	"Selected by: BAR\n" +	"  Defined at drivers/pci/Kconfig:47\n" +	"  Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" +	"  Location:\n" +	"    -> Bus options (PCI, PCMCIA, EISA, ISA)\n" +	"      -> PCI support (PCI [=y])\n" +	"(1)     -> PCI access mode (<choice> [=y])\n" +	"  Selects: LIBCRC32\n" +	"  Selected by: BAR\n"  	"-----------------------------------------------------------------\n" +	"o The line 'Type:' shows the type of the configuration option for\n" +	"  this symbol (boolean, tristate, string, ...)\n"  	"o The line 'Prompt:' shows the text used in the menu structure for\n"  	"  this symbol\n"  	"o The 'Defined at' line tell at what file / line number the symbol\n" @@ -254,8 +257,12 @@ search_help[] = N_(  	"  this symbol to be visible in the menu (selectable)\n"  	"o The 'Location:' lines tell where in the menu structure this symbol\n"  	"  is located\n" -	"    A location followed by a [=y] indicate that this is a selectable\n" -	"    menu item - and current value is displayed inside brackets.\n" +	"    A location followed by a [=y] indicates that this is a\n" +	"    selectable menu item - and the current value is displayed inside\n" +	"    brackets.\n" +	"    Press the key in the (#) prefix to jump directly to that\n" +	"    location. You will be returned to the current search results\n" +	"    after exiting this new menu.\n"  	"o The 'Selects:' line tell what symbol will be automatically\n"  	"  selected if this symbol is selected (y or m)\n"  	"o The 'Selected by' line tell what symbol has selected this symbol\n" @@ -273,12 +280,16 @@ static struct menu *current_menu;  static int child_count;  static int single_menu_mode;  static int show_all_options; +static int save_and_exit; -static void conf(struct menu *menu); +static void conf(struct menu *menu, struct menu *active_menu);  static void conf_choice(struct menu *menu);  static void conf_string(struct menu *menu);  static void conf_load(void);  static void conf_save(void); +static int show_textbox_ext(const char *title, char *text, int r, int c, +			    int *keys, int *vscroll, int *hscroll, +			    update_text_fn update_text, void *data);  static void show_textbox(const char *title, const char *text, int r, int c);  static void show_helptext(const char *title, const char *text);  static void show_help(struct menu *menu); @@ -301,17 +312,56 @@ static void set_config_filename(const char *config_filename)  } +struct search_data { +	struct list_head *head; +	struct menu **targets; +	int *keys; +}; + +static void update_text(char *buf, size_t start, size_t end, void *_data) +{ +	struct search_data *data = _data; +	struct jump_key *pos; +	int k = 0; + +	list_for_each_entry(pos, data->head, entries) { +		if (pos->offset >= start && pos->offset < end) { +			char header[4]; + +			if (k < JUMP_NB) { +				int key = '0' + (pos->index % JUMP_NB) + 1; + +				sprintf(header, "(%c)", key); +				data->keys[k] = key; +				data->targets[k] = pos->target; +				k++; +			} else { +				sprintf(header, "   "); +			} + +			memcpy(buf + pos->offset, header, sizeof(header) - 1); +		} +	} +	data->keys[k] = 0; +} +  static void search_conf(void)  {  	struct symbol **sym_arr;  	struct gstr res; +	struct gstr title;  	char *dialog_input; -	int dres; +	int dres, vscroll = 0, hscroll = 0; +	bool again; + +	title = str_new(); +	str_printf( &title, _("Enter %s (sub)string to search for " +			      "(with or without \"%s\")"), CONFIG_, CONFIG_); +  again:  	dialog_clear();  	dres = dialog_inputbox(_("Search Configuration Parameter"), -			      _("Enter " CONFIG_ " (sub)string to search for " -				"(with or without \"" CONFIG_ "\")"), +			      str_get(&title),  			      10, 75, "");  	switch (dres) {  	case 0: @@ -320,6 +370,7 @@ again:  		show_helptext(_("Search Configuration"), search_help);  		goto again;  	default: +		str_free(&title);  		return;  	} @@ -329,10 +380,31 @@ again:  		dialog_input += strlen(CONFIG_);  	sym_arr = sym_re_search(dialog_input); -	res = get_relations_str(sym_arr); +	do { +		LIST_HEAD(head); +		struct menu *targets[JUMP_NB]; +		int keys[JUMP_NB + 1], i; +		struct search_data data = { +			.head = &head, +			.targets = targets, +			.keys = keys, +		}; + +		res = get_relations_str(sym_arr, &head); +		dres = show_textbox_ext(_("Search Results"), (char *) +					str_get(&res), 0, 0, keys, &vscroll, +					&hscroll, &update_text, (void *) +					&data); +		again = false; +		for (i = 0; i < JUMP_NB && keys[i]; i++) +			if (dres == keys[i]) { +				conf(targets[i]->parent, targets[i]); +				again = true; +			} +		str_free(&res); +	} while (again);  	free(sym_arr); -	show_textbox(_("Search Results"), str_get(&res), 0, 0); -	str_free(&res); +	str_free(&title);  }  static void build_conf(struct menu *menu) @@ -513,12 +585,11 @@ conf_childs:  	indent -= doint;  } -static void conf(struct menu *menu) +static void conf(struct menu *menu, struct menu *active_menu)  {  	struct menu *submenu;  	const char *prompt = menu_get_prompt(menu);  	struct symbol *sym; -	struct menu *active_menu = NULL;  	int res;  	int s_scroll = 0; @@ -528,14 +599,6 @@ static void conf(struct menu *menu)  		build_conf(menu);  		if (!child_count)  			break; -		if (menu == &rootmenu) { -			item_make("--- "); -			item_set_tag(':'); -			item_make(_("    Load an Alternate Configuration File")); -			item_set_tag('L'); -			item_make(_("    Save an Alternate Configuration File")); -			item_set_tag('S'); -		}  		dialog_clear();  		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),  				  _(menu_instructions), @@ -561,23 +624,17 @@ static void conf(struct menu *menu)  				if (single_menu_mode)  					submenu->data = (void *) (long) !submenu->data;  				else -					conf(submenu); +					conf(submenu, NULL);  				break;  			case 't':  				if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)  					conf_choice(submenu);  				else if (submenu->prompt->type == P_MENU) -					conf(submenu); +					conf(submenu, NULL);  				break;  			case 's':  				conf_string(submenu);  				break; -			case 'L': -				conf_load(); -				break; -			case 'S': -				conf_save(); -				break;  			}  			break;  		case 2: @@ -587,6 +644,12 @@ static void conf(struct menu *menu)  				show_helptext(_("README"), _(mconf_readme));  			break;  		case 3: +			conf_save(); +			break; +		case 4: +			conf_load(); +			break; +		case 5:  			if (item_is_tag('t')) {  				if (sym_set_tristate_value(sym, yes))  					break; @@ -594,34 +657,43 @@ static void conf(struct menu *menu)  					show_textbox(NULL, setmod_text, 6, 74);  			}  			break; -		case 4: +		case 6:  			if (item_is_tag('t'))  				sym_set_tristate_value(sym, no);  			break; -		case 5: +		case 7:  			if (item_is_tag('t'))  				sym_set_tristate_value(sym, mod);  			break; -		case 6: +		case 8:  			if (item_is_tag('t'))  				sym_toggle_tristate_value(sym);  			else if (item_is_tag('m')) -				conf(submenu); +				conf(submenu, NULL);  			break; -		case 7: +		case 9:  			search_conf();  			break; -		case 8: +		case 10:  			show_all_options = !show_all_options;  			break;  		}  	}  } -static void show_textbox(const char *title, const char *text, int r, int c) +static int show_textbox_ext(const char *title, char *text, int r, int c, int +			    *keys, int *vscroll, int *hscroll, update_text_fn +			    update_text, void *data)  {  	dialog_clear(); -	dialog_textbox(title, text, r, c); +	return dialog_textbox(title, text, r, c, keys, vscroll, hscroll, +			      update_text, data); +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ +	show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL, +			 NULL, NULL);  }  static void show_helptext(const char *title, const char *text) @@ -629,6 +701,17 @@ static void show_helptext(const char *title, const char *text)  	show_textbox(title, text, 0, 0);  } +static void conf_message_callback(const char *fmt, va_list ap) +{ +	char buf[PATH_MAX+1]; + +	vsnprintf(buf, sizeof(buf), fmt, ap); +	if (save_and_exit) +		printf("%s", buf); +	else +		show_textbox(NULL, buf, 6, 60); +} +  static void show_help(struct menu *menu)  {  	struct gstr help = str_new(); @@ -793,9 +876,57 @@ static void conf_save(void)  	}  } +static int handle_exit(void) +{ +	int res; + +	save_and_exit = 1; +	dialog_clear(); +	if (conf_get_changed()) +		res = dialog_yesno(NULL, +				   _("Do you wish to save your new configuration ?\n" +				     "<ESC><ESC> to continue."), +				   6, 60); +	else +		res = -1; + +	end_dialog(saved_x, saved_y); + +	switch (res) { +	case 0: +		if (conf_write(filename)) { +			fprintf(stderr, _("\n\n" +					  "Error while writing of the configuration.\n" +					  "Your configuration changes were NOT saved." +					  "\n\n")); +			return 1; +		} +		/* fall through */ +	case -1: +		printf(_("\n\n" +			 "*** End of the configuration.\n" +			 "*** Execute 'make' to start the build or try 'make help'." +			 "\n\n")); +		res = 0; +		break; +	default: +		fprintf(stderr, _("\n\n" +				  "Your configuration changes were NOT saved." +				  "\n\n")); +		if (res != KEY_ESC) +			res = 0; +	} + +	return res; +} + +static void sig_handler(int signo) +{ +	exit(handle_exit()); +} +  int main(int ac, char **av)  { -	int saved_x, saved_y;  	char *mode;  	int res; @@ -803,6 +934,8 @@ int main(int ac, char **av)  	bindtextdomain(PACKAGE, LOCALEDIR);  	textdomain(PACKAGE); +	signal(SIGINT, sig_handler); +  	conf_parse(av[1]);  	conf_read(NULL); @@ -812,9 +945,6 @@ int main(int ac, char **av)  			single_menu_mode = 1;  	} -	initscr(); - -	getyx(stdscr, saved_y, saved_x);  	if (init_dialog(NULL)) {  		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));  		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); @@ -822,41 +952,12 @@ int main(int ac, char **av)  	}  	set_config_filename(conf_get_configname()); +	conf_set_message_callback(conf_message_callback);  	do { -		conf(&rootmenu); -		dialog_clear(); -		if (conf_get_changed()) -			res = dialog_yesno(NULL, -					   _("Do you wish to save your " -					     "new configuration?\n" -					     "<ESC><ESC> to continue."), -					   6, 60); -		else -			res = -1; +		conf(&rootmenu, NULL); +		res = handle_exit();  	} while (res == KEY_ESC); -	end_dialog(saved_x, saved_y); - -	switch (res) { -	case 0: -		if (conf_write(filename)) { -			fprintf(stderr, _("\n\n" -				"Error while writing of the configuration.\n" -				"Your configuration changes were NOT saved." -				"\n\n")); -			return 1; -		} -	case -1: -		printf(_("\n\n" -			"*** End of the configuration.\n" -			"*** Execute 'make' to start the build or try 'make help'." -			"\n\n")); -		break; -	default: -		fprintf(stderr, _("\n\n" -			"Your configuration changes were NOT saved." -			"\n\n")); -	} -	return 0; +	return res;  }  | 
