[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Bug with semicolon in target specific variable?
From: |
Paul D. Smith |
Subject: |
Re: Bug with semicolon in target specific variable? |
Date: |
Sat, 20 Apr 2002 14:18:34 -0400 |
%% "Bhatt, Milan C" <address@hidden> writes:
bmc> It seems GMAKE doesn't like having semicolons within the value of a
bmc> target specific variable.
It likes it just fine.
bmc> a : SOME_VAR := c; d
bmc> a :
bmc> @echo $(SOME_VAR)
If you remove the "@" here it'll be much simpler to see what's going on.
The value of the variable is correct; it's "c; d" (sans quotes). After
expansion, the command given to the shell is:
echo c; d
Well, that's a perfectly valid shell command that means "run the command
echo c, then run the command d". If you don't have a command "d", then
you'll get the error above. There's nothing different between what
you're seeing above and what would happen in a normal,
non-target-specific variable:
FOO = c; d
all: ; @echo $(FOO)
bmc> The above exampe gives me the following error:
bmc> c
bmc> /bin/sh: d: Execute permission denied.
bmc> gmake: *** [a] Error 127
Of course.
bmc> So it prints 'c' as expected and then tries to execute 'd' as if it were
bmc> a command. As a workaround I used quotes around the entire value of the
bmc> target specific variable and everything seemed to work fine
Exactly. Or, you can change the rule to be echo "$(SOME_VAR)" (i.e.,
put quotes around the variable in the rule instead of around the
contents when the variable is set). This is probably more generic.
bmc> until I hit about 130 or more characters:
bmc> a : SOME_VAR := "c; d;
bmc> eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
bmc> # 'e' x 130+ characters
bmc> a :
bmc> @echo $(SOME_VAR)
bmc> Once there are more than a 130 characters AND there is a semicolon
bmc> within the quoted string, I get this error message:
bmc> Makefile:3: Malformed per-target variable definition
bmc> Bus error (core dumped)
I think this is an instance of bug that's been fixed in the source for a
while now. I couldn't make it fail, but it depends on a specific line
length and contents and your mail client has sufficiently "massaged"
your message that I probably don't have exactly the same text you do.
Try the patch below and see if it helps.
--- make-3.79.1/read.c Wed Jun 21 15:33:30 2000
+++ make/read.c Fri Nov 24 09:12:25 2000
@@ -2142,15 +2142,16 @@
char *buffer = linebuffer->buffer;
register char *p = linebuffer->buffer;
register char *end = p + linebuffer->size;
- register int len, lastlen = 0;
- register char *p2;
register unsigned int nlines = 0;
- register int backslash;
*p = '\0';
while (fgets (p, end - p, stream) != 0)
{
+ char *p2;
+ unsigned long len;
+ int backslash;
+
len = strlen (p);
if (len == 0)
{
@@ -2164,51 +2165,42 @@
len = 1;
}
+ /* Jump past the text we just read. */
p += len;
+
+ /* If the last char isn't a newline, the whole line didn't fit into the
+ buffer. Get some more buffer and try again. */
if (p[-1] != '\n')
{
- /* Probably ran out of buffer space. */
- register unsigned int p_off = p - buffer;
+ unsigned long p_off = p - buffer;
linebuffer->size *= 2;
buffer = (char *) xrealloc (buffer, linebuffer->size);
p = buffer + p_off;
end = buffer + linebuffer->size;
linebuffer->buffer = buffer;
*p = '\0';
- lastlen = len;
continue;
}
+ /* We got a newline, so add one to the count of lines. */
++nlines;
#if !defined(WINDOWS32) && !defined(__MSDOS__)
/* Check to see if the line was really ended with CRLF; if so ignore
the CR. */
- if (len > 1 && p[-2] == '\r')
+ if ((p - buffer) > 1 && p[-2] == '\r')
{
- --len;
--p;
p[-1] = '\n';
}
#endif
- if (len == 1 && p > buffer)
- /* P is pointing at a newline and it's the beginning of
- the buffer returned by the last fgets call. However,
- it is not necessarily the beginning of a line if P is
- pointing past the beginning of the holding buffer.
- If the buffer was just enlarged (right before the newline),
- we must account for that, so we pretend that the two lines
- were one line. */
- len += lastlen;
- lastlen = len;
backslash = 0;
- for (p2 = p - 2; --len > 0; --p2)
+ for (p2 = p - 2; p2 >= buffer; --p2)
{
- if (*p2 == '\\')
- backslash = !backslash;
- else
+ if (*p2 != '\\')
break;
+ backslash = !backslash;
}
if (!backslash)
--
-------------------------------------------------------------------------------
Paul D. Smith <address@hidden> Find some GNU make tips at:
http://www.gnu.org http://www.paulandlesley.org/gmake/
"Please remain calm...I may be mad, but I am a professional." --Mad Scientist