]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 46433] Show recipe line offsets in line number messages.
authorPaul Smith <psmith@gnu.org>
Sun, 10 Apr 2016 21:12:48 +0000 (17:12 -0400)
committerPaul Smith <psmith@gnu.org>
Mon, 11 Apr 2016 11:51:05 +0000 (07:51 -0400)
While displaying line numbers, show the relevant line number inside
the recipe not just the first line of the entire recipe.
Sample changes suggested by Brian Vandenberg <phantall@gmail.com>

* gnumake.h (gmk_floc): Add an 'offset' to track the recipe offset.
* read.c (eval, eval_makefile, eval_buffer): Initialize 'offset'.
(record_files, install_pattern_rule): Ditto.
* job.c (new_job, job_next_command): Update 'offset' based on the
line of the recipe we're expanding or invoking.
(child_error): Add 'offset' when showing the line number.
* function.c (func_shell_base): Ditto.
* output.c (error, fatal): Ditto.
* NEWS: Mention the new ability.
* tests/scripts/features/errors: Check the line number on errors.
* tests/scripts/functions/warning: Check the line number on warnings.
* tests/scripts/features/output-sync,
tests/scripts/features/parallelism, tests/scripts/functions/shell,
tests/scripts/functions/error: Update line numbers.

14 files changed:
NEWS
function.c
gnumake.h
job.c
output.c
read.c
rule.c
tests/scripts/features/errors
tests/scripts/features/output-sync
tests/scripts/features/parallelism
tests/scripts/functions/error
tests/scripts/functions/shell
tests/scripts/functions/warning
variable.c

diff --git a/NEWS b/NEWS
index 4a38e4febd3e8fa89d491ce8e2b7505773300276..2c46e1e1bbc38586ef41f48d53a3ba069af39b83 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -24,6 +24,10 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=106&set
   The function is expanded to the contents of the file.  The contents are
   expanded verbatim except that the final newline, if any, is stripped.
 
+* The makefile line numbers shown by GNU make now point directly to the
+  specific line in the recipe where the failure or warning occurred.
+  Sample changes suggested by Brian Vandenberg <phantall@gmail.com>
+
 * The interface to GNU make's "jobserver" is stable as documented in the
   manual, for tools which may want to access it.
 
@@ -32,7 +36,7 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=106&set
 
 * The amount of parallelism can be determined by querying MAKEFLAGS, even when
   the job server is enabled (previously MAKEFLAGS would always contain only
-  "-j" when job server was enabled).
+  "-j", with no number, when job server was enabled).
 
 * VMS-specific changes:
 
index 28015981eef25ed6a1df2e22d24f0677c98bb573..b8e69b22e1c8e7ae83f3404e7c8def218ec7b9c2 100644 (file)
@@ -1734,7 +1734,8 @@ func_shell_base (char *o, char **argv, int trim_newlines)
   if (reading_file && reading_file->filenm)
     {
       char *p = alloca (strlen (reading_file->filenm)+11+4);
-      sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
+      sprintf (p, "%s:%lu: ", reading_file->filenm,
+               reading_file->lineno + reading_file->offset);
       error_prefix = p;
     }
   else
index b508562fbb12988d69131e47c2db2f98b36c66dd..5b441e58a85b0b5a87a5254147c88ceafd08bc6a 100644 (file)
--- a/gnumake.h
+++ b/gnumake.h
@@ -24,6 +24,7 @@ typedef struct
   {
     const char *filenm;
     unsigned long lineno;
+    unsigned long offset;
   } gmk_floc;
 
 typedef char *(*gmk_func_ptr)(const char *nm, unsigned int argc, char **argv);
diff --git a/job.c b/job.c
index 59f51cd24c64eda3873ff1e08ab0448b64244ad4..2d2c80377bb27f8d6098e31b602cbae7b0a1cf20 100644 (file)
--- a/job.c
+++ b/job.c
@@ -500,7 +500,7 @@ child_error (struct child *child,
   else
     {
       char *a = alloca (strlen (flocp->filenm) + 1 + 11 + 1);
-      sprintf (a, "%s:%lu", flocp->filenm, flocp->lineno);
+      sprintf (a, "%s:%lu", flocp->filenm, flocp->lineno + flocp->offset);
       nm = a;
     }
 
@@ -1745,10 +1745,12 @@ new_job (struct file *file)
         memmove (out, in, strlen (in) + 1);
 
       /* Finally, expand the line.  */
+      cmds->fileinfo.offset = i;
       lines[i] = allocated_variable_expand_for_file (cmds->command_lines[i],
                                                      file);
     }
 
+  cmds->fileinfo.offset = 0;
   c->command_lines = lines;
 
   /* Fetch the first command line to be run.  */
@@ -1873,12 +1875,15 @@ job_next_command (struct child *child)
         {
           /* There are no more lines to be expanded.  */
           child->command_ptr = 0;
+          child->file->cmds->fileinfo.offset = 0;
           return 0;
         }
       else
         /* Get the next line to run.  */
         child->command_ptr = child->command_lines[child->command_line++];
     }
+
+  child->file->cmds->fileinfo.offset = child->command_line - 1;
   return 1;
 }
 
index 7e905cc375e8a46c48f6892658b3b64f78136d8a..475862f09009bb89977512b242ab30c9e61ace14 100644 (file)
--- a/output.c
+++ b/output.c
@@ -651,7 +651,7 @@ error (const gmk_floc *flocp, size_t len, const char *fmt, ...)
   p = get_buffer (len);
 
   if (flocp && flocp->filenm)
-    sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno);
+    sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
   else if (makelevel == 0)
     sprintf (p, "%s: ", program);
   else
@@ -683,7 +683,7 @@ fatal (const gmk_floc *flocp, size_t len, const char *fmt, ...)
   p = get_buffer (len);
 
   if (flocp && flocp->filenm)
-    sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
+    sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
   else if (makelevel == 0)
     sprintf (p, "%s: *** ", program);
   else
diff --git a/read.c b/read.c
index 10b250e70d569f1945e1fd2c7015b605f7d33d6c..a71eaebe1bd4db65ee3d1cbd8b6720b815184197 100644 (file)
--- a/read.c
+++ b/read.c
@@ -324,6 +324,7 @@ eval_makefile (const char *filename, int flags)
 
   ebuf.floc.filenm = filename; /* Use the original file name.  */
   ebuf.floc.lineno = 1;
+  ebuf.floc.offset = 0;
 
   if (ISDB (DB_VERBOSE))
     {
@@ -470,6 +471,7 @@ eval_buffer (char *buffer, const gmk_floc *floc)
     {
       ebuf.floc.filenm = NULL;
       ebuf.floc.lineno = 1;
+      ebuf.floc.offset = 0;
     }
 
   curfile = reading_file;
@@ -592,6 +594,7 @@ eval (struct ebuffer *ebuf, int set_default)
       if (filenames != 0)                                                     \
         {                                                                     \
           fi.lineno = tgts_started;                                           \
+          fi.offset = 0;                                                      \
           record_files (filenames, pattern, pattern_percent, depstr,          \
                         cmds_started, commands, commands_idx, two_colon,      \
                         prefix, &fi);                                         \
@@ -1958,6 +1961,7 @@ record_files (struct nameseq *filenames, const char *pattern,
       cmds = xmalloc (sizeof (struct commands));
       cmds->fileinfo.filenm = flocp->filenm;
       cmds->fileinfo.lineno = cmds_started;
+      cmds->fileinfo.offset = 0;
       cmds->commands = xstrndup (commands, commands_idx);
       cmds->command_lines = 0;
       cmds->recipe_prefix = prefix;
diff --git a/rule.c b/rule.c
index fce8372ca5ae550af73eef59f443df5fdf5dbb37..de8b30464070e52237dc0e17a8605d2186f1e0a8 100644 (file)
--- a/rule.c
+++ b/rule.c
@@ -380,6 +380,7 @@ install_pattern_rule (struct pspec *p, int terminal)
       r->cmds = xmalloc (sizeof (struct commands));
       r->cmds->fileinfo.filenm = 0;
       r->cmds->fileinfo.lineno = 0;
+      r->cmds->fileinfo.offset = 0;
       /* These will all be string literals, but we malloc space for them
          anyway because somebody might want to free them later.  */
       r->cmds->commands = xstrdup (p->commands);
index 43b81d4dabad6be65819d9aa3746da559a852585..ebd43831b4e2249694c581959aaa1616aba68b35 100644 (file)
@@ -90,4 +90,18 @@ if (!$vos) {
    &compare_output($answer,&get_logfile(1));
 }
 
+# Test that error line offset works
+
+run_make_test(q!
+all:
+       @echo hi
+       @echo there
+       @exit 1
+!,
+              '', "hi\nthere\n#MAKE#: *** [#MAKEFILE#:5: all] Error 1", 512);
+
 1;
+
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End:
index 64d6fe080cffc93241b2b04f0a8597fc01f78060..7139e002507dae9687e32ed56f2acb683f71862e 100644 (file)
@@ -204,7 +204,7 @@ bar: end
 #MAKE#[1]: Entering directory '#PWD#/foo'
 foo-fail: start
 foo-fail: end
-#MAKE#[1]: *** [Makefile:20: foo-fail] Error 1
+#MAKE#[1]: *** [Makefile:23: foo-fail] Error 1
 #MAKE#[1]: Leaving directory '#PWD#/foo'
 #MAKE#: *** [#MAKEFILE#:4: make-foo-fail] Error 2\n",
 512);
index 6b9efe1bd40b185ed71a6c781b43ef72c9c4957e..fabe5485c61f0630b9e3dc70eceaaf3adaf5f7a3 100644 (file)
@@ -99,12 +99,12 @@ ok:
        \@$sleep_command 4
        \@echo Ok done",
               '-rR -j5', "Fail
-#MAKE#: *** [#MAKEFILE#:6: fail.1] Error 1
+#MAKE#: *** [#MAKEFILE#:8: fail.1] Error 1
 #MAKE#: *** Waiting for unfinished jobs....
 Fail
-#MAKE#: *** [#MAKEFILE#:6: fail.2] Error 1
+#MAKE#: *** [#MAKEFILE#:8: fail.2] Error 1
 Fail
-#MAKE#: *** [#MAKEFILE#:6: fail.3] Error 1
+#MAKE#: *** [#MAKEFILE#:8: fail.3] Error 1
 Ok done",
              512);
 
index 0d61177fc27b0c1869ff80aff17d305d3fade901..998afe481476aa02902897df9e45e188846443eb 100644 (file)
@@ -54,7 +54,7 @@ $answer = "Some stuff\n$makefile:12: *** error is maybe.  Stop.\n";
 # Test #4
 
 &run_make_with_options($makefile, "ERROR4=definitely", &get_logfile, 512);
-$answer = "Some stuff\n$makefile:16: *** error is definitely.  Stop.\n";
+$answer = "Some stuff\n$makefile:17: *** error is definitely.  Stop.\n";
 &compare_output($answer,&get_logfile(1));
 
 # Test #5
@@ -66,8 +66,6 @@ $answer = "$makefile:22: *** Error found!.  Stop.\n";
 # This tells the test driver that the perl test script executed properly.
 1;
 
-
-
-
-
-
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End:
index 4702b09669469df66b08c08e449df8163e3db63c..809c77fa6afdd4290a43106945397f40b7e99f4c 100644 (file)
@@ -44,4 +44,17 @@ export HI = $(shell echo hi)
 all: ; @echo $$HI
     ','','hi');
 
+# Test shell errors in recipes including offset
+run_make_test('
+all:
+       @echo hi
+       $(shell ./basdfdfsed there)
+       @echo there
+',
+              '', "#MAKE#: ./basdfdfsed: Command not found\nhi\nthere\n");
+
 1;
+
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End:
index cd452d41ad0be21c1716ff88698a5322cde2b367..16eb83bb457fc3e1af1b50e1ef625611d4c1f233 100644 (file)
@@ -52,14 +52,32 @@ $answer = "Some stuff\n$makefile:10: warning is maybe\nhi\n";
 # Test #4
 
 &run_make_with_options($makefile, "WARNING4=definitely", &get_logfile, 0);
-$answer = "Some stuff\n$makefile:14: warning is definitely\nhi\nthere\n";
+$answer = "Some stuff\n$makefile:15: warning is definitely\nhi\nthere\n";
 &compare_output($answer,&get_logfile(1));
 
+# Test linenumber offset
+
+run_make_test(q!
+all: one two
+       $(warning in $@ line 3)
+       @true
+       $(warning in $@ line 5)
+
+one two:
+       $(warning in $@ line 8)
+       @true
+       $(warning in $@ line 10)
+!,
+              '', "#MAKEFILE#:8: in one line 8
+#MAKEFILE#:10: in one line 10
+#MAKEFILE#:8: in two line 8
+#MAKEFILE#:10: in two line 10
+#MAKEFILE#:3: in all line 3
+#MAKEFILE#:5: in all line 5\n");
+
 # This tells the test driver that the perl test script executed properly.
 1;
 
-
-
-
-
-
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End:
index edbe5945519be9ddab9e9d73c5b8a5efe54a25be..b0d8d69c53029c813a14a111e7d1b071b354f0f0 100644 (file)
@@ -1657,7 +1657,7 @@ print_variable (const void *item, void *arg)
     fputs (" private", stdout);
   if (v->fileinfo.filenm)
     printf (_(" (from '%s', line %lu)"),
-            v->fileinfo.filenm, v->fileinfo.lineno);
+            v->fileinfo.filenm, v->fileinfo.lineno + v->fileinfo.offset);
   putchar ('\n');
   fputs (prefix, stdout);