kconfig: remove useless NULL pointer check in conf_write_dep()
[carl9170fw.git] / config / confdata.c
index 57c09a7d3883914627ea3ababa9b6f1bbe486bd0..f6461a6af4bc9a573305b7d1b6e8af5b0997980d 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
  */
 
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <ctype.h>
 #include <errno.h>
@@ -36,6 +37,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.
  *
@@ -582,6 +629,46 @@ kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
        fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);
 }
 
+static void
+kconfig_print_cmake_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+       switch (sym->type) {
+       case S_BOOLEAN:
+       case S_TRISTATE:
+               if (*value == 'n') {
+                       bool skip_unset = (arg != NULL);
+
+                       if (!skip_unset)
+                               fprintf(fp, "set(%s%s false)\n",
+                                       CONFIG_, sym->name, value);
+                       return;
+               } else if (*value == 'm') {
+                       abort();
+               } else {
+                       fprintf(fp, "set(%s%s true)\n", CONFIG_, sym->name, value);
+               }
+               break;
+       case S_HEX: {
+               const char *prefix = "";
+
+               if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X'))
+                       prefix = "0x";
+               fprintf(fp, "set(%s%s %s%s)\n",
+                   CONFIG_, sym->name, prefix, value);
+               break;
+       }
+       case S_STRING:
+       case S_INT:
+               fprintf(fp, "set(%s%s %s)\n",
+                   CONFIG_, sym->name, value);
+               break;
+       default:
+               break;
+       }
+
+}
+
 static void
 kconfig_print_comment(FILE *fp, const char *value, void *arg)
 {
@@ -608,6 +695,12 @@ static struct conf_printer kconfig_printer_cb =
        .print_comment = kconfig_print_comment,
 };
 
+static struct conf_printer kconfig_printer_cmake_cb =
+{
+       .print_symbol = kconfig_print_cmake_symbol,
+       .print_comment = kconfig_print_comment,
+};
+
 /*
  * Header printer
  *
@@ -817,40 +910,34 @@ 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;
 
-       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);
+       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) {
-               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;
@@ -897,14 +984,20 @@ next:
        fclose(out);
 
        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);
 
@@ -917,8 +1010,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;
@@ -1020,7 +1111,7 @@ 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;
+       FILE *out, *tristate, *out_h, *out_c;
        int i;
 
        if (!overwrite && is_present(autoconf_name))
@@ -1050,12 +1141,21 @@ int conf_write_autoconf(int overwrite)
                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);
+
        for_all_symbols(i, sym) {
                sym_calc_value(sym);
                if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
@@ -1067,10 +1167,13 @@ int conf_write_autoconf(int overwrite)
                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);
 
        name = getenv("KCONFIG_AUTOHEADER");
        if (!name)
@@ -1090,6 +1193,15 @@ int conf_write_autoconf(int overwrite)
 
        if (make_parent_dir(autoconf_name))
                return 1;
+
+       name = getenv("KCONFIG_CMAKE");
+       if (!name)
+               name = "config.cmake";
+       if (make_parent_dir(name))
+               return 1;
+       if (rename(".tmpconfig.cmake", name))
+               return 1;
+
        /*
         * This must be the last step, kbuild has a dependency on auto.conf
         * and this marks the successful completion of the previous steps.