1*cf5a6c84SAndroid Build Coastguard Worker /*
2*cf5a6c84SAndroid Build Coastguard Worker * Copyright (C) 2002 Roman Zippel <[email protected]>
3*cf5a6c84SAndroid Build Coastguard Worker * Released under the terms of the GNU GPL v2.0.
4*cf5a6c84SAndroid Build Coastguard Worker */
5*cf5a6c84SAndroid Build Coastguard Worker
6*cf5a6c84SAndroid Build Coastguard Worker #include <ctype.h>
7*cf5a6c84SAndroid Build Coastguard Worker #include <stdlib.h>
8*cf5a6c84SAndroid Build Coastguard Worker #include <string.h>
9*cf5a6c84SAndroid Build Coastguard Worker #include <regex.h>
10*cf5a6c84SAndroid Build Coastguard Worker #include <sys/utsname.h>
11*cf5a6c84SAndroid Build Coastguard Worker
12*cf5a6c84SAndroid Build Coastguard Worker #define LKC_DIRECT_LINK
13*cf5a6c84SAndroid Build Coastguard Worker #include "lkc.h"
14*cf5a6c84SAndroid Build Coastguard Worker
15*cf5a6c84SAndroid Build Coastguard Worker struct symbol symbol_yes = {
16*cf5a6c84SAndroid Build Coastguard Worker .name = "y",
17*cf5a6c84SAndroid Build Coastguard Worker .curr = { "y", yes },
18*cf5a6c84SAndroid Build Coastguard Worker .flags = SYMBOL_CONST|SYMBOL_VALID,
19*cf5a6c84SAndroid Build Coastguard Worker }, symbol_mod = {
20*cf5a6c84SAndroid Build Coastguard Worker .name = "m",
21*cf5a6c84SAndroid Build Coastguard Worker .curr = { "m", mod },
22*cf5a6c84SAndroid Build Coastguard Worker .flags = SYMBOL_CONST|SYMBOL_VALID,
23*cf5a6c84SAndroid Build Coastguard Worker }, symbol_no = {
24*cf5a6c84SAndroid Build Coastguard Worker .name = "n",
25*cf5a6c84SAndroid Build Coastguard Worker .curr = { "n", no },
26*cf5a6c84SAndroid Build Coastguard Worker .flags = SYMBOL_CONST|SYMBOL_VALID,
27*cf5a6c84SAndroid Build Coastguard Worker }, symbol_empty = {
28*cf5a6c84SAndroid Build Coastguard Worker .name = "",
29*cf5a6c84SAndroid Build Coastguard Worker .curr = { "", no },
30*cf5a6c84SAndroid Build Coastguard Worker .flags = SYMBOL_VALID,
31*cf5a6c84SAndroid Build Coastguard Worker };
32*cf5a6c84SAndroid Build Coastguard Worker
33*cf5a6c84SAndroid Build Coastguard Worker int sym_change_count;
34*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym_defconfig_list;
35*cf5a6c84SAndroid Build Coastguard Worker struct symbol *modules_sym;
36*cf5a6c84SAndroid Build Coastguard Worker tristate modules_val;
37*cf5a6c84SAndroid Build Coastguard Worker
sym_add_default(struct symbol * sym,const char * def)38*cf5a6c84SAndroid Build Coastguard Worker void sym_add_default(struct symbol *sym, const char *def)
39*cf5a6c84SAndroid Build Coastguard Worker {
40*cf5a6c84SAndroid Build Coastguard Worker struct property *prop = prop_alloc(P_DEFAULT, sym);
41*cf5a6c84SAndroid Build Coastguard Worker
42*cf5a6c84SAndroid Build Coastguard Worker prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
43*cf5a6c84SAndroid Build Coastguard Worker }
44*cf5a6c84SAndroid Build Coastguard Worker
sym_init(void)45*cf5a6c84SAndroid Build Coastguard Worker void sym_init(void)
46*cf5a6c84SAndroid Build Coastguard Worker {
47*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
48*cf5a6c84SAndroid Build Coastguard Worker struct utsname uts;
49*cf5a6c84SAndroid Build Coastguard Worker char *p;
50*cf5a6c84SAndroid Build Coastguard Worker static bool inited = false;
51*cf5a6c84SAndroid Build Coastguard Worker
52*cf5a6c84SAndroid Build Coastguard Worker if (inited)
53*cf5a6c84SAndroid Build Coastguard Worker return;
54*cf5a6c84SAndroid Build Coastguard Worker inited = true;
55*cf5a6c84SAndroid Build Coastguard Worker
56*cf5a6c84SAndroid Build Coastguard Worker uname(&uts);
57*cf5a6c84SAndroid Build Coastguard Worker
58*cf5a6c84SAndroid Build Coastguard Worker /*
59*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup("ARCH", 0);
60*cf5a6c84SAndroid Build Coastguard Worker sym->type = S_STRING;
61*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_AUTO;
62*cf5a6c84SAndroid Build Coastguard Worker p = getenv("ARCH");
63*cf5a6c84SAndroid Build Coastguard Worker if (p)
64*cf5a6c84SAndroid Build Coastguard Worker sym_add_default(sym, p);
65*cf5a6c84SAndroid Build Coastguard Worker */
66*cf5a6c84SAndroid Build Coastguard Worker
67*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup("KERNELVERSION", 0);
68*cf5a6c84SAndroid Build Coastguard Worker sym->type = S_STRING;
69*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_AUTO;
70*cf5a6c84SAndroid Build Coastguard Worker p = getenv("KERNELVERSION");
71*cf5a6c84SAndroid Build Coastguard Worker if (p)
72*cf5a6c84SAndroid Build Coastguard Worker sym_add_default(sym, p);
73*cf5a6c84SAndroid Build Coastguard Worker
74*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup("UNAME_RELEASE", 0);
75*cf5a6c84SAndroid Build Coastguard Worker sym->type = S_STRING;
76*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_AUTO;
77*cf5a6c84SAndroid Build Coastguard Worker sym_add_default(sym, uts.release);
78*cf5a6c84SAndroid Build Coastguard Worker }
79*cf5a6c84SAndroid Build Coastguard Worker
sym_get_type(struct symbol * sym)80*cf5a6c84SAndroid Build Coastguard Worker enum symbol_type sym_get_type(struct symbol *sym)
81*cf5a6c84SAndroid Build Coastguard Worker {
82*cf5a6c84SAndroid Build Coastguard Worker enum symbol_type type = sym->type;
83*cf5a6c84SAndroid Build Coastguard Worker
84*cf5a6c84SAndroid Build Coastguard Worker if (type == S_TRISTATE) {
85*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice_value(sym) && sym->visible == yes)
86*cf5a6c84SAndroid Build Coastguard Worker type = S_BOOLEAN;
87*cf5a6c84SAndroid Build Coastguard Worker else if (modules_val == no)
88*cf5a6c84SAndroid Build Coastguard Worker type = S_BOOLEAN;
89*cf5a6c84SAndroid Build Coastguard Worker }
90*cf5a6c84SAndroid Build Coastguard Worker return type;
91*cf5a6c84SAndroid Build Coastguard Worker }
92*cf5a6c84SAndroid Build Coastguard Worker
sym_type_name(enum symbol_type type)93*cf5a6c84SAndroid Build Coastguard Worker const char *sym_type_name(enum symbol_type type)
94*cf5a6c84SAndroid Build Coastguard Worker {
95*cf5a6c84SAndroid Build Coastguard Worker switch (type) {
96*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
97*cf5a6c84SAndroid Build Coastguard Worker return "boolean";
98*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
99*cf5a6c84SAndroid Build Coastguard Worker return "tristate";
100*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
101*cf5a6c84SAndroid Build Coastguard Worker return "integer";
102*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
103*cf5a6c84SAndroid Build Coastguard Worker return "hex";
104*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
105*cf5a6c84SAndroid Build Coastguard Worker return "string";
106*cf5a6c84SAndroid Build Coastguard Worker case S_UNKNOWN:
107*cf5a6c84SAndroid Build Coastguard Worker return "unknown";
108*cf5a6c84SAndroid Build Coastguard Worker case S_OTHER:
109*cf5a6c84SAndroid Build Coastguard Worker break;
110*cf5a6c84SAndroid Build Coastguard Worker }
111*cf5a6c84SAndroid Build Coastguard Worker return "???";
112*cf5a6c84SAndroid Build Coastguard Worker }
113*cf5a6c84SAndroid Build Coastguard Worker
sym_get_choice_prop(struct symbol * sym)114*cf5a6c84SAndroid Build Coastguard Worker struct property *sym_get_choice_prop(struct symbol *sym)
115*cf5a6c84SAndroid Build Coastguard Worker {
116*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
117*cf5a6c84SAndroid Build Coastguard Worker
118*cf5a6c84SAndroid Build Coastguard Worker for_all_choices(sym, prop)
119*cf5a6c84SAndroid Build Coastguard Worker return prop;
120*cf5a6c84SAndroid Build Coastguard Worker return NULL;
121*cf5a6c84SAndroid Build Coastguard Worker }
122*cf5a6c84SAndroid Build Coastguard Worker
sym_get_default_prop(struct symbol * sym)123*cf5a6c84SAndroid Build Coastguard Worker struct property *sym_get_default_prop(struct symbol *sym)
124*cf5a6c84SAndroid Build Coastguard Worker {
125*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
126*cf5a6c84SAndroid Build Coastguard Worker
127*cf5a6c84SAndroid Build Coastguard Worker for_all_defaults(sym, prop) {
128*cf5a6c84SAndroid Build Coastguard Worker prop->visible.tri = expr_calc_value(prop->visible.expr);
129*cf5a6c84SAndroid Build Coastguard Worker if (prop->visible.tri != no)
130*cf5a6c84SAndroid Build Coastguard Worker return prop;
131*cf5a6c84SAndroid Build Coastguard Worker }
132*cf5a6c84SAndroid Build Coastguard Worker return NULL;
133*cf5a6c84SAndroid Build Coastguard Worker }
134*cf5a6c84SAndroid Build Coastguard Worker
sym_get_range_prop(struct symbol * sym)135*cf5a6c84SAndroid Build Coastguard Worker struct property *sym_get_range_prop(struct symbol *sym)
136*cf5a6c84SAndroid Build Coastguard Worker {
137*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
138*cf5a6c84SAndroid Build Coastguard Worker
139*cf5a6c84SAndroid Build Coastguard Worker for_all_properties(sym, prop, P_RANGE) {
140*cf5a6c84SAndroid Build Coastguard Worker prop->visible.tri = expr_calc_value(prop->visible.expr);
141*cf5a6c84SAndroid Build Coastguard Worker if (prop->visible.tri != no)
142*cf5a6c84SAndroid Build Coastguard Worker return prop;
143*cf5a6c84SAndroid Build Coastguard Worker }
144*cf5a6c84SAndroid Build Coastguard Worker return NULL;
145*cf5a6c84SAndroid Build Coastguard Worker }
146*cf5a6c84SAndroid Build Coastguard Worker
sym_get_range_val(struct symbol * sym,int base)147*cf5a6c84SAndroid Build Coastguard Worker static int sym_get_range_val(struct symbol *sym, int base)
148*cf5a6c84SAndroid Build Coastguard Worker {
149*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
150*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
151*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
152*cf5a6c84SAndroid Build Coastguard Worker base = 10;
153*cf5a6c84SAndroid Build Coastguard Worker break;
154*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
155*cf5a6c84SAndroid Build Coastguard Worker base = 16;
156*cf5a6c84SAndroid Build Coastguard Worker break;
157*cf5a6c84SAndroid Build Coastguard Worker default:
158*cf5a6c84SAndroid Build Coastguard Worker break;
159*cf5a6c84SAndroid Build Coastguard Worker }
160*cf5a6c84SAndroid Build Coastguard Worker return strtol(sym->curr.val, NULL, base);
161*cf5a6c84SAndroid Build Coastguard Worker }
162*cf5a6c84SAndroid Build Coastguard Worker
sym_validate_range(struct symbol * sym)163*cf5a6c84SAndroid Build Coastguard Worker static void sym_validate_range(struct symbol *sym)
164*cf5a6c84SAndroid Build Coastguard Worker {
165*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
166*cf5a6c84SAndroid Build Coastguard Worker int base, val, val2;
167*cf5a6c84SAndroid Build Coastguard Worker char str[64];
168*cf5a6c84SAndroid Build Coastguard Worker
169*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
170*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
171*cf5a6c84SAndroid Build Coastguard Worker base = 10;
172*cf5a6c84SAndroid Build Coastguard Worker break;
173*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
174*cf5a6c84SAndroid Build Coastguard Worker base = 16;
175*cf5a6c84SAndroid Build Coastguard Worker break;
176*cf5a6c84SAndroid Build Coastguard Worker default:
177*cf5a6c84SAndroid Build Coastguard Worker return;
178*cf5a6c84SAndroid Build Coastguard Worker }
179*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_range_prop(sym);
180*cf5a6c84SAndroid Build Coastguard Worker if (!prop)
181*cf5a6c84SAndroid Build Coastguard Worker return;
182*cf5a6c84SAndroid Build Coastguard Worker val = strtol(sym->curr.val, NULL, base);
183*cf5a6c84SAndroid Build Coastguard Worker val2 = sym_get_range_val(prop->expr->left.sym, base);
184*cf5a6c84SAndroid Build Coastguard Worker if (val >= val2) {
185*cf5a6c84SAndroid Build Coastguard Worker val2 = sym_get_range_val(prop->expr->right.sym, base);
186*cf5a6c84SAndroid Build Coastguard Worker if (val <= val2)
187*cf5a6c84SAndroid Build Coastguard Worker return;
188*cf5a6c84SAndroid Build Coastguard Worker }
189*cf5a6c84SAndroid Build Coastguard Worker if (sym->type == S_INT)
190*cf5a6c84SAndroid Build Coastguard Worker sprintf(str, "%d", val2);
191*cf5a6c84SAndroid Build Coastguard Worker else
192*cf5a6c84SAndroid Build Coastguard Worker sprintf(str, "0x%x", val2);
193*cf5a6c84SAndroid Build Coastguard Worker sym->curr.val = strdup(str);
194*cf5a6c84SAndroid Build Coastguard Worker }
195*cf5a6c84SAndroid Build Coastguard Worker
sym_calc_visibility(struct symbol * sym)196*cf5a6c84SAndroid Build Coastguard Worker static void sym_calc_visibility(struct symbol *sym)
197*cf5a6c84SAndroid Build Coastguard Worker {
198*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
199*cf5a6c84SAndroid Build Coastguard Worker tristate tri;
200*cf5a6c84SAndroid Build Coastguard Worker
201*cf5a6c84SAndroid Build Coastguard Worker /* any prompt visible? */
202*cf5a6c84SAndroid Build Coastguard Worker tri = no;
203*cf5a6c84SAndroid Build Coastguard Worker for_all_prompts(sym, prop) {
204*cf5a6c84SAndroid Build Coastguard Worker prop->visible.tri = expr_calc_value(prop->visible.expr);
205*cf5a6c84SAndroid Build Coastguard Worker tri = E_OR(tri, prop->visible.tri);
206*cf5a6c84SAndroid Build Coastguard Worker }
207*cf5a6c84SAndroid Build Coastguard Worker if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
208*cf5a6c84SAndroid Build Coastguard Worker tri = yes;
209*cf5a6c84SAndroid Build Coastguard Worker if (sym->visible != tri) {
210*cf5a6c84SAndroid Build Coastguard Worker sym->visible = tri;
211*cf5a6c84SAndroid Build Coastguard Worker sym_set_changed(sym);
212*cf5a6c84SAndroid Build Coastguard Worker }
213*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice_value(sym))
214*cf5a6c84SAndroid Build Coastguard Worker return;
215*cf5a6c84SAndroid Build Coastguard Worker tri = no;
216*cf5a6c84SAndroid Build Coastguard Worker if (sym->rev_dep.expr)
217*cf5a6c84SAndroid Build Coastguard Worker tri = expr_calc_value(sym->rev_dep.expr);
218*cf5a6c84SAndroid Build Coastguard Worker if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
219*cf5a6c84SAndroid Build Coastguard Worker tri = yes;
220*cf5a6c84SAndroid Build Coastguard Worker if (sym->rev_dep.tri != tri) {
221*cf5a6c84SAndroid Build Coastguard Worker sym->rev_dep.tri = tri;
222*cf5a6c84SAndroid Build Coastguard Worker sym_set_changed(sym);
223*cf5a6c84SAndroid Build Coastguard Worker }
224*cf5a6c84SAndroid Build Coastguard Worker }
225*cf5a6c84SAndroid Build Coastguard Worker
sym_calc_choice(struct symbol * sym)226*cf5a6c84SAndroid Build Coastguard Worker static struct symbol *sym_calc_choice(struct symbol *sym)
227*cf5a6c84SAndroid Build Coastguard Worker {
228*cf5a6c84SAndroid Build Coastguard Worker struct symbol *def_sym;
229*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
230*cf5a6c84SAndroid Build Coastguard Worker struct expr *e;
231*cf5a6c84SAndroid Build Coastguard Worker
232*cf5a6c84SAndroid Build Coastguard Worker /* is the user choice visible? */
233*cf5a6c84SAndroid Build Coastguard Worker def_sym = sym->def[S_DEF_USER].val;
234*cf5a6c84SAndroid Build Coastguard Worker if (def_sym) {
235*cf5a6c84SAndroid Build Coastguard Worker sym_calc_visibility(def_sym);
236*cf5a6c84SAndroid Build Coastguard Worker if (def_sym->visible != no)
237*cf5a6c84SAndroid Build Coastguard Worker return def_sym;
238*cf5a6c84SAndroid Build Coastguard Worker }
239*cf5a6c84SAndroid Build Coastguard Worker
240*cf5a6c84SAndroid Build Coastguard Worker /* any of the defaults visible? */
241*cf5a6c84SAndroid Build Coastguard Worker for_all_defaults(sym, prop) {
242*cf5a6c84SAndroid Build Coastguard Worker prop->visible.tri = expr_calc_value(prop->visible.expr);
243*cf5a6c84SAndroid Build Coastguard Worker if (prop->visible.tri == no)
244*cf5a6c84SAndroid Build Coastguard Worker continue;
245*cf5a6c84SAndroid Build Coastguard Worker def_sym = prop_get_symbol(prop);
246*cf5a6c84SAndroid Build Coastguard Worker sym_calc_visibility(def_sym);
247*cf5a6c84SAndroid Build Coastguard Worker if (def_sym->visible != no)
248*cf5a6c84SAndroid Build Coastguard Worker return def_sym;
249*cf5a6c84SAndroid Build Coastguard Worker }
250*cf5a6c84SAndroid Build Coastguard Worker
251*cf5a6c84SAndroid Build Coastguard Worker /* just get the first visible value */
252*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_choice_prop(sym);
253*cf5a6c84SAndroid Build Coastguard Worker for (e = prop->expr; e; e = e->left.expr) {
254*cf5a6c84SAndroid Build Coastguard Worker def_sym = e->right.sym;
255*cf5a6c84SAndroid Build Coastguard Worker sym_calc_visibility(def_sym);
256*cf5a6c84SAndroid Build Coastguard Worker if (def_sym->visible != no)
257*cf5a6c84SAndroid Build Coastguard Worker return def_sym;
258*cf5a6c84SAndroid Build Coastguard Worker }
259*cf5a6c84SAndroid Build Coastguard Worker
260*cf5a6c84SAndroid Build Coastguard Worker /* no choice? reset tristate value */
261*cf5a6c84SAndroid Build Coastguard Worker sym->curr.tri = no;
262*cf5a6c84SAndroid Build Coastguard Worker return NULL;
263*cf5a6c84SAndroid Build Coastguard Worker }
264*cf5a6c84SAndroid Build Coastguard Worker
sym_calc_value(struct symbol * sym)265*cf5a6c84SAndroid Build Coastguard Worker void sym_calc_value(struct symbol *sym)
266*cf5a6c84SAndroid Build Coastguard Worker {
267*cf5a6c84SAndroid Build Coastguard Worker struct symbol_value newval, oldval;
268*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
269*cf5a6c84SAndroid Build Coastguard Worker struct expr *e;
270*cf5a6c84SAndroid Build Coastguard Worker
271*cf5a6c84SAndroid Build Coastguard Worker if (!sym)
272*cf5a6c84SAndroid Build Coastguard Worker return;
273*cf5a6c84SAndroid Build Coastguard Worker
274*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & SYMBOL_VALID)
275*cf5a6c84SAndroid Build Coastguard Worker return;
276*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_VALID;
277*cf5a6c84SAndroid Build Coastguard Worker
278*cf5a6c84SAndroid Build Coastguard Worker oldval = sym->curr;
279*cf5a6c84SAndroid Build Coastguard Worker
280*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
281*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
282*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
283*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
284*cf5a6c84SAndroid Build Coastguard Worker newval = symbol_empty.curr;
285*cf5a6c84SAndroid Build Coastguard Worker break;
286*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
287*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
288*cf5a6c84SAndroid Build Coastguard Worker newval = symbol_no.curr;
289*cf5a6c84SAndroid Build Coastguard Worker break;
290*cf5a6c84SAndroid Build Coastguard Worker default:
291*cf5a6c84SAndroid Build Coastguard Worker sym->curr.val = sym->name;
292*cf5a6c84SAndroid Build Coastguard Worker sym->curr.tri = no;
293*cf5a6c84SAndroid Build Coastguard Worker return;
294*cf5a6c84SAndroid Build Coastguard Worker }
295*cf5a6c84SAndroid Build Coastguard Worker if (!sym_is_choice_value(sym))
296*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= ~SYMBOL_WRITE;
297*cf5a6c84SAndroid Build Coastguard Worker
298*cf5a6c84SAndroid Build Coastguard Worker sym_calc_visibility(sym);
299*cf5a6c84SAndroid Build Coastguard Worker
300*cf5a6c84SAndroid Build Coastguard Worker /* set default if recursively called */
301*cf5a6c84SAndroid Build Coastguard Worker sym->curr = newval;
302*cf5a6c84SAndroid Build Coastguard Worker
303*cf5a6c84SAndroid Build Coastguard Worker switch (sym_get_type(sym)) {
304*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
305*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
306*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice_value(sym) && sym->visible == yes) {
307*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_choice_prop(sym);
308*cf5a6c84SAndroid Build Coastguard Worker newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
309*cf5a6c84SAndroid Build Coastguard Worker } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
310*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_WRITE;
311*cf5a6c84SAndroid Build Coastguard Worker if (sym_has_value(sym))
312*cf5a6c84SAndroid Build Coastguard Worker newval.tri = sym->def[S_DEF_USER].tri;
313*cf5a6c84SAndroid Build Coastguard Worker else if (!sym_is_choice(sym)) {
314*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_default_prop(sym);
315*cf5a6c84SAndroid Build Coastguard Worker if (prop)
316*cf5a6c84SAndroid Build Coastguard Worker newval.tri = expr_calc_value(prop->expr);
317*cf5a6c84SAndroid Build Coastguard Worker }
318*cf5a6c84SAndroid Build Coastguard Worker newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
319*cf5a6c84SAndroid Build Coastguard Worker } else if (!sym_is_choice(sym)) {
320*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_default_prop(sym);
321*cf5a6c84SAndroid Build Coastguard Worker if (prop) {
322*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_WRITE;
323*cf5a6c84SAndroid Build Coastguard Worker newval.tri = expr_calc_value(prop->expr);
324*cf5a6c84SAndroid Build Coastguard Worker }
325*cf5a6c84SAndroid Build Coastguard Worker }
326*cf5a6c84SAndroid Build Coastguard Worker if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
327*cf5a6c84SAndroid Build Coastguard Worker newval.tri = yes;
328*cf5a6c84SAndroid Build Coastguard Worker break;
329*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
330*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
331*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
332*cf5a6c84SAndroid Build Coastguard Worker if (sym->visible != no) {
333*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_WRITE;
334*cf5a6c84SAndroid Build Coastguard Worker if (sym_has_value(sym)) {
335*cf5a6c84SAndroid Build Coastguard Worker newval.val = sym->def[S_DEF_USER].val;
336*cf5a6c84SAndroid Build Coastguard Worker break;
337*cf5a6c84SAndroid Build Coastguard Worker }
338*cf5a6c84SAndroid Build Coastguard Worker }
339*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_default_prop(sym);
340*cf5a6c84SAndroid Build Coastguard Worker if (prop) {
341*cf5a6c84SAndroid Build Coastguard Worker struct symbol *ds = prop_get_symbol(prop);
342*cf5a6c84SAndroid Build Coastguard Worker if (ds) {
343*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_WRITE;
344*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(ds);
345*cf5a6c84SAndroid Build Coastguard Worker newval.val = ds->curr.val;
346*cf5a6c84SAndroid Build Coastguard Worker }
347*cf5a6c84SAndroid Build Coastguard Worker }
348*cf5a6c84SAndroid Build Coastguard Worker break;
349*cf5a6c84SAndroid Build Coastguard Worker default:
350*cf5a6c84SAndroid Build Coastguard Worker ;
351*cf5a6c84SAndroid Build Coastguard Worker }
352*cf5a6c84SAndroid Build Coastguard Worker
353*cf5a6c84SAndroid Build Coastguard Worker sym->curr = newval;
354*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice(sym) && newval.tri == yes)
355*cf5a6c84SAndroid Build Coastguard Worker sym->curr.val = sym_calc_choice(sym);
356*cf5a6c84SAndroid Build Coastguard Worker sym_validate_range(sym);
357*cf5a6c84SAndroid Build Coastguard Worker
358*cf5a6c84SAndroid Build Coastguard Worker if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
359*cf5a6c84SAndroid Build Coastguard Worker sym_set_changed(sym);
360*cf5a6c84SAndroid Build Coastguard Worker if (modules_sym == sym) {
361*cf5a6c84SAndroid Build Coastguard Worker sym_set_all_changed();
362*cf5a6c84SAndroid Build Coastguard Worker modules_val = modules_sym->curr.tri;
363*cf5a6c84SAndroid Build Coastguard Worker }
364*cf5a6c84SAndroid Build Coastguard Worker }
365*cf5a6c84SAndroid Build Coastguard Worker
366*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice(sym)) {
367*cf5a6c84SAndroid Build Coastguard Worker int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
368*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_choice_prop(sym);
369*cf5a6c84SAndroid Build Coastguard Worker for (e = prop->expr; e; e = e->left.expr) {
370*cf5a6c84SAndroid Build Coastguard Worker e->right.sym->flags |= flags;
371*cf5a6c84SAndroid Build Coastguard Worker if (flags & SYMBOL_CHANGED)
372*cf5a6c84SAndroid Build Coastguard Worker sym_set_changed(e->right.sym);
373*cf5a6c84SAndroid Build Coastguard Worker }
374*cf5a6c84SAndroid Build Coastguard Worker }
375*cf5a6c84SAndroid Build Coastguard Worker }
376*cf5a6c84SAndroid Build Coastguard Worker
sym_clear_all_valid(void)377*cf5a6c84SAndroid Build Coastguard Worker void sym_clear_all_valid(void)
378*cf5a6c84SAndroid Build Coastguard Worker {
379*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
380*cf5a6c84SAndroid Build Coastguard Worker int i;
381*cf5a6c84SAndroid Build Coastguard Worker
382*cf5a6c84SAndroid Build Coastguard Worker for_all_symbols(i, sym)
383*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= ~SYMBOL_VALID;
384*cf5a6c84SAndroid Build Coastguard Worker sym_change_count++;
385*cf5a6c84SAndroid Build Coastguard Worker if (modules_sym)
386*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(modules_sym);
387*cf5a6c84SAndroid Build Coastguard Worker }
388*cf5a6c84SAndroid Build Coastguard Worker
sym_set_changed(struct symbol * sym)389*cf5a6c84SAndroid Build Coastguard Worker void sym_set_changed(struct symbol *sym)
390*cf5a6c84SAndroid Build Coastguard Worker {
391*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
392*cf5a6c84SAndroid Build Coastguard Worker
393*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_CHANGED;
394*cf5a6c84SAndroid Build Coastguard Worker for (prop = sym->prop; prop; prop = prop->next) {
395*cf5a6c84SAndroid Build Coastguard Worker if (prop->menu)
396*cf5a6c84SAndroid Build Coastguard Worker prop->menu->flags |= MENU_CHANGED;
397*cf5a6c84SAndroid Build Coastguard Worker }
398*cf5a6c84SAndroid Build Coastguard Worker }
399*cf5a6c84SAndroid Build Coastguard Worker
sym_set_all_changed(void)400*cf5a6c84SAndroid Build Coastguard Worker void sym_set_all_changed(void)
401*cf5a6c84SAndroid Build Coastguard Worker {
402*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
403*cf5a6c84SAndroid Build Coastguard Worker int i;
404*cf5a6c84SAndroid Build Coastguard Worker
405*cf5a6c84SAndroid Build Coastguard Worker for_all_symbols(i, sym)
406*cf5a6c84SAndroid Build Coastguard Worker sym_set_changed(sym);
407*cf5a6c84SAndroid Build Coastguard Worker }
408*cf5a6c84SAndroid Build Coastguard Worker
sym_tristate_within_range(struct symbol * sym,tristate val)409*cf5a6c84SAndroid Build Coastguard Worker bool sym_tristate_within_range(struct symbol *sym, tristate val)
410*cf5a6c84SAndroid Build Coastguard Worker {
411*cf5a6c84SAndroid Build Coastguard Worker int type = sym_get_type(sym);
412*cf5a6c84SAndroid Build Coastguard Worker
413*cf5a6c84SAndroid Build Coastguard Worker if (sym->visible == no)
414*cf5a6c84SAndroid Build Coastguard Worker return false;
415*cf5a6c84SAndroid Build Coastguard Worker
416*cf5a6c84SAndroid Build Coastguard Worker if (type != S_BOOLEAN && type != S_TRISTATE)
417*cf5a6c84SAndroid Build Coastguard Worker return false;
418*cf5a6c84SAndroid Build Coastguard Worker
419*cf5a6c84SAndroid Build Coastguard Worker if (type == S_BOOLEAN && val == mod)
420*cf5a6c84SAndroid Build Coastguard Worker return false;
421*cf5a6c84SAndroid Build Coastguard Worker if (sym->visible <= sym->rev_dep.tri)
422*cf5a6c84SAndroid Build Coastguard Worker return false;
423*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice_value(sym) && sym->visible == yes)
424*cf5a6c84SAndroid Build Coastguard Worker return val == yes;
425*cf5a6c84SAndroid Build Coastguard Worker return val >= sym->rev_dep.tri && val <= sym->visible;
426*cf5a6c84SAndroid Build Coastguard Worker }
427*cf5a6c84SAndroid Build Coastguard Worker
sym_set_tristate_value(struct symbol * sym,tristate val)428*cf5a6c84SAndroid Build Coastguard Worker bool sym_set_tristate_value(struct symbol *sym, tristate val)
429*cf5a6c84SAndroid Build Coastguard Worker {
430*cf5a6c84SAndroid Build Coastguard Worker tristate oldval = sym_get_tristate_value(sym);
431*cf5a6c84SAndroid Build Coastguard Worker
432*cf5a6c84SAndroid Build Coastguard Worker if (oldval != val && !sym_tristate_within_range(sym, val))
433*cf5a6c84SAndroid Build Coastguard Worker return false;
434*cf5a6c84SAndroid Build Coastguard Worker
435*cf5a6c84SAndroid Build Coastguard Worker if (!(sym->flags & SYMBOL_DEF_USER)) {
436*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_DEF_USER;
437*cf5a6c84SAndroid Build Coastguard Worker sym_set_changed(sym);
438*cf5a6c84SAndroid Build Coastguard Worker }
439*cf5a6c84SAndroid Build Coastguard Worker /*
440*cf5a6c84SAndroid Build Coastguard Worker * setting a choice value also resets the new flag of the choice
441*cf5a6c84SAndroid Build Coastguard Worker * symbol and all other choice values.
442*cf5a6c84SAndroid Build Coastguard Worker */
443*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice_value(sym) && val == yes) {
444*cf5a6c84SAndroid Build Coastguard Worker struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
445*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
446*cf5a6c84SAndroid Build Coastguard Worker struct expr *e;
447*cf5a6c84SAndroid Build Coastguard Worker
448*cf5a6c84SAndroid Build Coastguard Worker cs->def[S_DEF_USER].val = sym;
449*cf5a6c84SAndroid Build Coastguard Worker cs->flags |= SYMBOL_DEF_USER;
450*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_choice_prop(cs);
451*cf5a6c84SAndroid Build Coastguard Worker for (e = prop->expr; e; e = e->left.expr) {
452*cf5a6c84SAndroid Build Coastguard Worker if (e->right.sym->visible != no)
453*cf5a6c84SAndroid Build Coastguard Worker e->right.sym->flags |= SYMBOL_DEF_USER;
454*cf5a6c84SAndroid Build Coastguard Worker }
455*cf5a6c84SAndroid Build Coastguard Worker }
456*cf5a6c84SAndroid Build Coastguard Worker
457*cf5a6c84SAndroid Build Coastguard Worker sym->def[S_DEF_USER].tri = val;
458*cf5a6c84SAndroid Build Coastguard Worker if (oldval != val)
459*cf5a6c84SAndroid Build Coastguard Worker sym_clear_all_valid();
460*cf5a6c84SAndroid Build Coastguard Worker
461*cf5a6c84SAndroid Build Coastguard Worker return true;
462*cf5a6c84SAndroid Build Coastguard Worker }
463*cf5a6c84SAndroid Build Coastguard Worker
sym_toggle_tristate_value(struct symbol * sym)464*cf5a6c84SAndroid Build Coastguard Worker tristate sym_toggle_tristate_value(struct symbol *sym)
465*cf5a6c84SAndroid Build Coastguard Worker {
466*cf5a6c84SAndroid Build Coastguard Worker tristate oldval, newval;
467*cf5a6c84SAndroid Build Coastguard Worker
468*cf5a6c84SAndroid Build Coastguard Worker oldval = newval = sym_get_tristate_value(sym);
469*cf5a6c84SAndroid Build Coastguard Worker do {
470*cf5a6c84SAndroid Build Coastguard Worker switch (newval) {
471*cf5a6c84SAndroid Build Coastguard Worker case no:
472*cf5a6c84SAndroid Build Coastguard Worker newval = mod;
473*cf5a6c84SAndroid Build Coastguard Worker break;
474*cf5a6c84SAndroid Build Coastguard Worker case mod:
475*cf5a6c84SAndroid Build Coastguard Worker newval = yes;
476*cf5a6c84SAndroid Build Coastguard Worker break;
477*cf5a6c84SAndroid Build Coastguard Worker case yes:
478*cf5a6c84SAndroid Build Coastguard Worker newval = no;
479*cf5a6c84SAndroid Build Coastguard Worker break;
480*cf5a6c84SAndroid Build Coastguard Worker }
481*cf5a6c84SAndroid Build Coastguard Worker if (sym_set_tristate_value(sym, newval))
482*cf5a6c84SAndroid Build Coastguard Worker break;
483*cf5a6c84SAndroid Build Coastguard Worker } while (oldval != newval);
484*cf5a6c84SAndroid Build Coastguard Worker return newval;
485*cf5a6c84SAndroid Build Coastguard Worker }
486*cf5a6c84SAndroid Build Coastguard Worker
sym_string_valid(struct symbol * sym,const char * str)487*cf5a6c84SAndroid Build Coastguard Worker bool sym_string_valid(struct symbol *sym, const char *str)
488*cf5a6c84SAndroid Build Coastguard Worker {
489*cf5a6c84SAndroid Build Coastguard Worker signed char ch;
490*cf5a6c84SAndroid Build Coastguard Worker
491*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
492*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
493*cf5a6c84SAndroid Build Coastguard Worker return true;
494*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
495*cf5a6c84SAndroid Build Coastguard Worker ch = *str++;
496*cf5a6c84SAndroid Build Coastguard Worker if (ch == '-')
497*cf5a6c84SAndroid Build Coastguard Worker ch = *str++;
498*cf5a6c84SAndroid Build Coastguard Worker if (!isdigit(ch))
499*cf5a6c84SAndroid Build Coastguard Worker return false;
500*cf5a6c84SAndroid Build Coastguard Worker if (ch == '0' && *str != 0)
501*cf5a6c84SAndroid Build Coastguard Worker return false;
502*cf5a6c84SAndroid Build Coastguard Worker while ((ch = *str++)) {
503*cf5a6c84SAndroid Build Coastguard Worker if (!isdigit(ch))
504*cf5a6c84SAndroid Build Coastguard Worker return false;
505*cf5a6c84SAndroid Build Coastguard Worker }
506*cf5a6c84SAndroid Build Coastguard Worker return true;
507*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
508*cf5a6c84SAndroid Build Coastguard Worker if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
509*cf5a6c84SAndroid Build Coastguard Worker str += 2;
510*cf5a6c84SAndroid Build Coastguard Worker ch = *str++;
511*cf5a6c84SAndroid Build Coastguard Worker do {
512*cf5a6c84SAndroid Build Coastguard Worker if (!isxdigit(ch))
513*cf5a6c84SAndroid Build Coastguard Worker return false;
514*cf5a6c84SAndroid Build Coastguard Worker } while ((ch = *str++));
515*cf5a6c84SAndroid Build Coastguard Worker return true;
516*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
517*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
518*cf5a6c84SAndroid Build Coastguard Worker switch (str[0]) {
519*cf5a6c84SAndroid Build Coastguard Worker case 'y': case 'Y':
520*cf5a6c84SAndroid Build Coastguard Worker case 'm': case 'M':
521*cf5a6c84SAndroid Build Coastguard Worker case 'n': case 'N':
522*cf5a6c84SAndroid Build Coastguard Worker return true;
523*cf5a6c84SAndroid Build Coastguard Worker }
524*cf5a6c84SAndroid Build Coastguard Worker return false;
525*cf5a6c84SAndroid Build Coastguard Worker default:
526*cf5a6c84SAndroid Build Coastguard Worker return false;
527*cf5a6c84SAndroid Build Coastguard Worker }
528*cf5a6c84SAndroid Build Coastguard Worker }
529*cf5a6c84SAndroid Build Coastguard Worker
sym_string_within_range(struct symbol * sym,const char * str)530*cf5a6c84SAndroid Build Coastguard Worker bool sym_string_within_range(struct symbol *sym, const char *str)
531*cf5a6c84SAndroid Build Coastguard Worker {
532*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
533*cf5a6c84SAndroid Build Coastguard Worker int val;
534*cf5a6c84SAndroid Build Coastguard Worker
535*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
536*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
537*cf5a6c84SAndroid Build Coastguard Worker return sym_string_valid(sym, str);
538*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
539*cf5a6c84SAndroid Build Coastguard Worker if (!sym_string_valid(sym, str))
540*cf5a6c84SAndroid Build Coastguard Worker return false;
541*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_range_prop(sym);
542*cf5a6c84SAndroid Build Coastguard Worker if (!prop)
543*cf5a6c84SAndroid Build Coastguard Worker return true;
544*cf5a6c84SAndroid Build Coastguard Worker val = strtol(str, NULL, 10);
545*cf5a6c84SAndroid Build Coastguard Worker return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
546*cf5a6c84SAndroid Build Coastguard Worker val <= sym_get_range_val(prop->expr->right.sym, 10);
547*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
548*cf5a6c84SAndroid Build Coastguard Worker if (!sym_string_valid(sym, str))
549*cf5a6c84SAndroid Build Coastguard Worker return false;
550*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_range_prop(sym);
551*cf5a6c84SAndroid Build Coastguard Worker if (!prop)
552*cf5a6c84SAndroid Build Coastguard Worker return true;
553*cf5a6c84SAndroid Build Coastguard Worker val = strtol(str, NULL, 16);
554*cf5a6c84SAndroid Build Coastguard Worker return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
555*cf5a6c84SAndroid Build Coastguard Worker val <= sym_get_range_val(prop->expr->right.sym, 16);
556*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
557*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
558*cf5a6c84SAndroid Build Coastguard Worker switch (str[0]) {
559*cf5a6c84SAndroid Build Coastguard Worker case 'y': case 'Y':
560*cf5a6c84SAndroid Build Coastguard Worker return sym_tristate_within_range(sym, yes);
561*cf5a6c84SAndroid Build Coastguard Worker case 'm': case 'M':
562*cf5a6c84SAndroid Build Coastguard Worker return sym_tristate_within_range(sym, mod);
563*cf5a6c84SAndroid Build Coastguard Worker case 'n': case 'N':
564*cf5a6c84SAndroid Build Coastguard Worker return sym_tristate_within_range(sym, no);
565*cf5a6c84SAndroid Build Coastguard Worker }
566*cf5a6c84SAndroid Build Coastguard Worker return false;
567*cf5a6c84SAndroid Build Coastguard Worker default:
568*cf5a6c84SAndroid Build Coastguard Worker return false;
569*cf5a6c84SAndroid Build Coastguard Worker }
570*cf5a6c84SAndroid Build Coastguard Worker }
571*cf5a6c84SAndroid Build Coastguard Worker
sym_set_string_value(struct symbol * sym,const char * newval)572*cf5a6c84SAndroid Build Coastguard Worker bool sym_set_string_value(struct symbol *sym, const char *newval)
573*cf5a6c84SAndroid Build Coastguard Worker {
574*cf5a6c84SAndroid Build Coastguard Worker const char *oldval;
575*cf5a6c84SAndroid Build Coastguard Worker char *val;
576*cf5a6c84SAndroid Build Coastguard Worker int size;
577*cf5a6c84SAndroid Build Coastguard Worker
578*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
579*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
580*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
581*cf5a6c84SAndroid Build Coastguard Worker switch (newval[0]) {
582*cf5a6c84SAndroid Build Coastguard Worker case 'y': case 'Y':
583*cf5a6c84SAndroid Build Coastguard Worker return sym_set_tristate_value(sym, yes);
584*cf5a6c84SAndroid Build Coastguard Worker case 'm': case 'M':
585*cf5a6c84SAndroid Build Coastguard Worker return sym_set_tristate_value(sym, mod);
586*cf5a6c84SAndroid Build Coastguard Worker case 'n': case 'N':
587*cf5a6c84SAndroid Build Coastguard Worker return sym_set_tristate_value(sym, no);
588*cf5a6c84SAndroid Build Coastguard Worker }
589*cf5a6c84SAndroid Build Coastguard Worker return false;
590*cf5a6c84SAndroid Build Coastguard Worker default:
591*cf5a6c84SAndroid Build Coastguard Worker ;
592*cf5a6c84SAndroid Build Coastguard Worker }
593*cf5a6c84SAndroid Build Coastguard Worker
594*cf5a6c84SAndroid Build Coastguard Worker if (!sym_string_within_range(sym, newval))
595*cf5a6c84SAndroid Build Coastguard Worker return false;
596*cf5a6c84SAndroid Build Coastguard Worker
597*cf5a6c84SAndroid Build Coastguard Worker if (!(sym->flags & SYMBOL_DEF_USER)) {
598*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_DEF_USER;
599*cf5a6c84SAndroid Build Coastguard Worker sym_set_changed(sym);
600*cf5a6c84SAndroid Build Coastguard Worker }
601*cf5a6c84SAndroid Build Coastguard Worker
602*cf5a6c84SAndroid Build Coastguard Worker oldval = sym->def[S_DEF_USER].val;
603*cf5a6c84SAndroid Build Coastguard Worker size = strlen(newval) + 1;
604*cf5a6c84SAndroid Build Coastguard Worker if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
605*cf5a6c84SAndroid Build Coastguard Worker size += 2;
606*cf5a6c84SAndroid Build Coastguard Worker sym->def[S_DEF_USER].val = val = malloc(size);
607*cf5a6c84SAndroid Build Coastguard Worker *val++ = '0';
608*cf5a6c84SAndroid Build Coastguard Worker *val++ = 'x';
609*cf5a6c84SAndroid Build Coastguard Worker } else if (!oldval || strcmp(oldval, newval))
610*cf5a6c84SAndroid Build Coastguard Worker sym->def[S_DEF_USER].val = val = malloc(size);
611*cf5a6c84SAndroid Build Coastguard Worker else
612*cf5a6c84SAndroid Build Coastguard Worker return true;
613*cf5a6c84SAndroid Build Coastguard Worker
614*cf5a6c84SAndroid Build Coastguard Worker strcpy(val, newval);
615*cf5a6c84SAndroid Build Coastguard Worker free((void *)oldval);
616*cf5a6c84SAndroid Build Coastguard Worker sym_clear_all_valid();
617*cf5a6c84SAndroid Build Coastguard Worker
618*cf5a6c84SAndroid Build Coastguard Worker return true;
619*cf5a6c84SAndroid Build Coastguard Worker }
620*cf5a6c84SAndroid Build Coastguard Worker
sym_get_string_value(struct symbol * sym)621*cf5a6c84SAndroid Build Coastguard Worker const char *sym_get_string_value(struct symbol *sym)
622*cf5a6c84SAndroid Build Coastguard Worker {
623*cf5a6c84SAndroid Build Coastguard Worker tristate val;
624*cf5a6c84SAndroid Build Coastguard Worker
625*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
626*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
627*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
628*cf5a6c84SAndroid Build Coastguard Worker val = sym_get_tristate_value(sym);
629*cf5a6c84SAndroid Build Coastguard Worker switch (val) {
630*cf5a6c84SAndroid Build Coastguard Worker case no:
631*cf5a6c84SAndroid Build Coastguard Worker return "n";
632*cf5a6c84SAndroid Build Coastguard Worker case mod:
633*cf5a6c84SAndroid Build Coastguard Worker return "m";
634*cf5a6c84SAndroid Build Coastguard Worker case yes:
635*cf5a6c84SAndroid Build Coastguard Worker return "y";
636*cf5a6c84SAndroid Build Coastguard Worker }
637*cf5a6c84SAndroid Build Coastguard Worker break;
638*cf5a6c84SAndroid Build Coastguard Worker default:
639*cf5a6c84SAndroid Build Coastguard Worker ;
640*cf5a6c84SAndroid Build Coastguard Worker }
641*cf5a6c84SAndroid Build Coastguard Worker return (const char *)sym->curr.val;
642*cf5a6c84SAndroid Build Coastguard Worker }
643*cf5a6c84SAndroid Build Coastguard Worker
sym_is_changable(struct symbol * sym)644*cf5a6c84SAndroid Build Coastguard Worker bool sym_is_changable(struct symbol *sym)
645*cf5a6c84SAndroid Build Coastguard Worker {
646*cf5a6c84SAndroid Build Coastguard Worker return sym->visible > sym->rev_dep.tri;
647*cf5a6c84SAndroid Build Coastguard Worker }
648*cf5a6c84SAndroid Build Coastguard Worker
sym_lookup(const char * name,int isconst)649*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym_lookup(const char *name, int isconst)
650*cf5a6c84SAndroid Build Coastguard Worker {
651*cf5a6c84SAndroid Build Coastguard Worker struct symbol *symbol;
652*cf5a6c84SAndroid Build Coastguard Worker const char *ptr;
653*cf5a6c84SAndroid Build Coastguard Worker char *new_name;
654*cf5a6c84SAndroid Build Coastguard Worker int hash = 0;
655*cf5a6c84SAndroid Build Coastguard Worker
656*cf5a6c84SAndroid Build Coastguard Worker if (name) {
657*cf5a6c84SAndroid Build Coastguard Worker if (name[0] && !name[1]) {
658*cf5a6c84SAndroid Build Coastguard Worker switch (name[0]) {
659*cf5a6c84SAndroid Build Coastguard Worker case 'y': return &symbol_yes;
660*cf5a6c84SAndroid Build Coastguard Worker case 'm': return &symbol_mod;
661*cf5a6c84SAndroid Build Coastguard Worker case 'n': return &symbol_no;
662*cf5a6c84SAndroid Build Coastguard Worker }
663*cf5a6c84SAndroid Build Coastguard Worker }
664*cf5a6c84SAndroid Build Coastguard Worker for (ptr = name; *ptr; ptr++)
665*cf5a6c84SAndroid Build Coastguard Worker hash += *ptr;
666*cf5a6c84SAndroid Build Coastguard Worker hash &= 0xff;
667*cf5a6c84SAndroid Build Coastguard Worker
668*cf5a6c84SAndroid Build Coastguard Worker for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
669*cf5a6c84SAndroid Build Coastguard Worker if (!strcmp(symbol->name, name)) {
670*cf5a6c84SAndroid Build Coastguard Worker if ((isconst && symbol->flags & SYMBOL_CONST) ||
671*cf5a6c84SAndroid Build Coastguard Worker (!isconst && !(symbol->flags & SYMBOL_CONST)))
672*cf5a6c84SAndroid Build Coastguard Worker return symbol;
673*cf5a6c84SAndroid Build Coastguard Worker }
674*cf5a6c84SAndroid Build Coastguard Worker }
675*cf5a6c84SAndroid Build Coastguard Worker new_name = strdup(name);
676*cf5a6c84SAndroid Build Coastguard Worker } else {
677*cf5a6c84SAndroid Build Coastguard Worker new_name = NULL;
678*cf5a6c84SAndroid Build Coastguard Worker hash = 256;
679*cf5a6c84SAndroid Build Coastguard Worker }
680*cf5a6c84SAndroid Build Coastguard Worker
681*cf5a6c84SAndroid Build Coastguard Worker symbol = malloc(sizeof(*symbol));
682*cf5a6c84SAndroid Build Coastguard Worker memset(symbol, 0, sizeof(*symbol));
683*cf5a6c84SAndroid Build Coastguard Worker symbol->name = new_name;
684*cf5a6c84SAndroid Build Coastguard Worker symbol->type = S_UNKNOWN;
685*cf5a6c84SAndroid Build Coastguard Worker if (isconst)
686*cf5a6c84SAndroid Build Coastguard Worker symbol->flags |= SYMBOL_CONST;
687*cf5a6c84SAndroid Build Coastguard Worker
688*cf5a6c84SAndroid Build Coastguard Worker symbol->next = symbol_hash[hash];
689*cf5a6c84SAndroid Build Coastguard Worker symbol_hash[hash] = symbol;
690*cf5a6c84SAndroid Build Coastguard Worker
691*cf5a6c84SAndroid Build Coastguard Worker return symbol;
692*cf5a6c84SAndroid Build Coastguard Worker }
693*cf5a6c84SAndroid Build Coastguard Worker
sym_find(const char * name)694*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym_find(const char *name)
695*cf5a6c84SAndroid Build Coastguard Worker {
696*cf5a6c84SAndroid Build Coastguard Worker struct symbol *symbol = NULL;
697*cf5a6c84SAndroid Build Coastguard Worker const char *ptr;
698*cf5a6c84SAndroid Build Coastguard Worker int hash = 0;
699*cf5a6c84SAndroid Build Coastguard Worker
700*cf5a6c84SAndroid Build Coastguard Worker if (!name)
701*cf5a6c84SAndroid Build Coastguard Worker return NULL;
702*cf5a6c84SAndroid Build Coastguard Worker
703*cf5a6c84SAndroid Build Coastguard Worker if (name[0] && !name[1]) {
704*cf5a6c84SAndroid Build Coastguard Worker switch (name[0]) {
705*cf5a6c84SAndroid Build Coastguard Worker case 'y': return &symbol_yes;
706*cf5a6c84SAndroid Build Coastguard Worker case 'm': return &symbol_mod;
707*cf5a6c84SAndroid Build Coastguard Worker case 'n': return &symbol_no;
708*cf5a6c84SAndroid Build Coastguard Worker }
709*cf5a6c84SAndroid Build Coastguard Worker }
710*cf5a6c84SAndroid Build Coastguard Worker for (ptr = name; *ptr; ptr++)
711*cf5a6c84SAndroid Build Coastguard Worker hash += *ptr;
712*cf5a6c84SAndroid Build Coastguard Worker hash &= 0xff;
713*cf5a6c84SAndroid Build Coastguard Worker
714*cf5a6c84SAndroid Build Coastguard Worker for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
715*cf5a6c84SAndroid Build Coastguard Worker if (!strcmp(symbol->name, name) &&
716*cf5a6c84SAndroid Build Coastguard Worker !(symbol->flags & SYMBOL_CONST))
717*cf5a6c84SAndroid Build Coastguard Worker break;
718*cf5a6c84SAndroid Build Coastguard Worker }
719*cf5a6c84SAndroid Build Coastguard Worker
720*cf5a6c84SAndroid Build Coastguard Worker return symbol;
721*cf5a6c84SAndroid Build Coastguard Worker }
722*cf5a6c84SAndroid Build Coastguard Worker
sym_re_search(const char * pattern)723*cf5a6c84SAndroid Build Coastguard Worker struct symbol **sym_re_search(const char *pattern)
724*cf5a6c84SAndroid Build Coastguard Worker {
725*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym, **sym_arr = NULL;
726*cf5a6c84SAndroid Build Coastguard Worker int i, cnt, size;
727*cf5a6c84SAndroid Build Coastguard Worker regex_t re;
728*cf5a6c84SAndroid Build Coastguard Worker
729*cf5a6c84SAndroid Build Coastguard Worker cnt = size = 0;
730*cf5a6c84SAndroid Build Coastguard Worker /* Skip if empty */
731*cf5a6c84SAndroid Build Coastguard Worker if (strlen(pattern) == 0)
732*cf5a6c84SAndroid Build Coastguard Worker return NULL;
733*cf5a6c84SAndroid Build Coastguard Worker if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
734*cf5a6c84SAndroid Build Coastguard Worker return NULL;
735*cf5a6c84SAndroid Build Coastguard Worker
736*cf5a6c84SAndroid Build Coastguard Worker for_all_symbols(i, sym) {
737*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & SYMBOL_CONST || !sym->name)
738*cf5a6c84SAndroid Build Coastguard Worker continue;
739*cf5a6c84SAndroid Build Coastguard Worker if (regexec(&re, sym->name, 0, NULL, 0))
740*cf5a6c84SAndroid Build Coastguard Worker continue;
741*cf5a6c84SAndroid Build Coastguard Worker if (cnt + 1 >= size) {
742*cf5a6c84SAndroid Build Coastguard Worker void *tmp = sym_arr;
743*cf5a6c84SAndroid Build Coastguard Worker size += 16;
744*cf5a6c84SAndroid Build Coastguard Worker sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
745*cf5a6c84SAndroid Build Coastguard Worker if (!sym_arr) {
746*cf5a6c84SAndroid Build Coastguard Worker free(tmp);
747*cf5a6c84SAndroid Build Coastguard Worker return NULL;
748*cf5a6c84SAndroid Build Coastguard Worker }
749*cf5a6c84SAndroid Build Coastguard Worker }
750*cf5a6c84SAndroid Build Coastguard Worker sym_arr[cnt++] = sym;
751*cf5a6c84SAndroid Build Coastguard Worker }
752*cf5a6c84SAndroid Build Coastguard Worker if (sym_arr)
753*cf5a6c84SAndroid Build Coastguard Worker sym_arr[cnt] = NULL;
754*cf5a6c84SAndroid Build Coastguard Worker regfree(&re);
755*cf5a6c84SAndroid Build Coastguard Worker
756*cf5a6c84SAndroid Build Coastguard Worker return sym_arr;
757*cf5a6c84SAndroid Build Coastguard Worker }
758*cf5a6c84SAndroid Build Coastguard Worker
759*cf5a6c84SAndroid Build Coastguard Worker
760*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym_check_deps(struct symbol *sym);
761*cf5a6c84SAndroid Build Coastguard Worker
sym_check_expr_deps(struct expr * e)762*cf5a6c84SAndroid Build Coastguard Worker static struct symbol *sym_check_expr_deps(struct expr *e)
763*cf5a6c84SAndroid Build Coastguard Worker {
764*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
765*cf5a6c84SAndroid Build Coastguard Worker
766*cf5a6c84SAndroid Build Coastguard Worker if (!e)
767*cf5a6c84SAndroid Build Coastguard Worker return NULL;
768*cf5a6c84SAndroid Build Coastguard Worker switch (e->type) {
769*cf5a6c84SAndroid Build Coastguard Worker case E_OR:
770*cf5a6c84SAndroid Build Coastguard Worker case E_AND:
771*cf5a6c84SAndroid Build Coastguard Worker sym = sym_check_expr_deps(e->left.expr);
772*cf5a6c84SAndroid Build Coastguard Worker if (sym)
773*cf5a6c84SAndroid Build Coastguard Worker return sym;
774*cf5a6c84SAndroid Build Coastguard Worker return sym_check_expr_deps(e->right.expr);
775*cf5a6c84SAndroid Build Coastguard Worker case E_NOT:
776*cf5a6c84SAndroid Build Coastguard Worker return sym_check_expr_deps(e->left.expr);
777*cf5a6c84SAndroid Build Coastguard Worker case E_EQUAL:
778*cf5a6c84SAndroid Build Coastguard Worker case E_UNEQUAL:
779*cf5a6c84SAndroid Build Coastguard Worker sym = sym_check_deps(e->left.sym);
780*cf5a6c84SAndroid Build Coastguard Worker if (sym)
781*cf5a6c84SAndroid Build Coastguard Worker return sym;
782*cf5a6c84SAndroid Build Coastguard Worker return sym_check_deps(e->right.sym);
783*cf5a6c84SAndroid Build Coastguard Worker case E_SYMBOL:
784*cf5a6c84SAndroid Build Coastguard Worker return sym_check_deps(e->left.sym);
785*cf5a6c84SAndroid Build Coastguard Worker default:
786*cf5a6c84SAndroid Build Coastguard Worker break;
787*cf5a6c84SAndroid Build Coastguard Worker }
788*cf5a6c84SAndroid Build Coastguard Worker printf("Oops! How to check %d?\n", e->type);
789*cf5a6c84SAndroid Build Coastguard Worker return NULL;
790*cf5a6c84SAndroid Build Coastguard Worker }
791*cf5a6c84SAndroid Build Coastguard Worker
sym_check_deps(struct symbol * sym)792*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym_check_deps(struct symbol *sym)
793*cf5a6c84SAndroid Build Coastguard Worker {
794*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym2;
795*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
796*cf5a6c84SAndroid Build Coastguard Worker
797*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & SYMBOL_CHECK) {
798*cf5a6c84SAndroid Build Coastguard Worker printf("Warning! Found recursive dependency: %s", sym->name);
799*cf5a6c84SAndroid Build Coastguard Worker return sym;
800*cf5a6c84SAndroid Build Coastguard Worker }
801*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & SYMBOL_CHECKED)
802*cf5a6c84SAndroid Build Coastguard Worker return NULL;
803*cf5a6c84SAndroid Build Coastguard Worker
804*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
805*cf5a6c84SAndroid Build Coastguard Worker sym2 = sym_check_expr_deps(sym->rev_dep.expr);
806*cf5a6c84SAndroid Build Coastguard Worker if (sym2)
807*cf5a6c84SAndroid Build Coastguard Worker goto out;
808*cf5a6c84SAndroid Build Coastguard Worker
809*cf5a6c84SAndroid Build Coastguard Worker for (prop = sym->prop; prop; prop = prop->next) {
810*cf5a6c84SAndroid Build Coastguard Worker if (prop->type == P_CHOICE || prop->type == P_SELECT)
811*cf5a6c84SAndroid Build Coastguard Worker continue;
812*cf5a6c84SAndroid Build Coastguard Worker sym2 = sym_check_expr_deps(prop->visible.expr);
813*cf5a6c84SAndroid Build Coastguard Worker if (sym2)
814*cf5a6c84SAndroid Build Coastguard Worker goto out;
815*cf5a6c84SAndroid Build Coastguard Worker if (prop->type != P_DEFAULT || sym_is_choice(sym))
816*cf5a6c84SAndroid Build Coastguard Worker continue;
817*cf5a6c84SAndroid Build Coastguard Worker sym2 = sym_check_expr_deps(prop->expr);
818*cf5a6c84SAndroid Build Coastguard Worker if (sym2)
819*cf5a6c84SAndroid Build Coastguard Worker goto out;
820*cf5a6c84SAndroid Build Coastguard Worker }
821*cf5a6c84SAndroid Build Coastguard Worker out:
822*cf5a6c84SAndroid Build Coastguard Worker if (sym2) {
823*cf5a6c84SAndroid Build Coastguard Worker printf(" %s", sym->name);
824*cf5a6c84SAndroid Build Coastguard Worker if (sym2 == sym) {
825*cf5a6c84SAndroid Build Coastguard Worker printf("\n");
826*cf5a6c84SAndroid Build Coastguard Worker sym2 = NULL;
827*cf5a6c84SAndroid Build Coastguard Worker }
828*cf5a6c84SAndroid Build Coastguard Worker }
829*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= ~SYMBOL_CHECK;
830*cf5a6c84SAndroid Build Coastguard Worker return sym2;
831*cf5a6c84SAndroid Build Coastguard Worker }
832*cf5a6c84SAndroid Build Coastguard Worker
prop_alloc(enum prop_type type,struct symbol * sym)833*cf5a6c84SAndroid Build Coastguard Worker struct property *prop_alloc(enum prop_type type, struct symbol *sym)
834*cf5a6c84SAndroid Build Coastguard Worker {
835*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
836*cf5a6c84SAndroid Build Coastguard Worker struct property **propp;
837*cf5a6c84SAndroid Build Coastguard Worker
838*cf5a6c84SAndroid Build Coastguard Worker prop = malloc(sizeof(*prop));
839*cf5a6c84SAndroid Build Coastguard Worker memset(prop, 0, sizeof(*prop));
840*cf5a6c84SAndroid Build Coastguard Worker prop->type = type;
841*cf5a6c84SAndroid Build Coastguard Worker prop->sym = sym;
842*cf5a6c84SAndroid Build Coastguard Worker prop->file = current_file;
843*cf5a6c84SAndroid Build Coastguard Worker prop->lineno = zconf_lineno();
844*cf5a6c84SAndroid Build Coastguard Worker
845*cf5a6c84SAndroid Build Coastguard Worker /* append property to the prop list of symbol */
846*cf5a6c84SAndroid Build Coastguard Worker if (sym) {
847*cf5a6c84SAndroid Build Coastguard Worker for (propp = &sym->prop; *propp; propp = &(*propp)->next)
848*cf5a6c84SAndroid Build Coastguard Worker ;
849*cf5a6c84SAndroid Build Coastguard Worker *propp = prop;
850*cf5a6c84SAndroid Build Coastguard Worker }
851*cf5a6c84SAndroid Build Coastguard Worker
852*cf5a6c84SAndroid Build Coastguard Worker return prop;
853*cf5a6c84SAndroid Build Coastguard Worker }
854*cf5a6c84SAndroid Build Coastguard Worker
prop_get_symbol(struct property * prop)855*cf5a6c84SAndroid Build Coastguard Worker struct symbol *prop_get_symbol(struct property *prop)
856*cf5a6c84SAndroid Build Coastguard Worker {
857*cf5a6c84SAndroid Build Coastguard Worker if (prop->expr && (prop->expr->type == E_SYMBOL ||
858*cf5a6c84SAndroid Build Coastguard Worker prop->expr->type == E_CHOICE))
859*cf5a6c84SAndroid Build Coastguard Worker return prop->expr->left.sym;
860*cf5a6c84SAndroid Build Coastguard Worker return NULL;
861*cf5a6c84SAndroid Build Coastguard Worker }
862*cf5a6c84SAndroid Build Coastguard Worker
prop_get_type_name(enum prop_type type)863*cf5a6c84SAndroid Build Coastguard Worker const char *prop_get_type_name(enum prop_type type)
864*cf5a6c84SAndroid Build Coastguard Worker {
865*cf5a6c84SAndroid Build Coastguard Worker switch (type) {
866*cf5a6c84SAndroid Build Coastguard Worker case P_PROMPT:
867*cf5a6c84SAndroid Build Coastguard Worker return "prompt";
868*cf5a6c84SAndroid Build Coastguard Worker case P_COMMENT:
869*cf5a6c84SAndroid Build Coastguard Worker return "comment";
870*cf5a6c84SAndroid Build Coastguard Worker case P_MENU:
871*cf5a6c84SAndroid Build Coastguard Worker return "menu";
872*cf5a6c84SAndroid Build Coastguard Worker case P_DEFAULT:
873*cf5a6c84SAndroid Build Coastguard Worker return "default";
874*cf5a6c84SAndroid Build Coastguard Worker case P_CHOICE:
875*cf5a6c84SAndroid Build Coastguard Worker return "choice";
876*cf5a6c84SAndroid Build Coastguard Worker case P_SELECT:
877*cf5a6c84SAndroid Build Coastguard Worker return "select";
878*cf5a6c84SAndroid Build Coastguard Worker case P_RANGE:
879*cf5a6c84SAndroid Build Coastguard Worker return "range";
880*cf5a6c84SAndroid Build Coastguard Worker case P_UNKNOWN:
881*cf5a6c84SAndroid Build Coastguard Worker break;
882*cf5a6c84SAndroid Build Coastguard Worker }
883*cf5a6c84SAndroid Build Coastguard Worker return "unknown";
884*cf5a6c84SAndroid Build Coastguard Worker }
885