2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
9 #include <sys/utsname.h>
11 #define LKC_DIRECT_LINK
14 struct symbol symbol_yes
= {
17 flags
: SYMBOL_YES
|SYMBOL_VALID
,
21 flags
: SYMBOL_MOD
|SYMBOL_VALID
,
25 flags
: SYMBOL_NO
|SYMBOL_VALID
,
33 struct symbol
*modules_sym
;
35 void sym_add_default(struct symbol
*sym
, const char *def
)
37 struct property
*prop
= create_prop(P_DEFAULT
);
38 struct property
**propp
;
41 prop
->def
= sym_lookup(def
, 1);
43 /* append property to the prop list of symbol */
45 for (propp
= &prop
->sym
->prop
; *propp
; propp
= &(*propp
)->next
)
56 static bool inited
= false;
65 sym
= sym_lookup("VERSION", 0);
67 sym
->flags
|= SYMBOL_AUTO
;
68 p
= getenv("VERSION");
70 sym_add_default(sym
, p
);
73 sym
= sym_lookup("TARGET_ARCH", 0);
75 sym
->flags
|= SYMBOL_AUTO
;
76 p
= getenv("TARGET_ARCH");
78 sym_add_default(sym
, p
);
81 int sym_get_type(struct symbol
*sym
)
84 if (type
== S_TRISTATE
) {
85 if (sym_is_choice_value(sym
) && sym
->visible
== yes
)
88 sym_calc_value(modules_sym
);
89 if (S_TRI(modules_sym
->curr
) == no
)
96 const char *sym_type_name(int type
)
115 struct property
*sym_get_choice_prop(struct symbol
*sym
)
117 struct property
*prop
;
119 for_all_choices(sym
, prop
)
124 struct property
*sym_get_default_prop(struct symbol
*sym
)
126 struct property
*prop
;
129 for_all_defaults(sym
, prop
) {
130 visible
= E_CALC(prop
->visible
);
137 void sym_calc_visibility(struct symbol
*sym
)
139 struct property
*prop
;
140 tristate visible
, oldvisible
;
142 /* any prompt visible? */
143 oldvisible
= sym
->visible
;
145 for_all_prompts(sym
, prop
)
146 visible
= E_OR(visible
, E_CALC(prop
->visible
));
147 if (oldvisible
!= visible
) {
148 sym
->visible
= visible
;
149 sym
->flags
|= SYMBOL_CHANGED
;
153 void sym_calc_value(struct symbol
*sym
)
155 struct symbol_value newval
, oldval
;
156 struct property
*prop
, *def_prop
;
157 struct symbol
*def_sym
;
160 if (sym
->flags
& SYMBOL_VALID
)
169 newval
= symbol_empty
.curr
;
173 newval
= symbol_no
.curr
;
176 S_VAL(newval
) = sym
->name
;
178 if (sym
->flags
& SYMBOL_CONST
) {
181 //newval = symbol_empty.curr;
182 // generate warning somewhere here later
183 //S_TRI(newval) = yes;
186 sym
->flags
|= SYMBOL_VALID
;
187 if (!sym_is_choice_value(sym
))
188 sym
->flags
&= ~SYMBOL_WRITE
;
190 sym_calc_visibility(sym
);
192 /* set default if recursively called */
195 if (sym
->visible
!= no
) {
196 sym
->flags
|= SYMBOL_WRITE
;
197 if (!sym_has_value(sym
)) {
198 if (!sym_is_choice(sym
)) {
199 prop
= sym_get_default_prop(sym
);
201 sym_calc_value(prop
->def
);
202 newval
= prop
->def
->curr
;
208 S_TRI(newval
) = E_AND(S_TRI(newval
), sym
->visible
);
209 /* if the symbol is visible and not optionial,
210 * possibly ignore old user choice. */
211 if (!sym_is_optional(sym
) && S_TRI(newval
) == no
)
212 S_TRI(newval
) = sym
->visible
;
213 if (sym_is_choice_value(sym
) && sym
->visible
== yes
) {
214 prop
= sym_get_choice_prop(sym
);
215 S_TRI(newval
) = (S_VAL(prop
->def
->curr
) == sym
) ? yes
: no
;
218 prop
= sym_get_default_prop(sym
);
220 sym
->flags
|= SYMBOL_WRITE
;
221 sym_calc_value(prop
->def
);
222 newval
= prop
->def
->curr
;
226 switch (sym_get_type(sym
)) {
228 if (S_TRI(newval
) != mod
)
230 sym_calc_value(modules_sym
);
231 if (S_TRI(modules_sym
->curr
) == no
)
235 if (S_TRI(newval
) == mod
)
242 if (sym_is_choice(sym
) && S_TRI(newval
) == yes
) {
243 def_sym
= S_VAL(sym
->def
);
245 sym_calc_visibility(def_sym
);
246 if (def_sym
->visible
== no
)
250 for_all_defaults(sym
, def_prop
) {
251 if (E_CALC(def_prop
->visible
) == no
)
253 sym_calc_visibility(def_prop
->def
);
254 if (def_prop
->def
->visible
!= no
) {
255 def_sym
= def_prop
->def
;
262 prop
= sym_get_choice_prop(sym
);
263 for (e
= prop
->dep
; e
; e
= e
->left
.expr
) {
264 sym_calc_visibility(e
->right
.sym
);
265 if (e
->right
.sym
->visible
!= no
) {
266 def_sym
= e
->right
.sym
;
272 S_VAL(newval
) = def_sym
;
275 if (memcmp(&oldval
, &newval
, sizeof(newval
)))
276 sym
->flags
|= SYMBOL_CHANGED
;
279 if (sym_is_choice(sym
)) {
280 int flags
= sym
->flags
& (SYMBOL_CHANGED
| SYMBOL_WRITE
);
281 prop
= sym_get_choice_prop(sym
);
282 for (e
= prop
->dep
; e
; e
= e
->left
.expr
)
283 e
->right
.sym
->flags
|= flags
;
287 void sym_clear_all_valid(void)
292 for_all_symbols(i
, sym
)
293 sym
->flags
&= ~SYMBOL_VALID
;
297 void sym_set_all_changed(void)
302 for_all_symbols(i
, sym
)
303 sym
->flags
|= SYMBOL_CHANGED
;
306 bool sym_tristate_within_range(struct symbol
*sym
, tristate val
)
308 int type
= sym_get_type(sym
);
310 if (sym
->visible
== no
)
313 if (type
!= S_BOOLEAN
&& type
!= S_TRISTATE
)
318 if (sym_is_choice_value(sym
) && sym
->visible
== yes
)
320 return sym_is_optional(sym
);
322 if (sym_is_choice_value(sym
) && sym
->visible
== yes
)
324 return type
== S_TRISTATE
;
326 return type
== S_BOOLEAN
|| sym
->visible
== yes
;
331 bool sym_set_tristate_value(struct symbol
*sym
, tristate val
)
333 tristate oldval
= sym_get_tristate_value(sym
);
335 if (oldval
!= val
&& !sym_tristate_within_range(sym
, val
))
338 if (sym
->flags
& SYMBOL_NEW
) {
339 sym
->flags
&= ~SYMBOL_NEW
;
340 sym
->flags
|= SYMBOL_CHANGED
;
342 if (sym_is_choice_value(sym
) && val
== yes
) {
343 struct property
*prop
= sym_get_choice_prop(sym
);
345 S_VAL(prop
->def
->def
) = sym
;
346 prop
->def
->flags
&= ~SYMBOL_NEW
;
349 S_TRI(sym
->def
) = val
;
351 sym_clear_all_valid();
352 if (sym
== modules_sym
)
353 sym_set_all_changed();
359 tristate
sym_toggle_tristate_value(struct symbol
*sym
)
361 tristate oldval
, newval
;
363 oldval
= newval
= sym_get_tristate_value(sym
);
376 if (sym_set_tristate_value(sym
, newval
))
378 } while (oldval
!= newval
);
382 bool sym_string_valid(struct symbol
*sym
, const char *str
)
393 if (!isdigit((int)ch
))
395 if (ch
== '0' && *str
!= 0)
397 while ((ch
= *str
++)) {
398 if (!isdigit((int)ch
))
403 if (str
[0] == '0' && (str
[1] == 'x' || str
[1] == 'X'))
407 if (!isxdigit((int)ch
))
409 } while ((ch
= *str
++));
416 return sym_tristate_within_range(sym
, yes
);
419 return sym_tristate_within_range(sym
, mod
);
422 return sym_tristate_within_range(sym
, no
);
430 bool sym_set_string_value(struct symbol
*sym
, const char *newval
)
442 return sym_set_tristate_value(sym
, yes
);
445 return sym_set_tristate_value(sym
, mod
);
448 return sym_set_tristate_value(sym
, no
);
455 if (!sym_string_valid(sym
, newval
))
458 if (sym
->flags
& SYMBOL_NEW
) {
459 sym
->flags
&= ~SYMBOL_NEW
;
460 sym
->flags
|= SYMBOL_CHANGED
;
463 oldval
= S_VAL(sym
->def
);
464 size
= strlen(newval
) + 1;
465 if (sym
->type
== S_HEX
&& (newval
[0] != '0' || (newval
[1] != 'x' && newval
[1] != 'X'))) {
467 S_VAL(sym
->def
) = val
= malloc(size
);
470 } else if (!oldval
|| strcmp(oldval
, newval
))
471 S_VAL(sym
->def
) = val
= malloc(size
);
476 free((void *)oldval
);
477 sym_clear_all_valid();
482 const char *sym_get_string_value(struct symbol
*sym
)
489 val
= sym_get_tristate_value(sym
);
502 return (const char *)S_VAL(sym
->curr
);
505 bool sym_is_changable(struct symbol
*sym
)
507 if (sym
->visible
== no
)
509 /* at least 'n' and 'y'/'m' is selectable */
510 if (sym_is_optional(sym
))
512 /* no 'n', so 'y' and 'm' must be selectable */
513 if (sym_get_type(sym
) == S_TRISTATE
&& sym
->visible
== yes
)
518 struct symbol
*sym_lookup(const char *name
, int isconst
)
520 struct symbol
*symbol
;
525 //printf("lookup: %s -> ", name);
527 if (name
[0] && !name
[1]) {
529 case 'y': return &symbol_yes
;
530 case 'm': return &symbol_mod
;
531 case 'n': return &symbol_no
;
534 for (ptr
= name
; *ptr
; ptr
++)
538 for (symbol
= symbol_hash
[hash
]; symbol
; symbol
= symbol
->next
) {
539 if (!strcmp(symbol
->name
, name
)) {
540 if ((isconst
&& symbol
->flags
& SYMBOL_CONST
) ||
541 (!isconst
&& !(symbol
->flags
& SYMBOL_CONST
))) {
542 //printf("h:%p\n", symbol);
547 new_name
= strdup(name
);
553 symbol
= malloc(sizeof(*symbol
));
554 memset(symbol
, 0, sizeof(*symbol
));
555 symbol
->name
= new_name
;
556 symbol
->type
= S_UNKNOWN
;
557 symbol
->flags
= SYMBOL_NEW
;
559 symbol
->flags
|= SYMBOL_CONST
;
561 symbol
->next
= symbol_hash
[hash
];
562 symbol_hash
[hash
] = symbol
;
564 //printf("n:%p\n", symbol);
568 struct symbol
*sym_find(const char *name
)
570 struct symbol
*symbol
= NULL
;
577 if (name
[0] && !name
[1]) {
579 case 'y': return &symbol_yes
;
580 case 'm': return &symbol_mod
;
581 case 'n': return &symbol_no
;
584 for (ptr
= name
; *ptr
; ptr
++)
588 for (symbol
= symbol_hash
[hash
]; symbol
; symbol
= symbol
->next
) {
589 if (!strcmp(symbol
->name
, name
) &&
590 !(symbol
->flags
& SYMBOL_CONST
))
597 const char *prop_get_type_name(enum prop_type type
)