-rw-r--r-- | scripts/kconfig/confdata.c | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c new file mode 100644 index 0000000..0f5fd97 --- a/dev/null +++ b/scripts/kconfig/confdata.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||
3 | * Released under the terms of the GNU GPL v2.0. | ||
4 | */ | ||
5 | |||
6 | #include <ctype.h> | ||
7 | #include <limits.h> | ||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | #include <unistd.h> | ||
12 | |||
13 | #define LKC_DIRECT_LINK | ||
14 | #include "lkc.h" | ||
15 | |||
16 | const char conf_def_filename[] = ".config"; | ||
17 | char conf_filename[PATH_MAX+1]; | ||
18 | |||
19 | const char conf_defname[] = "arch/$ARCH/defconfig"; | ||
20 | |||
21 | const char *conf_confnames[] = { | ||
22 | ".config", | ||
23 | "/lib/modules/$UNAME_RELEASE/.config", | ||
24 | "/etc/kernel-config", | ||
25 | "/boot/config-$UNAME_RELEASE", | ||
26 | conf_defname, | ||
27 | NULL, | ||
28 | }; | ||
29 | |||
30 | static char *conf_expand_value(const char *in) | ||
31 | { | ||
32 | struct symbol *sym; | ||
33 | const char *src; | ||
34 | static char res_value[SYMBOL_MAXLENGTH]; | ||
35 | char *dst, name[SYMBOL_MAXLENGTH]; | ||
36 | |||
37 | res_value[0] = 0; | ||
38 | dst = name; | ||
39 | while ((src = strchr(in, '$'))) { | ||
40 | strncat(res_value, in, src - in); | ||
41 | src++; | ||
42 | dst = name; | ||
43 | while (isalnum(*src) || *src == '_') | ||
44 | *dst++ = *src++; | ||
45 | *dst = 0; | ||
46 | sym = sym_lookup(name, 0); | ||
47 | sym_calc_value(sym); | ||
48 | strcat(res_value, sym_get_string_value(sym)); | ||
49 | in = src; | ||
50 | } | ||
51 | strcat(res_value, in); | ||
52 | |||
53 | return res_value; | ||
54 | } | ||
55 | |||
56 | char *conf_get_default_confname(void) | ||
57 | { | ||
58 | return conf_expand_value(conf_defname); | ||
59 | } | ||
60 | |||
61 | int conf_read(const char *name) | ||
62 | { | ||
63 | FILE *in = NULL; | ||
64 | char line[128]; | ||
65 | char *p, *p2; | ||
66 | int lineno = 0; | ||
67 | struct symbol *sym; | ||
68 | struct property *prop; | ||
69 | struct expr *e; | ||
70 | int i; | ||
71 | |||
72 | if (name) { | ||
73 | in = fopen(name, "r"); | ||
74 | if (in) | ||
75 | strcpy(conf_filename, name); | ||
76 | } else { | ||
77 | const char **names = conf_confnames; | ||
78 | while ((name = *names++)) { | ||
79 | name = conf_expand_value(name); | ||
80 | in = fopen(name, "r"); | ||
81 | if (in) { | ||
82 | printf("#\n" | ||
83 | "# using defaults found in %s\n" | ||
84 | "#\n", name); | ||
85 | break; | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | if (!in) | ||
91 | return 1; | ||
92 | |||
93 | for_all_symbols(i, sym) { | ||
94 | sym->flags |= SYMBOL_NEW; | ||
95 | switch (sym->type) { | ||
96 | case S_INT: | ||
97 | case S_HEX: | ||
98 | case S_STRING: | ||
99 | if (S_VAL(sym->def)) { | ||
100 | free(S_VAL(sym->def)); | ||
101 | S_VAL(sym->def) = NULL; | ||
102 | } | ||
103 | default: | ||
104 | ; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | while (fgets(line, 128, in)) { | ||
109 | lineno++; | ||
110 | switch (line[0]) { | ||
111 | case '#': | ||
112 | if (memcmp(line + 2, "CONFIG_", 7)) | ||
113 | continue; | ||
114 | p = strchr(line + 9, ' '); | ||
115 | if (!p) | ||
116 | continue; | ||
117 | *p++ = 0; | ||
118 | if (strncmp(p, "is not set", 10)) | ||
119 | continue; | ||
120 | //printf("%s -> n\n", line + 9); | ||
121 | sym = sym_lookup(line + 9, 0); | ||
122 | switch (sym->type) { | ||
123 | case S_BOOLEAN: | ||
124 | case S_TRISTATE: | ||
125 | sym->def = symbol_no.curr; | ||
126 | sym->flags &= ~SYMBOL_NEW; | ||
127 | break; | ||
128 | default: | ||
129 | ; | ||
130 | } | ||
131 | break; | ||
132 | case 'C': | ||
133 | if (memcmp(line, "CONFIG_", 7)) | ||
134 | continue; | ||
135 | p = strchr(line + 7, '='); | ||
136 | if (!p) | ||
137 | continue; | ||
138 | *p++ = 0; | ||
139 | p2 = strchr(p, '\n'); | ||
140 | if (p2) | ||
141 | *p2 = 0; | ||
142 | //printf("%s -> %s\n", line + 7, p); | ||
143 | sym = sym_find(line + 7); | ||
144 | if (!sym) { | ||
145 | fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); | ||
146 | break; | ||
147 | } | ||
148 | switch (sym->type) { | ||
149 | case S_BOOLEAN: | ||
150 | sym->def = symbol_yes.curr; | ||
151 | sym->flags &= ~SYMBOL_NEW; | ||
152 | break; | ||
153 | case S_TRISTATE: | ||
154 | if (p[0] == 'm') | ||
155 | sym->def = symbol_mod.curr; | ||
156 | else | ||
157 | sym->def = symbol_yes.curr; | ||
158 | sym->flags &= ~SYMBOL_NEW; | ||
159 | break; | ||
160 | case S_STRING: | ||
161 | if (*p++ != '"') | ||
162 | break; | ||
163 | for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { | ||
164 | if (*p2 == '"') { | ||
165 | *p2 = 0; | ||
166 | break; | ||
167 | } | ||
168 | memmove(p2, p2 + 1, strlen(p2)); | ||
169 | } | ||
170 | case S_INT: | ||
171 | case S_HEX: | ||
172 | if (sym_string_valid(sym, p)) { | ||
173 | S_VAL(sym->def) = strdup(p); | ||
174 | sym->flags &= ~SYMBOL_NEW; | ||
175 | } else | ||
176 | fprintf(stderr, "%s:%d:symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); | ||
177 | break; | ||
178 | default: | ||
179 | ; | ||
180 | } | ||
181 | if (sym_is_choice_value(sym)) { | ||
182 | prop = sym_get_choice_prop(sym); | ||
183 | switch (S_TRI(sym->def)) { | ||
184 | case mod: | ||
185 | if (S_TRI(prop->def->def) == yes) | ||
186 | /* warn? */; | ||
187 | break; | ||
188 | case yes: | ||
189 | if (S_TRI(prop->def->def) != no) | ||
190 | /* warn? */; | ||
191 | S_VAL(prop->def->def) = sym; | ||
192 | break; | ||
193 | case no: | ||
194 | break; | ||
195 | } | ||
196 | S_TRI(prop->def->def) = S_TRI(sym->def); | ||
197 | } | ||
198 | break; | ||
199 | case '\n': | ||
200 | break; | ||
201 | default: | ||
202 | continue; | ||
203 | } | ||
204 | } | ||
205 | fclose(in); | ||
206 | |||
207 | for_all_symbols(i, sym) { | ||
208 | if (!sym_is_choice(sym)) | ||
209 | continue; | ||
210 | prop = sym_get_choice_prop(sym); | ||
211 | sym->flags &= ~SYMBOL_NEW; | ||
212 | for (e = prop->dep; e; e = e->left.expr) | ||
213 | sym->flags |= e->right.sym->flags & SYMBOL_NEW; | ||
214 | } | ||
215 | |||
216 | sym_change_count = 1; | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | int conf_write(const char *name) | ||
222 | { | ||
223 | FILE *out, *out_h; | ||
224 | struct symbol *sym; | ||
225 | struct menu *menu; | ||
226 | char oldname[128]; | ||
227 | int type, l; | ||
228 | const char *str; | ||
229 | |||
230 | out = fopen(".tmpconfig", "w"); | ||
231 | if (!out) | ||
232 | return 1; | ||
233 | out_h = fopen(".tmpconfig.h", "w"); | ||
234 | if (!out_h) | ||
235 | return 1; | ||
236 | fprintf(out, "#\n" | ||
237 | "# Automatically generated make config: don't edit\n" | ||
238 | "#\n"); | ||
239 | fprintf(out_h, "/*\n" | ||
240 | " * Automatically generated C config: don't edit\n" | ||
241 | " */\n" | ||
242 | "#define AUTOCONF_INCLUDED\n"); | ||
243 | |||
244 | if (!sym_change_count) | ||
245 | sym_clear_all_valid(); | ||
246 | |||
247 | menu = rootmenu.list; | ||
248 | while (menu) { | ||
249 | sym = menu->sym; | ||
250 | if (!sym) { | ||
251 | if (!menu_is_visible(menu)) | ||
252 | goto next; | ||
253 | str = menu_get_prompt(menu); | ||
254 | fprintf(out, "\n" | ||
255 | "#\n" | ||
256 | "# %s\n" | ||
257 | "#\n", str); | ||
258 | fprintf(out_h, "\n" | ||
259 | "/*\n" | ||
260 | " * %s\n" | ||
261 | " */\n", str); | ||
262 | } else if (!(sym->flags & SYMBOL_CHOICE)) { | ||
263 | sym_calc_value(sym); | ||
264 | if (!(sym->flags & SYMBOL_WRITE)) | ||
265 | goto next; | ||
266 | sym->flags &= ~SYMBOL_WRITE; | ||
267 | type = sym->type; | ||
268 | if (type == S_TRISTATE) { | ||
269 | sym_calc_value(modules_sym); | ||
270 | if (S_TRI(modules_sym->curr) == no) | ||
271 | type = S_BOOLEAN; | ||
272 | } | ||
273 | switch (type) { | ||
274 | case S_BOOLEAN: | ||
275 | case S_TRISTATE: | ||
276 | switch (sym_get_tristate_value(sym)) { | ||
277 | case no: | ||
278 | fprintf(out, "# CONFIG_%s is not set\n", sym->name); | ||
279 | fprintf(out_h, "#undef CONFIG_%s\n", sym->name); | ||
280 | break; | ||
281 | case mod: | ||
282 | fprintf(out, "CONFIG_%s=m\n", sym->name); | ||
283 | fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); | ||
284 | break; | ||
285 | case yes: | ||
286 | fprintf(out, "CONFIG_%s=y\n", sym->name); | ||
287 | fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); | ||
288 | break; | ||
289 | } | ||
290 | break; | ||
291 | case S_STRING: | ||
292 | // fix me | ||
293 | str = sym_get_string_value(sym); | ||
294 | fprintf(out, "CONFIG_%s=\"", sym->name); | ||
295 | fprintf(out_h, "#define CONFIG_%s \"", sym->name); | ||
296 | do { | ||
297 | l = strcspn(str, "\"\\"); | ||
298 | if (l) { | ||
299 | fwrite(str, l, 1, out); | ||
300 | fwrite(str, l, 1, out_h); | ||
301 | } | ||
302 | str += l; | ||
303 | while (*str == '\\' || *str == '"') { | ||
304 | fprintf(out, "\\%c", *str); | ||
305 | fprintf(out_h, "\\%c", *str); | ||
306 | str++; | ||
307 | } | ||
308 | } while (*str); | ||
309 | fputs("\"\n", out); | ||
310 | fputs("\"\n", out_h); | ||
311 | break; | ||
312 | case S_HEX: | ||
313 | str = sym_get_string_value(sym); | ||
314 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { | ||
315 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
316 | fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); | ||
317 | break; | ||
318 | } | ||
319 | case S_INT: | ||
320 | str = sym_get_string_value(sym); | ||
321 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
322 | fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); | ||
323 | break; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | next: | ||
328 | if (menu->list) { | ||
329 | menu = menu->list; | ||
330 | continue; | ||
331 | } | ||
332 | if (menu->next) | ||
333 | menu = menu->next; | ||
334 | else while ((menu = menu->parent)) { | ||
335 | if (menu->next) { | ||
336 | menu = menu->next; | ||
337 | break; | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | fclose(out); | ||
342 | fclose(out_h); | ||
343 | |||
344 | if (!name) { | ||
345 | rename(".tmpconfig.h", "include/linux/autoconf.h"); | ||
346 | name = conf_def_filename; | ||
347 | file_write_dep(NULL); | ||
348 | } else | ||
349 | unlink(".tmpconfig.h"); | ||
350 | |||
351 | sprintf(oldname, "%s.old", name); | ||
352 | rename(name, oldname); | ||
353 | if (rename(".tmpconfig", name)) | ||
354 | return 1; | ||
355 | strcpy(conf_filename, name); | ||
356 | |||
357 | sym_change_count = 0; | ||
358 | |||
359 | return 0; | ||
360 | } | ||