Subject: bin/36128: CRLF handling for make
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <dholland@eecs.harvard.edu>
List: netbsd-bugs
Date: 04/06/2007 22:50:00
>Number:         36128
>Category:       bin
>Synopsis:       CRLF handling for make
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 06 22:50:00 +0000 2007
>Originator:     David A. Holland <dholland@eecs.harvard.edu>
>Release:        NetBSD 4.99.9 (20070221)
>Organization:
>Environment:
System: NetBSD tanaqui 4.99.9 NetBSD 4.99.9 (TANAQUI) #8: Tue Jan 30 17:29:55 EST 2007 dholland@tanaqui:/usr/src/sys/arch/i386/compile/TANAQUI i386
Architecture: i386
Machine: i386
>Description:

It was mentioned on #pkgsrc irc that our make doesn't handle makefiles
that have embedded carriage returns (DOS-style CR/LF end of lines)...
...and there seems no particular reason it shouldn't, since at least
one such makefile seems to exist in the wild.

Patch follows.

I've tested this myself and it seems to work with no ill effects,
although I don't have the actual offending makefile and I haven't
really tested all the possible strange corner cases. But I believe it
to be sound.

make currently fails regression, but this doesn't appear to be because
of anything I've done.


>How-To-Repeat:
n/a

>Fix:

Patch against latest parse.c:

Index: parse.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/parse.c,v
retrieving revision 1.133
diff -u -r1.133 parse.c
--- parse.c	24 Feb 2007 17:55:54 -0000	1.133
+++ parse.c	6 Apr 2007 22:46:41 -0000
@@ -2179,9 +2179,15 @@
 		/* Don't treat next character as special, remember first one */
 		if (escaped == NULL)
 		    escaped = ptr;
-		if (ptr[1] == '\n')
+		if (ptr[1] == '\r' && ptr[2] == '\n') {
 		    cf->lineno++;
-		ptr += 2;
+		    ptr += 3;
+		} else if (ptr[1] == '\n') {
+		    cf->lineno++;
+		    ptr += 2;
+		} else {
+		    ptr += 2;
+		}
 		line_end = ptr;
 		continue;
 	    }
@@ -2189,6 +2195,10 @@
 		/* Remember first '#' for comment stripping */
 		comment = line_end;
 	    }
+	    if (ch == '\r' && ptr[1] == '\n') {
+	        ptr++;
+		ch = '\n';
+	    }
 	    ptr++;
 	    if (ch == '\n')
 		break;
@@ -2261,6 +2271,9 @@
 	    /* Delete '\\' from before '#' on non-command lines */
 	    continue;
 
+	if (ch == '\r' && ptr[0] == '\n')
+	    ch = *ptr++;
+
 	if (ch != '\n') {
 	    /* Leave '\\' in buffer for later */
 	    *tp++ = '\\';