From 229d0cfae5b21bfc42525cf43b0b4279243acc4e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:44 +0900 Subject: kconfig: remove 'const' from the return type of sym_escape_string_value() sym_escape_string_value() returns a malloc'ed memory, but as (const char *). So, it must be casted to (void *) when it is free'd. This is odd. The return type of sym_escape_string_value() should be (char *). I exploited that free(NULL) has no effect. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index cf72680cd769..9b2271eb43d6 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -728,21 +728,22 @@ static struct conf_printer header_printer_cb = static void conf_write_symbol(FILE *fp, struct symbol *sym, struct conf_printer *printer, void *printer_arg) { - const char *str; + const char *val; + char *escaped = NULL; - switch (sym->type) { - case S_UNKNOWN: - break; - case S_STRING: - str = sym_get_string_value(sym); - str = sym_escape_string_value(str); - printer->print_symbol(fp, sym, str, printer_arg); - free((void *)str); - break; - default: - str = sym_get_string_value(sym); - printer->print_symbol(fp, sym, str, printer_arg); + if (sym->type == S_UNKNOWN) + return; + + val = sym_get_string_value(sym); + + if (sym->type == S_STRING) { + escaped = sym_escape_string_value(val); + val = escaped; } + + printer->print_symbol(fp, sym, val, printer_arg); + + free(escaped); } static void -- cgit v1.2.3 From ca51b26b4a25b05c9b438ed85c4750bfb6f2d9ab Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:45 +0900 Subject: kconfig: refactor conf_write_heading() All the call sites of conf_write_heading() pass NULL to the third argument, and it is not used in the function. Also, the print_comment hooks are doing much more complex than needed. Rewrite the code. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 95 ++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 62 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9b2271eb43d6..83e324b9b5e5 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -161,7 +161,6 @@ static int conf_touch_dep(const char *name) struct conf_printer { void (*print_symbol)(FILE *, struct symbol *, const char *, void *); - void (*print_comment)(FILE *, const char *, void *); }; static void conf_warning(const char *fmt, ...) @@ -594,6 +593,36 @@ int conf_read(const char *name) 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) +{ + 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); +} + /* * Kconfig configuration printer * @@ -625,30 +654,9 @@ 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_comment(FILE *fp, const char *value, void *arg) -{ - const char *p = value; - size_t l; - - for (;;) { - l = strcspn(p, "\n"); - fprintf(fp, "#"); - if (l) { - fprintf(fp, " "); - xfwrite(p, l, 1, fp); - p += l; - } - fprintf(fp, "\n"); - if (*p++ == '\0') - break; - } -} - static struct conf_printer kconfig_printer_cb = { .print_symbol = kconfig_print_symbol, - .print_comment = kconfig_print_comment, }; /* @@ -697,32 +705,9 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) } -static void -header_print_comment(FILE *fp, const char *value, void *arg) -{ - const char *p = value; - size_t l; - - fprintf(fp, "/*\n"); - for (;;) { - l = strcspn(p, "\n"); - fprintf(fp, " *"); - if (l) { - fprintf(fp, " "); - xfwrite(p, l, 1, fp); - p += l; - } - fprintf(fp, "\n"); - if (*p++ == '\0') - break; - } - fprintf(fp, " */\n"); -} - static struct conf_printer header_printer_cb = { .print_symbol = header_print_symbol, - .print_comment = header_print_comment, }; static void conf_write_symbol(FILE *fp, struct symbol *sym, @@ -746,20 +731,6 @@ static void conf_write_symbol(FILE *fp, struct symbol *sym, free(escaped); } -static void -conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg) -{ - char buf[256]; - - snprintf(buf, sizeof(buf), - "\n" - "Automatically generated file; DO NOT EDIT.\n" - "%s\n", - rootmenu.prompt->text); - - printer->print_comment(fp, buf, printer_arg); -} - /* * Write out a minimal config. * All values that has default values are skipped as this is redundant. @@ -876,7 +847,7 @@ int conf_write(const char *name) if (!out) return 1; - conf_write_heading(out, &kconfig_printer_cb, NULL); + conf_write_heading(out, &comment_style_pound); if (!conf_get_changed()) sym_clear_all_valid(); @@ -1080,8 +1051,8 @@ int conf_write_autoconf(int overwrite) return 1; } - conf_write_heading(out, &kconfig_printer_cb, NULL); - conf_write_heading(out_h, &header_printer_cb, NULL); + conf_write_heading(out, &comment_style_pound); + conf_write_heading(out_h, &comment_style_c); for_all_symbols(i, sym) { sym_calc_value(sym); -- cgit v1.2.3 From 6ce45a91a9826532dde7c89cd2d6388c0bcb0cf7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:46 +0900 Subject: kconfig: refactor conf_write_symbol() I do not think 'struct conf_printer' is so useful. Add simple functions, print_symbol_for_*() to write out one symbol. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 136 +++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 79 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 83e324b9b5e5..4e3fd194231b 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -159,10 +160,6 @@ static int conf_touch_dep(const char *name) return 0; } -struct conf_printer { - void (*print_symbol)(FILE *, struct symbol *, const char *, void *); -}; - static void conf_warning(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); @@ -629,91 +626,52 @@ static void conf_write_heading(FILE *fp, const struct comment_style *cs) * This printer is used when generating the resulting configuration after * kconfig invocation and `defconfig' files. Unset symbol might be omitted by * passing a non-NULL argument to the printer. - * */ -static void -kconfig_print_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, "# %s%s is not set\n", - CONFIG_, sym->name); - return; - } - break; - default: - break; - } - - fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value); -} +enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; -static struct conf_printer kconfig_printer_cb = +static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, + bool escape_string) { - .print_symbol = kconfig_print_symbol, -}; + const char *val; + char *escaped = NULL; -/* - * Header printer - * - * This printer is used when generating the `include/generated/autoconf.h' file. - */ -static void -header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) -{ + if (sym->type == S_UNKNOWN) + return; - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: { - const char *suffix = ""; + val = sym_get_string_value(sym); - switch (*value) { - case 'n': - break; - case 'm': - suffix = "_MODULE"; - /* fall through */ - default: - fprintf(fp, "#define %s%s%s 1\n", - CONFIG_, sym->name, suffix); - } - break; + 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; } - case S_HEX: { - const char *prefix = ""; - if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) - prefix = "0x"; - fprintf(fp, "#define %s%s %s%s\n", - CONFIG_, sym->name, prefix, value); - break; - } - case S_STRING: - case S_INT: - fprintf(fp, "#define %s%s %s\n", - CONFIG_, sym->name, value); - break; - default: - break; + if (sym->type == S_STRING && escape_string) { + escaped = sym_escape_string_value(val); + val = escaped; } + fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val); + + free(escaped); } -static struct conf_printer header_printer_cb = +static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym) { - .print_symbol = header_print_symbol, -}; + __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, true); +} -static void conf_write_symbol(FILE *fp, struct symbol *sym, - struct conf_printer *printer, void *printer_arg) +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) @@ -721,12 +679,32 @@ static void conf_write_symbol(FILE *fp, struct symbol *sym, val = sym_get_string_value(sym); - if (sym->type == S_STRING) { + 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 = sym_escape_string_value(val); val = escaped; + default: + break; } - printer->print_symbol(fp, sym, val, printer_arg); + fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, + val_prefix, val); free(escaped); } @@ -787,7 +765,7 @@ int conf_write_defconfig(const char *filename) goto next_menu; } } - conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); + print_symbol_for_dotconfig(out, sym); } next_menu: if (menu->list != NULL) { @@ -874,7 +852,7 @@ int conf_write(const char *name) need_newline = false; } sym->flags |= SYMBOL_WRITTEN; - conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); + print_symbol_for_dotconfig(out, sym); } next: @@ -1060,8 +1038,8 @@ int conf_write_autoconf(int overwrite) continue; /* write symbols to auto.conf and autoconf.h */ - conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); - conf_write_symbol(out_h, sym, &header_printer_cb, NULL); + print_symbol_for_autoconf(out, sym); + print_symbol_for_c(out_h, sym); } fclose(out); fclose(out_h); -- cgit v1.2.3 From 51d792cb5de87fa8777b4769a33c302e4ad0580a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:47 +0900 Subject: kconfig: refactor listnewconfig code We can reuse __print_symbol() helper to print symbols for listnewconfig. Only the difference is the format for "n" symbols. This prints "CONFIG_FOO=n" instead of "# CONFIG_FOO is not set". Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 14 ++------------ scripts/kconfig/confdata.c | 5 +++++ scripts/kconfig/lkc_proto.h | 1 + 3 files changed, 8 insertions(+), 12 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 310fdd408793..971da3598fe4 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -646,18 +646,8 @@ static void check_conf(struct menu *menu) switch (input_mode) { case listnewconfig: - if (sym->name) { - const char *val = sym_get_string_value(sym); - char *escaped = NULL; - - if (sym->type == S_STRING) { - escaped = sym_escape_string_value(val); - val = escaped; - } - - printf("%s%s=%s\n", CONFIG_, sym->name, val); - free(escaped); - } + if (sym->name) + print_symbol_for_listconfig(sym); break; case helpnewconfig: printf("-----\n"); diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 4e3fd194231b..f17a2a9562ee 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -667,6 +667,11 @@ static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym) __print_symbol(fp, sym, OUTPUT_N_NONE, true); } +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; diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index e6955df49973..ec4a01bb60ce 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -19,6 +19,7 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; struct symbol * sym_lookup(const char *name, int flags); struct symbol * sym_find(const char *name); char *sym_escape_string_value(const char *in); +void print_symbol_for_listconfig(struct symbol *sym); struct symbol ** sym_re_search(const char *pattern); const char * sym_type_name(enum symbol_type type); void sym_calc_value(struct symbol *sym); -- cgit v1.2.3 From 80f7bc7737630fb1b2c4f440fc7627337bd2f605 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:48 +0900 Subject: kconfig: move sym_escape_string_value() to confdata.c Now that sym_escape_string_value() is only used in confdata.c it can be a 'static' function. Rename it escape_string_value() because it is agnostic about (struct sym *). Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 47 +++++++++++++++++++++++++++++++++++++++++++-- scripts/kconfig/lkc_proto.h | 1 - scripts/kconfig/symbol.c | 44 ------------------------------------------ 3 files changed, 45 insertions(+), 47 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f17a2a9562ee..26b39d34e2be 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -620,6 +620,49 @@ static void conf_write_heading(FILE *fp, const struct comment_style *cs) 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; +} + /* * Kconfig configuration printer * @@ -648,7 +691,7 @@ static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, } if (sym->type == S_STRING && escape_string) { - escaped = sym_escape_string_value(val); + escaped = escape_string_value(val); val = escaped; } @@ -702,7 +745,7 @@ static void print_symbol_for_c(FILE *fp, struct symbol *sym) val_prefix = "0x"; break; case S_STRING: - escaped = sym_escape_string_value(val); + escaped = escape_string_value(val); val = escaped; default: break; diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index ec4a01bb60ce..edd1e617b25c 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -18,7 +18,6 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; struct symbol * sym_lookup(const char *name, int flags); struct symbol * sym_find(const char *name); -char *sym_escape_string_value(const char *in); void print_symbol_for_listconfig(struct symbol *sym); struct symbol ** sym_re_search(const char *pattern); const char * sym_type_name(enum symbol_type type); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 6bf8665a6a0f..0572330bf8a7 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -871,50 +871,6 @@ struct symbol *sym_find(const char *name) return symbol; } -/* The returned pointer must be freed on the caller side */ -char *sym_escape_string_value(const char *in) -{ - const char *p; - size_t reslen; - char *res; - size_t l; - - reslen = strlen(in) + strlen("\"\"") + 1; - - p = in; - for (;;) { - l = strcspn(p, "\"\\"); - p += l; - - if (p[0] == '\0') - break; - - reslen++; - p++; - } - - res = xmalloc(reslen); - res[0] = '\0'; - - strcat(res, "\""); - - p = in; - for (;;) { - l = strcspn(p, "\"\\"); - strncat(res, p, l); - p += l; - - if (p[0] == '\0') - break; - - strcat(res, "\\"); - strncat(res, p++, 1); - } - - strcat(res, "\""); - return res; -} - struct sym_match { struct symbol *sym; off_t so, eo; -- cgit v1.2.3 From 8499f2dd57ef099290fa5411c4498bccc9c407d9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:49 +0900 Subject: kconfig: add conf_get_autoheader_name() For consistency with conf_get_autoconfig_name() Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 26b39d34e2be..acf3d5a2973e 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -223,6 +223,13 @@ static const char *conf_get_autoconfig_name(void) 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 int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) { char *p2; @@ -1092,9 +1099,7 @@ int conf_write_autoconf(int overwrite) fclose(out); fclose(out_h); - name = getenv("KCONFIG_AUTOHEADER"); - if (!name) - name = "include/generated/autoconf.h"; + name = conf_get_autoheader_name(); if (make_parent_dir(name)) return 1; if (rename(".tmpconfig.h", name)) -- cgit v1.2.3 From 57ddd07c456053dfdabebc6a2d030c57cd3fb75b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:50 +0900 Subject: kconfig: refactor conf_write_autoconf() This function does similar for auto.conf and autoconf.h Create __conf_write_autoconf() helper to factor out the common code. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 94 ++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 37 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index acf3d5a2973e..7301f4b2f4d5 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -1058,13 +1058,53 @@ static int conf_touch_deps(void) 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, i; + + 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(i, sym) + if ((sym->flags & SYMBOL_WRITE) && sym->name) + print_symbol(file, sym); + + /* check possible errors in conf_write_heading() and print_symbol() */ + if (ferror(file)) + return -1; + + fclose(file); + + if (rename(tmp, filename)) { + perror("rename"); + return -1; + } + + return 0; +} + int conf_write_autoconf(int overwrite) { struct symbol *sym; - const char *name; const char *autoconf_name = conf_get_autoconfig_name(); - FILE *out, *out_h; - int i; + int ret, i; if (!overwrite && is_present(autoconf_name)) return 0; @@ -1074,45 +1114,25 @@ int conf_write_autoconf(int overwrite) if (conf_touch_deps()) return 1; - out = fopen(".tmpconfig", "w"); - if (!out) - return 1; - - out_h = fopen(".tmpconfig.h", "w"); - if (!out_h) { - fclose(out); - return 1; - } - - conf_write_heading(out, &comment_style_pound); - conf_write_heading(out_h, &comment_style_c); - - for_all_symbols(i, sym) { + for_all_symbols(i, sym) sym_calc_value(sym); - if (!(sym->flags & SYMBOL_WRITE) || !sym->name) - continue; - /* write symbols to auto.conf and autoconf.h */ - print_symbol_for_autoconf(out, sym); - print_symbol_for_c(out_h, sym); - } - fclose(out); - fclose(out_h); - - name = conf_get_autoheader_name(); - if (make_parent_dir(name)) - return 1; - if (rename(".tmpconfig.h", name)) - return 1; + ret = __conf_write_autoconf(conf_get_autoheader_name(), + print_symbol_for_c, + &comment_style_c); + if (ret) + return ret; - if (make_parent_dir(autoconf_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. + * 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. */ - if (rename(".tmpconfig", autoconf_name)) - return 1; + ret = __conf_write_autoconf(conf_get_autoconfig_name(), + print_symbol_for_autoconf, + &comment_style_pound); + if (ret) + return ret; return 0; } -- cgit v1.2.3 From 00d674cb35362dd30df7ff1e0003ad6d6c3ebf3a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:51 +0900 Subject: kconfig: refactor conf_write_dep() The if ... else inside the for-loop is unneeded because one empty line is placed after printing the last element of deps_config. Currently, all errors in conf_write_dep() are ignored. Add proper error checks. Rename it to conf_write_autoconf_cmd(), which is more intuitive. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 54 +++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 7301f4b2f4d5..6ac53bf7aa64 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -957,32 +957,50 @@ next: } /* write a dependency file as used by kbuild to track dependencies */ -static int conf_write_dep(const char *name) +static int conf_write_autoconf_cmd(const char *autoconf_name) { + char name[PATH_MAX], tmp[PATH_MAX]; struct file *file; FILE *out; + int ret; - 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); + 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, "\n%s: \\\n" - "\t$(deps_config)\n\n", conf_get_autoconfig_name()); - env_write_dep(out, conf_get_autoconfig_name()); + fprintf(out, "deps_config := \\\n"); + for (file = file_list; file; file = file->next) + fprintf(out, "\t%s \\\n", file->name); + + fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name); + + env_write_dep(out, autoconf_name); fprintf(out, "\n$(deps_config): ;\n"); + + if (ferror(out)) /* error check for all fprintf() calls */ + return -1; + fclose(out); - if (make_parent_dir(name)) - return 1; - rename("..config.tmp", name); + if (rename(tmp, name)) { + perror("rename"); + return -1; + } + return 0; } @@ -1109,7 +1127,9 @@ int conf_write_autoconf(int overwrite) if (!overwrite && is_present(autoconf_name)) return 0; - conf_write_dep("include/config/auto.conf.cmd"); + ret = conf_write_autoconf_cmd(autoconf_name); + if (ret) + return -1; if (conf_touch_deps()) return 1; -- cgit v1.2.3 From fee762d69ad5968dfd0ecbc300810f185ee5c5b8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 1 Oct 2021 14:32:52 +0900 Subject: kconfig: refactor conf_touch_dep() If this function fails to touch a dummy header due to missing parent directory, then it creates it and touches the file again. This was needed because CONFIG_FOO_BAR was previously tracked by include/config/foo/bar.h. (include/config/foo/ may not exist here) This is no longer the case since commit 0e0345b77ac4 ("kbuild: redo fake deps at include/config/*.h"); now all the fake headers are placed right under include/config/, like include/config/FOO_BAR. Do not try to create parent directory, include/config/, which already exists. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'scripts/kconfig/confdata.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 6ac53bf7aa64..42bc56ee238c 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -130,31 +130,17 @@ static size_t depfile_prefix_len; /* touch depfile for symbol 'name' */ static int conf_touch_dep(const char *name) { - int fd, ret; - char *d; + int fd; /* check overflow: prefix + name + '\0' must fit in buffer. */ if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) return -1; - d = depfile_path + depfile_prefix_len; - strcpy(d, name); + strcpy(depfile_path + depfile_prefix_len, name); - /* Assume directory path already exists. */ fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - if (errno != ENOENT) - return -1; - - ret = make_parent_dir(depfile_path); - if (ret) - return ret; - - /* Try it again. */ - fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) - return -1; - } + if (fd == -1) + return -1; close(fd); return 0; -- cgit v1.2.3