kconfig/confdata.c
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Jul 13 10:32:38 2008 +0000 (2008-07-13)
changeset 645 8e58024f8e37
parent 39 af42eec9d383
child 943 1cca90ce0481
permissions -rw-r--r--
Ioannis E. VENETIS <venetis@mail.capsl.udel.edu> pointed out that GMP and MPFR were not used by gcc.
Turned out that none could use GMP and MPFR as the config option changed its name, but the change was not propagated to all users.

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