From patchwork Sun Dec 5 06:35:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Lacombe X-Patchwork-Id: 380631 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oB56aBSX015917 for ; Sun, 5 Dec 2010 06:36:11 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752263Ab0LEGgL (ORCPT ); Sun, 5 Dec 2010 01:36:11 -0500 Received: from mail-gx0-f180.google.com ([209.85.161.180]:58930 "EHLO mail-gx0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751481Ab0LEGgK (ORCPT ); Sun, 5 Dec 2010 01:36:10 -0500 Received: by mail-gx0-f180.google.com with SMTP id 19so5952339gxk.11 for ; Sat, 04 Dec 2010 22:36:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=p2vpFk+nktidtf+r+GjNWnrOTOh24+RJUfBloVIFjik=; b=KFOSDGj9k0FVAywuhGLhht8hK77L7QjG7GAtIbOn1C6+CMtoJtQC6c90qKSG5ITnTs M6XEjnlAOueOPIsKYRZ+N1R71plDCvSm0XlN5eKD1reIA0mnAXqgsYohpLdqdpGOlNLF xxR6/C8SNorsHFcX3aOuR+FTcQt77Yq20OhLE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=eYuvvbH4La5c3Ps7Lj6DXT6h5RWzLfGpPWZHH0/iBnpbkXBcXk74pbfxeOs1Ez9BVA s3vq5EyBNTWYRXjIm35YAdb4urHKOiFHj9Li7MrfK4c/KBoz/mKVoGWGSNYo8KE8NSe8 1uXWPOLcL59Wd6c6BWtogpJO3Asyx65E+mFVA= Received: by 10.151.42.20 with SMTP id u20mr6966058ybj.133.1291530970188; Sat, 04 Dec 2010 22:36:10 -0800 (PST) Received: from localhost.localdomain (75-119-248-218.dsl.teksavvy.com [75.119.248.218]) by mx.google.com with ESMTPS id 31sm2268856yhl.30.2010.12.04.22.36.08 (version=SSLv3 cipher=RC4-MD5); Sat, 04 Dec 2010 22:36:09 -0800 (PST) From: Arnaud Lacombe To: linux-kbuild@vger.kernel.org Cc: Arnaud Lacombe , Ben Hutchings Subject: [PATCH 1/2] [RFC] kconfig: introduce specialized printer Date: Sun, 5 Dec 2010 01:35:18 -0500 Message-Id: <1291530919-5601-1-git-send-email-lacombar@gmail.com> X-Mailer: git-send-email 1.7.2.30.gc37d7.dirty Sender: linux-kbuild-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Sun, 05 Dec 2010 06:36:11 +0000 (UTC) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 6fd43d7..31d06da 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -417,64 +417,182 @@ int conf_read(const char *name) return 0; } -/* Write a S_STRING */ -static void conf_write_string(bool headerfile, const char *name, - const char *str, FILE *out) +/* + * Generic printers + */ +static void +kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) { - int l; - if (headerfile) - fprintf(out, "#define %s%s \"", CONFIG_, name); - else - fprintf(out, "%s%s=\"", CONFIG_, name); - - while (1) { - l = strcspn(str, "\"\\"); + + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (*value) { + case 'n': + if (arg != NULL) + return; + + fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name); + return; + default: + break; + } + default: + break; + } + + 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) { - xfwrite(str, l, 1, out); - str += l; + fprintf(fp, " "); + fwrite(p, l, 1, fp); + p += l; } - if (!*str) + fprintf(fp, "\n"); + if (*p++ == '\0') break; - fprintf(out, "\\%c", *str++); } - fputs("\"\n", out); } -static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no) +static struct conf_printer kconfig_printer_cb = { - const char *str; + .print_symbol = kconfig_print_symbol, + .print_comment = kconfig_print_comment, +}; + +static void +header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +{ + const char *suffix = ""; switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - switch (sym_get_tristate_value(sym)) { - case no: - if (write_no) - fprintf(out, "# %s%s is not set\n", - CONFIG_, sym->name); - break; - case mod: - fprintf(out, "%s%s=m\n", CONFIG_, sym->name); - break; - case yes: - fprintf(out, "%s%s=y\n", CONFIG_, sym->name); - break; + switch (*value) { + case 'n': + return; + case 'm': + suffix = "_MODULE"; + default: + value = "1"; } break; - case S_STRING: - conf_write_string(false, sym->name, sym_get_string_value(sym), out); + default: break; - case S_HEX: - case S_INT: - str = sym_get_string_value(sym); - fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str); + } + + fprintf(fp, "#define %s%s%s %s\n", + CONFIG_, sym->name, suffix, value); +} + +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, " "); + fwrite(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 +tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +{ + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + kconfig_print_symbol(fp, sym, value, arg); + break; + default: break; + } +} + +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) +{ + const char *str; + + switch (sym->type) { case S_OTHER: 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); } } +static void +conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg) +{ + const char *env; + char buf[256]; + time_t now; + int use_timestamp = 1; + + time(&now); + env = getenv("KCONFIG_NOTIMESTAMP"); + if (env && *env) + use_timestamp = 0; + + snprintf(buf, sizeof(buf), + "\n" + "Automatically generated file; DO NOT EDIT.\n" + "%s\n" + "%s", + rootmenu.prompt->text, + use_timestamp ? ctime(&now) : ""); + + printer->print_comment(fp, buf, printer_arg); +} + /* * Write out a minimal config. * All values that has default values are skipped as this is redundant. @@ -531,7 +649,7 @@ int conf_write_defconfig(const char *filename) goto next_menu; } } - conf_write_symbol(sym, out, true); + conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); } next_menu: if (menu->list != NULL) { @@ -561,9 +679,7 @@ int conf_write(const char *name) const char *str; char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; enum symbol_type type; - time_t now; - int use_timestamp = 1; - char *env; + const char *env; dirname[0] = 0; if (name && name[0]) { @@ -599,19 +715,7 @@ int conf_write(const char *name) if (!out) return 1; - time(&now); - env = getenv("KCONFIG_NOTIMESTAMP"); - if (env && *env) - use_timestamp = 0; - - fprintf(out, _("#\n" - "# Automatically generated make config: don't edit\n" - "# %s\n" - "%s%s" - "#\n"), - rootmenu.prompt->text, - use_timestamp ? "# " : "", - use_timestamp ? ctime(&now) : ""); + conf_write_heading(out, &kconfig_printer_cb, NULL); if (!conf_get_changed()) sym_clear_all_valid(); @@ -632,8 +736,8 @@ int conf_write(const char *name) if (!(sym->flags & SYMBOL_WRITE)) goto next; sym->flags &= ~SYMBOL_WRITE; - /* Write config symbol to file */ - conf_write_symbol(sym, out, true); + + conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); } next: @@ -782,10 +886,8 @@ out: int conf_write_autoconf(void) { struct symbol *sym; - const char *str; const char *name; FILE *out, *tristate, *out_h; - time_t now; int i; sym_clear_all_valid(); @@ -812,71 +914,23 @@ int conf_write_autoconf(void) return 1; } - time(&now); - fprintf(out, "#\n" - "# Automatically generated make config: don't edit\n" - "# %s\n" - "# %s" - "#\n", - rootmenu.prompt->text, ctime(&now)); - fprintf(tristate, "#\n" - "# Automatically generated - do not edit\n" - "\n"); - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" - " * %s\n" - " * %s" - " */\n", - rootmenu.prompt->text, ctime(&now)); + 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); for_all_symbols(i, sym) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE) || !sym->name) continue; - /* write symbol to config file */ - conf_write_symbol(sym, out, false); + /* write symbol to auto.conf, tristate and header files */ + conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); - /* update autoconf and tristate files */ - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - switch (sym_get_tristate_value(sym)) { - case no: - break; - case mod: - fprintf(tristate, "%s%s=M\n", - CONFIG_, sym->name); - fprintf(out_h, "#define %s%s_MODULE 1\n", - CONFIG_, sym->name); - break; - case yes: - if (sym->type == S_TRISTATE) - fprintf(tristate,"%s%s=Y\n", - CONFIG_, sym->name); - fprintf(out_h, "#define %s%s 1\n", - CONFIG_, sym->name); - break; - } - break; - case S_STRING: - conf_write_string(true, sym->name, sym_get_string_value(sym), out_h); - break; - case S_HEX: - str = sym_get_string_value(sym); - if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out_h, "#define %s%s 0x%s\n", - CONFIG_, sym->name, str); - break; - } - case S_INT: - str = sym_get_string_value(sym); - fprintf(out_h, "#define %s%s %s\n", - CONFIG_, sym->name, str); - break; - default: - break; - } + conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); + + conf_write_symbol(out_h, sym, &header_printer_cb, NULL); } fclose(out); fclose(tristate); diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 753cdbd..3633d5a 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -89,6 +89,11 @@ void sym_set_change_count(int count); void sym_add_change_count(int count); void conf_set_all_new_symbols(enum conf_def_mode mode); +struct conf_printer { + void (*print_symbol)(FILE *, struct symbol *, const char *, void *); + void (*print_comment)(FILE *, const char *, void *); +}; + /* confdata.c and expr.c */ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) { diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 17342fe..47fe9c3 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -31,6 +31,7 @@ P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); P(sym_lookup,struct symbol *,(const char *name, int flags)); P(sym_find,struct symbol *,(const char *name)); P(sym_expand_string_value,const char *,(const char *in)); +P(sym_escape_string_value, const char *,(const char *in)); P(sym_re_search,struct symbol **,(const char *pattern)); P(sym_type_name,const char *,(enum symbol_type type)); P(sym_calc_value,void,(struct symbol *sym)); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index ad7dbe7..e42240d 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -749,7 +749,8 @@ const char *sym_get_string_value(struct symbol *sym) case no: return "n"; case mod: - return "m"; + sym_calc_value(modules_sym); + return (modules_sym->curr.tri == no) ? "n" : "m"; case yes: return "y"; } @@ -891,6 +892,49 @@ const char *sym_expand_string_value(const char *in) return res; } +const 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 = malloc(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 symbol **sym_re_search(const char *pattern) { struct symbol *sym, **sym_arr = NULL;