Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make make(1): describe how Parse_Error might print s...



details:   https://anonhg.NetBSD.org/src/rev/a59dec86e441
branches:  trunk
changeset: 976227:a59dec86e441
user:      rillig <rillig%NetBSD.org@localhost>
date:      Mon Sep 14 19:59:47 2020 +0000

description:
make(1): describe how Parse_Error might print stack traces

In deeply nested include chains and .for loops this may be a useful
feature.  It's a little tricky to generate an intuitive stack trace,
though not impossible.  This explanation also serves as a detailed
documentation about how the .include and .for directives are
implemented.

diffstat:

 usr.bin/make/parse.c                     |  47 ++++++++++++++++++++++++++++---
 usr.bin/make/unit-tests/include-main.exp |   4 +-
 usr.bin/make/unit-tests/include-sub.mk   |  17 ++++++++++-
 3 files changed, 60 insertions(+), 8 deletions(-)

diffs (114 lines):

diff -r bb5b1d5270bc -r a59dec86e441 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c      Mon Sep 14 19:51:54 2020 +0000
+++ b/usr.bin/make/parse.c      Mon Sep 14 19:59:47 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parse.c,v 1.318 2020/09/14 18:21:26 rillig Exp $       */
+/*     $NetBSD: parse.c,v 1.319 2020/09/14 19:59:47 rillig Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -131,7 +131,7 @@
 #include "pathnames.h"
 
 /*     "@(#)parse.c    8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.318 2020/09/14 18:21:26 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.319 2020/09/14 19:59:47 rillig Exp $");
 
 /* types and constants */
 
@@ -245,9 +245,46 @@
 /* current file being read */
 static IFile *curFile;
 
-/* The current file from the command line (at the bottom of the stack) and
- * further up all the files that are currently being read due to nested
- * .include or .for directives. */
+/* The include chain of makefiles that leads to curFile.  At the bottom of
+ * the stack is the top-level makefile from the command line, and on top of
+ * this file, there are the included files or .for loops, up to but excluding
+ * curFile.
+ *
+ * This data could be used to print stack traces on parse errors.  As of
+ * 2020-09-14, this is not done though.  It seems quite simple to print the
+ * tuples (fname:lineno:fromForLoop), from top to bottom.  This simple idea is
+ * made complicated by the fact that the .for loops also use this stack for
+ * storing information.
+ *
+ * The lineno fields of the IFiles with fromForLoop == TRUE look confusing,
+ * which is demonstrated by the test 'include-main.mk'.  They seem sorted
+ * backwards since they tell the number of completely parsed lines, which for
+ * a .for loop is right after the terminating .endfor.  To compensate for this
+ * confusion, there is another field first_lineno pointing at the start of the
+ * .for loop, 1-based for human consumption.
+ *
+ * To make the stack trace intuitive, the entry below the first .for loop must
+ * be ignored completely since neither its lineno nor its first_lineno is
+ * useful.  Instead, the topmost .for loop needs to be printed twice, once
+ * with its first_lineno and once with its lineno.
+ *
+ * As of 2020-09-15, using the above rules, the stack trace for the .info line
+ * in include-subsub.mk would be:
+ *
+ *     curFile:        include-subsub.mk:4
+ *                     (lineno, from an .include)
+ *     includes[4]:    include-sub.mk:32
+ *                     (lineno, from a .for loop below an .include)
+ *     includes[4]:    include-sub.mk:31
+ *                     (first_lineno, from a .for loop, lineno == 32)
+ *     includes[3]:    include-sub.mk:30
+ *                     (first_lineno, from a .for loop, lineno == 33)
+ *     includes[2]:    include-sub.mk:29
+ *                     (first_lineno, from a .for loop, lineno == 34)
+ *     includes[1]:    include-sub.mk:35
+ *                     (not printed since it is below a .for loop)
+ *     includes[0]:    include-main.mk:27
+ */
 static Stack /* of *IFile */ includes;
 
 /* include paths (lists of directories) */
diff -r bb5b1d5270bc -r a59dec86e441 usr.bin/make/unit-tests/include-main.exp
--- a/usr.bin/make/unit-tests/include-main.exp  Mon Sep 14 19:51:54 2020 +0000
+++ b/usr.bin/make/unit-tests/include-main.exp  Mon Sep 14 19:59:47 2020 +0000
@@ -3,8 +3,8 @@
 make: "include-sub.mk" line 4: sub-before-ok
 make: "include-sub.mk" line 14: sub-before-for-ok
 make: "include-subsub.mk" line 4: subsub-ok
-make: "include-sub.mk" line 23: sub-after-ok
-make: "include-sub.mk" line 30: sub-after-for-ok
+make: "include-sub.mk" line 38: sub-after-ok
+make: "include-sub.mk" line 45: sub-after-for-ok
 make: "include-main.mk" line 30: main-after-ok
 make: "include-main.mk" line 37: main-after-for-ok
 exit status 0
diff -r bb5b1d5270bc -r a59dec86e441 usr.bin/make/unit-tests/include-sub.mk
--- a/usr.bin/make/unit-tests/include-sub.mk    Mon Sep 14 19:51:54 2020 +0000
+++ b/usr.bin/make/unit-tests/include-sub.mk    Mon Sep 14 19:59:47 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: include-sub.mk,v 1.3 2020/09/05 18:13:47 rillig Exp $
+# $NetBSD: include-sub.mk,v 1.4 2020/09/14 19:59:47 rillig Exp $
 
 .if ${.INCLUDEDFROMFILE} == "include-main.mk"
 .  info sub-before-ok
@@ -17,7 +17,22 @@
 .  endif
 .endfor
 
+# To see the variable 'includes' in action:
+#
+# Breakpoints:
+#      Parse_File              at "Stack_Push(&includes, curFile)"
+#      ParseMessage            at entry
+# Watches:
+#      ((const IFile *[10])(*includes.items))
+#      *curFile
+
+.for i in deeply
+.  for i in nested
+.    for i in include
 .include "include-subsub.mk"
+.    endfor
+.  endfor
+.endfor
 
 .if ${.INCLUDEDFROMFILE} == "include-main.mk"
 .  info sub-after-ok



Home | Main Index | Thread Index | Old Index