2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
9 #define LKC_DIRECT_LINK
13 struct menu
*current_menu
, *current_entry
;
14 static struct menu
**last_entry_ptr
;
16 struct file
*file_list
;
17 struct file
*current_file
;
21 current_entry
= current_menu
= &rootmenu
;
22 last_entry_ptr
= &rootmenu
.list
;
25 void menu_add_entry(struct symbol
*sym
)
29 menu
= malloc(sizeof(*menu
));
30 memset(menu
, 0, sizeof(*menu
));
32 menu
->parent
= current_menu
;
33 menu
->file
= current_file
;
34 menu
->lineno
= zconf_lineno();
36 *last_entry_ptr
= menu
;
37 last_entry_ptr
= &menu
->next
;
41 void menu_end_entry(void)
45 void menu_add_menu(void)
47 current_menu
= current_entry
;
48 last_entry_ptr
= ¤t_entry
->list
;
51 void menu_end_menu(void)
53 last_entry_ptr
= ¤t_menu
->next
;
54 current_menu
= current_menu
->parent
;
57 void menu_add_dep(struct expr
*dep
)
59 current_entry
->dep
= expr_alloc_and(current_entry
->dep
, dep
);
62 void menu_set_type(int type
)
64 struct symbol
*sym
= current_entry
->sym
;
66 if (sym
->type
== type
)
68 if (sym
->type
== S_UNKNOWN
) {
72 fprintf(stderr
, "%s:%d: type of '%s' redefined from '%s' to '%s'\n",
73 current_entry
->file
->name
, current_entry
->lineno
,
74 sym
->name
? sym
->name
: "<choice>", sym_type_name(sym
->type
), sym_type_name(type
));
77 struct property
*create_prop(enum prop_type type
)
79 struct property
*prop
;
81 prop
= malloc(sizeof(*prop
));
82 memset(prop
, 0, sizeof(*prop
));
84 prop
->file
= current_file
;
85 prop
->lineno
= zconf_lineno();
90 struct property
*menu_add_prop(int token
, char *prompt
, struct symbol
*def
, struct expr
*dep
)
92 struct property
*prop
= create_prop(token
);
93 struct property
**propp
;
95 prop
->sym
= current_entry
->sym
;
96 prop
->menu
= current_entry
;
99 E_EXPR(prop
->visible
) = dep
;
102 current_entry
->prompt
= prop
;
104 /* append property to the prop list of symbol */
106 for (propp
= &prop
->sym
->prop
; *propp
; propp
= &(*propp
)->next
)
114 void menu_add_prompt(int token
, char *prompt
, struct expr
*dep
)
116 current_entry
->prompt
= menu_add_prop(token
, prompt
, NULL
, dep
);
119 void menu_add_default(int token
, struct symbol
*def
, struct expr
*dep
)
121 current_entry
->prompt
= menu_add_prop(token
, NULL
, def
, dep
);
124 void menu_finalize(struct menu
*parent
)
126 struct menu
*menu
, *last_menu
;
128 struct property
*prop
;
129 struct expr
*parentdep
, *basedep
, *dep
, *dep2
;
133 if (sym
&& sym_is_choice(sym
)) {
134 /* find the first choice value and find out choice type */
135 for (menu
= parent
->list
; menu
; menu
= menu
->next
) {
137 current_entry
= parent
;
138 menu_set_type(menu
->sym
->type
);
139 current_entry
= menu
;
140 menu_set_type(sym
->type
);
144 parentdep
= expr_alloc_symbol(sym
);
145 } else if (parent
->prompt
)
146 parentdep
= E_EXPR(parent
->prompt
->visible
);
148 parentdep
= parent
->dep
;
150 for (menu
= parent
->list
; menu
; menu
= menu
->next
) {
151 basedep
= expr_transform(menu
->dep
);
152 basedep
= expr_alloc_and(expr_copy(parentdep
), basedep
);
153 basedep
= expr_eliminate_dups(basedep
);
156 prop
= menu
->sym
->prop
;
159 for (; prop
; prop
= prop
->next
) {
160 if (prop
->menu
!= menu
)
162 dep
= expr_transform(E_EXPR(prop
->visible
));
163 dep
= expr_alloc_and(expr_copy(basedep
), dep
);
164 dep
= expr_eliminate_dups(dep
);
165 if (menu
->sym
&& menu
->sym
->type
!= S_TRISTATE
)
166 dep
= expr_trans_bool(dep
);
167 E_EXPR(prop
->visible
) = dep
;
170 for (menu
= parent
->list
; menu
; menu
= menu
->next
)
172 } else if (sym
&& parent
->prompt
) {
173 basedep
= E_EXPR(parent
->prompt
->visible
);
174 basedep
= expr_trans_compare(basedep
, E_UNEQUAL
, &symbol_no
);
175 basedep
= expr_eliminate_dups(expr_transform(basedep
));
177 for (menu
= parent
->next
; menu
; menu
= menu
->next
) {
178 dep
= menu
->prompt
? E_EXPR(menu
->prompt
->visible
) : menu
->dep
;
179 if (!expr_contains_symbol(dep
, sym
))
181 if (expr_depends_symbol(dep
, sym
))
183 dep
= expr_trans_compare(dep
, E_UNEQUAL
, &symbol_no
);
184 dep
= expr_eliminate_dups(expr_transform(dep
));
185 dep2
= expr_copy(basedep
);
186 expr_eliminate_eq(&dep
, &dep2
);
188 if (!expr_is_yes(dep2
)) {
195 menu
->parent
= parent
;
199 parent
->list
= parent
->next
;
200 parent
->next
= last_menu
->next
;
201 last_menu
->next
= NULL
;
204 for (menu
= parent
->list
; menu
; menu
= menu
->next
) {
205 if (sym
&& sym_is_choice(sym
) && menu
->sym
) {
206 menu
->sym
->flags
|= SYMBOL_CHOICEVAL
;
207 current_entry
= menu
;
208 menu_set_type(sym
->type
);
209 menu_add_prop(P_CHOICE
, NULL
, parent
->sym
, NULL
);
210 prop
= sym_get_choice_prop(parent
->sym
);
211 //dep = expr_alloc_one(E_CHOICE, dep);
212 //dep->right.sym = menu->sym;
213 prop
->dep
= expr_alloc_one(E_CHOICE
, prop
->dep
);
214 prop
->dep
->right
.sym
= menu
->sym
;
216 if (menu
->list
&& (!menu
->prompt
|| !menu
->prompt
->text
)) {
217 for (last_menu
= menu
->list
; ; last_menu
= last_menu
->next
) {
218 last_menu
->parent
= parent
;
219 if (!last_menu
->next
)
222 last_menu
->next
= menu
->next
;
223 menu
->next
= menu
->list
;
229 bool menu_is_visible(struct menu
*menu
)
236 sym_calc_value(menu
->sym
);
237 visible
= E_TRI(menu
->prompt
->visible
);
239 visible
= E_CALC(menu
->prompt
->visible
);
240 return visible
!= no
;
243 const char *menu_get_prompt(struct menu
*menu
)
246 return menu
->prompt
->text
;
248 return menu
->sym
->name
;
252 struct menu
*menu_get_root_menu(struct menu
*menu
)
257 struct menu
*menu_get_parent_menu(struct menu
*menu
)
261 while (menu
!= &rootmenu
) {
263 type
= menu
->prompt
? menu
->prompt
->type
: 0;
264 if (type
== P_MENU
|| type
== P_ROOTMENU
)
270 struct file
*file_lookup(const char *name
)
274 for (file
= file_list
; file
; file
= file
->next
) {
275 if (!strcmp(name
, file
->name
))
279 file
= malloc(sizeof(*file
));
280 memset(file
, 0, sizeof(*file
));
281 file
->name
= strdup(name
);
282 file
->next
= file_list
;
287 int file_write_dep(const char *name
)
293 name
= ".config.cmd";
294 out
= fopen(".config.tmp", "w");
297 fprintf(out
, "deps_config := \\\n");
298 for (file
= file_list
; file
; file
= file
->next
) {
300 fprintf(out
, "\t%s \\\n", file
->name
);
302 fprintf(out
, "\t%s\n", file
->name
);
305 rename(".config.tmp", name
);