Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp7211711imm; Sun, 20 May 2018 21:46:45 -0700 (PDT) X-Google-Smtp-Source: AB8JxZoM7Wln457daYHzgCYUJptV8gWZG73NZQS2ranEi02lcfdlmDovGBVOUEA8Bwu/O2d2wYBE X-Received: by 2002:a63:2547:: with SMTP id l68-v6mr15043717pgl.40.1526878005060; Sun, 20 May 2018 21:46:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526878005; cv=none; d=google.com; s=arc-20160816; b=cHYKidtl8b/spV8Vebe+GeKz/sZj5sGbWvBFEenXPk+IHkj9jNS+/YhP2JKAA6oNf6 nL1wdTwqBCyO+6pqc6DJBPUimJbgw3EI/Z3+H3T4uhfGJfLIQxugtoygduRb9Y2E6jv6 /QkCK5AMsUrkKFLxQ5CQiCd0YSrbsJBOht42veZ2ExIgZLTMkKwYGH7x5ncY7fUG6MAY 2DeaNA0sOZ92DbX4k9Ex5XjwuOPHu5NoMsGw+Ugr2Nouwo1gFqvs6+/qYWT1Sidzw5ko cc3y9CGPfRL76dl0fBip0CCtYYYDPENFnKKX+yN+GVBh9JvryLiPUkw6Rxx0gn4lEd1K /aAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature:dkim-filter :arc-authentication-results; bh=Sekp5WdPCIzwYrl48bL0IZZjno98wf5Na0YRBNtv5w4=; b=STxoXUiz0yQCxXfskrzU4QzMBenp38ziwoEe0XP2Tep5pN/yXXs/9xC/xuDr1buwnW DmuJUmEXB/l+f3Kpr/wqepfGr9TnmyM14skC1Ix8+J/I3JncAynu2lXXSBjCYlY9s7p7 riywJT41RsnS7tq8uVbu0VhJBoyj7ZoOubmBf1a8Tyis3bnMtY76dpo0lBunIkUISsiF skhpNPLsdsnBAtM/X9zARJlYOH50TFFdHOR9ghX9in602cnh1MnVpyeRJfFJIb76ypJ7 6CcN/gJxcDW0kh+kpx/K2rETrhIqpRJcLrRkAyh1JTixNMQDcd30+qAI3i9yCBsLc7T5 kO6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=IIvP/JY3; 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 z9-v6si14077221pll.423.2018.05.20.21.46.30; Sun, 20 May 2018 21:46:45 -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=IIvP/JY3; 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 S1752766AbeEUEoi (ORCPT + 99 others); Mon, 21 May 2018 00:44:38 -0400 Received: from conssluserg-04.nifty.com ([210.131.2.83]:32715 "EHLO conssluserg-04.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751245AbeEUEoe (ORCPT ); Mon, 21 May 2018 00:44:34 -0400 Received: from mail-ua0-f173.google.com (mail-ua0-f173.google.com [209.85.217.173]) (authenticated) by conssluserg-04.nifty.com with ESMTP id w4L4iN3P029349; Mon, 21 May 2018 13:44:23 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conssluserg-04.nifty.com w4L4iN3P029349 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1526877864; bh=Sekp5WdPCIzwYrl48bL0IZZjno98wf5Na0YRBNtv5w4=; h=In-Reply-To:References:From:Date:Subject:To:Cc:From; b=IIvP/JY3TD96upslR1pr4Kj5Z7di9zbJ7ggEC4o7AzwXQ0VGJjiOk5waAO9kt2fwl 6Mw6a9TCb5SKHHJiuvnOqptwMR7cZdqD3Ib/so/i75Zy5ZamI+bdZFJwkO0rR1aVYc NE0XtiXKvn+GLgrsskIUXGcKUIT6ETLNJNUCQZoJSklqmSzOC3XJ/UqAFA4q9vuUKo YSqG04QIuXx+V0ew1OLlIkTEPO9mo0Jwf9aviuoC+cdGq8ByVLbESGCYPlnM4Dh3LK Zm/KyCYbcLWyKZA4ff5SgGiNXwHXPNG2oZGdCcLmPXDUwtJE4yam8j8xhV8CebZoYe 74tWzcbhGqetw== X-Nifty-SrcIP: [209.85.217.173] Received: by mail-ua0-f173.google.com with SMTP id f3-v6so9063970uan.9; Sun, 20 May 2018 21:44:23 -0700 (PDT) X-Gm-Message-State: ALKqPwdJtcrxv2t/RXAxb7HExDu3yCqYFm1njgc/KM9qjelZwze9Y7RO lecEz1APK9lJC6hfhYy6Z1SoHLoKjgXSbtIyVEQ= X-Received: by 2002:ab0:1014:: with SMTP id f20-v6mr13585670uab.141.1526877862441; Sun, 20 May 2018 21:44:22 -0700 (PDT) MIME-Version: 1.0 Received: by 10.176.85.216 with HTTP; Sun, 20 May 2018 21:43:42 -0700 (PDT) In-Reply-To: References: <1526537830-22606-1-git-send-email-yamada.masahiro@socionext.com> <1526537830-22606-4-git-send-email-yamada.masahiro@socionext.com> From: Masahiro Yamada Date: Mon, 21 May 2018 13:43:42 +0900 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH v4 03/31] kconfig: reference environment variables directly and remove 'option env=' To: Ulf Magnusson Cc: Linux Kbuild mailing list , Linus Torvalds , Sam Ravnborg , "Luis R . Rodriguez" , Linux Kernel Mailing List , Nicholas Piggin , Kees Cook , Emese Revfy , X86 ML Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi. 2018-05-21 0:46 GMT+09:00 Ulf Magnusson : > s/environments/environment variables/ Will fix. > >> + * They will be written out to include/config/auto.conf.cmd >> + */ >> + env_add(name, value); >> + >> + return xstrdup(value); >> +} >> + >> +void env_write_dep(FILE *f, const char *autoconfig_name) >> +{ >> + struct env *e, *tmp; >> + >> + list_for_each_entry_safe(e, tmp, &env_list, node) { >> + fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value); >> + fprintf(f, "%s: FORCE\n", autoconfig_name); >> + fprintf(f, "endif\n"); >> + env_del(e); >> + } >> +} >> + >> +static char *eval_clause(const char *in) >> +{ >> + char *res, *name; >> + >> + /* >> + * Returns an empty string because '$()' should be evaluated >> + * to a null string. >> + */ > > Do you know of cases where this is more useful than erroring out? > > Not saying it doesn't make sense. Just curious. I just followed how Make works. Anyway, eval_clause() will return null string for null input. I will remove that hunk. >> + if (!*in) >> + return xstrdup(""); >> + >> + name = expand_string(in); >> + >> + res = env_expand(name); >> + free(name); >> + >> + return res; >> +} >> + >> +/* >> + * Expand a string that follows '$' >> + * >> + * For example, if the input string is >> + * ($(FOO)$($(BAR)))$(BAZ) >> + * this helper evaluates >> + * $($(FOO)$($(BAR))) >> + * and returns the resulted string, then updates 'str' to point to the next > > s/resulted/resulting/ > > Maybe something like this would make the behavior a bit clearer: > > ...and returns a new string containing the expansion, also advancing > 'str' to point to the next character after... (note that this function does > a recursive expansion) ... Is this OK? /* * Expand a string that follows '$' * * For example, if the input string is * ($(FOO)$($(BAR)))$(BAZ) * this helper evaluates * $($(FOO)$($(BAR))) * and returns a new string containing the expansion (note that the string is * recursively expanded), also advancing 'str' to point to the next character * after the corresponding closing parenthesis, in this case, *str will be * $(BAR) */ >> + * character after the corresponding closing parenthesis, in this case, *str >> + * will be >> + * $(BAR) >> + */ >> +char *expand_dollar(const char **str) >> +{ >> + const char *p = *str; >> + const char *q; >> + char *tmp, *out; >> + int nest = 0; >> + >> + /* '$$' represents an escaped '$' */ >> + if (*p == '$') { >> + *str = p + 1; >> + return xstrdup("$"); >> + } >> + >> + /* >> + * Kconfig does not support single-letter variable as in $A >> + * or curly braces as in ${CC}. >> + */ >> + if (*p != '(') >> + pperror("syntax error: '$' not followed by '('", p); > > Could say "not followed by '(' by or '$'". Will do. >> + >> + p++; >> + q = p; >> + while (*q) { >> + if (*q == '(') { >> + nest++; >> + } else if (*q == ')') { >> + if (nest-- == 0) >> + break; >> + } >> + q++; >> + } >> + >> + if (!*q) >> + pperror("unterminated reference to '%s': missing ')'", p); >> + >> + tmp = xmalloc(q - p + 1); >> + memcpy(tmp, p, q - p); >> + tmp[q - p] = 0; >> + *str = q + 1; >> + out = eval_clause(tmp); >> + free(tmp); >> + >> + return out; > > This might be a bit clearer, since the 'str' update and the expansion > are independent: Indeed, will do. > > /* Advance 'str' to after the expanded initial portion of the string */ > *str = q + 1; > > /* Save the "FOO" part of "(FOO)" into 'tmp' and expand it recursively */ > tmp = xmalloc(q - p + 1); > memcpy(tmp, p, q - p); > tmp[q - p] = '\0'; > out = eval_clause(tmp); > free(tmp); > > return out; > > ...or switched around, but thought putting the 'str' bit first might > emphasize that it isn't modified. I prefer advancing the pointer at last. >> +} >> + >> +/* >> + * Expand variables in the given string. Undefined variables >> + * expand to an empty string. > > I wonder what the tradeoffs are vs. erroring out here (or leaving > undefined variables as-is). I want to stick to the Make-like behavior here and exploit it in some cases. We can set some variables in some arch/*/Kconfig, but unset in the others. In some arch/*/Kconfig: min-gcc-version := 40900 In init/Kconfig: # GCC 4.5 is required to build Linux Kernel. # Some architectures may override it (from arch/*/Kconfig) for their requirement. min-gcc-version := $(if,$(min-gcc-version),$(min-gcc-version),40500) ... check the gcc version, then show error if it is older than $(min-gcc-version). >> + * The returned string must be freed when done. >> + */ >> +char *expand_string(const char *in) >> +{ >> + const char *prev_in, *p; >> + char *new, *out; >> + size_t outlen; >> + >> + out = xmalloc(1); >> + *out = 0; >> + >> + while ((p = strchr(in, '$'))) { >> + prev_in = in; >> + in = p + 1; >> + new = expand_dollar(&in); >> + outlen = strlen(out) + (p - prev_in) + strlen(new) + 1; >> + out = xrealloc(out, outlen); >> + strncat(out, prev_in, p - prev_in); >> + strcat(out, new); >> + free(new); > > Some code duplication with expand_one_token() here. Do you think > something could be factored out/reorganized? Yes. For example, the following would work. If you prefer that, I can update it in v5. static char *__expand_string(const char **str, bool (*is_end)(const char *)) { const char *in, *prev_in, *p; char *new, *out; size_t outlen; out = xmalloc(1); *out = 0; p = in = *str; while (1) { if (*p == '$') { prev_in = in; in = p + 1; new = expand_dollar(&in); outlen = strlen(out) + (p - prev_in) + strlen(new) + 1; out = xrealloc(out, outlen); strncat(out, prev_in, p - prev_in); strcat(out, new); free(new); p = in; continue; } if (is_end(p)) break; p++; } outlen = strlen(out) + (p - in) + 1; out = xrealloc(out, outlen); strncat(out, in, p - in); *str = p; return out; } static bool is_end_of_str(const char *s) { return !*s; } char *expand_string(const char *in) { return __expand_string(&in, is_end_of_str); } static bool is_end_of_token(const char *s) { return !(isalnum(*s) || *s == '_' || *s == '-' || *s == '.' || *s == '/'); } char *expand_one_token(const char **str) { return __expand_string(str, is_end_of_token); } > I wonder if it might be cleaner to have expand_dollar() take a pointer > to the '$'. Might even out in terms of the +1's you'd have to add, as > all callers manually bump the pointer before the call now. I haven't > tried implementing it though, so hard to say. If I do this, I'd want to add a sanity check to expand_dollar(). I'd rather like to avoid unneeded code. static char *expand_dollar(...) { assert(*p == '$'); p++; /* '$$' represents an escaped '$' */ if (*p == '$') { *str = p + 1; return xstrdup("$"); } ... } > > Some short inline comments similar to above would help too I think. > -- Best Regards Masahiro Yamada