From owner-freebsd-bugs Sun Sep 15 15:30:04 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id PAA18943 for bugs-outgoing; Sun, 15 Sep 1996 15:30:04 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id PAA18926; Sun, 15 Sep 1996 15:30:02 -0700 (PDT) Date: Sun, 15 Sep 1996 15:30:02 -0700 (PDT) Message-Id: <199609152230.PAA18926@freefall.freebsd.org> To: freebsd-bugs Cc: From: Steve Price Subject: Re: bin/1095: make's continuation line handling buggy when used with .elif Reply-To: Steve Price Sender: owner-bugs@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk The following reply was made to PR bin/1095; it has been noted by GNATS. From: Steve Price To: asami@cs.berkeley.edu Cc: hackers@freebsd.org, FreeBSD-gnats-submit@freebsd.org Subject: Re: bin/1095: make's continuation line handling buggy when used with .elif Date: Sun, 15 Sep 1996 17:18:30 -0500 Attached is a patch that fixes the problem pointed out in bin/1095. steve[~]$ cat > Makefile1 all: .if defined(foo) @true .elif !defined(foo) && !defined(foo) @echo ok .else @echo not ok .endif steve[~]$ make -f Makefile1 ok steve[~]$ cat > Makefile2 all: .if defined(foo) @true .else .if !defined(foo) && \ !defined(foo) @echo ok .else @echo not ok .endif .endif steve[~]$ make -f Makefile2 ok steve[~]$ cat > Makefile3 all: .if defined(foo) @true .elif !defined(foo) && \ !defined(foo) @echo ok .else @echo not ok .endif steve[~]$ make -f Makefile3 ok steve[~]$ Steve Index: buf.c =================================================================== RCS file: /u/FreeBSD/cvs/src/usr.bin/make/buf.c,v retrieving revision 1.3 diff -u -r1.3 buf.c --- buf.c 1995/05/30 06:31:48 1.3 +++ buf.c 1996/09/14 14:49:25 @@ -434,3 +434,28 @@ } free ((char *)buf); } + +/*- + *----------------------------------------------------------------------- + * Buf_ReplaceLastByte -- + * Replace the last byte in a buffer. + * + * Results: + * None. + * + * Side Effects: + * If the buffer was empty intially, then a new byte will be added. + * Otherwise, the last byte is overwritten. + * + *----------------------------------------------------------------------- + */ +void +Buf_ReplaceLastByte (buf, byte) + Buffer buf; /* buffer to augment */ + Byte byte; /* byte to be written */ +{ + if (buf->inPtr == buf->outPtr) + Buf_AddByte(buf, byte); + else + *(buf->inPtr - 1) = byte; +} Index: buf.h =================================================================== RCS file: /u/FreeBSD/cvs/src/usr.bin/make/buf.h,v retrieving revision 1.2 diff -u -r1.2 buf.h --- buf.h 1995/01/23 21:00:21 1.2 +++ buf.h 1996/09/14 14:36:19 @@ -76,5 +76,6 @@ int Buf_Size __P((Buffer)); Buffer Buf_Init __P((int)); void Buf_Destroy __P((Buffer, Boolean)); +void Buf_ReplaceLastByte __P((Buffer, Byte)); #endif /* _BUF_H */ Index: parse.c =================================================================== RCS file: /u/FreeBSD/cvs/src/usr.bin/make/parse.c,v retrieving revision 1.9 diff -u -r1.9 parse.c --- parse.c 1996/09/12 03:03:25 1.9 +++ parse.c 1996/09/14 14:46:19 @@ -2009,54 +2009,43 @@ int skip; /* Skip lines that don't start with . */ { char *line; - int c, lastc = '\0', lineLength; + int c, lastc, lineLength = 0; Buffer buf; - c = ParseReadc(); + buf = Buf_Init(MAKE_BSIZE); - if (skip) { - /* - * Skip lines until get to one that begins with a - * special char. - */ - while ((c != '.') && (c != EOF)) { - while (((c != '\n') || (lastc == '\\')) && (c != EOF)) - { - /* - * Advance to next unescaped newline - */ - if ((lastc = c) == '\n') { - lineno++; - } - c = ParseReadc(); - } - lineno++; - - lastc = c; - c = ParseReadc (); - } - } - - if (c == EOF) { - Parse_Error (PARSE_FATAL, "Unclosed conditional/for loop"); - return ((char *)NULL); - } - - /* - * Read the entire line into buf - */ - buf = Buf_Init (MAKE_BSIZE); - if (c != '\n') { - do { - Buf_AddByte (buf, (Byte)c); - c = ParseReadc(); - } while ((c != '\n') && (c != EOF)); - } - lineno++; - - Buf_AddByte (buf, (Byte)'\0'); - line = (char *)Buf_GetAll (buf, &lineLength); - Buf_Destroy (buf, FALSE); + do { + Buf_Discard(buf, lineLength); + lastc = '\0'; + + while (((c = ParseReadc()) != '\n' || lastc == '\\') + && c != EOF) { + if (c == '\n') { + Buf_ReplaceLastByte(buf, (Byte)' '); + lineno++; + + while ((c = ParseReadc()) == ' ' || c == '\t'); + + if (c == EOF) + break; + } + + Buf_AddByte(buf, (Byte)c); + lastc = c; + } + + if (c == EOF) { + Parse_Error(PARSE_FATAL, "Unclosed conditional/for loop"); + return((char *)NULL); + } + + lineno++; + Buf_AddByte(buf, (Byte)c); + Buf_AddByte(buf, (Byte)'\0'); + line = (char *)Buf_GetAll(buf, &lineLength); + } while (skip == 1 && line[0] != '.'); + + Buf_Destroy(buf, FALSE); return line; }