// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
 */

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <xalloc.h>
#include "internal.h"
#include "lkc.h"

struct gstr autoconf_cmd;

/* return true if 'path' exists, false otherwise */
static bool is_present(const char *path)
{
	struct stat st;

	return !stat(path, &st);
}

/* return true if 'path' exists and it is a directory, false otherwise */
static bool is_dir(const char *path)
{
	struct stat st;

	if (stat(path, &st))
		return false;

	return S_ISDIR(st.st_mode);
}

/* return true if the given two files are the same, false otherwise */
static bool is_same(const char *file1, const char *file2)
{
	int fd1, fd2;
	struct stat st1, st2;
	void *map1, *map2;
	bool ret = false;

	fd1 = open(file1, O_RDONLY);
	if (fd1 < 0)
		return ret;

	fd2 = open(file2, O_RDONLY);
	if (fd2 < 0)
		goto close1;

	ret = fstat(fd1, &st1);
	if (ret)
		goto close2;
	ret = fstat(fd2, &st2);
	if (ret)
		goto close2;

	if (st1.st_size != st2.st_size)
		goto close2;

	map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
	if (map1 == MAP_FAILED)
		goto close2;

	map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
	if (map2 == MAP_FAILED)
		goto close2;

	if (bcmp(map1, map2, st1.st_size))
		goto close2;

	ret = true;
close2:
	close(fd2);
close1:
	close(fd1);

	return ret;
}

/*
 * Create the parent directory of the given path.
 *
 * For example, if 'include/config/auto.conf' is given, create 'include/config'.
 */
static int make_parent_dir(const char *path)
{
	char tmp[PATH_MAX + 1];
	char *p;

	strncpy(tmp, path, sizeof(tmp));
	tmp[sizeof(tmp) - 1] = 0;

	/* Remove the base name. Just return if nothing is left */
	p = strrchr(tmp, '/');
	if (!p)
		return 0;
	*(p + 1) = 0;

	/* Just in case it is an absolute path */
	p = tmp;
	while (*p == '/')
		p++;

	while ((p = strchr(p, '/'))) {
		*p = 0;

		/* skip if the directory exists */
		if (!is_dir(tmp) && mkdir(tmp, 0755))
			return -1;

		*p = '/';
		while (*p == '/')
			p++;
	}

	return 0;
}

static char depfile_path[PATH_MAX];
static size_t depfile_prefix_len;

/* touch depfile for symbol 'name' */
static int conf_touch_dep(const char *name)
{
	int fd;

	/* check overflow: prefix + name + '\0' must fit in buffer. */
	if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
		return -1;

	strcpy(depfile_path + depfile_prefix_len, name);

	fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
	if (fd == -1)
		return -1;
	close(fd);

	return 0;
}

static void conf_warning(const char *fmt, ...)
	__attribute__ ((format (printf, 1, 2)));

static void conf_message(const char *fmt, ...)
	__attribute__ ((format (printf, 1, 2)));

static const char *conf_filename;
static int conf_lineno, conf_warnings;

bool conf_errors(void)
{
	if (conf_warnings)
		return getenv("KCONFIG_WERROR");
	return false;
}

static void conf_warning(const char *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);
	fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
	vfprintf(stderr, fmt, ap);
	fprintf(stderr, "\n");
	va_end(ap);
	conf_warnings++;
}

static void conf_default_message_callback(const char *s)
{
	printf("#\n# ");
	printf("%s", s);
	printf("\n#\n");
}

static void (*conf_message_callback)(const char *s) =
	conf_default_message_callback;
void conf_set_message_callback(void (*fn)(const char *s))
{
	conf_message_callback = fn;
}

static void conf_message(const char *fmt, ...)
{
	va_list ap;
	char buf[4096];

	if (!conf_message_callback)
		return;

	va_start(ap, fmt);

	vsnprintf(buf, sizeof(buf), fmt, ap);
	conf_message_callback(buf);
	va_end(ap);
}

const char *conf_get_configname(void)
{
	char *name = getenv("KCONFIG_CONFIG");

	return name ? name : ".config";
}

static const char *conf_get_autoconfig_name(void)
{
	char *name = getenv("KCONFIG_AUTOCONFIG");

	return name ? name : "include/config/auto.conf";
}

static const char *conf_get_autoheader_name(void)
{
	char *name = getenv("KCONFIG_AUTOHEADER");

	return name ? name : "include/generated/autoconf.h";
}

static const char *conf_get_rustccfg_name(void)
{
	char *name = getenv("KCONFIG_RUSTCCFG");

	return name ? name : "include/generated/rustc_cfg";
}

static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
{
	char *p2;

	switch (sym->type) {
	case S_TRISTATE:
		if (p[0] == 'm') {
			sym->def[def].tri = mod;
			sym->flags |= def_flags;
			break;
		}
		/* fall through */
	case S_BOOLEAN:
		if (p[0] == 'y') {
			sym->def[def].tri = yes;
			sym->flags |= def_flags;
			break;
		}
		if (p[0] == 'n') {
			sym->def[def].tri = no;
			sym->flags |= def_flags;
			break;
		}
		if (def != S_DEF_AUTO)
			conf_warning("symbol value '%s' invalid for %s",
				     p, sym->name);
		return 1;
	case S_STRING:
		/* No escaping for S_DEF_AUTO (include/config/auto.conf) */
		if (def != S_DEF_AUTO) {
			if (*p++ != '"')
				break;
			for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
				if (*p2 == '"') {
					*p2 = 0;
					break;
				}
				memmove(p2, p2 + 1, strlen(p2));
			}
			if (!p2) {
				conf_warning("invalid string found");
				return 1;
			}
		}
		/* fall through */
	case S_INT:
	case S_HEX:
		if (sym_string_valid(sym, p)) {
			sym->def[def].val = xstrdup(p);
			sym->flags |= def_flags;
		} else {
			if (def != S_DEF_AUTO)
				conf_warning("symbol value '%s' invalid for %s",
					     p, sym->name);
			return 1;
		}
		break;
	default:
		;
	}
	return 0;
}

/* like getline(), but the newline character is stripped away */
static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
{
	ssize_t len;

	len = getline(lineptr, n, stream);

	if (len > 0 && (*lineptr)[len - 1] == '\n') {
		len--;
		(*lineptr)[len] = '\0';

		if (len > 0 && (*lineptr)[len - 1] == '\r') {
			len--;
			(*lineptr)[len] = '\0';
		}
	}

	return len;
}

int conf_read_simple(const char *name, int def)
{
	FILE *in = NULL;
	char   *line = NULL;
	size_t  line_asize = 0;
	char *p, *val;
	struct symbol *sym;
	int def_flags;
	const char *warn_unknown, *sym_name;

	warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
	if (name) {
		in = zconf_fopen(name);
	} else {
		char *env;

		name = conf_get_configname();
		in = zconf_fopen(name);
		if (in)
			goto load;
		conf_set_changed(true);

		env = getenv("KCONFIG_DEFCONFIG_LIST");
		if (!env)
			return 1;

		while (1) {
			bool is_last;

			while (isspace(*env))
				env++;

			if (!*env)
				break;

			p = env;
			while (*p && !isspace(*p))
				p++;

			is_last = (*p == '\0');

			*p = '\0';

			name = env;

			in = zconf_fopen(name);
			if (in) {
				conf_message("using defaults found in %s",
					     name);
				goto load;
			}

			if (is_last)
				break;

			env = p + 1;
		}
	}
	if (!in)
		return 1;

load:
	conf_filename = name;
	conf_lineno = 0;
	conf_warnings = 0;

	def_flags = SYMBOL_DEF << def;
	for_all_symbols(sym) {
		sym->flags &= ~def_flags;
		switch (sym->type) {
		case S_INT:
		case S_HEX:
		case S_STRING:
			free(sym->def[def].val);
			/* fall through */
		default:
			sym->def[def].val = NULL;
			sym->def[def].tri = no;
		}
	}

	if (def == S_DEF_USER) {
		for_all_symbols(sym)
			sym->flags &= ~SYMBOL_VALID;
		expr_invalidate_all();
	}

	while (getline_stripped(&line, &line_asize, in) != -1) {
		struct menu *choice;

		conf_lineno++;

		if (!line[0]) /* blank line */
			continue;

		if (line[0] == '#') {
			if (line[1] != ' ')
				continue;
			p = line + 2;
			if (memcmp(p, CONFIG_, strlen(CONFIG_)))
				continue;
			sym_name = p + strlen(CONFIG_);
			p = strchr(sym_name, ' ');
			if (!p)
				continue;
			*p++ = 0;
			if (strcmp(p, "is not set"))
				continue;

			val = "n";
		} else {
			if (memcmp(line, CONFIG_, strlen(CONFIG_))) {
				conf_warning("unexpected data: %s", line);
				continue;
			}

			sym_name = line + strlen(CONFIG_);
			p = strchr(sym_name, '=');
			if (!p) {
				conf_warning("unexpected data: %s", line);
				continue;
			}
			*p = 0;
			val = p + 1;
		}

		sym = sym_find(sym_name);
		if (!sym) {
			if (def == S_DEF_AUTO) {
				/*
				 * Reading from include/config/auto.conf.
				 * If CONFIG_FOO previously existed in auto.conf
				 * but it is missing now, include/config/FOO
				 * must be touched.
				 */
				conf_touch_dep(sym_name);
			} else {
				if (warn_unknown)
					conf_warning("unknown symbol: %s", sym_name);

				conf_set_changed(true);
			}
			continue;
		}

		if (sym->flags & def_flags)
			conf_warning("override: reassigning to symbol %s", sym->name);

		if (conf_set_sym_val(sym, def, def_flags, val))
			continue;

		if (def != S_DEF_USER)
			continue;

		/*
		 * If this is a choice member, give it the highest priority.
		 * If conflicting CONFIG options are given from an input file,
		 * the last one wins.
		 */
		choice = sym_get_choice_menu(sym);
		if (choice)
			list_move(&sym->choice_link, &choice->choice_members);
	}
	free(line);
	fclose(in);

	return 0;
}

int conf_read(const char *name)
{
	struct symbol *sym;

	conf_set_changed(false);

	if (conf_read_simple(name, S_DEF_USER)) {
		sym_calc_value(modules_sym);
		return 1;
	}

	sym_calc_value(modules_sym);

	for_all_symbols(sym) {
		sym_calc_value(sym);
		if (sym_is_choice(sym))
			continue;
		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
			/* check that calculated value agrees with saved value */
			switch (sym->type) {
			case S_BOOLEAN:
			case S_TRISTATE:
				if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
					continue;
				break;
			default:
				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
					continue;
				break;
			}
		} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
			/* no previous value and not saved */
			continue;
		conf_set_changed(true);
		/* maybe print value in verbose mode... */
	}

	if (conf_warnings)
		conf_set_changed(true);

	return 0;
}

struct comment_style {
	const char *decoration;
	const char *prefix;
	const char *postfix;
};

static const struct comment_style comment_style_pound = {
	.decoration = "#",
	.prefix = "#",
	.postfix = "#",
};

static const struct comment_style comment_style_c = {
	.decoration = " *",
	.prefix = "/*",
	.postfix = " */",
};

static void conf_write_heading(FILE *fp, const struct comment_style *cs)
{
	if (!cs)
		return;

	fprintf(fp, "%s\n", cs->prefix);

	fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
		cs->decoration);

	fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text);

	fprintf(fp, "%s\n", cs->postfix);
}

/* The returned pointer must be freed on the caller side */
static char *escape_string_value(const char *in)
{
	const char *p;
	char *out;
	size_t len;

	len = strlen(in) + strlen("\"\"") + 1;

	p = in;
	while (1) {
		p += strcspn(p, "\"\\");

		if (p[0] == '\0')
			break;

		len++;
		p++;
	}

	out = xmalloc(len);
	out[0] = '\0';

	strcat(out, "\"");

	p = in;
	while (1) {
		len = strcspn(p, "\"\\");
		strncat(out, p, len);
		p += len;

		if (p[0] == '\0')
			break;

		strcat(out, "\\");
		strncat(out, p++, 1);
	}

	strcat(out, "\"");

	return out;
}

enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };

static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
			   bool escape_string)
{
	const char *val;
	char *escaped = NULL;

	if (sym->type == S_UNKNOWN)
		return;

	val = sym_get_string_value(sym);

	if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) &&
	    output_n != OUTPUT_N && *val == 'n') {
		if (output_n == OUTPUT_N_AS_UNSET)
			fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name);
		return;
	}

	if (sym->type == S_STRING && escape_string) {
		escaped = escape_string_value(val);
		val = escaped;
	}

	fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);

	free(escaped);
}

static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
{
	__print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
}

static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
{
	__print_symbol(fp, sym, OUTPUT_N_NONE, false);
}

void print_symbol_for_listconfig(struct symbol *sym)
{
	__print_symbol(stdout, sym, OUTPUT_N, true);
}

static void print_symbol_for_c(FILE *fp, struct symbol *sym)
{
	const char *val;
	const char *sym_suffix = "";
	const char *val_prefix = "";
	char *escaped = NULL;

	if (sym->type == S_UNKNOWN)
		return;

	val = sym_get_string_value(sym);

	switch (sym->type) {
	case S_BOOLEAN:
	case S_TRISTATE:
		switch (*val) {
		case 'n':
			return;
		case 'm':
			sym_suffix = "_MODULE";
			/* fall through */
		default:
			val = "1";
		}
		break;
	case S_HEX:
		if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
			val_prefix = "0x";
		break;
	case S_STRING:
		escaped = escape_string_value(val);
		val = escaped;
	default:
		break;
	}

	fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix,
		val_prefix, val);

	free(escaped);
}

static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
{
	const char *val;
	const char *val_prefix = "";
	char *val_prefixed = NULL;
	size_t val_prefixed_len;
	char *escaped = NULL;

	if (sym->type == S_UNKNOWN)
		return;

	val = sym_get_string_value(sym);

	switch (sym->type) {
	case S_BOOLEAN:
	case S_TRISTATE:
		/*
		 * We do not care about disabled ones, i.e. no need for
		 * what otherwise are "comments" in other printers.
		 */
		if (*val == 'n')
			return;

		/*
		 * To have similar functionality to the C macro `IS_ENABLED()`
		 * we provide an empty `--cfg CONFIG_X` here in both `y`
		 * and `m` cases.
		 *
		 * Then, the common `fprintf()` below will also give us
		 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
		 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
		 */
		fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
		break;
	case S_HEX:
		if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
			val_prefix = "0x";
		break;
	default:
		break;
	}

	if (strlen(val_prefix) > 0) {
		val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
		val_prefixed = xmalloc(val_prefixed_len);
		snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
		val = val_prefixed;
	}

	/* All values get escaped: the `--cfg` option only takes strings */
	escaped = escape_string_value(val);
	val = escaped;

	fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);

	free(escaped);
	free(val_prefixed);
}

/*
 * Write out a minimal config.
 * All values that has default values are skipped as this is redundant.
 */
int conf_write_defconfig(const char *filename)
{
	struct symbol *sym;
	struct menu *menu;
	FILE *out;

	out = fopen(filename, "w");
	if (!out)
		return 1;

	sym_clear_all_valid();

	menu_for_each_entry(menu) {
		struct menu *choice;

		sym = menu->sym;

		if (!sym || sym_is_choice(sym))
			continue;

		sym_calc_value(sym);
		if (!(sym->flags & SYMBOL_WRITE))
			continue;
		sym->flags &= ~SYMBOL_WRITE;
		/* Skip unchangeable symbols */
		if (!sym_is_changeable(sym))
			continue;
		/* Skip symbols that are equal to the default */
		if (!strcmp(sym_get_string_value(sym), sym_get_string_default(sym)))
			continue;

		/* Skip choice values that are equal to the default */
		choice = sym_get_choice_menu(sym);
		if (choice) {
			struct symbol *ds;

			ds = sym_choice_default(choice);
			if (sym == ds && sym_get_tristate_value(sym) == yes)
				continue;
		}
		print_symbol_for_dotconfig(out, sym);
	}
	fclose(out);
	return 0;
}

int conf_write(const char *name)
{
	FILE *out;
	struct symbol *sym;
	struct menu *menu;
	const char *str;
	char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
	char *env;
	bool need_newline = false;

	if (!name)
		name = conf_get_configname();

	if (!*name) {
		fprintf(stderr, "config name is empty\n");
		return -1;
	}

	if (is_dir(name)) {
		fprintf(stderr, "%s: Is a directory\n", name);
		return -1;
	}

	if (make_parent_dir(name))
		return -1;

	env = getenv("KCONFIG_OVERWRITECONFIG");
	if (env && *env) {
		*tmpname = 0;
		out = fopen(name, "w");
	} else {
		snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
			 name, (int)getpid());
		out = fopen(tmpname, "w");
	}
	if (!out)
		return 1;

	conf_write_heading(out, &comment_style_pound);

	if (!conf_get_changed())
		sym_clear_all_valid();

	menu = rootmenu.list;
	while (menu) {
		sym = menu->sym;
		if (!sym) {
			if (!menu_is_visible(menu))
				goto next;
			str = menu_get_prompt(menu);
			fprintf(out, "\n"
				     "#\n"
				     "# %s\n"
				     "#\n", str);
			need_newline = false;
		} else if (!sym_is_choice(sym) &&
			   !(sym->flags & SYMBOL_WRITTEN)) {
			sym_calc_value(sym);
			if (!(sym->flags & SYMBOL_WRITE))
				goto next;
			if (need_newline) {
				fprintf(out, "\n");
				need_newline = false;
			}
			sym->flags |= SYMBOL_WRITTEN;
			print_symbol_for_dotconfig(out, sym);
		}

next:
		if (menu->list) {
			menu = menu->list;
			continue;
		}

end_check:
		if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
		    menu->prompt->type == P_MENU) {
			fprintf(out, "# end of %s\n", menu_get_prompt(menu));
			need_newline = true;
		}

		if (menu->next) {
			menu = menu->next;
		} else {
			menu = menu->parent;
			if (menu)
				goto end_check;
		}
	}
	fclose(out);

	for_all_symbols(sym)
		sym->flags &= ~SYMBOL_WRITTEN;

	if (*tmpname) {
		if (is_same(name, tmpname)) {
			conf_message("No change to %s", name);
			unlink(tmpname);
			conf_set_changed(false);
			return 0;
		}

		snprintf(oldname, sizeof(oldname), "%s.old", name);
		rename(name, oldname);
		if (rename(tmpname, name))
			return 1;
	}

	conf_message("configuration written to %s", name);

	conf_set_changed(false);

	return 0;
}

/* write a dependency file as used by kbuild to track dependencies */
static int conf_write_autoconf_cmd(const char *autoconf_name)
{
	char name[PATH_MAX], tmp[PATH_MAX];
	FILE *out;
	int ret;

	ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
	if (ret >= sizeof(name)) /* check truncation */
		return -1;

	if (make_parent_dir(name))
		return -1;

	ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
	if (ret >= sizeof(tmp)) /* check truncation */
		return -1;

	out = fopen(tmp, "w");
	if (!out) {
		perror("fopen");
		return -1;
	}

	fprintf(out, "autoconfig := %s\n", autoconf_name);

	fputs(str_get(&autoconf_cmd), out);

	fflush(out);
	ret = ferror(out); /* error check for all fprintf() calls */
	fclose(out);
	if (ret)
		return -1;

	if (rename(tmp, name)) {
		perror("rename");
		return -1;
	}

	return 0;
}

static int conf_touch_deps(void)
{
	const char *name, *tmp;
	struct symbol *sym;
	int res;

	name = conf_get_autoconfig_name();
	tmp = strrchr(name, '/');
	depfile_prefix_len = tmp ? tmp - name + 1 : 0;
	if (depfile_prefix_len + 1 > sizeof(depfile_path))
		return -1;

	strncpy(depfile_path, name, depfile_prefix_len);
	depfile_path[depfile_prefix_len] = 0;

	conf_read_simple(name, S_DEF_AUTO);

	for_all_symbols(sym) {
		if (sym_is_choice(sym))
			continue;
		if (sym->flags & SYMBOL_WRITE) {
			if (sym->flags & SYMBOL_DEF_AUTO) {
				/*
				 * symbol has old and new value,
				 * so compare them...
				 */
				switch (sym->type) {
				case S_BOOLEAN:
				case S_TRISTATE:
					if (sym_get_tristate_value(sym) ==
					    sym->def[S_DEF_AUTO].tri)
						continue;
					break;
				case S_STRING:
				case S_HEX:
				case S_INT:
					if (!strcmp(sym_get_string_value(sym),
						    sym->def[S_DEF_AUTO].val))
						continue;
					break;
				default:
					break;
				}
			} else {
				/*
				 * If there is no old value, only 'no' (unset)
				 * is allowed as new value.
				 */
				switch (sym->type) {
				case S_BOOLEAN:
				case S_TRISTATE:
					if (sym_get_tristate_value(sym) == no)
						continue;
					break;
				default:
					break;
				}
			}
		} else if (!(sym->flags & SYMBOL_DEF_AUTO))
			/* There is neither an old nor a new value. */
			continue;
		/* else
		 *	There is an old value, but no new value ('no' (unset)
		 *	isn't saved in auto.conf, so the old value is always
		 *	different from 'no').
		 */

		res = conf_touch_dep(sym->name);
		if (res)
			return res;
	}

	return 0;
}

static int __conf_write_autoconf(const char *filename,
				 void (*print_symbol)(FILE *, struct symbol *),
				 const struct comment_style *comment_style)
{
	char tmp[PATH_MAX];
	FILE *file;
	struct symbol *sym;
	int ret;

	if (make_parent_dir(filename))
		return -1;

	ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
	if (ret >= sizeof(tmp)) /* check truncation */
		return -1;

	file = fopen(tmp, "w");
	if (!file) {
		perror("fopen");
		return -1;
	}

	conf_write_heading(file, comment_style);

	for_all_symbols(sym)
		if ((sym->flags & SYMBOL_WRITE) && sym->name)
			print_symbol(file, sym);

	fflush(file);
	/* check possible errors in conf_write_heading() and print_symbol() */
	ret = ferror(file);
	fclose(file);
	if (ret)
		return -1;

	if (rename(tmp, filename)) {
		perror("rename");
		return -1;
	}

	return 0;
}

int conf_write_autoconf(int overwrite)
{
	struct symbol *sym;
	const char *autoconf_name = conf_get_autoconfig_name();
	int ret;

	if (!overwrite && is_present(autoconf_name))
		return 0;

	ret = conf_write_autoconf_cmd(autoconf_name);
	if (ret)
		return -1;

	for_all_symbols(sym)
		sym_calc_value(sym);

	if (conf_touch_deps())
		return 1;

	ret = __conf_write_autoconf(conf_get_autoheader_name(),
				    print_symbol_for_c,
				    &comment_style_c);
	if (ret)
		return ret;

	ret = __conf_write_autoconf(conf_get_rustccfg_name(),
				    print_symbol_for_rustccfg,
				    NULL);
	if (ret)
		return ret;

	/*
	 * Create include/config/auto.conf. This must be the last step because
	 * Kbuild has a dependency on auto.conf and this marks the successful
	 * completion of the previous steps.
	 */
	ret = __conf_write_autoconf(conf_get_autoconfig_name(),
				    print_symbol_for_autoconf,
				    &comment_style_pound);
	if (ret)
		return ret;

	return 0;
}

static bool conf_changed;
static void (*conf_changed_callback)(bool);

void conf_set_changed(bool val)
{
	if (conf_changed_callback && conf_changed != val)
		conf_changed_callback(val);

	conf_changed = val;
}

bool conf_get_changed(void)
{
	return conf_changed;
}

void conf_set_changed_callback(void (*fn)(bool))
{
	conf_changed_callback = fn;
}
