kconfig/confdata.c
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Apr 15 16:45:11 2007 +0000 (2007-04-15)
changeset 39 af42eec9d383
parent 1 eeea35fbf182
child 94 f32c4f663805
permissions -rw-r--r--
Update to latest kconfig from linux-2.6.20.7.
I'm not sure of the improvements, but at least we're up-to-date, and updating in the future will be easier.
     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 	printf(_("#\n"
   528 		 "# configuration written to %s\n"
   529 		 "#\n"), newname);
   530 
   531 	sym_set_change_count(0);
   532 
   533 	return 0;
   534 }
   535 
   536 int conf_split_config(void)
   537 {
   538 	char *name, path[128];
   539 	char *s, *d, c;
   540 	struct symbol *sym;
   541 	struct stat sb;
   542 	int res, i, fd;
   543 
   544 	name = getenv("KCONFIG_AUTOCONFIG");
   545 	if (!name)
   546 		name = "include/config/auto.conf";
   547 	conf_read_simple(name, S_DEF_AUTO);
   548 
   549 	if (chdir("include/config"))
   550 		return 1;
   551 
   552 	res = 0;
   553 	for_all_symbols(i, sym) {
   554 		sym_calc_value(sym);
   555 		if ((sym->flags & SYMBOL_AUTO) || !sym->name)
   556 			continue;
   557 		if (sym->flags & SYMBOL_WRITE) {
   558 			if (sym->flags & SYMBOL_DEF_AUTO) {
   559 				/*
   560 				 * symbol has old and new value,
   561 				 * so compare them...
   562 				 */
   563 				switch (sym->type) {
   564 				case S_BOOLEAN:
   565 				case S_TRISTATE:
   566 					if (sym_get_tristate_value(sym) ==
   567 					    sym->def[S_DEF_AUTO].tri)
   568 						continue;
   569 					break;
   570 				case S_STRING:
   571 				case S_HEX:
   572 				case S_INT:
   573 					if (!strcmp(sym_get_string_value(sym),
   574 						    sym->def[S_DEF_AUTO].val))
   575 						continue;
   576 					break;
   577 				default:
   578 					break;
   579 				}
   580 			} else {
   581 				/*
   582 				 * If there is no old value, only 'no' (unset)
   583 				 * is allowed as new value.
   584 				 */
   585 				switch (sym->type) {
   586 				case S_BOOLEAN:
   587 				case S_TRISTATE:
   588 					if (sym_get_tristate_value(sym) == no)
   589 						continue;
   590 					break;
   591 				default:
   592 					break;
   593 				}
   594 			}
   595 		} else if (!(sym->flags & SYMBOL_DEF_AUTO))
   596 			/* There is neither an old nor a new value. */
   597 			continue;
   598 		/* else
   599 		 *	There is an old value, but no new value ('no' (unset)
   600 		 *	isn't saved in auto.conf, so the old value is always
   601 		 *	different from 'no').
   602 		 */
   603 
   604 		/* Replace all '_' and append ".h" */
   605 		s = sym->name;
   606 		d = path;
   607 		while ((c = *s++)) {
   608 			c = tolower(c);
   609 			*d++ = (c == '_') ? '/' : c;
   610 		}
   611 		strcpy(d, ".h");
   612 
   613 		/* Assume directory path already exists. */
   614 		fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
   615 		if (fd == -1) {
   616 			if (errno != ENOENT) {
   617 				res = 1;
   618 				break;
   619 			}
   620 			/*
   621 			 * Create directory components,
   622 			 * unless they exist already.
   623 			 */
   624 			d = path;
   625 			while ((d = strchr(d, '/'))) {
   626 				*d = 0;
   627 				if (stat(path, &sb) && mkdir(path, 0755)) {
   628 					res = 1;
   629 					goto out;
   630 				}
   631 				*d++ = '/';
   632 			}
   633 			/* Try it again. */
   634 			fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
   635 			if (fd == -1) {
   636 				res = 1;
   637 				break;
   638 			}
   639 		}
   640 		close(fd);
   641 	}
   642 out:
   643 	if (chdir("../.."))
   644 		return 1;
   645 
   646 	return res;
   647 }
   648 
   649 int conf_write_autoconf(void)
   650 {
   651 	struct symbol *sym;
   652 	const char *str;
   653 	char *name;
   654 	FILE *out, *out_h;
   655 	time_t now;
   656 	int i, l;
   657 
   658 	sym_clear_all_valid();
   659 
   660 	file_write_dep("include/config/auto.conf.cmd");
   661 
   662 	if (conf_split_config())
   663 		return 1;
   664 
   665 	out = fopen(".tmpconfig", "w");
   666 	if (!out)
   667 		return 1;
   668 
   669 	out_h = fopen(".tmpconfig.h", "w");
   670 	if (!out_h) {
   671 		fclose(out);
   672 		return 1;
   673 	}
   674 
   675 	sym = sym_lookup("PROJECTVERSION", 0);
   676 	sym_calc_value(sym);
   677 	time(&now);
   678 	fprintf(out, "#\n"
   679 		     "# Automatically generated make config: don't edit\n"
   680 		     "# "PROJECT_NAME" version: %s\n"
   681 		     "# %s"
   682 		     "#\n",
   683 		     sym_get_string_value(sym), ctime(&now));
   684 	fprintf(out_h, "/*\n"
   685 		       " * Automatically generated C config: don't edit\n"
   686 		       " * "PROJECT_NAME" version: %s\n"
   687 		       " * %s"
   688 		       " */\n"
   689 		       "#define AUTOCONF_INCLUDED\n",
   690 		       sym_get_string_value(sym), ctime(&now));
   691 
   692 	for_all_symbols(i, sym) {
   693 		sym_calc_value(sym);
   694 		if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
   695 			continue;
   696 		switch (sym->type) {
   697 		case S_BOOLEAN:
   698 		case S_TRISTATE:
   699 			switch (sym_get_tristate_value(sym)) {
   700 			case no:
   701 				break;
   702 			case mod:
   703 				fprintf(out, "CT_%s=m\n", sym->name);
   704 				fprintf(out_h, "#define CT_%s_MODULE 1\n", sym->name);
   705 				break;
   706 			case yes:
   707 				fprintf(out, "CT_%s=y\n", sym->name);
   708 				fprintf(out_h, "#define CT_%s 1\n", sym->name);
   709 				break;
   710 			}
   711 			break;
   712 		case S_STRING:
   713 			str = sym_get_string_value(sym);
   714 			fprintf(out, "CT_%s=\"", sym->name);
   715 			fprintf(out_h, "#define CT_%s \"", sym->name);
   716 			while (1) {
   717 				l = strcspn(str, "\"\\");
   718 				if (l) {
   719 					fwrite(str, l, 1, out);
   720 					fwrite(str, l, 1, out_h);
   721 					str += l;
   722 				}
   723 				if (!*str)
   724 					break;
   725 				fprintf(out, "\\%c", *str);
   726 				fprintf(out_h, "\\%c", *str);
   727 				str++;
   728 			}
   729 			fputs("\"\n", out);
   730 			fputs("\"\n", out_h);
   731 			break;
   732 		case S_HEX:
   733 			str = sym_get_string_value(sym);
   734 			if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
   735 				fprintf(out, "CT_%s=%s\n", sym->name, str);
   736 				fprintf(out_h, "#define CT_%s 0x%s\n", sym->name, str);
   737 				break;
   738 			}
   739 		case S_INT:
   740 			str = sym_get_string_value(sym);
   741 			fprintf(out, "CT_%s=%s\n", sym->name, str);
   742 			fprintf(out_h, "#define CT_%s %s\n", sym->name, str);
   743 			break;
   744 		default:
   745 			break;
   746 		}
   747 	}
   748 	fclose(out);
   749 	fclose(out_h);
   750 
   751 	name = getenv("KCONFIG_AUTOHEADER");
   752 	if (!name)
   753 		name = "include/linux/autoconf.h";
   754 	if (rename(".tmpconfig.h", name))
   755 		return 1;
   756 	name = getenv("KCONFIG_AUTOCONFIG");
   757 	if (!name)
   758 		name = "include/config/auto.conf";
   759 	/*
   760 	 * This must be the last step, kbuild has a dependency on auto.conf
   761 	 * and this marks the successful completion of the previous steps.
   762 	 */
   763 	if (rename(".tmpconfig", name))
   764 		return 1;
   765 
   766 	return 0;
   767 }
   768 
   769 static int sym_change_count;
   770 static void (*conf_changed_callback)(void);
   771 
   772 void sym_set_change_count(int count)
   773 {
   774 	int _sym_change_count = sym_change_count;
   775 	sym_change_count = count;
   776 	if (conf_changed_callback &&
   777 	    (bool)_sym_change_count != (bool)count)
   778 		conf_changed_callback();
   779 }
   780 
   781 void sym_add_change_count(int count)
   782 {
   783 	sym_set_change_count(count + sym_change_count);
   784 }
   785 
   786 bool conf_get_changed(void)
   787 {
   788 	return sym_change_count;
   789 }
   790 
   791 void conf_set_changed_callback(void (*fn)(void))
   792 {
   793 	conf_changed_callback = fn;
   794 }