kconfig: remove unneeded setsym label in conf_read_simple()
[carl9170fw.git] / config / confdata.c
index 481b07b10eb9191fe4dde158e9feb43770b246fb..b7171503936a208af6e103d07ad54c2a8d95ce38 100644 (file)
 
 #include "lkc.h"
 
+/* 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 0;
+
+       return S_ISDIR(st.st_mode);
+}
+
+/*
+ * 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;
+}
+
 struct conf_printer {
        void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
        void (*print_comment)(FILE *, const char *, void *);
@@ -43,16 +101,16 @@ static void conf_warning(const char *fmt, ...)
        conf_warnings++;
 }
 
-static void conf_default_message_callback(const char *fmt, va_list ap)
+static void conf_default_message_callback(const char *s)
 {
        printf("#\n# ");
-       vprintf(fmt, ap);
+       printf("%s", s);
        printf("\n#\n");
 }
 
-static void (*conf_message_callback) (const char *fmt, va_list ap) =
+static void (*conf_message_callback)(const char *s) =
        conf_default_message_callback;
-void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
+void conf_set_message_callback(void (*fn)(const char *s))
 {
        conf_message_callback = fn;
 }
@@ -60,10 +118,15 @@ void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
 static void conf_message(const char *fmt, ...)
 {
        va_list ap;
+       char buf[4096];
+
+       if (!conf_message_callback)
+               return;
 
        va_start(ap, fmt);
-       if (conf_message_callback)
-               conf_message_callback(fmt, ap);
+
+       vsnprintf(buf, sizeof(buf), fmt, ap);
+       conf_message_callback(buf);
        va_end(ap);
 }
 
@@ -83,7 +146,6 @@ const char *conf_get_autoconfig_name(void)
 
 char *conf_get_default_confname(void)
 {
-       struct stat buf;
        static char fullname[PATH_MAX+1];
        char *env, *name;
 
@@ -91,7 +153,7 @@ char *conf_get_default_confname(void)
        env = getenv(SRCTREE);
        if (env) {
                sprintf(fullname, "%s/%s", env, name);
-               if (!stat(fullname, &buf))
+               if (is_present(fullname))
                        return fullname;
        }
        return name;
@@ -301,7 +363,7 @@ load:
                                sym = sym_find(line + 2 + strlen(CONFIG_));
                                if (!sym) {
                                        sym_add_change_count(1);
-                                       goto setsym;
+                                       continue;
                                }
                        } else {
                                sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
@@ -335,7 +397,7 @@ load:
                                sym = sym_find(line + strlen(CONFIG_));
                                if (!sym) {
                                        sym_add_change_count(1);
-                                       goto setsym;
+                                       continue;
                                }
                        } else {
                                sym = sym_lookup(line + strlen(CONFIG_), 0);
@@ -354,7 +416,7 @@ load:
 
                        continue;
                }
-setsym:
+
                if (sym && sym_is_choice_value(sym)) {
                        struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
                        switch (sym->def[def].tri) {
@@ -771,10 +833,9 @@ int conf_write(const char *name)
 
        dirname[0] = 0;
        if (name && name[0]) {
-               struct stat st;
                char *slash;
 
-               if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
+               if (is_dir(name)) {
                        strcpy(dirname, name);
                        strcat(dirname, "/");
                        basename = conf_get_configname();
@@ -859,19 +920,52 @@ next:
        return 0;
 }
 
+/* write a dependency file as used by kbuild to track dependencies */
+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;
+       fprintf(out, "deps_config := \\\n");
+       for (file = file_list; file; file = file->next) {
+               if (file->next)
+                       fprintf(out, "\t%s \\\n", file->name);
+               else
+                       fprintf(out, "\t%s\n", file->name);
+       }
+       fprintf(out, "\n%s: \\\n"
+                    "\t$(deps_config)\n\n", conf_get_autoconfig_name());
+
+       env_write_dep(out, conf_get_autoconfig_name());
+
+       fprintf(out, "\n$(deps_config): ;\n");
+       fclose(out);
+
+       if (make_parent_dir(name))
+               return 1;
+       rename("..config.tmp", name);
+       return 0;
+}
+
 static int conf_split_config(void)
 {
        const char *name;
        char path[PATH_MAX+1];
        char *s, *d, c;
        struct symbol *sym;
-       struct stat sb;
        int res, i, fd;
 
        name = conf_get_autoconfig_name();
        conf_read_simple(name, S_DEF_AUTO);
        sym_calc_value(modules_sym);
 
+       if (make_parent_dir("include/generated/foo.h"))
+               return 1;
        if (chdir("include/generated"))
                return 1;
 
@@ -943,19 +1037,12 @@ static int conf_split_config(void)
                                res = 1;
                                break;
                        }
-                       /*
-                        * Create directory components,
-                        * unless they exist already.
-                        */
-                       d = path;
-                       while ((d = strchr(d, '/'))) {
-                               *d = 0;
-                               if (stat(path, &sb) && mkdir(path, 0755)) {
-                                       res = 1;
-                                       goto out;
-                               }
-                               *d++ = '/';
+
+                       if (make_parent_dir(path)) {
+                               res = 1;
+                               goto out;
                        }
+
                        /* Try it again. */
                        fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                        if (fd == -1) {
@@ -981,7 +1068,7 @@ int conf_write_autoconf(void)
 
        sym_clear_all_valid();
 
-       file_write_dep("include/generated/auto.conf.cmd");
+       conf_write_dep("include/generated/auto.conf.cmd");
 
        if (conf_split_config())
                return 1;
@@ -1040,19 +1127,31 @@ int conf_write_autoconf(void)
        name = getenv("KCONFIG_AUTOHEADER");
        if (!name)
                name = "include/generated/autoconf.h";
+       if (make_parent_dir(name))
+               return 1;
        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;
+
        name = getenv("KCONFIG_CMAKE");
        if (!name)
                name = "config.cmake";
+       if (make_parent_dir(name))
+               return 1;
        if (rename(".tmpconfig.cmake", name))
                return 1;
+
        name = conf_get_autoconfig_name();
+       if (make_parent_dir(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.