summaryrefslogtreecommitdiff
path: root/scripts/kconfig/confdata.c
Unidiff
Diffstat (limited to 'scripts/kconfig/confdata.c') (more/less context) (ignore whitespace changes)
-rw-r--r--scripts/kconfig/confdata.c360
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
16const char conf_def_filename[] = ".config";
17char conf_filename[PATH_MAX+1];
18
19const char conf_defname[] = "arch/$ARCH/defconfig";
20
21const 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
30static 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
56char *conf_get_default_confname(void)
57{
58 return conf_expand_value(conf_defname);
59}
60
61int 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
221int 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}