blob: 91c1ed5fe7f83efbd28cd81d3e805000248eee00 [file] [log] [blame]
landley5257cf52006-10-31 23:30:06 -05001/*
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 <errno.h>
9#include <fcntl.h>
10#include <limits.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <time.h>
15#include <unistd.h>
16
17#define LKC_DIRECT_LINK
18#include "lkc.h"
19
20static void conf_warning(const char *fmt, ...)
21 __attribute__ ((format (printf, 1, 2)));
22
23static const char *conf_filename;
24static int conf_lineno, conf_warnings, conf_unsaved;
25
26#ifndef conf_defname
27const char conf_defname[] = "arch/$ARCH/defconfig";
28#endif
29
Rob Landleyd989df32007-03-15 13:59:06 -040030#ifndef CONFIG_PREFIX
31#define CONFIG_PREFIX "CONFIG_"
32#endif
33
landley5257cf52006-10-31 23:30:06 -050034static void conf_warning(const char *fmt, ...)
35{
36 va_list ap;
37 va_start(ap, fmt);
38 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
39 vfprintf(stderr, fmt, ap);
40 fprintf(stderr, "\n");
41 va_end(ap);
42 conf_warnings++;
43}
44
45const char *conf_get_configname(void)
46{
47 char *name = getenv("KCONFIG_CONFIG");
48
49 return name ? name : ".config";
50}
51
52static char *conf_expand_value(const char *in)
53{
54 struct symbol *sym;
55 const char *src;
56 static char res_value[SYMBOL_MAXLENGTH];
57 char *dst, name[SYMBOL_MAXLENGTH];
58
59 res_value[0] = 0;
60 dst = name;
61 while ((src = strchr(in, '$'))) {
62 strncat(res_value, in, src - in);
63 src++;
64 dst = name;
65 while (isalnum(*src) || *src == '_')
66 *dst++ = *src++;
67 *dst = 0;
68 sym = sym_lookup(name, 0);
69 sym_calc_value(sym);
70 strcat(res_value, sym_get_string_value(sym));
71 in = src;
72 }
73 strcat(res_value, in);
74
75 return res_value;
76}
77
78char *conf_get_default_confname(void)
79{
80 struct stat buf;
81 static char fullname[PATH_MAX+1];
82 char *env, *name;
83
84 name = conf_expand_value(conf_defname);
85 env = getenv(SRCTREE);
86 if (env) {
87 sprintf(fullname, "%s/%s", env, name);
88 if (!stat(fullname, &buf))
89 return fullname;
90 }
91 return name;
92}
93
94int conf_read_simple(const char *name, int def)
95{
96 FILE *in = NULL;
97 char line[1024];
98 char *p, *p2;
99 struct symbol *sym;
100 int i, def_flags;
101
102 if (name) {
103 in = zconf_fopen(name);
104 } else {
105 struct property *prop;
106
107 name = conf_get_configname();
108 in = zconf_fopen(name);
109 if (in)
110 goto load;
111 sym_change_count++;
112 if (!sym_defconfig_list)
113 return 1;
114
115 for_all_defaults(sym_defconfig_list, prop) {
116 if (expr_calc_value(prop->visible.expr) == no ||
117 prop->expr->type != E_SYMBOL)
118 continue;
119 name = conf_expand_value(prop->expr->left.sym->name);
120 in = zconf_fopen(name);
121 if (in) {
122 printf(_("#\n"
123 "# using defaults found in %s\n"
124 "#\n"), name);
125 goto load;
126 }
127 }
128 }
129 if (!in)
130 return 1;
131
132load:
133 conf_filename = name;
134 conf_lineno = 0;
135 conf_warnings = 0;
136 conf_unsaved = 0;
137
138 def_flags = SYMBOL_DEF << def;
139 for_all_symbols(i, sym) {
140 sym->flags |= SYMBOL_CHANGED;
141 sym->flags &= ~(def_flags|SYMBOL_VALID);
142 if (sym_is_choice(sym))
143 sym->flags |= def_flags;
144 switch (sym->type) {
145 case S_INT:
146 case S_HEX:
147 case S_STRING:
148 if (sym->def[def].val)
149 free(sym->def[def].val);
150 default:
151 sym->def[def].val = NULL;
152 sym->def[def].tri = no;
153 }
154 }
155
156 while (fgets(line, sizeof(line), in)) {
157 conf_lineno++;
158 sym = NULL;
159 switch (line[0]) {
160 case '#':
Rob Landleyd989df32007-03-15 13:59:06 -0400161 if (line[1]!=' ' || memcmp(line + 2, CONFIG_PREFIX,
162 strlen(CONFIG_PREFIX))) {
landley5257cf52006-10-31 23:30:06 -0500163 continue;
Rob Landleyd989df32007-03-15 13:59:06 -0400164 }
165 p = strchr(line + 2 + strlen(CONFIG_PREFIX), ' ');
landley5257cf52006-10-31 23:30:06 -0500166 if (!p)
167 continue;
168 *p++ = 0;
169 if (strncmp(p, "is not set", 10))
170 continue;
171 if (def == S_DEF_USER) {
Rob Landleyd989df32007-03-15 13:59:06 -0400172 sym = sym_find(line + 2 + strlen(CONFIG_PREFIX));
landley5257cf52006-10-31 23:30:06 -0500173 if (!sym) {
Rob Landleyd989df32007-03-15 13:59:06 -0400174 conf_warning("trying to assign nonexistent symbol %s", line + 2 + strlen(CONFIG_PREFIX));
landley5257cf52006-10-31 23:30:06 -0500175 break;
176 }
177 } else {
178 sym = sym_lookup(line + 9, 0);
179 if (sym->type == S_UNKNOWN)
180 sym->type = S_BOOLEAN;
181 }
182 if (sym->flags & def_flags) {
183 conf_warning("trying to reassign symbol %s", sym->name);
184 break;
185 }
186 switch (sym->type) {
187 case S_BOOLEAN:
188 case S_TRISTATE:
189 sym->def[def].tri = no;
190 sym->flags |= def_flags;
191 break;
192 default:
193 ;
194 }
195 break;
Rob Landleyd989df32007-03-15 13:59:06 -0400196 case 'A' ... 'Z':
197 if (memcmp(line, CONFIG_PREFIX, strlen(CONFIG_PREFIX))) {
landley5257cf52006-10-31 23:30:06 -0500198 conf_warning("unexpected data");
199 continue;
200 }
Rob Landleyd989df32007-03-15 13:59:06 -0400201 p = strchr(line + strlen(CONFIG_PREFIX), '=');
landley5257cf52006-10-31 23:30:06 -0500202 if (!p)
203 continue;
204 *p++ = 0;
205 p2 = strchr(p, '\n');
206 if (p2) {
207 *p2-- = 0;
208 if (*p2 == '\r')
209 *p2 = 0;
210 }
211 if (def == S_DEF_USER) {
Rob Landleyd989df32007-03-15 13:59:06 -0400212 sym = sym_find(line + strlen(CONFIG_PREFIX));
landley5257cf52006-10-31 23:30:06 -0500213 if (!sym) {
214 conf_warning("trying to assign nonexistent symbol %s", line + 7);
215 break;
216 }
217 } else {
Rob Landleyd989df32007-03-15 13:59:06 -0400218 sym = sym_lookup(line + strlen(CONFIG_PREFIX), 0);
landley5257cf52006-10-31 23:30:06 -0500219 if (sym->type == S_UNKNOWN)
220 sym->type = S_OTHER;
221 }
222 if (sym->flags & def_flags) {
223 conf_warning("trying to reassign symbol %s", sym->name);
224 break;
225 }
226 switch (sym->type) {
227 case S_TRISTATE:
228 if (p[0] == 'm') {
229 sym->def[def].tri = mod;
230 sym->flags |= def_flags;
231 break;
232 }
233 case S_BOOLEAN:
234 if (p[0] == 'y') {
235 sym->def[def].tri = yes;
236 sym->flags |= def_flags;
237 break;
238 }
239 if (p[0] == 'n') {
240 sym->def[def].tri = no;
241 sym->flags |= def_flags;
242 break;
243 }
244 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
245 break;
246 case S_OTHER:
247 if (*p != '"') {
248 for (p2 = p; *p2 && !isspace(*p2); p2++)
249 ;
250 sym->type = S_STRING;
251 goto done;
252 }
253 case S_STRING:
254 if (*p++ != '"')
255 break;
256 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
257 if (*p2 == '"') {
258 *p2 = 0;
259 break;
260 }
261 memmove(p2, p2 + 1, strlen(p2));
262 }
263 if (!p2) {
264 conf_warning("invalid string found");
265 continue;
266 }
267 case S_INT:
268 case S_HEX:
269 done:
270 if (sym_string_valid(sym, p)) {
271 sym->def[def].val = strdup(p);
272 sym->flags |= def_flags;
273 } else {
274 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
275 continue;
276 }
277 break;
278 default:
279 ;
280 }
281 break;
282 case '\r':
283 case '\n':
284 break;
285 default:
286 conf_warning("unexpected data");
287 continue;
288 }
289 if (sym && sym_is_choice_value(sym)) {
290 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
291 switch (sym->def[def].tri) {
292 case no:
293 break;
294 case mod:
295 if (cs->def[def].tri == yes) {
296 conf_warning("%s creates inconsistent choice state", sym->name);
297 cs->flags &= ~def_flags;
298 }
299 break;
300 case yes:
301 if (cs->def[def].tri != no) {
302 conf_warning("%s creates inconsistent choice state", sym->name);
303 cs->flags &= ~def_flags;
304 } else
305 cs->def[def].val = sym;
306 break;
307 }
308 cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
309 }
310 }
311 fclose(in);
312
313 if (modules_sym)
314 sym_calc_value(modules_sym);
315 return 0;
316}
317
318int conf_read(const char *name)
319{
320 struct symbol *sym;
321 struct property *prop;
322 struct expr *e;
323 int i, flags;
324
325 sym_change_count = 0;
326
327 if (conf_read_simple(name, S_DEF_USER))
328 return 1;
329
330 for_all_symbols(i, sym) {
331 sym_calc_value(sym);
332 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
333 goto sym_ok;
334 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
335 /* check that calculated value agrees with saved value */
336 switch (sym->type) {
337 case S_BOOLEAN:
338 case S_TRISTATE:
339 if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
340 break;
341 if (!sym_is_choice(sym))
342 goto sym_ok;
343 default:
344 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
345 goto sym_ok;
346 break;
347 }
348 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
349 /* no previous value and not saved */
350 goto sym_ok;
351 conf_unsaved++;
352 /* maybe print value in verbose mode... */
353 sym_ok:
354 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
355 if (sym->visible == no)
356 sym->flags &= ~SYMBOL_DEF_USER;
357 switch (sym->type) {
358 case S_STRING:
359 case S_INT:
360 case S_HEX:
361 if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
362 sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
363 default:
364 break;
365 }
366 }
367 if (!sym_is_choice(sym))
368 continue;
369 prop = sym_get_choice_prop(sym);
370 flags = sym->flags;
371 for (e = prop->expr; e; e = e->left.expr)
372 if (e->right.sym->visible != no)
373 flags &= e->right.sym->flags;
374 sym->flags &= flags | ~SYMBOL_DEF_USER;
375 }
376
377 sym_change_count += conf_warnings || conf_unsaved;
378
379 return 0;
380}
381
382struct menu *next_menu(struct menu *menu)
383{
384 if (menu->list) return menu->list;
385 do {
386 if (menu->next) {
387 menu = menu->next;
388 break;
389 }
390 } while ((menu = menu->parent));
391
392 return menu;
393}
394
395#define SYMBOL_FORCEWRITE (1<<31)
396
397int conf_write(const char *name)
398{
399 FILE *out;
400 struct symbol *sym;
401 struct menu *menu;
402 const char *basename;
403 char dirname[128], tmpname[128], newname[128];
404 int type, l, writetype;
405 const char *str;
406 time_t now;
407 int use_timestamp = 1;
408 char *env;
409
410 dirname[0] = 0;
411 if (name && name[0]) {
412 struct stat st;
413 char *slash;
414
415 if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
416 strcpy(dirname, name);
417 strcat(dirname, "/");
418 basename = conf_get_configname();
419 } else if ((slash = strrchr(name, '/'))) {
420 int size = slash - name + 1;
421 memcpy(dirname, name, size);
422 dirname[size] = 0;
423 if (slash[1])
424 basename = slash + 1;
425 else
426 basename = conf_get_configname();
427 } else
428 basename = name;
429 } else
430 basename = conf_get_configname();
431
432 sprintf(newname, "%s%s", dirname, basename);
433 env = getenv("KCONFIG_OVERWRITECONFIG");
434 if (!env || !*env) {
435 sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
436 out = fopen(tmpname, "w");
437 } else {
438 *tmpname = 0;
439 out = fopen(newname, "w");
440 }
441 if (!out)
442 return 1;
443
Rob Landleyd989df32007-03-15 13:59:06 -0400444 sym = sym_lookup("KCONFIG_VERSION", 0);
landley5257cf52006-10-31 23:30:06 -0500445 sym_calc_value(sym);
446 time(&now);
447 env = getenv("KCONFIG_NOTIMESTAMP");
448 if (env && *env)
449 use_timestamp = 0;
450
451 fprintf(out, _("#\n"
452 "# Automatically generated make config: don't edit\n"
453 "# "PROJECT_NAME" version: %s\n"
454 "%s%s"
455 "#\n"),
456 sym_get_string_value(sym),
457 use_timestamp ? "# " : "",
458 use_timestamp ? ctime(&now) : "");
459
460 if (!sym_change_count)
461 sym_clear_all_valid();
462
463 // Write out all symbols (even in closed sub-menus).
464 if (1) {
465 for (menu = rootmenu.list; menu; menu = next_menu(menu))
466 if (menu->sym) menu->sym->flags |= SYMBOL_FORCEWRITE;
467 writetype = SYMBOL_FORCEWRITE;
468
469 // Don't write out symbols in closed menus.
470
471 } else writetype = SYMBOL_WRITE;
472
473
474 menu = rootmenu.list;
475 while (menu) {
476 sym = menu->sym;
477 if (!sym) {
478 if (!menu_is_visible(menu))
479 goto next;
480 str = menu_get_prompt(menu);
481 fprintf(out, "\n"
482 "#\n"
483 "# %s\n"
484 "#\n", str);
485 } else if (!(sym->flags & SYMBOL_CHOICE)) {
486 sym_calc_value(sym);
487 if (!(sym->flags & writetype))
488 goto next;
489 sym->flags &= ~writetype;
490 type = sym->type;
491 if (type == S_TRISTATE) {
492 sym_calc_value(modules_sym);
493 if (modules_sym->curr.tri == no)
494 type = S_BOOLEAN;
495 }
496 switch (type) {
497 case S_BOOLEAN:
498 case S_TRISTATE:
499 switch (sym_get_tristate_value(sym)) {
500 case no:
Rob Landleyd989df32007-03-15 13:59:06 -0400501 fprintf(out, "# "CONFIG_PREFIX"%s is not set\n", sym->name);
landley5257cf52006-10-31 23:30:06 -0500502 break;
503 case mod:
Rob Landleyd989df32007-03-15 13:59:06 -0400504 fprintf(out, CONFIG_PREFIX"%s=m\n", sym->name);
landley5257cf52006-10-31 23:30:06 -0500505 break;
506 case yes:
Rob Landleyd989df32007-03-15 13:59:06 -0400507 fprintf(out, CONFIG_PREFIX"%s=y\n", sym->name);
landley5257cf52006-10-31 23:30:06 -0500508 break;
509 }
510 break;
511 case S_STRING:
512 str = sym_get_string_value(sym);
Rob Landleyd989df32007-03-15 13:59:06 -0400513 fprintf(out, CONFIG_PREFIX"%s=\"", sym->name);
landley5257cf52006-10-31 23:30:06 -0500514 while (1) {
515 l = strcspn(str, "\"\\");
516 if (l) {
517 fwrite(str, l, 1, out);
518 str += l;
519 }
520 if (!*str)
521 break;
522 fprintf(out, "\\%c", *str++);
523 }
524 fputs("\"\n", out);
525 break;
526 case S_HEX:
527 str = sym_get_string_value(sym);
528 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
Rob Landleyd989df32007-03-15 13:59:06 -0400529 fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, *str ? str : "0");
landley5257cf52006-10-31 23:30:06 -0500530 break;
531 }
532 case S_INT:
533 str = sym_get_string_value(sym);
Rob Landleyd989df32007-03-15 13:59:06 -0400534 fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, *str ? str : "0");
landley5257cf52006-10-31 23:30:06 -0500535 break;
536 }
537 }
538
539 next:
540 if (writetype == SYMBOL_WRITE) {
541 if (menu->list) {
542 menu = menu->list;
543 continue;
544 }
545 if (menu->next)
546 menu = menu->next;
547 else while ((menu = menu->parent)) {
548 if (menu->next) {
549 menu = menu->next;
550 break;
551 }
552 }
553 } else
554 menu = next_menu(menu);
555 }
556 fclose(out);
557
558 if (*tmpname) {
559 strcat(dirname, basename);
560 strcat(dirname, ".old");
561 rename(newname, dirname);
562 if (rename(tmpname, newname))
563 return 1;
564 }
565
566 printf(_("#\n"
567 "# configuration written to %s\n"
568 "#\n"), newname);
569
570 sym_change_count = 0;
571
572 return 0;
573}
574
575int conf_split_config(void)
576{
577 char *name, path[128];
578 char *s, *d, c;
579 struct symbol *sym;
580 struct stat sb;
581 int res, i, fd;
582
583 name = getenv("KCONFIG_AUTOCONFIG");
584 if (!name)
585 name = "include/config/auto.conf";
586 conf_read_simple(name, S_DEF_AUTO);
587
588 if (chdir("include/config"))
589 return 1;
590
591 res = 0;
592 for_all_symbols(i, sym) {
593 sym_calc_value(sym);
594 if ((sym->flags & SYMBOL_AUTO) || !sym->name)
595 continue;
596 if (sym->flags & SYMBOL_WRITE) {
597 if (sym->flags & SYMBOL_DEF_AUTO) {
598 /*
599 * symbol has old and new value,
600 * so compare them...
601 */
602 switch (sym->type) {
603 case S_BOOLEAN:
604 case S_TRISTATE:
605 if (sym_get_tristate_value(sym) ==
606 sym->def[S_DEF_AUTO].tri)
607 continue;
608 break;
609 case S_STRING:
610 case S_HEX:
611 case S_INT:
612 if (!strcmp(sym_get_string_value(sym),
613 sym->def[S_DEF_AUTO].val))
614 continue;
615 break;
616 default:
617 break;
618 }
619 } else {
620 /*
621 * If there is no old value, only 'no' (unset)
622 * is allowed as new value.
623 */
624 switch (sym->type) {
625 case S_BOOLEAN:
626 case S_TRISTATE:
627 if (sym_get_tristate_value(sym) == no)
628 continue;
629 break;
630 default:
631 break;
632 }
633 }
634 } else if (!(sym->flags & SYMBOL_DEF_AUTO))
635 /* There is neither an old nor a new value. */
636 continue;
637 /* else
638 * There is an old value, but no new value ('no' (unset)
639 * isn't saved in auto.conf, so the old value is always
640 * different from 'no').
641 */
642
643 /* Replace all '_' and append ".h" */
644 s = sym->name;
645 d = path;
646 while ((c = *s++)) {
647 c = tolower(c);
648 *d++ = (c == '_') ? '/' : c;
649 }
650 strcpy(d, ".h");
651
652 /* Assume directory path already exists. */
653 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
654 if (fd == -1) {
655 if (errno != ENOENT) {
656 res = 1;
657 break;
658 }
659 /*
660 * Create directory components,
661 * unless they exist already.
662 */
663 d = path;
664 while ((d = strchr(d, '/'))) {
665 *d = 0;
666 if (stat(path, &sb) && mkdir(path, 0755)) {
667 res = 1;
668 goto out;
669 }
670 *d++ = '/';
671 }
672 /* Try it again. */
673 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
674 if (fd == -1) {
675 res = 1;
676 break;
677 }
678 }
679 close(fd);
680 }
681out:
682 if (chdir("../.."))
683 return 1;
684
685 return res;
686}
687
688int conf_write_autoconf(void)
689{
690 struct symbol *sym;
691 const char *str;
692 char *name;
693 FILE *out, *out_h;
694 time_t now;
695 int i, l;
696
697 sym_clear_all_valid();
698
699 file_write_dep("include/config/auto.conf.cmd");
700
701 if (conf_split_config())
702 return 1;
703
704 out = fopen(".tmpconfig", "w");
705 if (!out)
706 return 1;
707
708 out_h = fopen(".tmpconfig.h", "w");
709 if (!out_h) {
710 fclose(out);
711 return 1;
712 }
713
Rob Landleyd989df32007-03-15 13:59:06 -0400714 sym = sym_lookup("KCONFIG_VERSION", 0);
landley5257cf52006-10-31 23:30:06 -0500715 sym_calc_value(sym);
716 time(&now);
717 fprintf(out, "#\n"
718 "# Automatically generated make config: don't edit\n"
719 "# "PROJECT_NAME" version: %s\n"
720 "# %s"
721 "#\n",
722 sym_get_string_value(sym), ctime(&now));
723 fprintf(out_h, "/*\n"
724 " * Automatically generated C config: don't edit\n"
725 " * "PROJECT_NAME" version: %s\n"
726 " * %s"
727 " */\n"
Rob Landleyd989df32007-03-15 13:59:06 -0400728 // "#define AUTOCONF_INCLUDED\n"
729 , sym_get_string_value(sym), ctime(&now));
landley5257cf52006-10-31 23:30:06 -0500730
731 for_all_symbols(i, sym) {
732 sym_calc_value(sym);
733 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
734 continue;
735 switch (sym->type) {
736 case S_BOOLEAN:
737 case S_TRISTATE:
738 switch (sym_get_tristate_value(sym)) {
739 case no:
740 break;
741 case mod:
Rob Landleyd989df32007-03-15 13:59:06 -0400742 fprintf(out, CONFIG_PREFIX"%s=m\n", sym->name);
landley5257cf52006-10-31 23:30:06 -0500743 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
744 break;
745 case yes:
Rob Landleyd989df32007-03-15 13:59:06 -0400746 fprintf(out, CONFIG_PREFIX"%s=y\n", sym->name);
747 fprintf(out_h, "#define "CONFIG_PREFIX"%s 1\n", sym->name);
landley5257cf52006-10-31 23:30:06 -0500748 break;
749 }
750 break;
751 case S_STRING:
752 str = sym_get_string_value(sym);
Rob Landleyd989df32007-03-15 13:59:06 -0400753 fprintf(out, CONFIG_PREFIX"%s=\"", sym->name);
754 fprintf(out_h, "#define "CONFIG_PREFIX"%s \"", sym->name);
landley5257cf52006-10-31 23:30:06 -0500755 while (1) {
756 l = strcspn(str, "\"\\");
757 if (l) {
758 fwrite(str, l, 1, out);
759 fwrite(str, l, 1, out_h);
760 str += l;
761 }
762 if (!*str)
763 break;
764 fprintf(out, "\\%c", *str);
765 fprintf(out_h, "\\%c", *str);
766 str++;
767 }
768 fputs("\"\n", out);
769 fputs("\"\n", out_h);
770 break;
771 case S_HEX:
772 str = sym_get_string_value(sym);
773 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
Rob Landleyd989df32007-03-15 13:59:06 -0400774 fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, str);
775 fprintf(out_h, "#define "CONFIG_PREFIX"%s 0x%s\n", sym->name, str);
landley5257cf52006-10-31 23:30:06 -0500776 break;
777 }
778 case S_INT:
779 str = sym_get_string_value(sym);
Rob Landleyd989df32007-03-15 13:59:06 -0400780 fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, str);
781 fprintf(out_h, "#define "CONFIG_PREFIX"%s %s\n", sym->name, str);
landley5257cf52006-10-31 23:30:06 -0500782 break;
783 default:
784 break;
785 }
786 }
787 fclose(out);
788 fclose(out_h);
789
790 name = getenv("KCONFIG_AUTOHEADER");
791 if (!name)
792 name = "include/linux/autoconf.h";
793 if (rename(".tmpconfig.h", name))
794 return 1;
795 name = getenv("KCONFIG_AUTOCONFIG");
796 if (!name)
797 name = "include/config/auto.conf";
798 /*
799 * This must be the last step, kbuild has a dependency on auto.conf
800 * and this marks the successful completion of the previous steps.
801 */
802 if (rename(".tmpconfig", name))
803 return 1;
804
805 return 0;
806}