The expansion of .elif uses everything up to '\n' & allows no '#' comment delimeter as available to simpler .if & .else & .endif commands. Fix: Document it - until a make guru fixes it sometime, maybe. How-To-Repeat: mkdir ~/tmp ; cd ~/tmp ; cat > Makefile << EOF break: .if defined(AA) #{AA @echo 11 .elif defined(BB) #}{!AA{BB @echo 22 .else #}{!BB @echo 33 .endif #}} ok: .if defined(AA) #{AA @echo 11 .else #}{!AA .if defined(BB) #{BB @echo 22 .else #}{!BB @echo 33 .endif #} .endif #} EOF make "Makefile", line 4: Malformed conditional (defined(BB) #}{!AA{BB) make: fatal errors encountered -- cannot continue
Make's parser skips down to the next conditional (line beginning with a '.') when the current conditional evaluates to false. The function parse.c:ParseSkipLine() does not handle comments in the same way that parse.c:ParseReadLine() does, and thus causes errors such as this one. This patch adds the correct behavior to parse.c:ParseSkipLine. Index: parse.c =================================================================== RCS file: /ncvs/src/usr.bin/make/parse.c,v retrieving revision 1.22 diff -u -r1.22 parse.c --- parse.c 1999/08/28 01:03:35 1.22 +++ parse.c 2001/03/14 21:02:37 @@ -2059,18 +2059,24 @@ while (((c = ParseReadc()) != '\n' || lastc == '\\') && c != EOF) { - if (c == '\n') { - Buf_ReplaceLastByte(buf, (Byte)' '); - lineno++; + if (c == '#' && lastc != '\\') { + while ((c = ParseReadc()) != '\n' && c != EOF); - while ((c = ParseReadc()) == ' ' || c == '\t'); + break; + } else { + if (c == '\n') { + Buf_ReplaceLastByte(buf, (Byte)' '); + lineno++; - if (c == EOF) - break; - } + while ((c = ParseReadc()) == ' ' || c == '\t'); + + if (c == EOF) + break; + } - Buf_AddByte(buf, (Byte)c); - lastc = c; + Buf_AddByte(buf, (Byte)c); + lastc = c; + } } if (c == EOF) { -- || Seth Kingsley || BSDi/Open Source Division || sethk@osd.bsdi.com ||
Responsible Changed From-To: freebsd-bugs->will Remind myself to get this fixed.
State Changed From-To: open->suspended Reminder to MFC this after sufficient testing in -CURRENT.
Responsible Changed From-To: will->freebsd-bugs I don't have time for make(1) anymore...
For the audit trail: This one is _not_ awaiting MFC. The patch was backed out in the following commit to parse.c: -------- revision 1.28 date: 2001/03/15 10:22:50; author: will; state: Exp; lines: +10 -16 Revert previous change -- apparently it's not quite right. It broke src/sys/modules/if_ef and possibly other things. I tested the build with a make based on rev. 1.26, and it worked fine. Since I'm not particularly inclined to figure out what's going on with this, it's probably prudent just to back it out for now. Found by: jkh Suggested by: jhay -------- Jordan, John? Does either one of you have any more information that's likely to get this PR out of suspended state? The audit trail doesn't include any objections to the patch. Ciao, Sheldon.
> For the audit trail: > > This one is _not_ awaiting MFC. The patch was backed out in the following > commit to parse.c: > > -------- > revision 1.28 > date: 2001/03/15 10:22:50; author: will; state: Exp; lines: +10 -16 > Revert previous change -- apparently it's not quite right. It broke > src/sys/modules/if_ef and possibly other things. I tested the build > with > a make based on rev. 1.26, and it worked fine. Since I'm not > particularly > inclined to figure out what's going on with this, it's probably prudent > just to back it out for now. > > Found by: jkh > Suggested by: jhay > -------- > > Jordan, John? Does either one of you have any more information that's > likely to get this PR out of suspended state? The audit trail doesn't > include any objections to the patch. The only reason my name got dragged into this pr is because I complained that the patch caused make world/release to fail. As such I don't have anything against what the patch try to achieve as long as it does not break things. John -- John Hay -- John.Hay@icomtek.csir.co.za / jhay@FreeBSD.org
On Sat, 30 Jan 2002 11:32:42 +0200, John Hay wrote: > The only reason my name got dragged into this pr is because I complained > that the patch caused make world/release to fail. As such I don't have > anything against what the patch try to achieve as long as it does not > break things. Okay, so if I can come up with a patch that doesn't break world, you're okay with it? Would you be prepared to test patches through the release target? Ciao, Sheldon.
> > > The only reason my name got dragged into this pr is because I complained > > that the patch caused make world/release to fail. As such I don't have > > anything against what the patch try to achieve as long as it does not > > break things. > > Okay, so if I can come up with a patch that doesn't break world, you're > okay with it? Would you be prepared to test patches through the release > target? Yes I'll push them through a "make release" for you. John -- John Hay -- John.Hay@icomtek.csir.co.za / jhay@FreeBSD.org
Hi Seth, The patch you submitted against make(1) to fix the problem reported in FreeBSD PR bin/25627 was reported to break the 'release' target. Did you do any further work in this area? Ciao, Sheldon.
State Changed From-To: suspended->open I think I have a working patch. The problem with the original patch seems to be that the function in question (ParseSkipLine) is called from two places to do two entirely different things: with skip=true it is called from the conditional handling code to skip false .if contents until a line beginning with a dot is found. All input is discarded in this case. It is also called from the .for handling code to collect the for loop. In this case skip=false and the function will return the entire for loop. In the latter case we should not skip comments, because this must be done in the main code. Comment skipping is just a little bit more complex than just looking for a '#'. Think of: foo: echo '#define INET' >opt_inet.h
Responsible Changed From-To: freebsd-bugs->harti I think I have a working patch. The problem with the original patch seems to be that the function in question (ParseSkipLine) is called from two places to do two entirely different things: with skip=true it is called from the conditional handling code to skip false .if contents until a line beginning with a dot is found. All input is discarded in this case. It is also called from the .for handling code to collect the for loop. In this case skip=false and the function will return the entire for loop. In the latter case we should not skip comments, because this must be done in the main code. Comment skipping is just a little bit more complex than just looking for a '#'. Think of: foo: echo '#define INET' >opt_inet.h harti
State Changed From-To: open->closed New patch committed. Thanks.