diff options
| -rw-r--r-- | extra/config/checklist.c | 17 | ||||
| -rw-r--r-- | extra/config/confdata.c | 12 | ||||
| -rw-r--r-- | extra/config/expr.c | 50 | ||||
| -rw-r--r-- | extra/config/expr.h | 1 | ||||
| -rw-r--r-- | extra/config/mconf.c | 19 | ||||
| -rw-r--r-- | extra/config/menu.c | 125 | ||||
| -rw-r--r-- | extra/config/symbol.c | 52 | ||||
| -rw-r--r-- | extra/config/textbox.c | 4 | ||||
| -rw-r--r-- | extra/config/util.c | 2 | 
9 files changed, 174 insertions, 108 deletions
| diff --git a/extra/config/checklist.c b/extra/config/checklist.c index c4a9289b9..71de4a191 100644 --- a/extra/config/checklist.c +++ b/extra/config/checklist.c @@ -138,10 +138,12 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,      /* Initializes status */      for (i = 0; i < item_no; i++) { -	status[i] = items[i]->selected; -	if (!choice && status[i]) -            choice = i; +	status[i] = (items[i]->selected == 1); /* ON */ +	if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */ +            choice = i + 1;      } +    if (choice) +	    choice--;      max_choice = MIN (list_height, item_no); @@ -303,6 +305,9 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,  	case 'H':  	case 'h':  	case '?': +	    for (i = 0; i < item_no; i++) +		items[i]->selected = 0; +	    items[scroll + choice]->selected = 1;  	    delwin (dialog);  	    free (status);  	    return 1; @@ -341,7 +346,11 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,  		for (i = 0; i < item_no; i++) {  			items[i]->selected = status[i];  		} -            } +            } else { +		    for (i = 0; i < item_no; i++) +			    items[i]->selected = 0; +		    items[scroll + choice]->selected = 1; +	    }  	    delwin (dialog);  	    free (status);  	    return button; diff --git a/extra/config/confdata.c b/extra/config/confdata.c index 4b4d150c7..56aff3c03 100644 --- a/extra/config/confdata.c +++ b/extra/config/confdata.c @@ -225,6 +225,8 @@ int conf_read(const char *name)  	}  	fclose(in); +	if (modules_sym) +		sym_calc_value(modules_sym);  	for_all_symbols(i, sym) {  		sym_calc_value(sym);  		if (sym_has_value(sym) && !sym_is_choice_value(sym)) { @@ -265,8 +267,14 @@ int conf_write(const char *name)  	dirname[0] = 0;  	if (name && name[0]) { -		char *slash = strrchr(name, '/'); -		if (slash) { +		struct stat st; +		char *slash; + +		if (!stat(name, &st) && S_ISDIR(st.st_mode)) { +			strcpy(dirname, name); +			strcat(dirname, "/"); +			basename = conf_def_filename; +		} else if ((slash = strrchr(name, '/'))) {  			int size = slash - name + 1;  			memcpy(dirname, name, size);  			dirname[size] = 0; diff --git a/extra/config/expr.c b/extra/config/expr.c index 3f15ae859..10f45232b 100644 --- a/extra/config/expr.c +++ b/extra/config/expr.c @@ -10,6 +10,8 @@  #define LKC_DIRECT_LINK  #include "lkc.h" +#define DEBUG_EXPR	0 +  struct expr *expr_alloc_symbol(struct symbol *sym)  {  	struct expr *e = malloc(sizeof(*e)); @@ -220,10 +222,12 @@ int expr_eq(struct expr *e1, struct expr *e2)  		/* panic */;  	} -	print_expr(0, e1, 0); -	printf(" = "); -	print_expr(0, e2, 0); -	printf(" ?\n"); +	if (DEBUG_EXPR) { +		expr_fprint(e1, stdout); +		printf(" = "); +		expr_fprint(e2, stdout); +		printf(" ?\n"); +	}  	return 0;  } @@ -397,11 +401,13 @@ struct expr *expr_join_or(struct expr *e1, struct expr *e2)  			return expr_alloc_symbol(&symbol_yes);  	} -	printf("optimize "); -	print_expr(0, e1, 0); -	printf(" || "); -	print_expr(0, e2, 0); -	printf(" ?\n"); +	if (DEBUG_EXPR) { +		printf("optimize ("); +		expr_fprint(e1, stdout); +		printf(") || ("); +		expr_fprint(e2, stdout); +		printf(")?\n"); +	}  	return NULL;  } @@ -444,6 +450,11 @@ struct expr *expr_join_and(struct expr *e1, struct expr *e2)  		// (a) && (a!='n') -> (a)  		return expr_alloc_symbol(sym1); +	if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || +	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) +		// (a) && (a!='m') -> (a='y') +		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); +  	if (sym1->type == S_TRISTATE) {  		if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {  			// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' @@ -483,11 +494,14 @@ struct expr *expr_join_and(struct expr *e1, struct expr *e2)  		    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))  			return NULL;  	} -	printf("optimize "); -	print_expr(0, e1, 0); -	printf(" && "); -	print_expr(0, e2, 0); -	printf(" ?\n"); + +	if (DEBUG_EXPR) { +		printf("optimize ("); +		expr_fprint(e1, stdout); +		printf(") && ("); +		expr_fprint(e2, stdout); +		printf(")?\n"); +	}  	return NULL;  } @@ -1073,11 +1087,3 @@ void expr_fprint(struct expr *e, FILE *out)  {  	expr_print(e, expr_print_file_helper, out, E_NONE);  } - -void print_expr(int mask, struct expr *e, int prevtoken) -{ -	if (!(cdebug & mask)) -		return; -	expr_fprint(e, stdout); -} - diff --git a/extra/config/expr.h b/extra/config/expr.h index cc616f1f8..cac51f6a8 100644 --- a/extra/config/expr.h +++ b/extra/config/expr.h @@ -174,7 +174,6 @@ void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, s  struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);  void expr_fprint(struct expr *e, FILE *out); -void print_expr(int mask, struct expr *e, int prevtoken);  static inline int expr_is_yes(struct expr *e)  { diff --git a/extra/config/mconf.c b/extra/config/mconf.c index 2193c7351..810032d59 100644 --- a/extra/config/mconf.c +++ b/extra/config/mconf.c @@ -515,9 +515,9 @@ static void conf_choice(struct menu *menu)  	struct menu *child;  	struct symbol *active; +	active = sym_get_choice_value(menu->sym);  	while (1) {  		current_menu = menu; -		active = sym_get_choice_value(menu->sym);  		cdone(); cinit();  		for (child = menu->list; child; child = child->next) {  			if (!menu_is_visible(child)) @@ -525,19 +525,28 @@ static void conf_choice(struct menu *menu)  			cmake();  			cprint_tag("%p", child);  			cprint_name("%s", menu_get_prompt(child)); -			items[item_no - 1]->selected = (child->sym == active); +			if (child->sym == sym_get_choice_value(menu->sym)) +				items[item_no - 1]->selected = 1; /* ON */ +			else if (child->sym == active) +				items[item_no - 1]->selected = 2; /* SELECTED */ +			else +				items[item_no - 1]->selected = 0; /* OFF */  		}  		switch (dialog_checklist(prompt ? prompt : "Main Menu",  					radiolist_instructions, 15, 70, 6,  					item_no, items, FLAG_RADIO)) {  		case 0: -			if (sscanf(first_sel_item(item_no, items)->tag, "%p", &menu) != 1) +			if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) != 1)  				break; -			sym_set_tristate_value(menu->sym, yes); +			sym_set_tristate_value(child->sym, yes);  			return;  		case 1: -			show_help(menu); +			if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) == 1) { +				show_help(child); +				active = child->sym; +			} else +				show_help(menu);  			break;  		case 255:  			return; diff --git a/extra/config/menu.c b/extra/config/menu.c index ba5c6a6c5..bcc4f098b 100644 --- a/extra/config/menu.c +++ b/extra/config/menu.c @@ -16,6 +16,26 @@ static struct menu **last_entry_ptr;  struct file *file_list;  struct file *current_file; +static void menu_warn(struct menu *menu, const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); +	vfprintf(stderr, fmt, ap); +	fprintf(stderr, "\n"); +	va_end(ap); +} + +static void prop_warn(struct property *prop, const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); +	vfprintf(stderr, fmt, ap); +	fprintf(stderr, "\n"); +	va_end(ap); +} +  void menu_init(void)  {  	current_entry = current_menu = &rootmenu; @@ -94,9 +114,9 @@ void menu_set_type(int type)  		sym->type = type;  		return;  	} -	fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n", -		current_entry->file->name, current_entry->lineno, -		sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type)); +	menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n", +	    sym->name ? sym->name : "<choice>", +	    sym_type_name(sym->type), sym_type_name(type));  }  struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) @@ -110,8 +130,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e  	if (prompt) {  		if (current_entry->prompt) -			fprintf(stderr, "%s:%d: prompt redefined\n", -				current_entry->file->name, current_entry->lineno); +			menu_warn(current_entry, "prompt redefined\n");  		current_entry->prompt = prop;  	} @@ -133,6 +152,50 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)  	menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);  } +void sym_check_prop(struct symbol *sym) +{ +	struct property *prop; +	struct symbol *sym2; +	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) && +			    prop->expr->type != E_SYMBOL) +				prop_warn(prop, +				    "default for config symbol '%'" +				    " must be a single symbol", sym->name); +			break; +		case P_SELECT: +			sym2 = prop_get_symbol(prop); +			if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) +				prop_warn(prop, +				    "config symbol '%s' uses select, but is " +				    "not boolean or tristate", sym->name); +			else if (sym2->type == S_UNKNOWN) +				prop_warn(prop, +				    "'select' used by config symbol '%s' " +				    "refer to undefined symbol '%s'", +				    sym->name, sym2->name); +			else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) +				prop_warn(prop, +				    "'%s' has wrong type. 'select' only " +				    "accept arguments of boolean and " +				    "tristate type", sym2->name); +			break; +		case P_RANGE: +			if (sym->type != S_INT && sym->type != S_HEX) +				prop_warn(prop, "range is only allowed " +				                "for int or hex symbols"); +			if (!sym_string_valid(sym, prop->expr->left.sym->name) || +			    !sym_string_valid(sym, prop->expr->right.sym->name)) +				prop_warn(prop, "range is invalid"); +			break; +		default: +			; +		} +	} +} +  void menu_finalize(struct menu *parent)  {  	struct menu *menu, *last_menu; @@ -222,17 +285,16 @@ void menu_finalize(struct menu *parent)  		if (sym && sym_is_choice(sym) && menu->sym) {  			menu->sym->flags |= SYMBOL_CHOICEVAL;  			if (!menu->prompt) -				fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n", -					menu->file->name, menu->lineno); +				menu_warn(menu, "choice value must have a prompt");  			for (prop = menu->sym->prop; prop; prop = prop->next) {  				if (prop->type == P_PROMPT && prop->menu != menu) { -					fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n", -						prop->file->name, prop->lineno); -					 +					prop_warn(prop, "choice values " +					    "currently only support a " +					    "single prompt");  				}  				if (prop->type == P_DEFAULT) -					fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n", -						prop->file->name, prop->lineno); +					prop_warn(prop, "defaults for choice " +					    "values not supported");  			}  			current_entry = menu;  			menu_set_type(sym->type); @@ -256,42 +318,15 @@ void menu_finalize(struct menu *parent)  	}  	if (sym && !(sym->flags & SYMBOL_WARNED)) { -		struct symbol *sym2;  		if (sym->type == S_UNKNOWN) -			fprintf(stderr, "%s:%d:warning: config symbol defined without type\n", -				parent->file->name, parent->lineno); +			menu_warn(parent, "config symbol defined " +			    "without type\n");  		if (sym_is_choice(sym) && !parent->prompt) -			fprintf(stderr, "%s:%d:warning: choice must have a prompt\n", -				parent->file->name, parent->lineno); - -		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) && -				    prop->expr->type != E_SYMBOL) -					fprintf(stderr, "%s:%d:warning: default must be a single symbol\n", -						prop->file->name, prop->lineno); -				break; -			case P_SELECT: -				sym2 = prop_get_symbol(prop); -				if ((sym->type != S_BOOLEAN) || (sym2->type != S_BOOLEAN)) -					fprintf(stderr, "%s:%d:warning: enable is only allowed with booleans\n", -						prop->file->name, prop->lineno); -				break; -			case P_RANGE: -				if (sym->type != S_INT && sym->type != S_HEX) -					fprintf(stderr, "%s:%d:warning: range is only allowed for int or hex symbols\n", -						prop->file->name, prop->lineno); -				if (!sym_string_valid(sym, prop->expr->left.sym->name) || -				    !sym_string_valid(sym, prop->expr->right.sym->name)) -					fprintf(stderr, "%s:%d:warning: range is invalid\n", -						prop->file->name, prop->lineno); -				break; -			default: -				; -			} -		} +			menu_warn(parent, "choice must have a prompt\n"); + +		/* Check properties connected to this symbol */ +		sym_check_prop(sym);  		sym->flags |= SYMBOL_WARNED;  	} diff --git a/extra/config/symbol.c b/extra/config/symbol.c index 29d8d3e0b..a9fae9c13 100644 --- a/extra/config/symbol.c +++ b/extra/config/symbol.c @@ -12,25 +12,26 @@  #include "lkc.h"  struct symbol symbol_yes = { -	name: "y", -	curr: { "y", yes }, -	flags: SYMBOL_YES|SYMBOL_VALID, +	.name = "y", +	.curr = { "y", yes }, +	.flags = SYMBOL_YES|SYMBOL_VALID,  }, symbol_mod = { -	name: "m", -	curr: { "m", mod }, -	flags: SYMBOL_MOD|SYMBOL_VALID, +	.name = "m", +	.curr = { "m", mod }, +	.flags = SYMBOL_MOD|SYMBOL_VALID,  }, symbol_no = { -	name: "n", -	curr: { "n", no }, -	flags: SYMBOL_NO|SYMBOL_VALID, +	.name = "n", +	.curr = { "n", no }, +	.flags = SYMBOL_NO|SYMBOL_VALID,  }, symbol_empty = { -	name: "", -	curr: { "", no }, -	flags: SYMBOL_VALID, +	.name = "", +	.curr = { "", no }, +	.flags = SYMBOL_VALID,  };  int sym_change_count;  struct symbol *modules_sym; +tristate modules_val;  void sym_add_default(struct symbol *sym, const char *def)  { @@ -72,11 +73,8 @@ enum symbol_type sym_get_type(struct symbol *sym)  	if (type == S_TRISTATE) {  		if (sym_is_choice_value(sym) && sym->visible == yes)  			type = S_BOOLEAN; -		else { -			sym_calc_value(modules_sym); -			if (modules_sym->curr.tri == no) -				type = S_BOOLEAN; -		} +		else if (modules_val == no) +			type = S_BOOLEAN;  	}  	return type;  } @@ -146,6 +144,8 @@ static void sym_calc_visibility(struct symbol *sym)  		prop->visible.tri = expr_calc_value(prop->visible.expr);  		tri = E_OR(tri, prop->visible.tri);  	} +	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) +		tri = yes;  	if (sym->visible != tri) {  		sym->visible = tri;  		sym_set_changed(sym); @@ -155,6 +155,8 @@ static void sym_calc_visibility(struct symbol *sym)  	tri = no;  	if (sym->rev_dep.expr)  		tri = expr_calc_value(sym->rev_dep.expr); +	if (tri == mod && sym_get_type(sym) == S_BOOLEAN) +		tri = yes;  	if (sym->rev_dep.tri != tri) {  		sym->rev_dep.tri = tri;  		sym_set_changed(sym); @@ -261,14 +263,8 @@ void sym_calc_value(struct symbol *sym)  				newval.tri = expr_calc_value(prop->expr);  			}  		} -		if (sym_get_type(sym) == S_BOOLEAN) { -			if (newval.tri == mod) -				newval.tri = yes; -			if (sym->visible == mod) -				sym->visible = yes; -			if (sym->rev_dep.tri == mod) -				sym->rev_dep.tri = yes; -		} +		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) +			newval.tri = yes;  		break;  	case S_STRING:  	case S_HEX: @@ -300,6 +296,8 @@ void sym_calc_value(struct symbol *sym)  	if (memcmp(&oldval, &sym->curr, sizeof(oldval)))  		sym_set_changed(sym); +	if (modules_sym == sym) +		modules_val = modules_sym->curr.tri;  	if (sym_is_choice(sym)) {  		int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); @@ -320,6 +318,8 @@ void sym_clear_all_valid(void)  	for_all_symbols(i, sym)  		sym->flags &= ~SYMBOL_VALID;  	sym_change_count++; +	if (modules_sym) +		sym_calc_value(modules_sym);  }  void sym_set_changed(struct symbol *sym) @@ -699,7 +699,7 @@ struct symbol *sym_check_deps(struct symbol *sym)  		goto out;  	for (prop = sym->prop; prop; prop = prop->next) { -		if (prop->type == P_CHOICE) +		if (prop->type == P_CHOICE || prop->type == P_SELECT)  			continue;  		sym2 = sym_check_expr_deps(prop->visible.expr);  		if (sym2) diff --git a/extra/config/textbox.c b/extra/config/textbox.c index 8fe907718..a5a460b5c 100644 --- a/extra/config/textbox.c +++ b/extra/config/textbox.c @@ -27,8 +27,8 @@ static void print_line (WINDOW * win, int row, int width);  static char *get_line (void);  static void print_position (WINDOW * win, int height, int width); -static int hscroll = 0, fd, file_size, bytes_read; -static int begin_reached = 1, end_reached = 0, page_length; +static int hscroll, fd, file_size, bytes_read; +static int begin_reached = 1, end_reached, page_length;  static char *buf, *page;  /* diff --git a/extra/config/util.c b/extra/config/util.c index d20730b88..d0cfa58ee 100644 --- a/extra/config/util.c +++ b/extra/config/util.c @@ -348,7 +348,7 @@ first_alpha(const char *string, const char *exempt)  		c = tolower(string[i]);  		if (strchr("<[(", c)) ++in_paren; -		if (strchr(">])", c)) --in_paren; +		if (strchr(">])", c) && in_paren > 0) --in_paren;  		if ((! in_paren) && isalpha(c) &&   		     strchr(exempt, c) == 0) | 
