blob: ca693fcd023f0eb747f7e96e57c17ed5bf567165 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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 <sys/stat.h>
7#include <ctype.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <time.h>
12#include <unistd.h>
13
14#define LKC_DIRECT_LINK
15#include "lkc.h"
16
Roman Zippelc1a0f5e2005-11-08 21:34:54 -080017static void conf_warning(const char *fmt, ...)
18 __attribute__ ((format (printf, 1, 2)));
19
20static const char *conf_filename;
21static int conf_lineno, conf_warnings, conf_unsaved;
22
Linus Torvalds1da177e2005-04-16 15:20:36 -070023const char conf_def_filename[] = ".config";
24
25const char conf_defname[] = "arch/$ARCH/defconfig";
26
27const char *conf_confnames[] = {
28 ".config",
29 "/lib/modules/$UNAME_RELEASE/.config",
30 "/etc/kernel-config",
31 "/boot/config-$UNAME_RELEASE",
32 conf_defname,
33 NULL,
34};
35
Roman Zippelc1a0f5e2005-11-08 21:34:54 -080036static void conf_warning(const char *fmt, ...)
37{
38 va_list ap;
39 va_start(ap, fmt);
40 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
41 vfprintf(stderr, fmt, ap);
42 fprintf(stderr, "\n");
43 va_end(ap);
44 conf_warnings++;
45}
46
J.A. Magallon48b9d032005-06-25 14:59:22 -070047static char *conf_expand_value(const char *in)
Linus Torvalds1da177e2005-04-16 15:20:36 -070048{
49 struct symbol *sym;
J.A. Magallon48b9d032005-06-25 14:59:22 -070050 const char *src;
Linus Torvalds1da177e2005-04-16 15:20:36 -070051 static char res_value[SYMBOL_MAXLENGTH];
52 char *dst, name[SYMBOL_MAXLENGTH];
53
54 res_value[0] = 0;
55 dst = name;
56 while ((src = strchr(in, '$'))) {
57 strncat(res_value, in, src - in);
58 src++;
59 dst = name;
60 while (isalnum(*src) || *src == '_')
61 *dst++ = *src++;
62 *dst = 0;
63 sym = sym_lookup(name, 0);
64 sym_calc_value(sym);
65 strcat(res_value, sym_get_string_value(sym));
66 in = src;
67 }
68 strcat(res_value, in);
69
70 return res_value;
71}
72
73char *conf_get_default_confname(void)
74{
75 struct stat buf;
76 static char fullname[PATH_MAX+1];
77 char *env, *name;
78
79 name = conf_expand_value(conf_defname);
80 env = getenv(SRCTREE);
81 if (env) {
82 sprintf(fullname, "%s/%s", env, name);
83 if (!stat(fullname, &buf))
84 return fullname;
85 }
86 return name;
87}
88
Roman Zippel669bfad2006-06-08 22:12:42 -070089int conf_read_simple(const char *name, int def)
Linus Torvalds1da177e2005-04-16 15:20:36 -070090{
91 FILE *in = NULL;
92 char line[1024];
93 char *p, *p2;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 struct symbol *sym;
Roman Zippel669bfad2006-06-08 22:12:42 -070095 int i, def_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97 if (name) {
98 in = zconf_fopen(name);
99 } else {
100 const char **names = conf_confnames;
Roman Zippelddc97ca2006-06-08 22:12:38 -0700101 name = *names++;
102 if (!name)
103 return 1;
104 in = zconf_fopen(name);
105 if (in)
106 goto load;
107 sym_change_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 while ((name = *names++)) {
109 name = conf_expand_value(name);
110 in = zconf_fopen(name);
111 if (in) {
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700112 printf(_("#\n"
Roman Zippelddc97ca2006-06-08 22:12:38 -0700113 "# using defaults found in %s\n"
114 "#\n"), name);
115 goto load;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 }
117 }
118 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 if (!in)
120 return 1;
121
Roman Zippelddc97ca2006-06-08 22:12:38 -0700122load:
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800123 conf_filename = name;
124 conf_lineno = 0;
125 conf_warnings = 0;
126 conf_unsaved = 0;
127
Roman Zippel669bfad2006-06-08 22:12:42 -0700128 def_flags = SYMBOL_DEF << def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 for_all_symbols(i, sym) {
Roman Zippel669bfad2006-06-08 22:12:42 -0700130 sym->flags |= SYMBOL_CHANGED;
131 sym->flags &= ~(def_flags|SYMBOL_VALID);
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800132 if (sym_is_choice(sym))
Roman Zippel669bfad2006-06-08 22:12:42 -0700133 sym->flags |= def_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 switch (sym->type) {
135 case S_INT:
136 case S_HEX:
137 case S_STRING:
Roman Zippel669bfad2006-06-08 22:12:42 -0700138 if (sym->def[def].val)
139 free(sym->def[def].val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 default:
Roman Zippel669bfad2006-06-08 22:12:42 -0700141 sym->def[def].val = NULL;
142 sym->def[def].tri = no;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 }
144 }
145
146 while (fgets(line, sizeof(line), in)) {
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800147 conf_lineno++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 sym = NULL;
149 switch (line[0]) {
150 case '#':
151 if (memcmp(line + 2, "CONFIG_", 7))
152 continue;
153 p = strchr(line + 9, ' ');
154 if (!p)
155 continue;
156 *p++ = 0;
157 if (strncmp(p, "is not set", 10))
158 continue;
Roman Zippel669bfad2006-06-08 22:12:42 -0700159 if (def == S_DEF_USER) {
160 sym = sym_find(line + 9);
161 if (!sym) {
162 conf_warning("trying to assign nonexistent symbol %s", line + 9);
163 break;
164 }
165 } else {
166 sym = sym_lookup(line + 9, 0);
167 if (sym->type == S_UNKNOWN)
168 sym->type = S_BOOLEAN;
169 }
170 if (sym->flags & def_flags) {
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800171 conf_warning("trying to reassign symbol %s", sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 break;
173 }
174 switch (sym->type) {
175 case S_BOOLEAN:
176 case S_TRISTATE:
Roman Zippel669bfad2006-06-08 22:12:42 -0700177 sym->def[def].tri = no;
178 sym->flags |= def_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 break;
180 default:
181 ;
182 }
183 break;
184 case 'C':
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800185 if (memcmp(line, "CONFIG_", 7)) {
186 conf_warning("unexpected data");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 continue;
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800188 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 p = strchr(line + 7, '=');
190 if (!p)
191 continue;
192 *p++ = 0;
193 p2 = strchr(p, '\n');
194 if (p2)
195 *p2 = 0;
Roman Zippel669bfad2006-06-08 22:12:42 -0700196 if (def == S_DEF_USER) {
197 sym = sym_find(line + 7);
198 if (!sym) {
199 conf_warning("trying to assign nonexistent symbol %s", line + 7);
200 break;
201 }
202 } else {
203 sym = sym_lookup(line + 7, 0);
204 if (sym->type == S_UNKNOWN)
205 sym->type = S_OTHER;
206 }
207 if (sym->flags & def_flags) {
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800208 conf_warning("trying to reassign symbol %s", sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 break;
210 }
211 switch (sym->type) {
212 case S_TRISTATE:
213 if (p[0] == 'm') {
Roman Zippel669bfad2006-06-08 22:12:42 -0700214 sym->def[def].tri = mod;
215 sym->flags |= def_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 break;
217 }
218 case S_BOOLEAN:
219 if (p[0] == 'y') {
Roman Zippel669bfad2006-06-08 22:12:42 -0700220 sym->def[def].tri = yes;
221 sym->flags |= def_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 break;
223 }
224 if (p[0] == 'n') {
Roman Zippel669bfad2006-06-08 22:12:42 -0700225 sym->def[def].tri = no;
226 sym->flags |= def_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 break;
228 }
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800229 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 break;
Roman Zippel669bfad2006-06-08 22:12:42 -0700231 case S_OTHER:
232 if (*p != '"') {
233 for (p2 = p; *p2 && !isspace(*p2); p2++)
234 ;
235 sym->type = S_STRING;
236 goto done;
237 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 case S_STRING:
239 if (*p++ != '"')
240 break;
241 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
242 if (*p2 == '"') {
243 *p2 = 0;
244 break;
245 }
246 memmove(p2, p2 + 1, strlen(p2));
247 }
248 if (!p2) {
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800249 conf_warning("invalid string found");
250 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 }
252 case S_INT:
253 case S_HEX:
Roman Zippel669bfad2006-06-08 22:12:42 -0700254 done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 if (sym_string_valid(sym, p)) {
Roman Zippel669bfad2006-06-08 22:12:42 -0700256 sym->def[def].val = strdup(p);
257 sym->flags |= def_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 } else {
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800259 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
260 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 }
262 break;
263 default:
264 ;
265 }
266 break;
267 case '\n':
268 break;
269 default:
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800270 conf_warning("unexpected data");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 continue;
272 }
273 if (sym && sym_is_choice_value(sym)) {
274 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
Roman Zippel669bfad2006-06-08 22:12:42 -0700275 switch (sym->def[def].tri) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 case no:
277 break;
278 case mod:
Roman Zippel669bfad2006-06-08 22:12:42 -0700279 if (cs->def[def].tri == yes) {
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800280 conf_warning("%s creates inconsistent choice state", sym->name);
Roman Zippel669bfad2006-06-08 22:12:42 -0700281 cs->flags &= ~def_flags;
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800282 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 break;
284 case yes:
Roman Zippel669bfad2006-06-08 22:12:42 -0700285 if (cs->def[def].tri != no) {
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800286 conf_warning("%s creates inconsistent choice state", sym->name);
Roman Zippel669bfad2006-06-08 22:12:42 -0700287 cs->flags &= ~def_flags;
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800288 } else
Roman Zippel669bfad2006-06-08 22:12:42 -0700289 cs->def[def].val = sym;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 break;
291 }
Roman Zippel669bfad2006-06-08 22:12:42 -0700292 cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 }
294 }
295 fclose(in);
296
297 if (modules_sym)
298 sym_calc_value(modules_sym);
Roman Zippel90389162005-11-08 21:34:49 -0800299 return 0;
300}
301
302int conf_read(const char *name)
303{
304 struct symbol *sym;
305 struct property *prop;
306 struct expr *e;
Roman Zippel669bfad2006-06-08 22:12:42 -0700307 int i, flags;
Roman Zippel90389162005-11-08 21:34:49 -0800308
Roman Zippelddc97ca2006-06-08 22:12:38 -0700309 sym_change_count = 0;
310
Roman Zippel669bfad2006-06-08 22:12:42 -0700311 if (conf_read_simple(name, S_DEF_USER))
Roman Zippel90389162005-11-08 21:34:49 -0800312 return 1;
313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 for_all_symbols(i, sym) {
315 sym_calc_value(sym);
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800316 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
317 goto sym_ok;
318 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
319 /* check that calculated value agrees with saved value */
320 switch (sym->type) {
321 case S_BOOLEAN:
322 case S_TRISTATE:
Roman Zippel0c1822e2006-06-08 22:12:41 -0700323 if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800324 break;
325 if (!sym_is_choice(sym))
326 goto sym_ok;
327 default:
Roman Zippel0c1822e2006-06-08 22:12:41 -0700328 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
Roman Zippelc1a0f5e2005-11-08 21:34:54 -0800329 goto sym_ok;
330 break;
331 }
332 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
333 /* no previous value and not saved */
334 goto sym_ok;
335 conf_unsaved++;
336 /* maybe print value in verbose mode... */
337 sym_ok:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
339 if (sym->visible == no)
Roman Zippel669bfad2006-06-08 22:12:42 -0700340 sym->flags &= ~SYMBOL_DEF_USER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 switch (sym->type) {
342 case S_STRING:
343 case S_INT:
344 case S_HEX:
Roman Zippel669bfad2006-06-08 22:12:42 -0700345 if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
346 sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 default:
348 break;
349 }
350 }
351 if (!sym_is_choice(sym))
352 continue;
353 prop = sym_get_choice_prop(sym);
Roman Zippel669bfad2006-06-08 22:12:42 -0700354 flags = sym->flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 for (e = prop->expr; e; e = e->left.expr)
356 if (e->right.sym->visible != no)
Roman Zippel669bfad2006-06-08 22:12:42 -0700357 flags &= e->right.sym->flags;
358 sym->flags |= flags & SYMBOL_DEF_USER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 }
360
Roman Zippelddc97ca2006-06-08 22:12:38 -0700361 sym_change_count += conf_warnings || conf_unsaved;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362
363 return 0;
364}
365
366int conf_write(const char *name)
367{
Roman Zippelc955cca2006-06-08 22:12:39 -0700368 FILE *out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 struct symbol *sym;
370 struct menu *menu;
371 const char *basename;
372 char dirname[128], tmpname[128], newname[128];
373 int type, l;
374 const char *str;
375 time_t now;
376 int use_timestamp = 1;
377 char *env;
378
379 dirname[0] = 0;
380 if (name && name[0]) {
381 struct stat st;
382 char *slash;
383
384 if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
385 strcpy(dirname, name);
386 strcat(dirname, "/");
387 basename = conf_def_filename;
388 } else if ((slash = strrchr(name, '/'))) {
389 int size = slash - name + 1;
390 memcpy(dirname, name, size);
391 dirname[size] = 0;
392 if (slash[1])
393 basename = slash + 1;
394 else
395 basename = conf_def_filename;
396 } else
397 basename = name;
398 } else
399 basename = conf_def_filename;
400
401 sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
402 out = fopen(newname, "w");
403 if (!out)
404 return 1;
Sam Ravnborg2244cbd2006-01-16 12:12:12 +0100405 sym = sym_lookup("KERNELVERSION", 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 sym_calc_value(sym);
407 time(&now);
408 env = getenv("KCONFIG_NOTIMESTAMP");
409 if (env && *env)
410 use_timestamp = 0;
411
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700412 fprintf(out, _("#\n"
413 "# Automatically generated make config: don't edit\n"
414 "# Linux kernel version: %s\n"
415 "%s%s"
416 "#\n"),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 sym_get_string_value(sym),
418 use_timestamp ? "# " : "",
419 use_timestamp ? ctime(&now) : "");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
421 if (!sym_change_count)
422 sym_clear_all_valid();
423
424 menu = rootmenu.list;
425 while (menu) {
426 sym = menu->sym;
427 if (!sym) {
428 if (!menu_is_visible(menu))
429 goto next;
430 str = menu_get_prompt(menu);
431 fprintf(out, "\n"
432 "#\n"
433 "# %s\n"
434 "#\n", str);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 } else if (!(sym->flags & SYMBOL_CHOICE)) {
436 sym_calc_value(sym);
437 if (!(sym->flags & SYMBOL_WRITE))
438 goto next;
439 sym->flags &= ~SYMBOL_WRITE;
440 type = sym->type;
441 if (type == S_TRISTATE) {
442 sym_calc_value(modules_sym);
443 if (modules_sym->curr.tri == no)
444 type = S_BOOLEAN;
445 }
446 switch (type) {
447 case S_BOOLEAN:
448 case S_TRISTATE:
449 switch (sym_get_tristate_value(sym)) {
450 case no:
451 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 break;
453 case mod:
454 fprintf(out, "CONFIG_%s=m\n", sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 break;
456 case yes:
457 fprintf(out, "CONFIG_%s=y\n", sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 break;
459 }
460 break;
461 case S_STRING:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 str = sym_get_string_value(sym);
463 fprintf(out, "CONFIG_%s=\"", sym->name);
Roman Zippelc955cca2006-06-08 22:12:39 -0700464 while (1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 l = strcspn(str, "\"\\");
466 if (l) {
467 fwrite(str, l, 1, out);
Roman Zippelc955cca2006-06-08 22:12:39 -0700468 str += l;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 }
Roman Zippelc955cca2006-06-08 22:12:39 -0700470 if (!*str)
471 break;
472 fprintf(out, "\\%c", *str++);
473 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 fputs("\"\n", out);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 break;
476 case S_HEX:
477 str = sym_get_string_value(sym);
478 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
479 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 break;
481 }
482 case S_INT:
483 str = sym_get_string_value(sym);
484 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 break;
486 }
487 }
488
489 next:
490 if (menu->list) {
491 menu = menu->list;
492 continue;
493 }
494 if (menu->next)
495 menu = menu->next;
496 else while ((menu = menu->parent)) {
497 if (menu->next) {
498 menu = menu->next;
499 break;
500 }
501 }
502 }
503 fclose(out);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 if (!name || basename != conf_def_filename) {
505 if (!name)
506 name = conf_def_filename;
507 sprintf(tmpname, "%s.old", name);
508 rename(name, tmpname);
509 }
510 sprintf(tmpname, "%s%s", dirname, basename);
511 if (rename(newname, tmpname))
512 return 1;
513
Roman Zippelddc97ca2006-06-08 22:12:38 -0700514 printf(_("#\n"
515 "# configuration written to %s\n"
516 "#\n"), tmpname);
517
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 sym_change_count = 0;
519
520 return 0;
521}
Roman Zippelc955cca2006-06-08 22:12:39 -0700522
523int conf_write_autoconf(void)
524{
525 struct symbol *sym;
526 const char *str;
527 char *name;
528 FILE *out, *out_h;
529 time_t now;
530 int i, l;
531
532 file_write_dep("include/config/auto.conf.cmd");
533
534 out = fopen(".tmpconfig", "w");
535 if (!out)
536 return 1;
537
538 out_h = fopen(".tmpconfig.h", "w");
539 if (!out_h) {
540 fclose(out);
541 return 1;
542 }
543
544 sym = sym_lookup("KERNELVERSION", 0);
545 sym_calc_value(sym);
546 time(&now);
547 fprintf(out, "#\n"
548 "# Automatically generated make config: don't edit\n"
549 "# Linux kernel version: %s\n"
550 "# %s"
551 "#\n",
552 sym_get_string_value(sym), ctime(&now));
553 fprintf(out_h, "/*\n"
554 " * Automatically generated C config: don't edit\n"
555 " * Linux kernel version: %s\n"
556 " * %s"
557 " */\n"
558 "#define AUTOCONF_INCLUDED\n",
559 sym_get_string_value(sym), ctime(&now));
560
561 sym_clear_all_valid();
562
563 for_all_symbols(i, sym) {
564 sym_calc_value(sym);
565 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
566 continue;
567 switch (sym->type) {
568 case S_BOOLEAN:
569 case S_TRISTATE:
570 switch (sym_get_tristate_value(sym)) {
571 case no:
572 break;
573 case mod:
574 fprintf(out, "CONFIG_%s=m\n", sym->name);
575 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
576 break;
577 case yes:
578 fprintf(out, "CONFIG_%s=y\n", sym->name);
579 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
580 break;
581 }
582 break;
583 case S_STRING:
584 str = sym_get_string_value(sym);
585 fprintf(out, "CONFIG_%s=\"", sym->name);
586 fprintf(out_h, "#define CONFIG_%s \"", sym->name);
587 while (1) {
588 l = strcspn(str, "\"\\");
589 if (l) {
590 fwrite(str, l, 1, out);
591 fwrite(str, l, 1, out_h);
592 str += l;
593 }
594 if (!*str)
595 break;
596 fprintf(out, "\\%c", *str);
597 fprintf(out_h, "\\%c", *str);
598 str++;
599 }
600 fputs("\"\n", out);
601 fputs("\"\n", out_h);
602 break;
603 case S_HEX:
604 str = sym_get_string_value(sym);
605 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
606 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
607 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
608 break;
609 }
610 case S_INT:
611 str = sym_get_string_value(sym);
612 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
613 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
614 break;
615 default:
616 break;
617 }
618 }
619 fclose(out);
620 fclose(out_h);
621
622 name = getenv("KCONFIG_AUTOHEADER");
623 if (!name)
624 name = "include/linux/autoconf.h";
625 if (rename(".tmpconfig.h", name))
626 return 1;
627 name = getenv("KCONFIG_AUTOCONFIG");
628 if (!name)
629 name = "include/config/auto.conf";
630 /*
631 * This must be the last step, kbuild has a dependency on auto.conf
632 * and this marks the successful completion of the previous steps.
633 */
634 if (rename(".tmpconfig", name))
635 return 1;
636
637 return 0;
638}