From patchwork Tue Mar 27 05:29:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 132448 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp4655042ljb; Mon, 26 Mar 2018 22:34:34 -0700 (PDT) X-Google-Smtp-Source: AG47ELswxuK/c40gEsJKjKsy6EvfXqOjX/rmat1lzdAgy+5Upj5iUmLXUcGrYq4q2AgtcC1YTlNd X-Received: by 10.98.214.218 with SMTP id a87mr27391763pfl.124.1522128873840; Mon, 26 Mar 2018 22:34:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522128873; cv=none; d=google.com; s=arc-20160816; b=BjcGRRXrMxUlD666WaSqMFPniX933FlvO+YUYKu9PXBDalDXh6zQkNByz+L5HTRDy7 a2BsQ2f01rxmB2+baIuzdYtXguEtLXAvx1qR7vG+fb54XXBZs9gUeSJntsPQomJb/fSq /eg1+oBXsIcsRbPrYDBNtBrvmjAg54u9VM5AjMDxzm32DCLBfib+ILshC5XMJldl3Sqi 1QUm36JZmFEVnk3Ta3nt9ceXGaWlVUNj7u2y0+tVsWx8f8Mg5jmJ2zA7u3nBndv168zl alPRswXKTM4znXTYACb9UDE7qQ+kmO6VxrPZ/tl4T3D+6bZ8OWyudX+oth9cKGrX1hT6 NfQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter :arc-authentication-results; bh=hfxSFq+yfNF9k+XV5X1In6K3Q3h/kBskgYYt0vXrL38=; b=x+EfUlPJOLuWgizyDFTcAOKMF8FDn0+I/xeRmTMQg28pLS7U6eeL0Q6P+PtQMlwGoC bBjmi1UuiyQVyXlOFgtuuuHqcEuPNrDK8fUECCTM5RZo4eU60RWM4NfarlyAFqRQNjJ8 bCStzM2ukhVJFalKtmF08in8U8kQzYxTIVjoflHyKw08BbJN5FN85RjMZvdoVNS4ZWul acm2ZrP+Q9tssc8EcozrYMkwWVHTvq3kSndBW8kqDOomt5pokaFJ6uHFcJ0w7q1kJBkO ZRMahBGGU+TxcGmaIOoV69WCKhkwRofXuNYeUcrES4pdsi1cKl4jLVCgOpA+8l3CKU4M Z/LQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=Oy8mxPFr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g1-v6si510327plt.54.2018.03.26.22.34.33; Mon, 26 Mar 2018 22:34:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=Oy8mxPFr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752503AbeC0FeE (ORCPT + 28 others); Tue, 27 Mar 2018 01:34:04 -0400 Received: from conuserg-09.nifty.com ([210.131.2.76]:44833 "EHLO conuserg-09.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752106AbeC0FcF (ORCPT ); Tue, 27 Mar 2018 01:32:05 -0400 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id w2R5TaLs011947; Tue, 27 Mar 2018 14:29:48 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com w2R5TaLs011947 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1522128589; bh=hfxSFq+yfNF9k+XV5X1In6K3Q3h/kBskgYYt0vXrL38=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Oy8mxPFrwIuszmZOxa/6y0/zQ1vP/db79vbjx2m8E1svGtah16HnA7zrScZKaQt8o PhL2923YUk3GzZjnz29RIM7Lrux7cjLCUHg9cg6xPKXO9Ynz+1XN6PpiowHEElA8Nn 6120k1MYSUjWwiZrb2MZmds3OtGg9L/18L5lYAll5j5Tzbkt0oB8ESK8h0yYxpSSds 5nPsBP/MkoH0hW1rdighPolCQNf5cVIMjpedbLlxdSBQaxRO41d++zADDx86ZRUGsX u3uyreSBxGmHh9eFecG6ZX/hayw7tdj9ygpdpPMPFozi0YqdINAbM7WJozaE330QA8 QPmWIb96FFlvw== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: Sam Ravnborg , Linus Torvalds , Arnd Bergmann , Ulf Magnusson , Kees Cook , Thomas Gleixner , Greg Kroah-Hartman , Randy Dunlap , "Luis R . Rodriguez" , Nicolas Pitre , Masahiro Yamada , linux-kernel@vger.kernel.org Subject: [PATCH v2 09/21] kconfig: add 'macro' keyword to support user-defined function Date: Tue, 27 Mar 2018 14:29:23 +0900 Message-Id: <1522128575-5326-10-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1522128575-5326-1-git-send-email-yamada.masahiro@socionext.com> References: <1522128575-5326-1-git-send-email-yamada.masahiro@socionext.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now, we got a basic ability to test compiler capability in Kconfig. config CC_HAS_STACKPROTECTOR def_bool $(shell (($CC -Werror -fstack-protector -c -x c /dev/null -o /dev/null) && echo y) || echo n) This works, but it is ugly to repeat this long boilerplate. We want to describe like this: config CC_HAS_STACKPROTECTOR bool default $(cc-option -fstack-protector) It is straight-forward to add a new function, but I do not like to hard-code specialized functions like this. Hence, here is another feature to add functions from Kconfig files. A user-defined function is defined with a special keyword 'macro'. It can be referenced in the same way as built-in functions. This feature was also inspired by Makefile where user-defined functions are referenced by $(call func-name, args...), but I omitted the 'call' to makes it shorter. The macro definition can contain $(1), $(2), ... which will be replaced with arguments from the caller. The macro works just as a textual shorthand, which is also expanded in the lexer phase. [Example Code] macro success $(shell ($(1) && echo y) || echo n) config TRUE bool "true" default $(success true) config FALSE bool "false" default $(success false) [Result] $ make -s alldefconfig $ tail -n 2 .config CONFIG_TRUE=y # CONFIG_FALSE is not set [Example Code] macro success $(shell ($(1) && echo y) || echo n) macro cc-option $(success $CC -Werror $(1) -c -x c /dev/null -o /dev/null) config CC_HAS_STACKPROTECTOR def_bool $(cc-option -fstack-protector) [Result] $ make -s alldefconfig $ tail -n 1 .config CONFIG_CC_HAS_STACKPROTECTOR=y Signed-off-by: Masahiro Yamada --- Reminder for myself: Update Documentation/kbuild/kconfig-language.txt Changes in v2: - Use 'macro' directly instead of inside the string type symbol. scripts/kconfig/function.c | 59 +++++++++++++++++++++++++++++++++++++++++++-- scripts/kconfig/lkc_proto.h | 1 + scripts/kconfig/zconf.l | 31 ++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) -- 2.7.4 diff --git a/scripts/kconfig/function.c b/scripts/kconfig/function.c index 913685f..389bb44 100644 --- a/scripts/kconfig/function.c +++ b/scripts/kconfig/function.c @@ -15,6 +15,7 @@ static LIST_HEAD(function_list); struct function { char *name; char *(*func)(struct function *f, int argc, char *argv[]); + char *macro; struct list_head node; }; @@ -31,7 +32,8 @@ static struct function *func_lookup(const char *name) } static void func_add(const char *name, - char *(*func)(struct function *f, int argc, char *argv[])) + char *(*func)(struct function *f, int argc, char *argv[]), + const char *macro) { struct function *f; @@ -44,6 +46,7 @@ static void func_add(const char *name, f = xmalloc(sizeof(*f)); f->name = xstrdup(name); f->func = func; + f->macro = macro ? xstrdup(macro) : NULL; list_add_tail(&f->node, &function_list); } @@ -51,6 +54,7 @@ static void func_add(const char *name, static void func_del(struct function *f) { list_del(&f->node); + free(f->macro); free(f->name); free(f); } @@ -108,6 +112,57 @@ char *func_eval_n(const char *func, size_t n) return res; } +/* run user-defined function */ +static char *do_macro(struct function *f, int argc, char *argv[]) +{ + char *new; + char *src, *p, *res; + size_t newlen; + int n; + + new = xmalloc(1); + *new = 0; + + /* + * This is a format string. $(1), $(2), ... must be replaced with + * function arguments. + */ + src = f->macro; + p = src; + + while ((p = strstr(p, "$("))) { + if (isdigit(p[2]) && p[3] == ')') { + n = p[2] - '0'; + if (n < argc) { + newlen = strlen(new) + (p - src) + + strlen(argv[n]) + 1; + new = xrealloc(new, newlen); + strncat(new, src, p - src); + strcat(new, argv[n]); + src = p + 4; + } + p += 2; + } + p += 2; + } + + newlen = strlen(new) + strlen(src) + 1; + new = xrealloc(new, newlen); + strcat(new, src); + + res = expand_string_value(new); + + free(new); + + return res; +} + +/* add user-defined function (macro) */ +void func_add_macro(const char *name, const char *macro) +{ + func_add(name, do_macro, macro); +} + /* built-in functions */ static char *do_shell(struct function *f, int argc, char *argv[]) { @@ -157,7 +212,7 @@ static char *do_shell(struct function *f, int argc, char *argv[]) void func_init(void) { /* register built-in functions */ - func_add("shell", do_shell); + func_add("shell", do_shell, NULL); } void func_exit(void) diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 09a4f53..48699c0 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -50,6 +50,7 @@ const char * prop_get_type_name(enum prop_type type); /* function.c */ char *func_eval_n(const char *func, size_t n); +void func_add_macro(const char *name, const char *macro); void func_init(void); void func_exit(void); diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 551ca47..6a18c68 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -74,6 +74,36 @@ static void warn_ignored_character(char chr) "%s:%d:warning: ignoring unsupported character '%c'\n", zconf_curname(), zconf_lineno(), chr); } + +static void handle_macro(const char *text) +{ + char *p, *q; + + while (isspace(*text)) + text++; + + p = xstrdup(text); + + q = p; + while (isalnum(*q) || *q == '_' || *q == '-') + q++; + + if (q == p || !*q) { + yyerror("invalid\n"); + goto free; + } + + *q = '\0'; + + q++; + while (isspace(*q)) + q++; + + func_add_macro(p, q); +free: + free(p); +} + %} n [A-Za-z0-9_-] @@ -82,6 +112,7 @@ n [A-Za-z0-9_-] int str = 0; int ts, i; +"macro"[ \t].* handle_macro(yytext + 6); [ \t]*#.*\n | [ \t]*\n { return T_EOL;