Make reduces two (empty) quotes to one if they are not the first word in a string. This work with :S, :C, :M and others and is true for double and single quotes. Fix: It looks like brk_string in src/usr.bin/make/str.c is responsible for that: inquote = '\0'; for (p = str, start = t = buffer;; ++p) { switch(ch = *p) { case '"': case '\'': if (inquote) { if (inquote == ch) inquote = '\0'; else break; } else { inquote = (char) ch; /* Don't miss "" or '' */ if (start == NULL && p[1] == inquote) { start = t + 1; break; } } if (!expand) { if (!start) start = t; *t++ = ch; } continue; [...] } if (!start) start = t; *t++ = (char) ch; } Essentially the part after /* Don't miss "" or '' */. Maybe something like this will do the trick: inquote = '\0'; start = (char *)NULL; for (p = str, t = buffer;; ++p) { switch(ch = *p) { case '"': case '\'': if (inquote) { if (inquote == ch) inquote = '\0'; else break; } else { inquote = (char) ch; } if (!expand) { if (!start) start = t; *t++ = ch; } continue; [...] } if (!start) start = t; *t++ = (char) ch; } How-To-Repeat: * Makefile: QUOTETEST1= "" QUOTETEST2= "" ab QUOTETEST3= ab "" QUOTETEST4= ab "" cd QUOTETEST5= ab "" "cd - ef" "" jk all: @echo 'QUOTETEST1: ${QUOTETEST1:M*}' @echo 'QUOTETEST2: ${QUOTETEST2:M*}' @echo 'QUOTETEST3: ${QUOTETEST3:M*}' @echo 'QUOTETEST4: ${QUOTETEST4:M*}' @echo 'QUOTETEST5a: ${QUOTETEST5:S/^/</:S/$/>/}' @echo 'QUOTETEST5b: ${QUOTETEST5:S/$/>/:S/^/</}' * Result: QUOTETEST1: "" QUOTETEST2: "" ab QUOTETEST3: ab " QUOTETEST4: ab " cd QUOTETEST5a: <ab> <" <"cd> -> ef" <"> <jk> QUOTETEST5b: <ab> <"> "cd <- <ef"> "> <jk> * Expected result: QUOTETEST1: "" QUOTETEST2: "" ab QUOTETEST3: ab "" QUOTETEST4: ab "" cd QUOTETEST5a: <ab> <""> <"cd - ef"> <""> <jk> QUOTETEST5b: <ab> <""> <"cd - ef"> <""> <jk>
Responsible Changed From-To: freebsd-bugs->ru Assign to myself.
State Changed From-To: open->patched Fixed in make/str.c,v 1.28 in 5.2-CURRENT.
State Changed From-To: patched->closed Fixed in make/str.c,v 1.12.2.2 in 4.9-STABLE.