-rw-r--r-- | scripts/kconfig/conf.c | 222 |
1 files changed, 110 insertions, 112 deletions
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 1602d5f..3c27a78 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -1,568 +1,566 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | 2 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
3 | * Released under the terms of the GNU GPL v2.0. | 3 | * Released under the terms of the GNU GPL v2.0. |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <ctype.h> | 6 | #include <ctype.h> |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include <unistd.h> | 9 | #include <unistd.h> |
10 | #include <time.h> | 10 | #include <time.h> |
11 | #include <sys/stat.h> | 11 | #include <sys/stat.h> |
12 | 12 | ||
13 | #define LKC_DIRECT_LINK | 13 | #define LKC_DIRECT_LINK |
14 | #include "lkc.h" | 14 | #include "lkc.h" |
15 | 15 | ||
16 | static void conf(struct menu *menu); | 16 | static void conf(struct menu *menu); |
17 | static void check_conf(struct menu *menu); | 17 | static void check_conf(struct menu *menu); |
18 | 18 | ||
19 | enum { | 19 | enum { |
20 | ask_all, | 20 | ask_all, |
21 | ask_new, | 21 | ask_new, |
22 | ask_silent, | 22 | ask_silent, |
23 | set_default, | 23 | set_default, |
24 | set_yes, | 24 | set_yes, |
25 | set_mod, | 25 | set_mod, |
26 | set_no, | 26 | set_no, |
27 | set_random | 27 | set_random |
28 | } input_mode = ask_all; | 28 | } input_mode = ask_all; |
29 | 29 | ||
30 | static int indent = 1; | 30 | static int indent = 1; |
31 | static int valid_stdin = 1; | 31 | static int valid_stdin = 1; |
32 | static int conf_cnt; | 32 | static int conf_cnt; |
33 | static char line[128]; | 33 | static char line[128]; |
34 | static struct menu *rootEntry; | 34 | static struct menu *rootEntry; |
35 | 35 | ||
36 | static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; | 36 | static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; |
37 | 37 | ||
38 | #if 0 | ||
39 | static void printc(int ch) | ||
40 | { | ||
41 | static int sep = 0; | ||
42 | |||
43 | if (!sep) { | ||
44 | putchar('['); | ||
45 | sep = 1; | ||
46 | } else if (ch) | ||
47 | putchar('/'); | ||
48 | if (!ch) { | ||
49 | putchar(']'); | ||
50 | putchar(' '); | ||
51 | sep = 0; | ||
52 | } else | ||
53 | putchar(ch); | ||
54 | } | ||
55 | #endif | ||
56 | |||
57 | static void printo(const char *o) | ||
58 | { | ||
59 | static int sep = 0; | ||
60 | |||
61 | if (!sep) { | ||
62 | putchar('('); | ||
63 | sep = 1; | ||
64 | } else if (o) { | ||
65 | putchar(','); | ||
66 | putchar(' '); | ||
67 | } | ||
68 | if (!o) { | ||
69 | putchar(')'); | ||
70 | putchar(' '); | ||
71 | sep = 0; | ||
72 | } else | ||
73 | printf("%s", o); | ||
74 | } | ||
75 | |||
76 | static void strip(char *str) | 38 | static void strip(char *str) |
77 | { | 39 | { |
78 | char *p = str; | 40 | char *p = str; |
79 | int l; | 41 | int l; |
80 | 42 | ||
81 | while ((isspace(*p))) | 43 | while ((isspace(*p))) |
82 | p++; | 44 | p++; |
83 | l = strlen(p); | 45 | l = strlen(p); |
84 | if (p != str) | 46 | if (p != str) |
85 | memmove(str, p, l + 1); | 47 | memmove(str, p, l + 1); |
86 | if (!l) | 48 | if (!l) |
87 | return; | 49 | return; |
88 | p = str + l - 1; | 50 | p = str + l - 1; |
89 | while ((isspace(*p))) | 51 | while ((isspace(*p))) |
90 | *p-- = 0; | 52 | *p-- = 0; |
91 | } | 53 | } |
92 | 54 | ||
55 | static void check_stdin(void) | ||
56 | { | ||
57 | if (!valid_stdin && input_mode == ask_silent) { | ||
58 | printf("aborted!\n\n"); | ||
59 | printf("Console input/output is redirected. "); | ||
60 | printf("Run 'make oldconfig' to update configuration.\n\n"); | ||
61 | exit(1); | ||
62 | } | ||
63 | } | ||
64 | |||
93 | static void conf_askvalue(struct symbol *sym, const char *def) | 65 | static void conf_askvalue(struct symbol *sym, const char *def) |
94 | { | 66 | { |
95 | enum symbol_type type = sym_get_type(sym); | 67 | enum symbol_type type = sym_get_type(sym); |
96 | tristate val; | 68 | tristate val; |
97 | 69 | ||
98 | if (!sym_has_value(sym)) | 70 | if (!sym_has_value(sym)) |
99 | printf("(NEW) "); | 71 | printf("(NEW) "); |
100 | 72 | ||
101 | line[0] = '\n'; | 73 | line[0] = '\n'; |
102 | line[1] = 0; | 74 | line[1] = 0; |
103 | 75 | ||
76 | if (!sym_is_changable(sym)) { | ||
77 | printf("%s\n", def); | ||
78 | line[0] = '\n'; | ||
79 | line[1] = 0; | ||
80 | return; | ||
81 | } | ||
82 | |||
104 | switch (input_mode) { | 83 | switch (input_mode) { |
105 | case ask_new: | 84 | case ask_new: |
106 | case ask_silent: | 85 | case ask_silent: |
107 | if (sym_has_value(sym)) { | 86 | if (sym_has_value(sym)) { |
108 | printf("%s\n", def); | 87 | printf("%s\n", def); |
109 | return; | 88 | return; |
110 | } | 89 | } |
111 | if (!valid_stdin && input_mode == ask_silent) { | 90 | check_stdin(); |
112 | printf("aborted!\n\n"); | ||
113 | printf("Console input/output is redirected. "); | ||
114 | printf("Run 'make oldconfig' to update configuration.\n\n"); | ||
115 | exit(1); | ||
116 | } | ||
117 | case ask_all: | 91 | case ask_all: |
118 | fflush(stdout); | 92 | fflush(stdout); |
119 | fgets(line, 128, stdin); | 93 | fgets(line, 128, stdin); |
120 | return; | 94 | return; |
121 | case set_default: | 95 | case set_default: |
122 | printf("%s\n", def); | 96 | printf("%s\n", def); |
123 | return; | 97 | return; |
124 | default: | 98 | default: |
125 | break; | 99 | break; |
126 | } | 100 | } |
127 | 101 | ||
128 | switch (type) { | 102 | switch (type) { |
129 | case S_INT: | 103 | case S_INT: |
130 | case S_HEX: | 104 | case S_HEX: |
131 | case S_STRING: | 105 | case S_STRING: |
132 | printf("%s\n", def); | 106 | printf("%s\n", def); |
133 | return; | 107 | return; |
134 | default: | 108 | default: |
135 | ; | 109 | ; |
136 | } | 110 | } |
137 | switch (input_mode) { | 111 | switch (input_mode) { |
138 | case set_yes: | 112 | case set_yes: |
139 | if (sym_tristate_within_range(sym, yes)) { | 113 | if (sym_tristate_within_range(sym, yes)) { |
140 | line[0] = 'y'; | 114 | line[0] = 'y'; |
141 | line[1] = '\n'; | 115 | line[1] = '\n'; |
142 | line[2] = 0; | 116 | line[2] = 0; |
143 | break; | 117 | break; |
144 | } | 118 | } |
145 | case set_mod: | 119 | case set_mod: |
146 | if (type == S_TRISTATE) { | 120 | if (type == S_TRISTATE) { |
147 | if (sym_tristate_within_range(sym, mod)) { | 121 | if (sym_tristate_within_range(sym, mod)) { |
148 | line[0] = 'm'; | 122 | line[0] = 'm'; |
149 | line[1] = '\n'; | 123 | line[1] = '\n'; |
150 | line[2] = 0; | 124 | line[2] = 0; |
151 | break; | 125 | break; |
152 | } | 126 | } |
153 | } else { | 127 | } else { |
154 | if (sym_tristate_within_range(sym, yes)) { | 128 | if (sym_tristate_within_range(sym, yes)) { |
155 | line[0] = 'y'; | 129 | line[0] = 'y'; |
156 | line[1] = '\n'; | 130 | line[1] = '\n'; |
157 | line[2] = 0; | 131 | line[2] = 0; |
158 | break; | 132 | break; |
159 | } | 133 | } |
160 | } | 134 | } |
161 | case set_no: | 135 | case set_no: |
162 | if (sym_tristate_within_range(sym, no)) { | 136 | if (sym_tristate_within_range(sym, no)) { |
163 | line[0] = 'n'; | 137 | line[0] = 'n'; |
164 | line[1] = '\n'; | 138 | line[1] = '\n'; |
165 | line[2] = 0; | 139 | line[2] = 0; |
166 | break; | 140 | break; |
167 | } | 141 | } |
168 | case set_random: | 142 | case set_random: |
169 | do { | 143 | do { |
170 | val = (tristate)(random() % 3); | 144 | val = (tristate)(random() % 3); |
171 | } while (!sym_tristate_within_range(sym, val)); | 145 | } while (!sym_tristate_within_range(sym, val)); |
172 | switch (val) { | 146 | switch (val) { |
173 | case no: line[0] = 'n'; break; | 147 | case no: line[0] = 'n'; break; |
174 | case mod: line[0] = 'm'; break; | 148 | case mod: line[0] = 'm'; break; |
175 | case yes: line[0] = 'y'; break; | 149 | case yes: line[0] = 'y'; break; |
176 | } | 150 | } |
177 | line[1] = '\n'; | 151 | line[1] = '\n'; |
178 | line[2] = 0; | 152 | line[2] = 0; |
179 | break; | 153 | break; |
180 | default: | 154 | default: |
181 | break; | 155 | break; |
182 | } | 156 | } |
183 | printf("%s", line); | 157 | printf("%s", line); |
184 | } | 158 | } |
185 | 159 | ||
186 | int conf_string(struct menu *menu) | 160 | int conf_string(struct menu *menu) |
187 | { | 161 | { |
188 | struct symbol *sym = menu->sym; | 162 | struct symbol *sym = menu->sym; |
189 | const char *def, *help; | 163 | const char *def, *help; |
190 | 164 | ||
191 | while (1) { | 165 | while (1) { |
192 | printf("%*s%s ", indent - 1, "", menu->prompt->text); | 166 | printf("%*s%s ", indent - 1, "", menu->prompt->text); |
193 | printf("(%s) ", sym->name); | 167 | printf("(%s) ", sym->name); |
194 | def = sym_get_string_value(sym); | 168 | def = sym_get_string_value(sym); |
195 | if (sym_get_string_value(sym)) | 169 | if (sym_get_string_value(sym)) |
196 | printf("[%s] ", def); | 170 | printf("[%s] ", def); |
197 | conf_askvalue(sym, def); | 171 | conf_askvalue(sym, def); |
198 | switch (line[0]) { | 172 | switch (line[0]) { |
199 | case '\n': | 173 | case '\n': |
200 | break; | 174 | break; |
201 | case '?': | 175 | case '?': |
202 | /* print help */ | 176 | /* print help */ |
203 | if (line[1] == 0) { | 177 | if (line[1] == 0) { |
204 | help = nohelp_text; | 178 | help = nohelp_text; |
205 | if (menu->sym->help) | 179 | if (menu->sym->help) |
206 | help = menu->sym->help; | 180 | help = menu->sym->help; |
207 | printf("\n%s\n", menu->sym->help); | 181 | printf("\n%s\n", menu->sym->help); |
208 | def = NULL; | 182 | def = NULL; |
209 | break; | 183 | break; |
210 | } | 184 | } |
211 | default: | 185 | default: |
212 | line[strlen(line)-1] = 0; | 186 | line[strlen(line)-1] = 0; |
213 | def = line; | 187 | def = line; |
214 | } | 188 | } |
215 | if (def && sym_set_string_value(sym, def)) | 189 | if (def && sym_set_string_value(sym, def)) |
216 | return 0; | 190 | return 0; |
217 | } | 191 | } |
218 | } | 192 | } |
219 | 193 | ||
220 | static int conf_sym(struct menu *menu) | 194 | static int conf_sym(struct menu *menu) |
221 | { | 195 | { |
222 | struct symbol *sym = menu->sym; | 196 | struct symbol *sym = menu->sym; |
223 | int type; | 197 | int type; |
224 | tristate oldval, newval; | 198 | tristate oldval, newval; |
225 | const char *help; | 199 | const char *help; |
226 | 200 | ||
227 | while (1) { | 201 | while (1) { |
228 | printf("%*s%s ", indent - 1, "", menu->prompt->text); | 202 | printf("%*s%s ", indent - 1, "", menu->prompt->text); |
229 | if (sym->name) | 203 | if (sym->name) |
230 | printf("(%s) ", sym->name); | 204 | printf("(%s) ", sym->name); |
231 | type = sym_get_type(sym); | 205 | type = sym_get_type(sym); |
232 | putchar('['); | 206 | putchar('['); |
233 | oldval = sym_get_tristate_value(sym); | 207 | oldval = sym_get_tristate_value(sym); |
234 | switch (oldval) { | 208 | switch (oldval) { |
235 | case no: | 209 | case no: |
236 | putchar('N'); | 210 | putchar('N'); |
237 | break; | 211 | break; |
238 | case mod: | 212 | case mod: |
239 | putchar('M'); | 213 | putchar('M'); |
240 | break; | 214 | break; |
241 | case yes: | 215 | case yes: |
242 | putchar('Y'); | 216 | putchar('Y'); |
243 | break; | 217 | break; |
244 | } | 218 | } |
245 | if (oldval != no && sym_tristate_within_range(sym, no)) | 219 | if (oldval != no && sym_tristate_within_range(sym, no)) |
246 | printf("/n"); | 220 | printf("/n"); |
247 | if (oldval != mod && sym_tristate_within_range(sym, mod)) | 221 | if (oldval != mod && sym_tristate_within_range(sym, mod)) |
248 | printf("/m"); | 222 | printf("/m"); |
249 | if (oldval != yes && sym_tristate_within_range(sym, yes)) | 223 | if (oldval != yes && sym_tristate_within_range(sym, yes)) |
250 | printf("/y"); | 224 | printf("/y"); |
251 | if (sym->help) | 225 | if (sym->help) |
252 | printf("/?"); | 226 | printf("/?"); |
253 | printf("] "); | 227 | printf("] "); |
254 | conf_askvalue(sym, sym_get_string_value(sym)); | 228 | conf_askvalue(sym, sym_get_string_value(sym)); |
255 | strip(line); | 229 | strip(line); |
256 | 230 | ||
257 | switch (line[0]) { | 231 | switch (line[0]) { |
258 | case 'n': | 232 | case 'n': |
259 | case 'N': | 233 | case 'N': |
260 | newval = no; | 234 | newval = no; |
261 | if (!line[1] || !strcmp(&line[1], "o")) | 235 | if (!line[1] || !strcmp(&line[1], "o")) |
262 | break; | 236 | break; |
263 | continue; | 237 | continue; |
264 | case 'm': | 238 | case 'm': |
265 | case 'M': | 239 | case 'M': |
266 | newval = mod; | 240 | newval = mod; |
267 | if (!line[1]) | 241 | if (!line[1]) |
268 | break; | 242 | break; |
269 | continue; | 243 | continue; |
270 | case 'y': | 244 | case 'y': |
271 | case 'Y': | 245 | case 'Y': |
272 | newval = yes; | 246 | newval = yes; |
273 | if (!line[1] || !strcmp(&line[1], "es")) | 247 | if (!line[1] || !strcmp(&line[1], "es")) |
274 | break; | 248 | break; |
275 | continue; | 249 | continue; |
276 | case 0: | 250 | case 0: |
277 | newval = oldval; | 251 | newval = oldval; |
278 | break; | 252 | break; |
279 | case '?': | 253 | case '?': |
280 | goto help; | 254 | goto help; |
281 | default: | 255 | default: |
282 | continue; | 256 | continue; |
283 | } | 257 | } |
284 | if (sym_set_tristate_value(sym, newval)) | 258 | if (sym_set_tristate_value(sym, newval)) |
285 | return 0; | 259 | return 0; |
286 | help: | 260 | help: |
287 | help = nohelp_text; | 261 | help = nohelp_text; |
288 | if (sym->help) | 262 | if (sym->help) |
289 | help = sym->help; | 263 | help = sym->help; |
290 | printf("\n%s\n", help); | 264 | printf("\n%s\n", help); |
291 | } | 265 | } |
292 | } | 266 | } |
293 | 267 | ||
294 | static int conf_choice(struct menu *menu) | 268 | static int conf_choice(struct menu *menu) |
295 | { | 269 | { |
296 | struct symbol *sym, *def_sym; | 270 | struct symbol *sym, *def_sym; |
297 | struct menu *cmenu, *def_menu; | 271 | struct menu *child; |
298 | const char *help; | 272 | int type; |
299 | int type, len; | ||
300 | bool is_new; | 273 | bool is_new; |
301 | 274 | ||
302 | sym = menu->sym; | 275 | sym = menu->sym; |
303 | type = sym_get_type(sym); | 276 | type = sym_get_type(sym); |
304 | is_new = !sym_has_value(sym); | 277 | is_new = !sym_has_value(sym); |
305 | if (sym_is_changable(sym)) { | 278 | if (sym_is_changable(sym)) { |
306 | conf_sym(menu); | 279 | conf_sym(menu); |
307 | sym_calc_value(sym); | 280 | sym_calc_value(sym); |
308 | switch (sym_get_tristate_value(sym)) { | 281 | switch (sym_get_tristate_value(sym)) { |
309 | case no: | 282 | case no: |
310 | return 1; | 283 | return 1; |
311 | case mod: | 284 | case mod: |
312 | return 0; | 285 | return 0; |
313 | case yes: | 286 | case yes: |
314 | break; | 287 | break; |
315 | } | 288 | } |
316 | } else { | 289 | } else { |
317 | sym->def = sym->curr; | 290 | switch (sym_get_tristate_value(sym)) { |
318 | if (S_TRI(sym->curr) == mod) { | 291 | case no: |
292 | return 1; | ||
293 | case mod: | ||
319 | printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); | 294 | printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); |
320 | return 0; | 295 | return 0; |
296 | case yes: | ||
297 | break; | ||
321 | } | 298 | } |
322 | } | 299 | } |
323 | 300 | ||
324 | while (1) { | 301 | while (1) { |
325 | printf("%*s%s ", indent - 1, "", menu_get_prompt(menu)); | 302 | int cnt, def; |
303 | |||
304 | printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); | ||
326 | def_sym = sym_get_choice_value(sym); | 305 | def_sym = sym_get_choice_value(sym); |
327 | def_menu = NULL; | 306 | cnt = def = 0; |
328 | for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { | 307 | line[0] = '0'; |
329 | if (!menu_is_visible(cmenu)) | 308 | line[1] = 0; |
309 | for (child = menu->list; child; child = child->next) { | ||
310 | if (!menu_is_visible(child)) | ||
330 | continue; | 311 | continue; |
331 | printo(menu_get_prompt(cmenu)); | 312 | if (!child->sym) { |
332 | if (cmenu->sym == def_sym) | 313 | printf("%*c %s\n", indent, '*', menu_get_prompt(child)); |
333 | def_menu = cmenu; | 314 | continue; |
334 | } | 315 | } |
335 | printo(NULL); | 316 | cnt++; |
336 | if (def_menu) | 317 | if (child->sym == def_sym) { |
337 | printf("[%s] ", menu_get_prompt(def_menu)); | 318 | def = cnt; |
338 | else { | 319 | printf("%*c", indent, '>'); |
320 | } else | ||
321 | printf("%*c", indent, ' '); | ||
322 | printf(" %d. %s", cnt, menu_get_prompt(child)); | ||
323 | if (child->sym->name) | ||
324 | printf(" (%s)", child->sym->name); | ||
325 | if (!sym_has_value(child->sym)) | ||
326 | printf(" (NEW)"); | ||
339 | printf("\n"); | 327 | printf("\n"); |
340 | return 1; | ||
341 | } | 328 | } |
329 | printf("%*schoice", indent - 1, ""); | ||
330 | if (cnt == 1) { | ||
331 | printf("[1]: 1\n"); | ||
332 | goto conf_childs; | ||
333 | } | ||
334 | printf("[1-%d", cnt); | ||
335 | if (sym->help) | ||
336 | printf("?"); | ||
337 | printf("]: "); | ||
342 | switch (input_mode) { | 338 | switch (input_mode) { |
343 | case ask_new: | 339 | case ask_new: |
344 | case ask_silent: | 340 | case ask_silent: |
341 | if (!is_new) { | ||
342 | cnt = def; | ||
343 | printf("%d\n", cnt); | ||
344 | break; | ||
345 | } | ||
346 | check_stdin(); | ||
345 | case ask_all: | 347 | case ask_all: |
346 | if (is_new) | 348 | fflush(stdout); |
347 | sym->flags |= SYMBOL_NEW; | 349 | fgets(line, 128, stdin); |
348 | conf_askvalue(sym, menu_get_prompt(def_menu)); | ||
349 | strip(line); | 350 | strip(line); |
351 | if (line[0] == '?') { | ||
352 | printf("\n%s\n", menu->sym->help ? | ||
353 | menu->sym->help : nohelp_text); | ||
354 | continue; | ||
355 | } | ||
356 | if (!line[0]) | ||
357 | cnt = def; | ||
358 | else if (isdigit(line[0])) | ||
359 | cnt = atoi(line); | ||
360 | else | ||
361 | continue; | ||
362 | break; | ||
363 | case set_random: | ||
364 | def = (random() % cnt) + 1; | ||
365 | case set_default: | ||
366 | case set_yes: | ||
367 | case set_mod: | ||
368 | case set_no: | ||
369 | cnt = def; | ||
370 | printf("%d\n", cnt); | ||
350 | break; | 371 | break; |
351 | default: | ||
352 | line[0] = 0; | ||
353 | printf("\n"); | ||
354 | } | 372 | } |
355 | if (line[0] == '?' && !line[1]) { | 373 | |
356 | help = nohelp_text; | 374 | conf_childs: |
357 | if (menu->sym->help) | 375 | for (child = menu->list; child; child = child->next) { |
358 | help = menu->sym->help; | 376 | if (!child->sym || !menu_is_visible(child)) |
359 | printf("\n%s\n", help); | 377 | continue; |
360 | continue; | 378 | if (!--cnt) |
379 | break; | ||
361 | } | 380 | } |
362 | if (line[0]) { | 381 | if (!child) |
363 | len = strlen(line); | 382 | continue; |
364 | line[len] = 0; | 383 | if (line[strlen(line) - 1] == '?') { |
365 | 384 | printf("\n%s\n", child->sym->help ? | |
366 | def_menu = NULL; | 385 | child->sym->help : nohelp_text); |
367 | for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { | 386 | continue; |
368 | if (!cmenu->sym || !menu_is_visible(cmenu)) | ||
369 | continue; | ||
370 | if (!strncasecmp(line, menu_get_prompt(cmenu), len)) { | ||
371 | def_menu = cmenu; | ||
372 | break; | ||
373 | } | ||
374 | } | ||
375 | } | 387 | } |
376 | if (def_menu) { | 388 | sym_set_choice_value(sym, child->sym); |
377 | sym_set_choice_value(sym, def_menu->sym); | 389 | if (child->list) { |
378 | if (def_menu->list) { | 390 | indent += 2; |
379 | indent += 2; | 391 | conf(child->list); |
380 | conf(def_menu->list); | 392 | indent -= 2; |
381 | indent -= 2; | ||
382 | } | ||
383 | return 1; | ||
384 | } | 393 | } |
394 | return 1; | ||
385 | } | 395 | } |
386 | } | 396 | } |
387 | 397 | ||
388 | static void conf(struct menu *menu) | 398 | static void conf(struct menu *menu) |
389 | { | 399 | { |
390 | struct symbol *sym; | 400 | struct symbol *sym; |
391 | struct property *prop; | 401 | struct property *prop; |
392 | struct menu *child; | 402 | struct menu *child; |
393 | 403 | ||
394 | if (!menu_is_visible(menu)) | 404 | if (!menu_is_visible(menu)) |
395 | return; | 405 | return; |
396 | 406 | ||
397 | sym = menu->sym; | 407 | sym = menu->sym; |
398 | prop = menu->prompt; | 408 | prop = menu->prompt; |
399 | if (prop) { | 409 | if (prop) { |
400 | const char *prompt; | 410 | const char *prompt; |
401 | 411 | ||
402 | switch (prop->type) { | 412 | switch (prop->type) { |
403 | case P_MENU: | 413 | case P_MENU: |
404 | if (input_mode == ask_silent && rootEntry != menu) { | 414 | if (input_mode == ask_silent && rootEntry != menu) { |
405 | check_conf(menu); | 415 | check_conf(menu); |
406 | return; | 416 | return; |
407 | } | 417 | } |
408 | case P_COMMENT: | 418 | case P_COMMENT: |
409 | prompt = menu_get_prompt(menu); | 419 | prompt = menu_get_prompt(menu); |
410 | if (prompt) | 420 | if (prompt) |
411 | printf("%*c\n%*c %s\n%*c\n", | 421 | printf("%*c\n%*c %s\n%*c\n", |
412 | indent, '*', | 422 | indent, '*', |
413 | indent, '*', prompt, | 423 | indent, '*', prompt, |
414 | indent, '*'); | 424 | indent, '*'); |
415 | default: | 425 | default: |
416 | ; | 426 | ; |
417 | } | 427 | } |
418 | } | 428 | } |
419 | 429 | ||
420 | if (!sym) | 430 | if (!sym) |
421 | goto conf_childs; | 431 | goto conf_childs; |
422 | 432 | ||
423 | if (sym_is_choice(sym)) { | 433 | if (sym_is_choice(sym)) { |
424 | conf_choice(menu); | 434 | conf_choice(menu); |
425 | if (S_TRI(sym->curr) != mod) | 435 | if (sym->curr.tri != mod) |
426 | return; | 436 | return; |
427 | goto conf_childs; | 437 | goto conf_childs; |
428 | } | 438 | } |
429 | 439 | ||
430 | switch (sym->type) { | 440 | switch (sym->type) { |
431 | case S_INT: | 441 | case S_INT: |
432 | case S_HEX: | 442 | case S_HEX: |
433 | case S_STRING: | 443 | case S_STRING: |
434 | conf_string(menu); | 444 | conf_string(menu); |
435 | break; | 445 | break; |
436 | default: | 446 | default: |
437 | conf_sym(menu); | 447 | conf_sym(menu); |
438 | break; | 448 | break; |
439 | } | 449 | } |
440 | 450 | ||
441 | conf_childs: | 451 | conf_childs: |
442 | if (sym) | 452 | if (sym) |
443 | indent += 2; | 453 | indent += 2; |
444 | for (child = menu->list; child; child = child->next) | 454 | for (child = menu->list; child; child = child->next) |
445 | conf(child); | 455 | conf(child); |
446 | if (sym) | 456 | if (sym) |
447 | indent -= 2; | 457 | indent -= 2; |
448 | } | 458 | } |
449 | 459 | ||
450 | static void check_conf(struct menu *menu) | 460 | static void check_conf(struct menu *menu) |
451 | { | 461 | { |
452 | struct symbol *sym; | 462 | struct symbol *sym; |
453 | struct menu *child; | 463 | struct menu *child; |
454 | 464 | ||
455 | if (!menu_is_visible(menu)) | 465 | if (!menu_is_visible(menu)) |
456 | return; | 466 | return; |
457 | 467 | ||
458 | sym = menu->sym; | 468 | sym = menu->sym; |
459 | if (!sym) | 469 | if (sym) { |
460 | goto conf_childs; | 470 | if (sym_is_changable(sym) && !sym_has_value(sym)) { |
461 | |||
462 | if (sym_is_choice(sym)) { | ||
463 | if (!sym_has_value(sym)) { | ||
464 | if (!conf_cnt++) | 471 | if (!conf_cnt++) |
465 | printf("*\n* Restart config...\n*\n"); | 472 | printf("*\n* Restart config...\n*\n"); |
466 | rootEntry = menu_get_parent_menu(menu); | 473 | rootEntry = menu_get_parent_menu(menu); |
467 | conf(rootEntry); | 474 | conf(rootEntry); |
468 | } | 475 | } |
469 | if (sym_get_tristate_value(sym) != mod) | 476 | if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod) |
470 | return; | 477 | return; |
471 | goto conf_childs; | ||
472 | } | 478 | } |
473 | 479 | ||
474 | if (!sym_has_value(sym)) { | ||
475 | if (!conf_cnt++) | ||
476 | printf("*\n* Restart config...\n*\n"); | ||
477 | rootEntry = menu_get_parent_menu(menu); | ||
478 | conf(rootEntry); | ||
479 | } | ||
480 | |||
481 | conf_childs: | ||
482 | for (child = menu->list; child; child = child->next) | 480 | for (child = menu->list; child; child = child->next) |
483 | check_conf(child); | 481 | check_conf(child); |
484 | } | 482 | } |
485 | 483 | ||
486 | int main(int ac, char **av) | 484 | int main(int ac, char **av) |
487 | { | 485 | { |
488 | const char *name; | 486 | const char *name; |
489 | struct stat tmpstat; | 487 | struct stat tmpstat; |
490 | 488 | ||
491 | if (ac > 1 && av[1][0] == '-') { | 489 | if (ac > 1 && av[1][0] == '-') { |
492 | switch (av[1][1]) { | 490 | switch (av[1][1]) { |
493 | case 'o': | 491 | case 'o': |
494 | input_mode = ask_new; | 492 | input_mode = ask_new; |
495 | break; | 493 | break; |
496 | case 's': | 494 | case 's': |
497 | input_mode = ask_silent; | 495 | input_mode = ask_silent; |
498 | valid_stdin = isatty(0) && isatty(1) && isatty(2); | 496 | valid_stdin = isatty(0) && isatty(1) && isatty(2); |
499 | break; | 497 | break; |
500 | case 'd': | 498 | case 'd': |
501 | input_mode = set_default; | 499 | input_mode = set_default; |
502 | break; | 500 | break; |
503 | case 'n': | 501 | case 'n': |
504 | input_mode = set_no; | 502 | input_mode = set_no; |
505 | break; | 503 | break; |
506 | case 'm': | 504 | case 'm': |
507 | input_mode = set_mod; | 505 | input_mode = set_mod; |
508 | break; | 506 | break; |
509 | case 'y': | 507 | case 'y': |
510 | input_mode = set_yes; | 508 | input_mode = set_yes; |
511 | break; | 509 | break; |
512 | case 'r': | 510 | case 'r': |
513 | input_mode = set_random; | 511 | input_mode = set_random; |
514 | srandom(time(NULL)); | 512 | srandom(time(NULL)); |
515 | break; | 513 | break; |
516 | case 'h': | 514 | case 'h': |
517 | case '?': | 515 | case '?': |
518 | printf("%s [-o|-s] config\n", av[0]); | 516 | printf("%s [-o|-s] config\n", av[0]); |
519 | exit(0); | 517 | exit(0); |
520 | } | 518 | } |
521 | name = av[2]; | 519 | name = av[2]; |
522 | } else | 520 | } else |
523 | name = av[1]; | 521 | name = av[1]; |
524 | conf_parse(name); | 522 | conf_parse(name); |
525 | //zconfdump(stdout); | 523 | //zconfdump(stdout); |
526 | switch (input_mode) { | 524 | switch (input_mode) { |
527 | case set_default: | 525 | case set_default: |
528 | name = conf_get_default_confname(); | 526 | name = conf_get_default_confname(); |
529 | if (conf_read(name)) { | 527 | if (conf_read(name)) { |
530 | printf("***\n" | 528 | printf("***\n" |
531 | "*** Can't find default configuration \"%s\"!\n" | 529 | "*** Can't find default configuration \"%s\"!\n" |
532 | "***\n", name); | 530 | "***\n", name); |
533 | exit(1); | 531 | exit(1); |
534 | } | 532 | } |
535 | break; | 533 | break; |
536 | case ask_silent: | 534 | case ask_silent: |
537 | if (stat(".config", &tmpstat)) { | 535 | if (stat(".config", &tmpstat)) { |
538 | printf("***\n" | 536 | printf("***\n" |
539 | "*** You have not yet configured your kernel!\n" | 537 | "*** You have not yet configured!\n" |
540 | "***\n" | 538 | "***\n" |
541 | "*** Please run some configurator (e.g. \"make oldconfig\" or\n" | 539 | "*** Please run some configurator (e.g. \"make oldconfig\" or\n" |
542 | "*** \"make menuconfig\" or \"make xconfig\").\n" | 540 | "*** \"make menuconfig\" or \"make xconfig\").\n" |
543 | "***\n"); | 541 | "***\n"); |
544 | exit(1); | 542 | exit(1); |
545 | } | 543 | } |
546 | case ask_all: | 544 | case ask_all: |
547 | case ask_new: | 545 | case ask_new: |
548 | conf_read(NULL); | 546 | conf_read(NULL); |
549 | break; | 547 | break; |
550 | default: | 548 | default: |
551 | break; | 549 | break; |
552 | } | 550 | } |
553 | 551 | ||
554 | if (input_mode != ask_silent) { | 552 | if (input_mode != ask_silent) { |
555 | rootEntry = &rootmenu; | 553 | rootEntry = &rootmenu; |
556 | conf(&rootmenu); | 554 | conf(&rootmenu); |
557 | if (input_mode == ask_all) { | 555 | if (input_mode == ask_all) { |
558 | input_mode = ask_silent; | 556 | input_mode = ask_silent; |
559 | valid_stdin = 1; | 557 | valid_stdin = 1; |
560 | } | 558 | } |
561 | } | 559 | } |
562 | do { | 560 | do { |
563 | conf_cnt = 0; | 561 | conf_cnt = 0; |
564 | check_conf(&rootmenu); | 562 | check_conf(&rootmenu); |
565 | } while (conf_cnt); | 563 | } while (conf_cnt); |
566 | conf_write(NULL); | 564 | conf_write(NULL); |
567 | return 0; | 565 | return 0; |
568 | } | 566 | } |