Bug 61673 - make(1) word splitting swallows quotes
Summary: make(1) word splitting swallows quotes
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 4.9-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: ru
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-01-21 12:00 UTC by Oliver Eikemeier
Modified: 2004-02-23 12:12 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oliver Eikemeier 2004-01-21 12:00:31 UTC
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>
Comment 1 ru freebsd_committer freebsd_triage 2004-01-21 14:12:57 UTC
Responsible Changed
From-To: freebsd-bugs->ru

Assign to myself.
Comment 2 ru freebsd_committer freebsd_triage 2004-01-22 18:18:07 UTC
State Changed
From-To: open->patched

Fixed in make/str.c,v 1.28 in 5.2-CURRENT.
Comment 3 ru freebsd_committer freebsd_triage 2004-02-23 12:11:23 UTC
State Changed
From-To: patched->closed

Fixed in make/str.c,v 1.12.2.2 in 4.9-STABLE.