* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
*/
+#include <sys/mman.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
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.
*
static const char *conf_filename;
static int conf_lineno, conf_warnings;
-const char conf_defname[] = "include/generated/defconfig";
-
static void conf_warning(const char *fmt, ...)
{
va_list ap;
return name ? name : ".config";
}
-const char *conf_get_autoconfig_name(void)
+static const char *conf_get_autoconfig_name(void)
{
char *name = getenv("KCONFIG_AUTOCONFIG");
return name ? name : "include/generated/auto.conf";
}
-char *conf_get_default_confname(void)
-{
- static char fullname[PATH_MAX+1];
- char *env, *name;
-
- name = expand_string(conf_defname);
- env = getenv(SRCTREE);
- if (env) {
- sprintf(fullname, "%s/%s", env, name);
- if (is_present(fullname))
- return fullname;
- }
- return name;
-}
-
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
{
char *p2;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
- if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
- break;
- if (!sym_is_choice(sym))
+ if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
continue;
- /* fall through */
+ break;
default:
if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
continue;
goto next_menu;
sym->flags &= ~SYMBOL_WRITE;
/* If we cannot change the symbol - skip */
- if (!sym_is_changable(sym))
+ if (!sym_is_changeable(sym))
goto next_menu;
/* If symbol equals to default value - skip */
if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
const char *str;
char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
char *env;
+ int i;
+ bool need_newline = false;
if (!name)
name = conf_get_configname();
return -1;
}
+ if (make_parent_dir(name))
+ return -1;
+
env = getenv("KCONFIG_OVERWRITECONFIG");
if (env && *env) {
*tmpname = 0;
"#\n"
"# %s\n"
"#\n", str);
- } else if (!(sym->flags & SYMBOL_CHOICE)) {
+ need_newline = false;
+ } else if (!(sym->flags & SYMBOL_CHOICE) &&
+ !(sym->flags & SYMBOL_WRITTEN)) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
goto next;
- sym->flags &= ~SYMBOL_WRITE;
-
+ if (need_newline) {
+ fprintf(out, "\n");
+ need_newline = false;
+ }
+ sym->flags |= SYMBOL_WRITTEN;
conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
}
if (menu->next)
menu = menu->next;
else while ((menu = menu->parent)) {
+ if (!menu->sym && menu_is_visible(menu) &&
+ menu != &rootmenu) {
+ str = menu_get_prompt(menu);
+ fprintf(out, "# end of %s\n", str);
+ need_newline = true;
+ }
if (menu->next) {
menu = menu->next;
break;
}
fclose(out);
+ for_all_symbols(i, sym)
+ sym->flags &= ~SYMBOL_WRITTEN;
+
if (*tmpname) {
+ if (is_same(name, tmpname)) {
+ conf_message("No change to %s", name);
+ unlink(tmpname);
+ sym_set_change_count(0);
+ return 0;
+ }
+
snprintf(oldname, sizeof(oldname), "%s.old", name);
rename(name, oldname);
if (rename(tmpname, name))
struct file *file;
FILE *out;
- if (!name)
- name = ".kconfig.d";
out = fopen("..config.tmp", "w");
if (!out)
return 1;
if (!overwrite && is_present(autoconf_name))
return 0;
- sym_clear_all_valid();
-
conf_write_dep("include/generated/auto.conf.cmd");
if (conf_touch_deps())