tech-userlevel archive

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

Re: regression/bug in /usr/bin/make



>So you are trying to evaluate (and which fails the same way):
>       .if !empty(var:M${:Uhead\:tail:C/:.*//})
>Since the .for code tries to escape the ':'.

AFACT the problem is that :M compresses the \:, which should really be
left for Var_Subst.

The following diff seems to address the issue and adds a unit-test:

PR: 41998
Reviewed by:

:Ufu\:goo

should expand to fu:goo even when it appears in :M${:Ufu\:goo}
When scanning for :M do not compress \: if we know we have
to call Var_Subst.

Index: var.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/var.c,v
retrieving revision 1.152
diff -u -p -r1.152 var.c
--- var.c       16 Jun 2009 05:44:06 -0000      1.152
+++ var.c       5 Sep 2009 21:55:37 -0000
@@ -2763,9 +2763,11 @@ ApplyModifiers(char *nstr, const char *t
                const char *endpat; /* points just after end of pattern */
                char    *cp2;
                Boolean copy;   /* pattern should be, or has been, copied */
+               Boolean needSubst;
                int nest;
 
                copy = FALSE;
+               needSubst = FALSE;
                nest = 1;
                /*
                 * In the loop below, ignore ':' unless we are at
@@ -2780,10 +2782,15 @@ ApplyModifiers(char *nstr, const char *t
                        if (*cp == '\\' &&
                            (cp[1] == ':' ||
                             cp[1] == endc || cp[1] == startc)) {
-                           copy = TRUE;
+                           if (!needSubst) {
+                               copy = TRUE;
+                           }
                            cp++;
                            continue;
                        }
+                       if (*cp == '$') {
+                           needSubst = TRUE;
+                       }
                        if (*cp == '(' || *cp == '{')
                            ++nest;
                        if (*cp == ')' || *cp == '}') {
@@ -2822,7 +2829,7 @@ ApplyModifiers(char *nstr, const char *t
                     */
                    pattern = bmake_strndup(tstr+1, endpat - (tstr + 1));
                }
-               if (strchr(pattern, '$') != NULL) {
+               if (needSubst) {
                    /*
                     * pattern contains embedded '$', so use Var_Subst to
                     * expand it.
Index: unit-tests/modmatch
===================================================================
RCS file: /cvsroot/src/usr.bin/make/unit-tests/modmatch,v
retrieving revision 1.1
diff -u -p -r1.1 modmatch
--- unit-tests/modmatch 20 Feb 2004 09:03:26 -0000      1.1
+++ unit-tests/modmatch 5 Sep 2009 21:55:37 -0000
@@ -9,8 +9,15 @@ X_LIBS= ${LIBA} ${LIBD} ${LIBE}
 
 LIB?=a
 
+var = head
+res = no
+.if !empty(var:M${:Uhead\:tail:C/:.*//})
+res = OK
+.endif
+
 all:
        @for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done
+       @echo "Mscanner=${res}"
 
 show:
        @echo 'LIB=${LIB} X_LIBS:M$${LIB$${LIB:tu}} is 
"${X_LIBS:M${LIB${LIB:tu}}}"'
Index: unit-tests/test.exp
===================================================================
RCS file: /cvsroot/src/usr.bin/make/unit-tests/test.exp,v
retrieving revision 1.27
diff -u -p -r1.27 test.exp
--- unit-tests/test.exp 3 Feb 2009 23:11:12 -0000       1.27
+++ unit-tests/test.exp 5 Sep 2009 21:55:37 -0000
@@ -97,6 +97,7 @@ LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/
 LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a"
 LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a"
 LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A"
+Mscanner=OK
 path=':/bin:/usr/bin::/sbin:/usr/sbin:.:/home/user/bin:.'
 path='/bin:/usr/bin:/sbin:/usr/sbin:/home/user/bin'
 path='/bin:/usr/bin:/sbin:/usr/sbin:/homes/user/bin'


Home | Main Index | Thread Index | Old Index