[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;
+      /* We got a newline, so add one to the count of lines.  */
 #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[-1] = '\n';
-      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 != '\\')
+          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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]