kconfig/symbol.c
branchgcc-4.4
changeset 1368 ec1cffe6d30b
parent 39 af42eec9d383
child 1843 266166448ffd
     1.1 --- a/kconfig/symbol.c	Sun Apr 15 16:45:11 2007 +0000
     1.2 +++ b/kconfig/symbol.c	Thu May 21 19:00:55 2009 +0000
     1.3 @@ -34,19 +34,21 @@
     1.4  struct symbol *modules_sym;
     1.5  tristate modules_val;
     1.6  
     1.7 +struct expr *sym_env_list;
     1.8 +
     1.9  void sym_add_default(struct symbol *sym, const char *def)
    1.10  {
    1.11  	struct property *prop = prop_alloc(P_DEFAULT, sym);
    1.12  
    1.13 -	prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
    1.14 +	prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
    1.15  }
    1.16  
    1.17  void sym_init(void)
    1.18  {
    1.19  	struct symbol *sym;
    1.20  	struct utsname uts;
    1.21 -	char *p;
    1.22  	static bool inited = false;
    1.23 +	char* p;
    1.24  
    1.25  	if (inited)
    1.26  		return;
    1.27 @@ -54,12 +56,10 @@
    1.28  
    1.29  	uname(&uts);
    1.30  
    1.31 -	sym = sym_lookup("ARCH", 0);
    1.32 +	sym = sym_lookup("UNAME_RELEASE", 0);
    1.33  	sym->type = S_STRING;
    1.34  	sym->flags |= SYMBOL_AUTO;
    1.35 -	p = getenv("ARCH");
    1.36 -	if (p)
    1.37 -		sym_add_default(sym, p);
    1.38 +	sym_add_default(sym, uts.release);
    1.39  
    1.40  	sym = sym_lookup("PROJECTVERSION", 0);
    1.41  	sym->type = S_STRING;
    1.42 @@ -67,11 +67,6 @@
    1.43  	p = getenv("PROJECTVERSION");
    1.44  	if (p)
    1.45  		sym_add_default(sym, p);
    1.46 -
    1.47 -	sym = sym_lookup("UNAME_RELEASE", 0);
    1.48 -	sym->type = S_STRING;
    1.49 -	sym->flags |= SYMBOL_AUTO;
    1.50 -	sym_add_default(sym, uts.release);
    1.51  }
    1.52  
    1.53  enum symbol_type sym_get_type(struct symbol *sym)
    1.54 @@ -117,6 +112,15 @@
    1.55  	return NULL;
    1.56  }
    1.57  
    1.58 +struct property *sym_get_env_prop(struct symbol *sym)
    1.59 +{
    1.60 +	struct property *prop;
    1.61 +
    1.62 +	for_all_properties(sym, prop, P_ENV)
    1.63 +		return prop;
    1.64 +	return NULL;
    1.65 +}
    1.66 +
    1.67  struct property *sym_get_default_prop(struct symbol *sym)
    1.68  {
    1.69  	struct property *prop;
    1.70 @@ -199,7 +203,7 @@
    1.71  	tri = no;
    1.72  	for_all_prompts(sym, prop) {
    1.73  		prop->visible.tri = expr_calc_value(prop->visible.expr);
    1.74 -		tri = E_OR(tri, prop->visible.tri);
    1.75 +		tri = EXPR_OR(tri, prop->visible.tri);
    1.76  	}
    1.77  	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
    1.78  		tri = yes;
    1.79 @@ -247,8 +251,7 @@
    1.80  
    1.81  	/* just get the first visible value */
    1.82  	prop = sym_get_choice_prop(sym);
    1.83 -	for (e = prop->expr; e; e = e->left.expr) {
    1.84 -		def_sym = e->right.sym;
    1.85 +	expr_list_for_each_sym(prop->expr, e, def_sym) {
    1.86  		sym_calc_visibility(def_sym);
    1.87  		if (def_sym->visible != no)
    1.88  			return def_sym;
    1.89 @@ -303,22 +306,30 @@
    1.90  		if (sym_is_choice_value(sym) && sym->visible == yes) {
    1.91  			prop = sym_get_choice_prop(sym);
    1.92  			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
    1.93 -		} else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
    1.94 -			sym->flags |= SYMBOL_WRITE;
    1.95 -			if (sym_has_value(sym))
    1.96 -				newval.tri = sym->def[S_DEF_USER].tri;
    1.97 -			else if (!sym_is_choice(sym)) {
    1.98 +		} else {
    1.99 +			if (sym->visible != no) {
   1.100 +				/* if the symbol is visible use the user value
   1.101 +				 * if available, otherwise try the default value
   1.102 +				 */
   1.103 +				sym->flags |= SYMBOL_WRITE;
   1.104 +				if (sym_has_value(sym)) {
   1.105 +					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
   1.106 +							      sym->visible);
   1.107 +					goto calc_newval;
   1.108 +				}
   1.109 +			}
   1.110 +			if (sym->rev_dep.tri != no)
   1.111 +				sym->flags |= SYMBOL_WRITE;
   1.112 +			if (!sym_is_choice(sym)) {
   1.113  				prop = sym_get_default_prop(sym);
   1.114 -				if (prop)
   1.115 -					newval.tri = expr_calc_value(prop->expr);
   1.116 +				if (prop) {
   1.117 +					sym->flags |= SYMBOL_WRITE;
   1.118 +					newval.tri = EXPR_AND(expr_calc_value(prop->expr),
   1.119 +							      prop->visible.tri);
   1.120 +				}
   1.121  			}
   1.122 -			newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
   1.123 -		} else if (!sym_is_choice(sym)) {
   1.124 -			prop = sym_get_default_prop(sym);
   1.125 -			if (prop) {
   1.126 -				sym->flags |= SYMBOL_WRITE;
   1.127 -				newval.tri = expr_calc_value(prop->expr);
   1.128 -			}
   1.129 +		calc_newval:
   1.130 +			newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
   1.131  		}
   1.132  		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
   1.133  			newval.tri = yes;
   1.134 @@ -361,14 +372,19 @@
   1.135  	}
   1.136  
   1.137  	if (sym_is_choice(sym)) {
   1.138 +		struct symbol *choice_sym;
   1.139  		int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
   1.140 +
   1.141  		prop = sym_get_choice_prop(sym);
   1.142 -		for (e = prop->expr; e; e = e->left.expr) {
   1.143 -			e->right.sym->flags |= flags;
   1.144 +		expr_list_for_each_sym(prop->expr, e, choice_sym) {
   1.145 +			choice_sym->flags |= flags;
   1.146  			if (flags & SYMBOL_CHANGED)
   1.147 -				sym_set_changed(e->right.sym);
   1.148 +				sym_set_changed(choice_sym);
   1.149  		}
   1.150  	}
   1.151 +
   1.152 +	if (sym->flags & SYMBOL_AUTO)
   1.153 +		sym->flags &= ~SYMBOL_WRITE;
   1.154  }
   1.155  
   1.156  void sym_clear_all_valid(void)
   1.157 @@ -643,7 +659,7 @@
   1.158  	return sym->visible > sym->rev_dep.tri;
   1.159  }
   1.160  
   1.161 -struct symbol *sym_lookup(const char *name, int isconst)
   1.162 +struct symbol *sym_lookup(const char *name, int flags)
   1.163  {
   1.164  	struct symbol *symbol;
   1.165  	const char *ptr;
   1.166 @@ -663,11 +679,10 @@
   1.167  		hash &= 0xff;
   1.168  
   1.169  		for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
   1.170 -			if (!strcmp(symbol->name, name)) {
   1.171 -				if ((isconst && symbol->flags & SYMBOL_CONST) ||
   1.172 -				    (!isconst && !(symbol->flags & SYMBOL_CONST)))
   1.173 -					return symbol;
   1.174 -			}
   1.175 +			if (!strcmp(symbol->name, name) &&
   1.176 +			    (flags ? symbol->flags & flags
   1.177 +				   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
   1.178 +				return symbol;
   1.179  		}
   1.180  		new_name = strdup(name);
   1.181  	} else {
   1.182 @@ -679,8 +694,7 @@
   1.183  	memset(symbol, 0, sizeof(*symbol));
   1.184  	symbol->name = new_name;
   1.185  	symbol->type = S_UNKNOWN;
   1.186 -	if (isconst)
   1.187 -		symbol->flags |= SYMBOL_CONST;
   1.188 +	symbol->flags |= flags;
   1.189  
   1.190  	symbol->next = symbol_hash[hash];
   1.191  	symbol_hash[hash] = symbol;
   1.192 @@ -754,8 +768,6 @@
   1.193  }
   1.194  
   1.195  
   1.196 -struct symbol *sym_check_deps(struct symbol *sym);
   1.197 -
   1.198  static struct symbol *sym_check_expr_deps(struct expr *e)
   1.199  {
   1.200  	struct symbol *sym;
   1.201 @@ -786,44 +798,101 @@
   1.202  	return NULL;
   1.203  }
   1.204  
   1.205 +/* return NULL when dependencies are OK */
   1.206 +static struct symbol *sym_check_sym_deps(struct symbol *sym)
   1.207 +{
   1.208 +	struct symbol *sym2;
   1.209 +	struct property *prop;
   1.210 +
   1.211 +	sym2 = sym_check_expr_deps(sym->rev_dep.expr);
   1.212 +	if (sym2)
   1.213 +		return sym2;
   1.214 +
   1.215 +	for (prop = sym->prop; prop; prop = prop->next) {
   1.216 +		if (prop->type == P_CHOICE || prop->type == P_SELECT)
   1.217 +			continue;
   1.218 +		sym2 = sym_check_expr_deps(prop->visible.expr);
   1.219 +		if (sym2)
   1.220 +			break;
   1.221 +		if (prop->type != P_DEFAULT || sym_is_choice(sym))
   1.222 +			continue;
   1.223 +		sym2 = sym_check_expr_deps(prop->expr);
   1.224 +		if (sym2)
   1.225 +			break;
   1.226 +	}
   1.227 +
   1.228 +	return sym2;
   1.229 +}
   1.230 +
   1.231 +static struct symbol *sym_check_choice_deps(struct symbol *choice)
   1.232 +{
   1.233 +	struct symbol *sym, *sym2;
   1.234 +	struct property *prop;
   1.235 +	struct expr *e;
   1.236 +
   1.237 +	prop = sym_get_choice_prop(choice);
   1.238 +	expr_list_for_each_sym(prop->expr, e, sym)
   1.239 +		sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
   1.240 +
   1.241 +	choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
   1.242 +	sym2 = sym_check_sym_deps(choice);
   1.243 +	choice->flags &= ~SYMBOL_CHECK;
   1.244 +	if (sym2)
   1.245 +		goto out;
   1.246 +
   1.247 +	expr_list_for_each_sym(prop->expr, e, sym) {
   1.248 +		sym2 = sym_check_sym_deps(sym);
   1.249 +		if (sym2) {
   1.250 +			fprintf(stderr, " -> %s", sym->name);
   1.251 +			break;
   1.252 +		}
   1.253 +	}
   1.254 +out:
   1.255 +	expr_list_for_each_sym(prop->expr, e, sym)
   1.256 +		sym->flags &= ~SYMBOL_CHECK;
   1.257 +
   1.258 +	if (sym2 && sym_is_choice_value(sym2) &&
   1.259 +	    prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
   1.260 +		sym2 = choice;
   1.261 +
   1.262 +	return sym2;
   1.263 +}
   1.264 +
   1.265  struct symbol *sym_check_deps(struct symbol *sym)
   1.266  {
   1.267  	struct symbol *sym2;
   1.268  	struct property *prop;
   1.269  
   1.270  	if (sym->flags & SYMBOL_CHECK) {
   1.271 -		printf("Warning! Found recursive dependency: %s", sym->name);
   1.272 +		fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
   1.273 +		        sym->prop->file->name, sym->prop->lineno,
   1.274 +			sym->name ? sym->name : "<choice>");
   1.275  		return sym;
   1.276  	}
   1.277  	if (sym->flags & SYMBOL_CHECKED)
   1.278  		return NULL;
   1.279  
   1.280 -	sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
   1.281 -	sym2 = sym_check_expr_deps(sym->rev_dep.expr);
   1.282 -	if (sym2)
   1.283 -		goto out;
   1.284 +	if (sym_is_choice_value(sym)) {
   1.285 +		/* for choice groups start the check with main choice symbol */
   1.286 +		prop = sym_get_choice_prop(sym);
   1.287 +		sym2 = sym_check_deps(prop_get_symbol(prop));
   1.288 +	} else if (sym_is_choice(sym)) {
   1.289 +		sym2 = sym_check_choice_deps(sym);
   1.290 +	} else {
   1.291 +		sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
   1.292 +		sym2 = sym_check_sym_deps(sym);
   1.293 +		sym->flags &= ~SYMBOL_CHECK;
   1.294 +	}
   1.295  
   1.296 -	for (prop = sym->prop; prop; prop = prop->next) {
   1.297 -		if (prop->type == P_CHOICE || prop->type == P_SELECT)
   1.298 -			continue;
   1.299 -		sym2 = sym_check_expr_deps(prop->visible.expr);
   1.300 -		if (sym2)
   1.301 -			goto out;
   1.302 -		if (prop->type != P_DEFAULT || sym_is_choice(sym))
   1.303 -			continue;
   1.304 -		sym2 = sym_check_expr_deps(prop->expr);
   1.305 -		if (sym2)
   1.306 -			goto out;
   1.307 -	}
   1.308 -out:
   1.309  	if (sym2) {
   1.310 -		printf(" %s", sym->name);
   1.311 +		fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
   1.312  		if (sym2 == sym) {
   1.313 -			printf("\n");
   1.314 +			fprintf(stderr, "\n");
   1.315 +			zconfnerrs++;
   1.316  			sym2 = NULL;
   1.317  		}
   1.318  	}
   1.319 -	sym->flags &= ~SYMBOL_CHECK;
   1.320 +
   1.321  	return sym2;
   1.322  }
   1.323  
   1.324 @@ -852,7 +921,7 @@
   1.325  struct symbol *prop_get_symbol(struct property *prop)
   1.326  {
   1.327  	if (prop->expr && (prop->expr->type == E_SYMBOL ||
   1.328 -			   prop->expr->type == E_CHOICE))
   1.329 +			   prop->expr->type == E_LIST))
   1.330  		return prop->expr->left.sym;
   1.331  	return NULL;
   1.332  }
   1.333 @@ -862,6 +931,8 @@
   1.334  	switch (type) {
   1.335  	case P_PROMPT:
   1.336  		return "prompt";
   1.337 +	case P_ENV:
   1.338 +		return "env";
   1.339  	case P_COMMENT:
   1.340  		return "comment";
   1.341  	case P_MENU:
   1.342 @@ -879,3 +950,32 @@
   1.343  	}
   1.344  	return "unknown";
   1.345  }
   1.346 +
   1.347 +void prop_add_env(const char *env)
   1.348 +{
   1.349 +	struct symbol *sym, *sym2;
   1.350 +	struct property *prop;
   1.351 +	char *p;
   1.352 +
   1.353 +	sym = current_entry->sym;
   1.354 +	sym->flags |= SYMBOL_AUTO;
   1.355 +	for_all_properties(sym, prop, P_ENV) {
   1.356 +		sym2 = prop_get_symbol(prop);
   1.357 +		if (strcmp(sym2->name, env))
   1.358 +			menu_warn(current_entry, "redefining environment symbol from %s",
   1.359 +				  sym2->name);
   1.360 +		return;
   1.361 +	}
   1.362 +
   1.363 +	prop = prop_alloc(P_ENV, sym);
   1.364 +	prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
   1.365 +
   1.366 +	sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
   1.367 +	sym_env_list->right.sym = sym;
   1.368 +
   1.369 +	p = getenv(env);
   1.370 +	if (p)
   1.371 +		sym_add_default(sym, p);
   1.372 +	else
   1.373 +		menu_warn(current_entry, "environment variable %s undefined", env);
   1.374 +}