kconfig/confdata.c
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue May 01 16:49:15 2007 +0000 (2007-05-01)
changeset 56 07a6a48962b7
parent 1 eeea35fbf182
child 94 f32c4f663805
permissions -rw-r--r--
Merge patches sent by Robert P. J. Day <rpjday@mindspring.com>.
Warning: the buildroot folks purposedly removed the skip-comment patch but didn't really said why. Keeping it for the sake of having it in svn just in case (removing it will be easier thant not having it at all).
     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 }