carl9170: Update to latest upstream
[linux-libre-firmware.git] / carl9170fw / config / confdata.c
index d67695d19ac77fdad52cbc4f4f005e8110ffcb58..99664fd2de23bb15dc29dd6d1897a0dcc1a6f60a 100644 (file)
@@ -3,7 +3,9 @@
  * 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>
@@ -36,6 +38,52 @@ static bool is_dir(const char *path)
        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.
  *
@@ -130,8 +178,6 @@ static void conf_message(const char *fmt, ...)
 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;
@@ -179,28 +225,13 @@ const char *conf_get_configname(void)
        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;
@@ -504,11 +535,9 @@ int conf_read(const char *name)
                        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;
@@ -728,25 +757,6 @@ static struct conf_printer header_printer_cb =
        .print_comment = header_print_comment,
 };
 
-/*
- * Tristate printer
- *
- * This printer is used when generating the `include/generated/tristate.conf' file.
- */
-static void
-tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
-{
-
-       if (sym->type == S_TRISTATE && *value != 'n')
-               fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value));
-}
-
-static struct conf_printer tristate_printer_cb =
-{
-       .print_symbol = tristate_print_symbol,
-       .print_comment = kconfig_print_comment,
-};
-
 static void conf_write_symbol(FILE *fp, struct symbol *sym,
                              struct conf_printer *printer, void *printer_arg)
 {
@@ -812,7 +822,7 @@ int conf_write_defconfig(const char *filename)
                                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)
@@ -863,40 +873,36 @@ int conf_write(const char *name)
        FILE *out;
        struct symbol *sym;
        struct menu *menu;
-       const char *basename;
        const char *str;
-       char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];
+       char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
        char *env;
+       int i;
+       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;
 
-       dirname[0] = 0;
-       if (name && name[0]) {
-               char *slash;
-
-               if (is_dir(name)) {
-                       strcpy(dirname, name);
-                       strcat(dirname, "/");
-                       basename = conf_get_configname();
-               } else if ((slash = strrchr(name, '/'))) {
-                       int size = slash - name + 1;
-                       memcpy(dirname, name, size);
-                       dirname[size] = 0;
-                       if (slash[1])
-                               basename = slash + 1;
-                       else
-                               basename = conf_get_configname();
-               } else
-                       basename = name;
-       } else
-               basename = conf_get_configname();
-
-       sprintf(newname, "%s%s", dirname, basename);
        env = getenv("KCONFIG_OVERWRITECONFIG");
-       if (!env || !*env) {
-               sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
-               out = fopen(tmpname, "w");
-       } else {
+       if (env && *env) {
                *tmpname = 0;
-               out = fopen(newname, "w");
+               out = fopen(name, "w");
+       } else {
+               snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
+                        name, (int)getpid());
+               out = fopen(tmpname, "w");
        }
        if (!out)
                return 1;
@@ -917,12 +923,17 @@ int conf_write(const char *name)
                                     "#\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);
                }
 
@@ -934,6 +945,12 @@ next:
                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;
@@ -942,15 +959,24 @@ next:
        }
        fclose(out);
 
+       for_all_symbols(i, sym)
+               sym->flags &= ~SYMBOL_WRITTEN;
+
        if (*tmpname) {
-               strcat(dirname, basename);
-               strcat(dirname, ".old");
-               rename(newname, dirname);
-               if (rename(tmpname, newname))
+               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))
                        return 1;
        }
 
-       conf_message("configuration written to %s", newname);
+       conf_message("configuration written to %s", name);
 
        sym_set_change_count(0);
 
@@ -963,8 +989,6 @@ static int conf_write_dep(const char *name)
        struct file *file;
        FILE *out;
 
-       if (!name)
-               name = ".kconfig.d";
        out = fopen("..config.tmp", "w");
        if (!out)
                return 1;
@@ -1066,14 +1090,12 @@ int conf_write_autoconf(int overwrite)
        struct symbol *sym;
        const char *name;
        const char *autoconf_name = conf_get_autoconfig_name();
-       FILE *out, *tristate, *out_h, *out_c;
+       FILE *out, *out_h, *out_c;
        int i;
 
        if (!overwrite && is_present(autoconf_name))
                return 0;
 
-       sym_clear_all_valid();
-
        conf_write_dep("include/generated/auto.conf.cmd");
 
        if (conf_touch_deps())
@@ -1083,30 +1105,20 @@ int conf_write_autoconf(int overwrite)
        if (!out)
                return 1;
 
-       tristate = fopen(".tmpconfig_tristate", "w");
-       if (!tristate) {
-               fclose(out);
-               return 1;
-       }
-
        out_h = fopen(".tmpconfig.h", "w");
        if (!out_h) {
                fclose(out);
-               fclose(tristate);
                return 1;
        }
 
        out_c = fopen(".tmpconfig.cmake", "w");
        if (!out_c) {
                fclose(out);
-               fclose(tristate);
                fclose(out_h);
        }
 
        conf_write_heading(out, &kconfig_printer_cb, NULL);
 
-       conf_write_heading(tristate, &tristate_printer_cb, NULL);
-
        conf_write_heading(out_h, &header_printer_cb, NULL);
 
        conf_write_heading(out_c, &kconfig_printer_cmake_cb, NULL);
@@ -1116,17 +1128,14 @@ int conf_write_autoconf(int overwrite)
                if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
                        continue;
 
-               /* write symbol to auto.conf, tristate and header files */
+               /* write symbol to auto.conf and header files */
                conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
 
-               conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
-
                conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
 
                conf_write_symbol(out_c, sym, &kconfig_printer_cmake_cb, NULL);
        }
        fclose(out);
-       fclose(tristate);
        fclose(out_h);
        fclose(out_c);
 
@@ -1138,14 +1147,6 @@ int conf_write_autoconf(int overwrite)
        if (rename(".tmpconfig.h", name))
                return 1;
 
-       name = getenv("KCONFIG_TRISTATE");
-       if (!name)
-               name = "include/generated/tristate.conf";
-       if (make_parent_dir(name))
-               return 1;
-       if (rename(".tmpconfig_tristate", name))
-               return 1;
-
        if (make_parent_dir(autoconf_name))
                return 1;
 
@@ -1380,7 +1381,7 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode)
 
                sym_calc_value(csym);
                if (mode == def_random)
-                       has_changed = randomize_choice_values(csym);
+                       has_changed |= randomize_choice_values(csym);
                else {
                        set_all_choice_values(csym);
                        has_changed = true;
@@ -1389,3 +1390,18 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode)
 
        return has_changed;
 }
+
+void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
+{
+       struct symbol *sym;
+       int i;
+       tristate old_val = (mode == def_y2m) ? yes : mod;
+       tristate new_val = (mode == def_y2m) ? mod : yes;
+
+       for_all_symbols(i, sym) {
+               if (sym_get_type(sym) == S_TRISTATE &&
+                   sym->def[S_DEF_USER].tri == old_val)
+                       sym->def[S_DEF_USER].tri = new_val;
+       }
+       sym_clear_all_valid();
+}