Module Name:    src
Committed By:   rillig
Date:           Sat Jan  8 20:21:34 UTC 2022

Modified Files:
        src/usr.bin/make: for.c nonints.h parse.c
        src/usr.bin/make/unit-tests: cond-token-plain.exp cond-token-string.exp
            directive-for.exp directive-info.exp directive-info.mk
            directive-undef.exp opt-debug-parse.exp varmod-indirect.exp
            varmod-indirect.mk

Log Message:
make: fix reported line numbers of continuation lines (since 2002)

Previously, multi-line directives like '.info' or '.error' reported the
line number of their last line instead of their first line, which is
more usual.  This also affected the debug log from '-dp'.


To generate a diff of this commit:
cvs rdiff -u -r1.159 -r1.160 src/usr.bin/make/for.c
cvs rdiff -u -r1.233 -r1.234 src/usr.bin/make/nonints.h
cvs rdiff -u -r1.638 -r1.639 src/usr.bin/make/parse.c
cvs rdiff -u -r1.14 -r1.15 src/usr.bin/make/unit-tests/cond-token-plain.exp
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/cond-token-string.exp \
    src/usr.bin/make/unit-tests/directive-info.exp
cvs rdiff -u -r1.11 -r1.12 src/usr.bin/make/unit-tests/directive-for.exp
cvs rdiff -u -r1.8 -r1.9 src/usr.bin/make/unit-tests/directive-info.mk
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/unit-tests/directive-undef.exp
cvs rdiff -u -r1.2 -r1.3 src/usr.bin/make/unit-tests/opt-debug-parse.exp
cvs rdiff -u -r1.20 -r1.21 src/usr.bin/make/unit-tests/varmod-indirect.exp
cvs rdiff -u -r1.9 -r1.10 src/usr.bin/make/unit-tests/varmod-indirect.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/for.c
diff -u src/usr.bin/make/for.c:1.159 src/usr.bin/make/for.c:1.160
--- src/usr.bin/make/for.c:1.159	Sat Jan  8 17:25:19 2022
+++ src/usr.bin/make/for.c	Sat Jan  8 20:21:34 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: for.c,v 1.159 2022/01/08 17:25:19 rillig Exp $	*/
+/*	$NetBSD: for.c,v 1.160 2022/01/08 20:21:34 rillig Exp $	*/
 
 /*
  * Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
 #include "make.h"
 
 /*	"@(#)for.c	8.1 (Berkeley) 6/6/93"	*/
-MAKE_RCSID("$NetBSD: for.c,v 1.159 2022/01/08 17:25:19 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.160 2022/01/08 20:21:34 rillig Exp $");
 
 
 typedef struct ForLoop {
@@ -469,7 +469,7 @@ For_NextIteration(ForLoop *f, Buffer *bo
 
 /* Run the .for loop, imitating the actions of an include file. */
 void
-For_Run(int lineno)
+For_Run(int headLineno, int bodyReadLines)
 {
 	Buffer buf;
 	ForLoop *f = accumFor;
@@ -477,7 +477,7 @@ For_Run(int lineno)
 
 	if (f->items.len > 0) {
 		Buf_Init(&buf);
-		Parse_PushInput(NULL, lineno, buf, f);
+		Parse_PushInput(NULL, headLineno, bodyReadLines, buf, f);
 	} else
 		ForLoop_Free(f);
 }

Index: src/usr.bin/make/nonints.h
diff -u src/usr.bin/make/nonints.h:1.233 src/usr.bin/make/nonints.h:1.234
--- src/usr.bin/make/nonints.h:1.233	Fri Jan  7 20:54:45 2022
+++ src/usr.bin/make/nonints.h	Sat Jan  8 20:21:34 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: nonints.h,v 1.233 2022/01/07 20:54:45 rillig Exp $	*/
+/*	$NetBSD: nonints.h,v 1.234 2022/01/08 20:21:34 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -119,7 +119,7 @@ void SearchPath_Free(SearchPath *);
 struct ForLoop;
 int For_Eval(const char *) MAKE_ATTR_USE;
 bool For_Accum(const char *, int *) MAKE_ATTR_USE;
-void For_Run(int);
+void For_Run(int, int);
 bool For_NextIteration(struct ForLoop *, Buffer *);
 
 /* job.c */
@@ -147,7 +147,7 @@ void Parse_Error(ParseErrorLevel, const 
 bool Parse_VarAssign(const char *, bool, GNode *) MAKE_ATTR_USE;
 void Parse_AddIncludeDir(const char *);
 void Parse_File(const char *, int);
-void Parse_PushInput(const char *, int, Buffer, struct ForLoop *);
+void Parse_PushInput(const char *, int, int, Buffer, struct ForLoop *);
 void Parse_MainName(GNodeList *);
 int Parse_NumErrors(void) MAKE_ATTR_USE;
 

Index: src/usr.bin/make/parse.c
diff -u src/usr.bin/make/parse.c:1.638 src/usr.bin/make/parse.c:1.639
--- src/usr.bin/make/parse.c:1.638	Sat Jan  8 09:55:32 2022
+++ src/usr.bin/make/parse.c	Sat Jan  8 20:21:34 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.638 2022/01/08 09:55:32 rillig Exp $	*/
+/*	$NetBSD: parse.c,v 1.639 2022/01/08 20:21:34 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -106,26 +106,20 @@
 #include "pathnames.h"
 
 /*	"@(#)parse.c	8.3 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: parse.c,v 1.638 2022/01/08 09:55:32 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.639 2022/01/08 20:21:34 rillig Exp $");
 
 /*
  * A file being read.
  */
 typedef struct IncludedFile {
 	FStr name;		/* absolute or relative to the cwd */
-	/* TODO: add lineno for accurate line number information */
+	int lineno;		/* 1-based */
 	int readLines;		/* the number of physical lines that have
-				 * been read from the file; for lines without
-				 * backslash continuation, it coincidentally
-				 * equals the 1-based human-readable line
-				 * number for messages */
-	/* TODO: add forHeadLineno for accurate line number information */
+				 * been read from the file */
+	int forHeadLineno;	/* 1-based */
 	int forBodyReadLines;	/* the number of physical lines that have
 				 * been read from the file above the body of
-				 * the .for loop; in .for loops whose head
-				 * fits in a single line, it coincidentally
-				 * equals the 1-based human-readable line
-				 * number for messages */
+				 * the .for loop */
 	unsigned int cond_depth; /* 'if' nesting when file opened */
 	bool depending;		/* state of doing_depend on EOF */
 
@@ -359,20 +353,12 @@ PrintStackTrace(void)
 		if (fname[0] != '/' && strcmp(fname, "(stdin)") != 0)
 			fname = realpath(fname, dirbuf);
 
-		/*
-		 * FIXME: Using readLines is incorrect for multi-line
-		 *  .include directives.
-		 */
 		if (entries[i + 1 < n ? i + 1 : i].forLoop == NULL)
 			debug_printf("\tin .include from %s:%d\n",
-			    fname, entry->readLines - 1 + 1);
-		/*
-		 * FIXME: Using forBodyReadLines is incorrect for multi-line
-		 *  .for directives.
-		 */
+			    fname, entry->lineno);
 		if (entry->forLoop != NULL)
 			debug_printf("\tin .for loop from %s:%d\n",
-			    fname, entry->forBodyReadLines - 1 + 1);
+			    fname, entry->forHeadLineno);
 	}
 }
 
@@ -395,8 +381,7 @@ RememberLocation(GNode *gn)
 {
 	IncludedFile *curFile = CurFile();
 	gn->fname = Str_Intern(curFile->name.str);
-	/* FIXME: mismatch between lineno and readLines */
-	gn->lineno = curFile->readLines;
+	gn->lineno = curFile->lineno;
 }
 
 /*
@@ -521,8 +506,7 @@ Parse_Error(ParseErrorLevel type, const 
 	} else {
 		IncludedFile *curFile = CurFile();
 		fname = curFile->name.str;
-		/* FIXME: mismatch between lineno and readLines */
-		lineno = (size_t)curFile->readLines;
+		lineno = (size_t)curFile->lineno;
 	}
 
 	(void)fflush(stdout);
@@ -1921,7 +1905,7 @@ IncludeFile(const char *file, bool isSys
 	buf = loadfile(fullname, fd);
 	(void)close(fd);
 
-	Parse_PushInput(fullname, 0, buf, NULL);
+	Parse_PushInput(fullname, 1, 0, buf, NULL);
 	if (depinc)
 		doing_depend = depinc;	/* only turn it on */
 	free(fullname);
@@ -2097,7 +2081,7 @@ TrackInput(const char *name)
 
 /* Parse from the given buffer, later return to the current file. */
 void
-Parse_PushInput(const char *name, int lineno, Buffer buf,
+Parse_PushInput(const char *name, int lineno, int readLines, Buffer buf,
 		struct ForLoop *forLoop)
 {
 	IncludedFile *curFile;
@@ -2112,10 +2096,10 @@ Parse_PushInput(const char *name, int li
 
 	curFile = Vector_Push(&includes);
 	curFile->name = FStr_InitOwn(bmake_strdup(name));
-	/* FIXME: mismatch between readLines and lineno */
-	curFile->readLines = lineno;
-	/* FIXME: mismatch between readLines and lineno */
-	curFile->forBodyReadLines = lineno;
+	curFile->lineno = lineno;
+	curFile->readLines = readLines;
+	curFile->forHeadLineno = lineno;
+	curFile->forBodyReadLines = readLines;
 	curFile->buf = buf;
 	curFile->depending = doing_depend;	/* restore this on EOF */
 	curFile->forLoop = forLoop;
@@ -2278,9 +2262,8 @@ ParseEOF(void)
 	}
 
 	curFile = CurFile();
-	/* FIXME: mismatch between lineno and readLines */
 	DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n",
-	    curFile->name.str, curFile->readLines);
+	    curFile->name.str, curFile->lineno);
 
 	SetParseFile(curFile->name.str);
 	return true;
@@ -2450,13 +2433,15 @@ static char *
 ReadLowLevelLine(LineKind kind)
 {
 	IncludedFile *curFile = CurFile();
+	ParseRawLineResult res;
 	char *line;
 	char *line_end;
 	char *firstBackslash;
 	char *commentLineEnd;
 
 	for (;;) {
-		ParseRawLineResult res = ParseRawLine(curFile,
+		curFile->lineno = curFile->readLines + 1;
+		res = ParseRawLine(curFile,
 		    &line, &line_end, &firstBackslash, &commentLineEnd);
 		if (res == PRLR_ERROR)
 			return NULL;
@@ -2517,20 +2502,20 @@ static bool
 ParseForLoop(const char *line)
 {
 	int rval;
-	int firstLineno;
+	int forHeadLineno;
+	int bodyReadLines;
 	int forLevel;
 
+	forHeadLineno = CurFile()->lineno;
 	rval = For_Eval(line);
 	if (rval == 0)
 		return false;	/* Not a .for line */
 	if (rval < 0)
 		return true;	/* Syntax error - error printed, ignore line */
 
-	/* FIXME: mismatch between lineno and readLines */
-	firstLineno = CurFile()->readLines;
-
 	/* Accumulate the loop body until the matching '.endfor'. */
 	forLevel = 1;
+	bodyReadLines = CurFile()->readLines;
 	do {
 		line = ReadLowLevelLine(LK_FOR_BODY);
 		if (line == NULL) {
@@ -2540,7 +2525,7 @@ ParseForLoop(const char *line)
 		}
 	} while (For_Accum(line, &forLevel));
 
-	For_Run(firstLineno);
+	For_Run(forHeadLineno, bodyReadLines);
 	return true;
 }
 
@@ -2859,13 +2844,12 @@ Parse_File(const char *name, int fd)
 
 	assert(targets == NULL);
 
-	Parse_PushInput(name, 0, buf, NULL);
+	Parse_PushInput(name, 1, 0, buf, NULL);
 
 	do {
 		while ((line = ReadHighLevelLine()) != NULL) {
-			/* FIXME: mismatch between lineno and readLines */
 			DEBUG2(PARSE, "Parsing line %d: %s\n",
-			    CurFile()->readLines, line);
+			    CurFile()->lineno, line);
 			ParseLine(line);
 		}
 		/* Reached EOF, but it may be just EOF of an include file. */

Index: src/usr.bin/make/unit-tests/cond-token-plain.exp
diff -u src/usr.bin/make/unit-tests/cond-token-plain.exp:1.14 src/usr.bin/make/unit-tests/cond-token-plain.exp:1.15
--- src/usr.bin/make/unit-tests/cond-token-plain.exp:1.14	Thu Dec 30 02:14:55 2021
+++ src/usr.bin/make/unit-tests/cond-token-plain.exp	Sat Jan  8 20:21:34 2022
@@ -27,7 +27,7 @@ lhs = "var&&name", rhs = "var&&name", op
 CondParser_Eval: ${:Uvar}||name != "var||name"
 lhs = "var||name", rhs = "var||name", op = !=
 CondParser_Eval: bare
-make: "cond-token-plain.mk" line 106: A bare word is treated like defined(...), and the variable 'bare' is not defined.
+make: "cond-token-plain.mk" line 105: A bare word is treated like defined(...), and the variable 'bare' is not defined.
 CondParser_Eval: VAR
 make: "cond-token-plain.mk" line 111: A bare word is treated like defined(...).
 CondParser_Eval: V${:UA}R

Index: src/usr.bin/make/unit-tests/cond-token-string.exp
diff -u src/usr.bin/make/unit-tests/cond-token-string.exp:1.6 src/usr.bin/make/unit-tests/cond-token-string.exp:1.7
--- src/usr.bin/make/unit-tests/cond-token-string.exp:1.6	Tue Feb 23 15:19:41 2021
+++ src/usr.bin/make/unit-tests/cond-token-string.exp	Sat Jan  8 20:21:34 2022
@@ -6,9 +6,9 @@ make: "cond-token-string.mk" line 37: Ex
 CondParser_Eval: "UNDEF"
 make: "cond-token-string.mk" line 46: The string literal "UNDEF" is not empty.
 CondParser_Eval: " "
-make: "cond-token-string.mk" line 55: The string literal " " is not empty, even though it consists of whitespace only.
+make: "cond-token-string.mk" line 54: The string literal " " is not empty, even though it consists of whitespace only.
 CondParser_Eval: "${UNDEF}"
-make: "cond-token-string.mk" line 64: An undefined variable in quotes expands to an empty string, which then evaluates to false.
+make: "cond-token-string.mk" line 63: An undefined variable in quotes expands to an empty string, which then evaluates to false.
 CondParser_Eval: "${:Uvalue}"
 make: "cond-token-string.mk" line 68: A nonempty variable expression evaluates to true.
 CondParser_Eval: "${:U}"
Index: src/usr.bin/make/unit-tests/directive-info.exp
diff -u src/usr.bin/make/unit-tests/directive-info.exp:1.6 src/usr.bin/make/unit-tests/directive-info.exp:1.7
--- src/usr.bin/make/unit-tests/directive-info.exp:1.6	Sat Dec 19 22:33:11 2020
+++ src/usr.bin/make/unit-tests/directive-info.exp	Sat Jan  8 20:21:34 2022
@@ -9,7 +9,7 @@ make: "directive-info.mk" line 22: Missi
 make: "directive-info.mk" line 23: Missing argument for ".info"
 make: "directive-info.mk" line 26: Unknown directive "info-message"
 make: "directive-info.mk" line 27: no-target: no-source
-make: "directive-info.mk" line 36: expect line 30 for multi-line message
+make: "directive-info.mk" line 35: expect line 35 for multi-line message
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1

Index: src/usr.bin/make/unit-tests/directive-for.exp
diff -u src/usr.bin/make/unit-tests/directive-for.exp:1.11 src/usr.bin/make/unit-tests/directive-for.exp:1.12
--- src/usr.bin/make/unit-tests/directive-for.exp:1.11	Sat Jan  8 10:22:03 2022
+++ src/usr.bin/make/unit-tests/directive-for.exp	Sat Jan  8 20:21:34 2022
@@ -36,7 +36,7 @@ make: "directive-for.mk" line 229: Unexp
 For: loop body:
 .\
    endfor
-make: "directive-for.mk" line 228: for-less endfor
+make: "directive-for.mk" line 227: for-less endfor
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1

Index: src/usr.bin/make/unit-tests/directive-info.mk
diff -u src/usr.bin/make/unit-tests/directive-info.mk:1.8 src/usr.bin/make/unit-tests/directive-info.mk:1.9
--- src/usr.bin/make/unit-tests/directive-info.mk:1.8	Sat Dec 19 22:33:11 2020
+++ src/usr.bin/make/unit-tests/directive-info.mk	Sat Jan  8 20:21:34 2022
@@ -1,4 +1,4 @@
-# $NetBSD: directive-info.mk,v 1.8 2020/12/19 22:33:11 rillig Exp $
+# $NetBSD: directive-info.mk,v 1.9 2022/01/08 20:21:34 rillig Exp $
 #
 # Tests for the .info directive.
 #
@@ -27,11 +27,12 @@
 .info no-target: no-source	# This is a .info directive, not a dependency.
 # See directive.mk for more tests of this kind.
 
-# Since at least 2002-01-01, the line number that is used in error messages
-# and the .info directives is the number of completely read lines.  For the
-# following multi-line directive, this means that the reported line number is
-# the one of the last line, not the first line.
-.info expect line 30 for\
+# Since at least 2002-01-01 and before parse.c 1.639 from 2022-01-08, the line
+# number that is used in error messages and the .info directives was the
+# number of completely read lines.  For the following multi-line directive,
+# this meant that the reported line number was the one of the last line, not
+# of the first line.
+.info expect line 35 for\
 	multi$\
 	-line message
 

Index: src/usr.bin/make/unit-tests/directive-undef.exp
diff -u src/usr.bin/make/unit-tests/directive-undef.exp:1.7 src/usr.bin/make/unit-tests/directive-undef.exp:1.8
--- src/usr.bin/make/unit-tests/directive-undef.exp:1.7	Tue Feb 23 15:19:41 2021
+++ src/usr.bin/make/unit-tests/directive-undef.exp	Sat Jan  8 20:21:34 2022
@@ -1,6 +1,6 @@
 make: "directive-undef.mk" line 29: The .undef directive requires an argument
 make: "directive-undef.mk" line 86: Unknown modifier "Z"
-make: "directive-undef.mk" line 103: warning: UT_EXPORTED is still listed in .MAKE.EXPORTED even though spaceit is not exported anymore.
+make: "directive-undef.mk" line 102: warning: UT_EXPORTED is still listed in .MAKE.EXPORTED even though spaceit is not exported anymore.
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1

Index: src/usr.bin/make/unit-tests/opt-debug-parse.exp
diff -u src/usr.bin/make/unit-tests/opt-debug-parse.exp:1.2 src/usr.bin/make/unit-tests/opt-debug-parse.exp:1.3
--- src/usr.bin/make/unit-tests/opt-debug-parse.exp:1.2	Sun Jan  2 03:23:55 2022
+++ src/usr.bin/make/unit-tests/opt-debug-parse.exp	Sat Jan  8 20:21:34 2022
@@ -1,4 +1,4 @@
-Parse_PushInput: .for loop in opt-debug-parse.mk, line 16
+Parse_PushInput: .for loop in opt-debug-parse.mk, line 13
 SetFilenameVars: ${.PARSEDIR} = `<curdir>' ${.PARSEFILE} = `opt-debug-parse.mk'
 Parsing line 17: .info trace with multi-line .for loop head
 make: "opt-debug-parse.mk" line 17: trace with multi-line .for loop head

Index: src/usr.bin/make/unit-tests/varmod-indirect.exp
diff -u src/usr.bin/make/unit-tests/varmod-indirect.exp:1.20 src/usr.bin/make/unit-tests/varmod-indirect.exp:1.21
--- src/usr.bin/make/unit-tests/varmod-indirect.exp:1.20	Tue Dec 28 15:49:00 2021
+++ src/usr.bin/make/unit-tests/varmod-indirect.exp	Sat Jan  8 20:21:34 2022
@@ -1,6 +1,6 @@
 make: "varmod-indirect.mk" line 19: Unknown modifier "${"
 make: "varmod-indirect.mk" line 52: Unknown modifier "${"
-make: "varmod-indirect.mk" line 55: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression.
+make: "varmod-indirect.mk" line 53: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression.
 make: "varmod-indirect.mk" line 140: before
 make: "varmod-indirect.mk" line 140: after
 make: "varmod-indirect.mk" line 146: before

Index: src/usr.bin/make/unit-tests/varmod-indirect.mk
diff -u src/usr.bin/make/unit-tests/varmod-indirect.mk:1.9 src/usr.bin/make/unit-tests/varmod-indirect.mk:1.10
--- src/usr.bin/make/unit-tests/varmod-indirect.mk:1.9	Mon Mar 15 20:00:50 2021
+++ src/usr.bin/make/unit-tests/varmod-indirect.mk	Sat Jan  8 20:21:34 2022
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-indirect.mk,v 1.9 2021/03/15 20:00:50 rillig Exp $
+# $NetBSD: varmod-indirect.mk,v 1.10 2022/01/08 20:21:34 rillig Exp $
 #
 # Tests for indirect variable modifiers, such as in ${VAR:${M_modifiers}}.
 # These can be used for very basic purposes like converting a string to either
@@ -47,7 +47,7 @@
 # error.  Because of this parse error, this feature cannot be used reasonably
 # in practice.
 #
-# expect+1: Unknown modifier '$'
+# expect+2: Unknown modifier '$'
 #.MAKEFLAGS: -dvc
 .if ${value:L:${:UM*}S,value,replaced,} == "M*S,value,replaced,}"
 .  warning	FIXME: this expression should have resulted in a parse $\

Reply via email to