-rw-r--r-- | scripts/kconfig/symbol.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 59c88d2..845d8a3 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -104,288 +104,303 @@ const char *sym_type_name(int type) | |||
104 | case S_TRISTATE: | 104 | case S_TRISTATE: |
105 | return "tristate"; | 105 | return "tristate"; |
106 | case S_INT: | 106 | case S_INT: |
107 | return "integer"; | 107 | return "integer"; |
108 | case S_HEX: | 108 | case S_HEX: |
109 | return "hex"; | 109 | return "hex"; |
110 | case S_STRING: | 110 | case S_STRING: |
111 | return "string"; | 111 | return "string"; |
112 | case S_UNKNOWN: | 112 | case S_UNKNOWN: |
113 | return "unknown"; | 113 | return "unknown"; |
114 | } | 114 | } |
115 | return "???"; | 115 | return "???"; |
116 | } | 116 | } |
117 | 117 | ||
118 | struct property *sym_get_choice_prop(struct symbol *sym) | 118 | struct property *sym_get_choice_prop(struct symbol *sym) |
119 | { | 119 | { |
120 | struct property *prop; | 120 | struct property *prop; |
121 | 121 | ||
122 | for_all_choices(sym, prop) | 122 | for_all_choices(sym, prop) |
123 | return prop; | 123 | return prop; |
124 | return NULL; | 124 | return NULL; |
125 | } | 125 | } |
126 | 126 | ||
127 | struct property *sym_get_default_prop(struct symbol *sym) | 127 | struct property *sym_get_default_prop(struct symbol *sym) |
128 | { | 128 | { |
129 | struct property *prop; | 129 | struct property *prop; |
130 | tristate visible; | 130 | tristate visible; |
131 | 131 | ||
132 | for_all_defaults(sym, prop) { | 132 | for_all_defaults(sym, prop) { |
133 | visible = E_CALC(prop->visible); | 133 | visible = E_CALC(prop->visible); |
134 | if (visible != no) | 134 | if (visible != no) |
135 | return prop; | 135 | return prop; |
136 | } | 136 | } |
137 | return NULL; | 137 | return NULL; |
138 | } | 138 | } |
139 | 139 | ||
140 | void sym_calc_visibility(struct symbol *sym) | 140 | void sym_calc_visibility(struct symbol *sym) |
141 | { | 141 | { |
142 | struct property *prop; | 142 | struct property *prop; |
143 | tristate visible, oldvisible; | 143 | tristate visible, oldvisible; |
144 | 144 | ||
145 | /* any prompt visible? */ | 145 | /* any prompt visible? */ |
146 | oldvisible = sym->visible; | 146 | oldvisible = sym->visible; |
147 | visible = no; | 147 | visible = no; |
148 | for_all_prompts(sym, prop) | 148 | for_all_prompts(sym, prop) |
149 | visible = E_OR(visible, E_CALC(prop->visible)); | 149 | visible = E_OR(visible, E_CALC(prop->visible)); |
150 | if (oldvisible != visible) { | 150 | if (oldvisible != visible) { |
151 | sym->visible = visible; | 151 | sym->visible = visible; |
152 | sym->flags |= SYMBOL_CHANGED; | 152 | sym_set_changed(sym); |
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
156 | void sym_calc_value(struct symbol *sym) | 156 | void sym_calc_value(struct symbol *sym) |
157 | { | 157 | { |
158 | struct symbol_value newval, oldval; | 158 | struct symbol_value newval, oldval; |
159 | struct property *prop, *def_prop; | 159 | struct property *prop, *def_prop; |
160 | struct symbol *def_sym; | 160 | struct symbol *def_sym; |
161 | struct expr *e; | 161 | struct expr *e; |
162 | 162 | ||
163 | if (sym->flags & SYMBOL_VALID) | 163 | if (sym->flags & SYMBOL_VALID) |
164 | return; | 164 | return; |
165 | 165 | ||
166 | oldval = sym->curr; | 166 | oldval = sym->curr; |
167 | 167 | ||
168 | switch (sym->type) { | 168 | switch (sym->type) { |
169 | case S_INT: | 169 | case S_INT: |
170 | case S_HEX: | 170 | case S_HEX: |
171 | case S_STRING: | 171 | case S_STRING: |
172 | newval = symbol_empty.curr; | 172 | newval = symbol_empty.curr; |
173 | break; | 173 | break; |
174 | case S_BOOLEAN: | 174 | case S_BOOLEAN: |
175 | case S_TRISTATE: | 175 | case S_TRISTATE: |
176 | newval = symbol_no.curr; | 176 | newval = symbol_no.curr; |
177 | break; | 177 | break; |
178 | default: | 178 | default: |
179 | S_VAL(newval) = sym->name; | 179 | S_VAL(newval) = sym->name; |
180 | S_TRI(newval) = no; | 180 | S_TRI(newval) = no; |
181 | if (sym->flags & SYMBOL_CONST) { | 181 | if (sym->flags & SYMBOL_CONST) { |
182 | goto out; | 182 | goto out; |
183 | } | 183 | } |
184 | //newval = symbol_empty.curr; | 184 | //newval = symbol_empty.curr; |
185 | // generate warning somewhere here later | 185 | // generate warning somewhere here later |
186 | //S_TRI(newval) = yes; | 186 | //S_TRI(newval) = yes; |
187 | goto out; | 187 | goto out; |
188 | } | 188 | } |
189 | sym->flags |= SYMBOL_VALID; | 189 | sym->flags |= SYMBOL_VALID; |
190 | if (!sym_is_choice_value(sym)) | 190 | if (!sym_is_choice_value(sym)) |
191 | sym->flags &= ~SYMBOL_WRITE; | 191 | sym->flags &= ~SYMBOL_WRITE; |
192 | 192 | ||
193 | sym_calc_visibility(sym); | 193 | sym_calc_visibility(sym); |
194 | 194 | ||
195 | /* set default if recursively called */ | 195 | /* set default if recursively called */ |
196 | sym->curr = newval; | 196 | sym->curr = newval; |
197 | 197 | ||
198 | if (sym->visible != no) { | 198 | if (sym->visible != no) { |
199 | sym->flags |= SYMBOL_WRITE; | 199 | sym->flags |= SYMBOL_WRITE; |
200 | if (!sym_has_value(sym)) { | 200 | if (!sym_has_value(sym)) { |
201 | if (!sym_is_choice(sym)) { | 201 | if (!sym_is_choice(sym)) { |
202 | prop = sym_get_default_prop(sym); | 202 | prop = sym_get_default_prop(sym); |
203 | if (prop) { | 203 | if (prop) { |
204 | sym_calc_value(prop->def); | 204 | sym_calc_value(prop->def); |
205 | newval = prop->def->curr; | 205 | newval = prop->def->curr; |
206 | } | 206 | } |
207 | } | 207 | } else |
208 | S_TRI(newval) = S_TRI(sym->def); | ||
208 | } else | 209 | } else |
209 | newval = sym->def; | 210 | newval = sym->def; |
210 | 211 | ||
211 | S_TRI(newval) = E_AND(S_TRI(newval), sym->visible); | 212 | S_TRI(newval) = E_AND(S_TRI(newval), sym->visible); |
212 | /* if the symbol is visible and not optionial, | 213 | /* if the symbol is visible and not optionial, |
213 | * possibly ignore old user choice. */ | 214 | * possibly ignore old user choice. */ |
214 | if (!sym_is_optional(sym) && S_TRI(newval) == no) | 215 | if (!sym_is_optional(sym) && S_TRI(newval) == no) |
215 | S_TRI(newval) = sym->visible; | 216 | S_TRI(newval) = sym->visible; |
216 | if (sym_is_choice_value(sym) && sym->visible == yes) { | 217 | if (sym_is_choice_value(sym) && sym->visible == yes) { |
217 | prop = sym_get_choice_prop(sym); | 218 | prop = sym_get_choice_prop(sym); |
218 | S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; | 219 | S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; |
219 | } | 220 | } |
220 | } else { | 221 | } else { |
221 | prop = sym_get_default_prop(sym); | 222 | prop = sym_get_default_prop(sym); |
222 | if (prop) { | 223 | if (prop) { |
223 | sym->flags |= SYMBOL_WRITE; | 224 | sym->flags |= SYMBOL_WRITE; |
224 | sym_calc_value(prop->def); | 225 | sym_calc_value(prop->def); |
225 | newval = prop->def->curr; | 226 | newval = prop->def->curr; |
226 | } | 227 | } |
227 | } | 228 | } |
228 | 229 | ||
229 | switch (sym_get_type(sym)) { | 230 | switch (sym_get_type(sym)) { |
230 | case S_TRISTATE: | 231 | case S_TRISTATE: |
231 | if (S_TRI(newval) != mod) | 232 | if (S_TRI(newval) != mod) |
232 | break; | 233 | break; |
233 | sym_calc_value(modules_sym); | 234 | sym_calc_value(modules_sym); |
234 | if (S_TRI(modules_sym->curr) == no) | 235 | if (S_TRI(modules_sym->curr) == no) |
235 | S_TRI(newval) = yes; | 236 | S_TRI(newval) = yes; |
236 | break; | 237 | break; |
237 | case S_BOOLEAN: | 238 | case S_BOOLEAN: |
238 | if (S_TRI(newval) == mod) | 239 | if (S_TRI(newval) == mod) |
239 | S_TRI(newval) = yes; | 240 | S_TRI(newval) = yes; |
240 | } | 241 | } |
241 | 242 | ||
242 | out: | 243 | out: |
243 | sym->curr = newval; | 244 | sym->curr = newval; |
244 | 245 | ||
245 | if (sym_is_choice(sym) && S_TRI(newval) == yes) { | 246 | if (sym_is_choice(sym) && S_TRI(newval) == yes) { |
246 | def_sym = S_VAL(sym->def); | 247 | def_sym = S_VAL(sym->def); |
247 | if (def_sym) { | 248 | if (def_sym) { |
248 | sym_calc_visibility(def_sym); | 249 | sym_calc_visibility(def_sym); |
249 | if (def_sym->visible == no) | 250 | if (def_sym->visible == no) |
250 | def_sym = NULL; | 251 | def_sym = NULL; |
251 | } | 252 | } |
252 | if (!def_sym) { | 253 | if (!def_sym) { |
253 | for_all_defaults(sym, def_prop) { | 254 | for_all_defaults(sym, def_prop) { |
254 | if (E_CALC(def_prop->visible) == no) | 255 | if (E_CALC(def_prop->visible) == no) |
255 | continue; | 256 | continue; |
256 | sym_calc_visibility(def_prop->def); | 257 | sym_calc_visibility(def_prop->def); |
257 | if (def_prop->def->visible != no) { | 258 | if (def_prop->def->visible != no) { |
258 | def_sym = def_prop->def; | 259 | def_sym = def_prop->def; |
259 | break; | 260 | break; |
260 | } | 261 | } |
261 | } | 262 | } |
262 | } | 263 | } |
263 | 264 | ||
264 | if (!def_sym) { | 265 | if (!def_sym) { |
265 | prop = sym_get_choice_prop(sym); | 266 | prop = sym_get_choice_prop(sym); |
266 | for (e = prop->dep; e; e = e->left.expr) { | 267 | for (e = prop->dep; e; e = e->left.expr) { |
267 | sym_calc_visibility(e->right.sym); | 268 | sym_calc_visibility(e->right.sym); |
268 | if (e->right.sym->visible != no) { | 269 | if (e->right.sym->visible != no) { |
269 | def_sym = e->right.sym; | 270 | def_sym = e->right.sym; |
270 | break; | 271 | break; |
271 | } | 272 | } |
272 | } | 273 | } |
273 | } | 274 | } |
274 | 275 | ||
275 | S_VAL(newval) = def_sym; | 276 | S_VAL(newval) = def_sym; |
276 | } | 277 | } |
277 | 278 | ||
278 | if (memcmp(&oldval, &newval, sizeof(newval))) | 279 | if (memcmp(&oldval, &newval, sizeof(newval))) |
279 | sym->flags |= SYMBOL_CHANGED; | 280 | sym_set_changed(sym); |
280 | sym->curr = newval; | 281 | sym->curr = newval; |
281 | 282 | ||
282 | if (sym_is_choice(sym)) { | 283 | if (sym_is_choice(sym)) { |
283 | int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); | 284 | int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); |
284 | prop = sym_get_choice_prop(sym); | 285 | prop = sym_get_choice_prop(sym); |
285 | for (e = prop->dep; e; e = e->left.expr) | 286 | for (e = prop->dep; e; e = e->left.expr) { |
286 | e->right.sym->flags |= flags; | 287 | e->right.sym->flags |= flags; |
288 | if (flags & SYMBOL_CHANGED) | ||
289 | sym_set_changed(e->right.sym); | ||
290 | } | ||
287 | } | 291 | } |
288 | } | 292 | } |
289 | 293 | ||
290 | void sym_clear_all_valid(void) | 294 | void sym_clear_all_valid(void) |
291 | { | 295 | { |
292 | struct symbol *sym; | 296 | struct symbol *sym; |
293 | int i; | 297 | int i; |
294 | 298 | ||
295 | for_all_symbols(i, sym) | 299 | for_all_symbols(i, sym) |
296 | sym->flags &= ~SYMBOL_VALID; | 300 | sym->flags &= ~SYMBOL_VALID; |
297 | sym_change_count++; | 301 | sym_change_count++; |
298 | } | 302 | } |
299 | 303 | ||
304 | void sym_set_changed(struct symbol *sym) | ||
305 | { | ||
306 | struct property *prop; | ||
307 | |||
308 | sym->flags |= SYMBOL_CHANGED; | ||
309 | for (prop = sym->prop; prop; prop = prop->next) { | ||
310 | if (prop->menu) | ||
311 | prop->menu->flags |= MENU_CHANGED; | ||
312 | } | ||
313 | } | ||
314 | |||
300 | void sym_set_all_changed(void) | 315 | void sym_set_all_changed(void) |
301 | { | 316 | { |
302 | struct symbol *sym; | 317 | struct symbol *sym; |
303 | int i; | 318 | int i; |
304 | 319 | ||
305 | for_all_symbols(i, sym) | 320 | for_all_symbols(i, sym) |
306 | sym->flags |= SYMBOL_CHANGED; | 321 | sym_set_changed(sym); |
307 | } | 322 | } |
308 | 323 | ||
309 | bool sym_tristate_within_range(struct symbol *sym, tristate val) | 324 | bool sym_tristate_within_range(struct symbol *sym, tristate val) |
310 | { | 325 | { |
311 | int type = sym_get_type(sym); | 326 | int type = sym_get_type(sym); |
312 | 327 | ||
313 | if (sym->visible == no) | 328 | if (sym->visible == no) |
314 | return false; | 329 | return false; |
315 | 330 | ||
316 | if (type != S_BOOLEAN && type != S_TRISTATE) | 331 | if (type != S_BOOLEAN && type != S_TRISTATE) |
317 | return false; | 332 | return false; |
318 | 333 | ||
319 | switch (val) { | 334 | switch (val) { |
320 | case no: | 335 | case no: |
321 | if (sym_is_choice_value(sym) && sym->visible == yes) | 336 | if (sym_is_choice_value(sym) && sym->visible == yes) |
322 | return false; | 337 | return false; |
323 | return sym_is_optional(sym); | 338 | return sym_is_optional(sym); |
324 | case mod: | 339 | case mod: |
325 | if (sym_is_choice_value(sym) && sym->visible == yes) | 340 | if (sym_is_choice_value(sym) && sym->visible == yes) |
326 | return false; | 341 | return false; |
327 | return type == S_TRISTATE; | 342 | return type == S_TRISTATE; |
328 | case yes: | 343 | case yes: |
329 | return type == S_BOOLEAN || sym->visible == yes; | 344 | return type == S_BOOLEAN || sym->visible == yes; |
330 | } | 345 | } |
331 | return false; | 346 | return false; |
332 | } | 347 | } |
333 | 348 | ||
334 | bool sym_set_tristate_value(struct symbol *sym, tristate val) | 349 | bool sym_set_tristate_value(struct symbol *sym, tristate val) |
335 | { | 350 | { |
336 | tristate oldval = sym_get_tristate_value(sym); | 351 | tristate oldval = sym_get_tristate_value(sym); |
337 | 352 | ||
338 | if (oldval != val && !sym_tristate_within_range(sym, val)) | 353 | if (oldval != val && !sym_tristate_within_range(sym, val)) |
339 | return false; | 354 | return false; |
340 | 355 | ||
341 | if (sym->flags & SYMBOL_NEW) { | 356 | if (sym->flags & SYMBOL_NEW) { |
342 | sym->flags &= ~SYMBOL_NEW; | 357 | sym->flags &= ~SYMBOL_NEW; |
343 | sym->flags |= SYMBOL_CHANGED; | 358 | sym_set_changed(sym); |
344 | } | 359 | } |
345 | if (sym_is_choice_value(sym) && val == yes) { | 360 | if (sym_is_choice_value(sym) && val == yes) { |
346 | struct property *prop = sym_get_choice_prop(sym); | 361 | struct property *prop = sym_get_choice_prop(sym); |
347 | 362 | ||
348 | S_VAL(prop->def->def) = sym; | 363 | S_VAL(prop->def->def) = sym; |
349 | prop->def->flags &= ~SYMBOL_NEW; | 364 | prop->def->flags &= ~SYMBOL_NEW; |
350 | } | 365 | } |
351 | 366 | ||
352 | S_TRI(sym->def) = val; | 367 | S_TRI(sym->def) = val; |
353 | if (oldval != val) { | 368 | if (oldval != val) { |
354 | sym_clear_all_valid(); | 369 | sym_clear_all_valid(); |
355 | if (sym == modules_sym) | 370 | if (sym == modules_sym) |
356 | sym_set_all_changed(); | 371 | sym_set_all_changed(); |
357 | } | 372 | } |
358 | 373 | ||
359 | return true; | 374 | return true; |
360 | } | 375 | } |
361 | 376 | ||
362 | tristate sym_toggle_tristate_value(struct symbol *sym) | 377 | tristate sym_toggle_tristate_value(struct symbol *sym) |
363 | { | 378 | { |
364 | tristate oldval, newval; | 379 | tristate oldval, newval; |
365 | 380 | ||
366 | oldval = newval = sym_get_tristate_value(sym); | 381 | oldval = newval = sym_get_tristate_value(sym); |
367 | do { | 382 | do { |
368 | switch (newval) { | 383 | switch (newval) { |
369 | case no: | 384 | case no: |
370 | newval = mod; | 385 | newval = mod; |
371 | break; | 386 | break; |
372 | case mod: | 387 | case mod: |
373 | newval = yes; | 388 | newval = yes; |
374 | break; | 389 | break; |
375 | case yes: | 390 | case yes: |
376 | newval = no; | 391 | newval = no; |
377 | break; | 392 | break; |
378 | } | 393 | } |
379 | if (sym_set_tristate_value(sym, newval)) | 394 | if (sym_set_tristate_value(sym, newval)) |
380 | break; | 395 | break; |
381 | } while (oldval != newval); | 396 | } while (oldval != newval); |
382 | return newval; | 397 | return newval; |
383 | } | 398 | } |
384 | 399 | ||
385 | bool sym_string_valid(struct symbol *sym, const char *str) | 400 | bool sym_string_valid(struct symbol *sym, const char *str) |
386 | { | 401 | { |
387 | char ch; | 402 | char ch; |
388 | 403 | ||
389 | switch (sym->type) { | 404 | switch (sym->type) { |
390 | case S_STRING: | 405 | case S_STRING: |
391 | return true; | 406 | return true; |
@@ -415,201 +430,197 @@ bool sym_string_valid(struct symbol *sym, const char *str) | |||
415 | case S_TRISTATE: | 430 | case S_TRISTATE: |
416 | switch (str[0]) { | 431 | switch (str[0]) { |
417 | case 'y': | 432 | case 'y': |
418 | case 'Y': | 433 | case 'Y': |
419 | return sym_tristate_within_range(sym, yes); | 434 | return sym_tristate_within_range(sym, yes); |
420 | case 'm': | 435 | case 'm': |
421 | case 'M': | 436 | case 'M': |
422 | return sym_tristate_within_range(sym, mod); | 437 | return sym_tristate_within_range(sym, mod); |
423 | case 'n': | 438 | case 'n': |
424 | case 'N': | 439 | case 'N': |
425 | return sym_tristate_within_range(sym, no); | 440 | return sym_tristate_within_range(sym, no); |
426 | } | 441 | } |
427 | return false; | 442 | return false; |
428 | default: | 443 | default: |
429 | return false; | 444 | return false; |
430 | } | 445 | } |
431 | } | 446 | } |
432 | 447 | ||
433 | bool sym_set_string_value(struct symbol *sym, const char *newval) | 448 | bool sym_set_string_value(struct symbol *sym, const char *newval) |
434 | { | 449 | { |
435 | const char *oldval; | 450 | const char *oldval; |
436 | char *val; | 451 | char *val; |
437 | int size; | 452 | int size; |
438 | 453 | ||
439 | switch (sym->type) { | 454 | switch (sym->type) { |
440 | case S_BOOLEAN: | 455 | case S_BOOLEAN: |
441 | case S_TRISTATE: | 456 | case S_TRISTATE: |
442 | switch (newval[0]) { | 457 | switch (newval[0]) { |
443 | case 'y': | 458 | case 'y': |
444 | case 'Y': | 459 | case 'Y': |
445 | return sym_set_tristate_value(sym, yes); | 460 | return sym_set_tristate_value(sym, yes); |
446 | case 'm': | 461 | case 'm': |
447 | case 'M': | 462 | case 'M': |
448 | return sym_set_tristate_value(sym, mod); | 463 | return sym_set_tristate_value(sym, mod); |
449 | case 'n': | 464 | case 'n': |
450 | case 'N': | 465 | case 'N': |
451 | return sym_set_tristate_value(sym, no); | 466 | return sym_set_tristate_value(sym, no); |
452 | } | 467 | } |
453 | return false; | 468 | return false; |
454 | default: | 469 | default: |
455 | ; | 470 | ; |
456 | } | 471 | } |
457 | 472 | ||
458 | if (!sym_string_valid(sym, newval)) | 473 | if (!sym_string_valid(sym, newval)) |
459 | return false; | 474 | return false; |
460 | 475 | ||
461 | if (sym->flags & SYMBOL_NEW) { | 476 | if (sym->flags & SYMBOL_NEW) { |
462 | sym->flags &= ~SYMBOL_NEW; | 477 | sym->flags &= ~SYMBOL_NEW; |
463 | sym->flags |= SYMBOL_CHANGED; | 478 | sym_set_changed(sym); |
464 | } | 479 | } |
465 | 480 | ||
466 | oldval = S_VAL(sym->def); | 481 | oldval = S_VAL(sym->def); |
467 | size = strlen(newval) + 1; | 482 | size = strlen(newval) + 1; |
468 | if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { | 483 | if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { |
469 | size += 2; | 484 | size += 2; |
470 | S_VAL(sym->def) = val = malloc(size); | 485 | S_VAL(sym->def) = val = malloc(size); |
471 | *val++ = '0'; | 486 | *val++ = '0'; |
472 | *val++ = 'x'; | 487 | *val++ = 'x'; |
473 | } else if (!oldval || strcmp(oldval, newval)) | 488 | } else if (!oldval || strcmp(oldval, newval)) |
474 | S_VAL(sym->def) = val = malloc(size); | 489 | S_VAL(sym->def) = val = malloc(size); |
475 | else | 490 | else |
476 | return true; | 491 | return true; |
477 | 492 | ||
478 | strcpy(val, newval); | 493 | strcpy(val, newval); |
479 | free((void *)oldval); | 494 | free((void *)oldval); |
480 | sym_clear_all_valid(); | 495 | sym_clear_all_valid(); |
481 | 496 | ||
482 | return true; | 497 | return true; |
483 | } | 498 | } |
484 | 499 | ||
485 | const char *sym_get_string_value(struct symbol *sym) | 500 | const char *sym_get_string_value(struct symbol *sym) |
486 | { | 501 | { |
487 | tristate val; | 502 | tristate val; |
488 | 503 | ||
489 | switch (sym->type) { | 504 | switch (sym->type) { |
490 | case S_BOOLEAN: | 505 | case S_BOOLEAN: |
491 | case S_TRISTATE: | 506 | case S_TRISTATE: |
492 | val = sym_get_tristate_value(sym); | 507 | val = sym_get_tristate_value(sym); |
493 | switch (val) { | 508 | switch (val) { |
494 | case no: | 509 | case no: |
495 | return "n"; | 510 | return "n"; |
496 | case mod: | 511 | case mod: |
497 | return "m"; | 512 | return "m"; |
498 | case yes: | 513 | case yes: |
499 | return "y"; | 514 | return "y"; |
500 | } | 515 | } |
501 | break; | 516 | break; |
502 | default: | 517 | default: |
503 | ; | 518 | ; |
504 | } | 519 | } |
505 | return (const char *)S_VAL(sym->curr); | 520 | return (const char *)S_VAL(sym->curr); |
506 | } | 521 | } |
507 | 522 | ||
508 | bool sym_is_changable(struct symbol *sym) | 523 | bool sym_is_changable(struct symbol *sym) |
509 | { | 524 | { |
510 | if (sym->visible == no) | 525 | if (sym->visible == no) |
511 | return false; | 526 | return false; |
512 | /* at least 'n' and 'y'/'m' is selectable */ | 527 | /* at least 'n' and 'y'/'m' is selectable */ |
513 | if (sym_is_optional(sym)) | 528 | if (sym_is_optional(sym)) |
514 | return true; | 529 | return true; |
515 | /* no 'n', so 'y' and 'm' must be selectable */ | 530 | /* no 'n', so 'y' and 'm' must be selectable */ |
516 | if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes) | 531 | if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes) |
517 | return true; | 532 | return true; |
518 | return false; | 533 | return false; |
519 | } | 534 | } |
520 | 535 | ||
521 | struct symbol *sym_lookup(const char *name, int isconst) | 536 | struct symbol *sym_lookup(const char *name, int isconst) |
522 | { | 537 | { |
523 | struct symbol *symbol; | 538 | struct symbol *symbol; |
524 | const char *ptr; | 539 | const char *ptr; |
525 | char *new_name; | 540 | char *new_name; |
526 | int hash = 0; | 541 | int hash = 0; |
527 | 542 | ||
528 | //printf("lookup: %s -> ", name); | ||
529 | if (name) { | 543 | if (name) { |
530 | if (name[0] && !name[1]) { | 544 | if (name[0] && !name[1]) { |
531 | switch (name[0]) { | 545 | switch (name[0]) { |
532 | case 'y': return &symbol_yes; | 546 | case 'y': return &symbol_yes; |
533 | case 'm': return &symbol_mod; | 547 | case 'm': return &symbol_mod; |
534 | case 'n': return &symbol_no; | 548 | case 'n': return &symbol_no; |
535 | } | 549 | } |
536 | } | 550 | } |
537 | for (ptr = name; *ptr; ptr++) | 551 | for (ptr = name; *ptr; ptr++) |
538 | hash += *ptr; | 552 | hash += *ptr; |
539 | hash &= 0xff; | 553 | hash &= 0xff; |
540 | 554 | ||
541 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { | 555 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { |
542 | if (!strcmp(symbol->name, name)) { | 556 | if (!strcmp(symbol->name, name)) { |
543 | if ((isconst && symbol->flags & SYMBOL_CONST) || | 557 | if ((isconst && symbol->flags & SYMBOL_CONST) || |
544 | (!isconst && !(symbol->flags & SYMBOL_CONST))) { | 558 | (!isconst && !(symbol->flags & SYMBOL_CONST))) |
545 | //printf("h:%p\n", symbol); | ||
546 | return symbol; | 559 | return symbol; |
547 | } | 560 | } |
548 | } | 561 | } |
549 | } | ||
550 | new_name = strdup(name); | 562 | new_name = strdup(name); |
551 | } else { | 563 | } else { |
552 | new_name = NULL; | 564 | new_name = NULL; |
553 | hash = 256; | 565 | hash = 256; |
554 | } | 566 | } |
555 | 567 | ||
556 | symbol = malloc(sizeof(*symbol)); | 568 | symbol = malloc(sizeof(*symbol)); |
557 | memset(symbol, 0, sizeof(*symbol)); | 569 | memset(symbol, 0, sizeof(*symbol)); |
558 | symbol->name = new_name; | 570 | symbol->name = new_name; |
559 | symbol->type = S_UNKNOWN; | 571 | symbol->type = S_UNKNOWN; |
560 | symbol->flags = SYMBOL_NEW; | 572 | symbol->flags = SYMBOL_NEW; |
561 | if (isconst) | 573 | if (isconst) |
562 | symbol->flags |= SYMBOL_CONST; | 574 | symbol->flags |= SYMBOL_CONST; |
563 | 575 | ||
564 | symbol->next = symbol_hash[hash]; | 576 | symbol->next = symbol_hash[hash]; |
565 | symbol_hash[hash] = symbol; | 577 | symbol_hash[hash] = symbol; |
566 | 578 | ||
567 | //printf("n:%p\n", symbol); | ||
568 | return symbol; | 579 | return symbol; |
569 | } | 580 | } |
570 | 581 | ||
571 | struct symbol *sym_find(const char *name) | 582 | struct symbol *sym_find(const char *name) |
572 | { | 583 | { |
573 | struct symbol *symbol = NULL; | 584 | struct symbol *symbol = NULL; |
574 | const char *ptr; | 585 | const char *ptr; |
575 | int hash = 0; | 586 | int hash = 0; |
576 | 587 | ||
577 | if (!name) | 588 | if (!name) |
578 | return NULL; | 589 | return NULL; |
579 | 590 | ||
580 | if (name[0] && !name[1]) { | 591 | if (name[0] && !name[1]) { |
581 | switch (name[0]) { | 592 | switch (name[0]) { |
582 | case 'y': return &symbol_yes; | 593 | case 'y': return &symbol_yes; |
583 | case 'm': return &symbol_mod; | 594 | case 'm': return &symbol_mod; |
584 | case 'n': return &symbol_no; | 595 | case 'n': return &symbol_no; |
585 | } | 596 | } |
586 | } | 597 | } |
587 | for (ptr = name; *ptr; ptr++) | 598 | for (ptr = name; *ptr; ptr++) |
588 | hash += *ptr; | 599 | hash += *ptr; |
589 | hash &= 0xff; | 600 | hash &= 0xff; |
590 | 601 | ||
591 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { | 602 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { |
592 | if (!strcmp(symbol->name, name) && | 603 | if (!strcmp(symbol->name, name) && |
593 | !(symbol->flags & SYMBOL_CONST)) | 604 | !(symbol->flags & SYMBOL_CONST)) |
594 | break; | 605 | break; |
595 | } | 606 | } |
596 | 607 | ||
597 | return symbol; | 608 | return symbol; |
598 | } | 609 | } |
599 | 610 | ||
600 | const char *prop_get_type_name(enum prop_type type) | 611 | const char *prop_get_type_name(enum prop_type type) |
601 | { | 612 | { |
602 | switch (type) { | 613 | switch (type) { |
603 | case P_PROMPT: | 614 | case P_PROMPT: |
604 | return "prompt"; | 615 | return "prompt"; |
605 | case P_COMMENT: | 616 | case P_COMMENT: |
606 | return "comment"; | 617 | return "comment"; |
607 | case P_MENU: | 618 | case P_MENU: |
608 | return "menu"; | 619 | return "menu"; |
609 | case P_ROOTMENU: | 620 | case P_ROOTMENU: |
610 | return "rootmenu"; | 621 | return "rootmenu"; |
611 | case P_DEFAULT: | 622 | case P_DEFAULT: |
612 | return "default"; | 623 | return "default"; |
613 | case P_CHOICE: | 624 | case P_CHOICE: |
614 | return "choice"; | 625 | return "choice"; |
615 | default: | 626 | default: |