Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make make: only evaluate the ':@' modifier if the re...



details:   https://anonhg.NetBSD.org/src/rev/a43f786d1d37
branches:  trunk
changeset: 1019580:a43f786d1d37
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun Mar 14 18:02:44 2021 +0000

description:
make: only evaluate the ':@' modifier if the result is actually used

The test 'var-eval-short' had produced the output 'unexpected' before,
on stderr.  It had been generated by '${:Uword:@${FAIL}@expr@}' by
combining the following obscure "features" of make:

1.  the ':@' modifier loops over the words of the variable.  This
    modifier is not really obscure, it still takes some time to get used
    to it.

2.  the ':@' modifier allows a '$' sign in the variable name, which is
    useless in practice.

3.  the ':@' modifier creates a temporary loop variable in the global
    namespace.  Luckily there are only few collisions with other
    variable names since their naming conventions differ.

4.  after looping over the words of the expression, the temporary global
    loop variable is deleted, and at that point the '$' is expanded,
    being interpreted as the start of a variable expression.

5.  The ':@' modifier deleted the global variable even when it was
    called in parse-only mode (without VARE_WANTRES).

When the modifier ':@' was initially added to make in var.c 1.40 from
2000-04-29, Var_Delete didn't expand the variable name.  That feature
was added in var.c 1.174 from 2013-05-18, probably without thinking of
this very edge-casey combination of features.

This commit fixes item 5 from the above list.  The other obscurities
remain for now.

diffstat:

 usr.bin/make/unit-tests/var-eval-short.exp |  1 -
 usr.bin/make/var.c                         |  9 +++++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diffs (45 lines):

diff -r 411f1f97464c -r a43f786d1d37 usr.bin/make/unit-tests/var-eval-short.exp
--- a/usr.bin/make/unit-tests/var-eval-short.exp        Sun Mar 14 17:38:24 2021 +0000
+++ b/usr.bin/make/unit-tests/var-eval-short.exp        Sun Mar 14 18:02:44 2021 +0000
@@ -1,4 +1,3 @@
-unexpected
 make: Bad modifier ":[${FAIL" for variable ""
 make: "var-eval-short.mk" line 43: Malformed conditional (0 && ${:Uword:[${FAIL}]})
 make: "var-eval-short.mk" line 63: Invalid time value: ${FAIL}}
diff -r 411f1f97464c -r a43f786d1d37 usr.bin/make/var.c
--- a/usr.bin/make/var.c        Sun Mar 14 17:38:24 2021 +0000
+++ b/usr.bin/make/var.c        Sun Mar 14 18:02:44 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: var.c,v 1.869 2021/03/14 17:38:24 rillig Exp $ */
+/*     $NetBSD: var.c,v 1.870 2021/03/14 18:02:44 rillig Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
 #include "metachar.h"
 
 /*     "@(#)var.c      8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.869 2021/03/14 17:38:24 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.870 2021/03/14 18:02:44 rillig Exp $");
 
 typedef enum VarFlags {
        VFL_NONE        = 0,
@@ -2429,6 +2429,9 @@
        if (res != VPR_OK)
                return AMR_CLEANUP;
 
+       if (!(expr->eflags & VARE_WANTRES))
+               goto done;
+
        args.eflags = expr->eflags & ~(unsigned)VARE_KEEP_DOLLAR;
        prev_sep = st->sep;
        st->sep = ' ';          /* XXX: should be st->sep for consistency */
@@ -2440,6 +2443,8 @@
         * ModifyWord_Loop.
         */
        Var_DeleteExpand(expr->scope, args.tvar);
+
+done:
        free(args.tvar);
        free(args.str);
        return AMR_OK;



Home | Main Index | Thread Index | Old Index