[moving to automake-patches]

On 05/10/2012 02:03 PM, Nikolai Weibull wrote:
> Hi!
>
Hi Nikolai, sorry for the delay, and thanks for the patch.

> If Automake is used in non-recursive mode and one of the inputs is a
> yacc file, for example, src/grammar.y, ylwrap will remove too many
> directories from the output file when it adjusts the paths in it.
> This results in #line directives referring to grammar.y instead of
> src/grammar.y.
> 
> This is a result of input_rx simply taking all the directory
> components of the absolute input path and removing them.
> 
> One solution is to store the path passed to ylwrap and replace input_rx
> with it:
>
> --- build/ylwrap.old    2012-05-10 13:59:19.495291713 +0200
> +++ build/ylwrap        2012-05-10 13:59:24.579351693 +0200
> @@ -67,6 +67,8 @@
>  # The input.
>  input="$1"
>  shift
> +input_orgdir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
> +input_sub=`echo "$input_orgdir" | sed 's,\\\\,\\\\\\\\,g'`
>  case "$input" in
>    [\\/]* | ?:[\\/]*)
>      # Absolute path; do nothing.
> @@ -175,7 +177,7 @@
>              -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
>              -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
> 
> -      sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \
> +      sed -e "/^#/!b" -e "s,$input_rx,$input_sub," -e "s,$from,$2," \
>            -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$?
> 
>        # Check whether header files must be updated.
> 
> I’m sure that there’s a much better way of doing this, but this seems to work.
> 
I like your idea.  I've turned it into a two patch series (see attachment).  I
will push by tomorrow if there is no objection.

Regards,
  Stefano
>From 0ce63a38ab7c87502504ba7d2319886d4f4a7d15 Mon Sep 17 00:00:00 2001
Message-Id: <0ce63a38ab7c87502504ba7d2319886d4f4a7d15.1337185019.git.stefano.lattar...@gmail.com>
From: Stefano Lattarini <stefano.lattar...@gmail.com>
Date: Wed, 16 May 2012 17:35:05 +0200
Subject: [PATCH 1/2] ylwrap: preparatory refactoring

This commit should cause no semantic change in the ylwrap behaviour.
It will only be needed in light of a future change.  See:
<http://lists.gnu.org/archive/html/automake/2012-05/msg00013.html>

* lib/ylwrap (get_dirname, quote_for_sed): New functions, factoring
out some non-trivial code.  Use them where appropriate.

Signed-off-by: Stefano Lattarini <stefano.lattar...@gmail.com>
---
 lib/ylwrap |   19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/ylwrap b/lib/ylwrap
index 36543da..8a20288 100755
--- a/lib/ylwrap
+++ b/lib/ylwrap
@@ -62,6 +62,19 @@ EOF
     ;;
 esac
 
+get_dirname ()
+{
+  case $1 in
+    */*|*\\*) printf '%s\n' "$1" | sed -e 's,\([\\/]\)[^\\/]*$,\1,';;
+    # Otherwise,  we want the empty string (not ".").
+  esac
+}
+
+quote_for_sed ()
+{
+  # FIXME: really we should care about more than '.' and '\'.
+  sed -e 's,[\\.],\\&,g'
+}
 
 # The input.
 input="$1"
@@ -125,11 +138,7 @@ if test $ret -eq 0; then
     y_tab_nodot="yes"
   fi
 
-  # The directory holding the input.
-  input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
-  # Quote $INPUT_DIR so we can use it in a regexp.
-  # FIXME: really we should care about more than '.' and '\'.
-  input_rx=`echo "$input_dir" | sed 's,\\\\,\\\\\\\\,g;s,\\.,\\\\.,g'`
+  input_rx=`get_dirname "$input" | quote_for_sed`
 
   while test "$#" -ne 0; do
     from="$1"
-- 
1.7.9.5

>From 0abcb8dec4bc9284ce7ff03ac14c5cf7e33b3788 Mon Sep 17 00:00:00 2001
Message-Id: <0abcb8dec4bc9284ce7ff03ac14c5cf7e33b3788.1337185019.git.stefano.lattar...@gmail.com>
In-Reply-To: <0ce63a38ab7c87502504ba7d2319886d4f4a7d15.1337185019.git.stefano.lattar...@gmail.com>
References: <0ce63a38ab7c87502504ba7d2319886d4f4a7d15.1337185019.git.stefano.lattar...@gmail.com>
From: Nikolai Weibull <n...@bitwi.se>
Date: Wed, 16 May 2012 18:16:41 +0200
Subject: [PATCH 2/2] ylwrap: preserve subdirectories in "#line" munging

If Automake is used in non-recursive mode and one of the inputs is a
yacc file, for example, "src/grammar.y", ylwrap will remove too many
directories from the output file when it adjusts the paths in it.
This results in #line directives referring to "grammar.y" instead of
"src/grammar.y".

This is a result of $input_rx simply taking all the directory
components of the absolute input path and removing them.

One solution is to store the path passed to ylwrap and replace
$input_rx with it.  This is what we do.

Suggestion and initial patch (without tests) by Nikolai Weibull:
<http://lists.gnu.org/archive/html/automake/2012-05/msg00013.html>
Final patch by Stefano Lattarini.

* lib/ylwrap ($input_sub_rx): New.
When munging the #line directives, substitute '$input_rx' with it,
instead of stripping it altogether.
Adjust comments.
* t/yacc-line.sh: Adjust and extend.
* NEWS, THANKS: Update.

Copyright-paperwork-exempt: yes
Co-authored-by: Stefano Lattarini <stefano.lattar...@gmail.com>
Signed-off-by: Stefano Lattarini <stefano.lattar...@gmail.com>
---
 NEWS           |    9 +++++++++
 THANKS         |    1 +
 lib/ylwrap     |   12 +++++-------
 t/yacc-line.sh |   27 +++++++++++++++++++--------
 4 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/NEWS b/NEWS
index d0575e6..944f7f9 100644
--- a/NEWS
+++ b/NEWS
@@ -103,6 +103,15 @@ Bugs fixed in 1.12.1:
   - Several inefficiencies and poor performances in the implementation
     of the parallel-tests 'check' and 'recheck' targets have been fixed.
 
+  - The post-processing of output "#line" directives done the ylwrap
+    script is more faithful w.r.t. files in a subdirectory; for example,
+    if the processed file is "src/grammar.y", ylwrap will correctly
+    produce directives like:
+        #line 7 "src/grammar.y"
+    rather than like
+        #line 7 "grammar.y"
+    as it did before.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 New in 1.12:
diff --git a/THANKS b/THANKS
index b98b2b7..0824c4f 100644
--- a/THANKS
+++ b/THANKS
@@ -269,6 +269,7 @@ Nicolas Joly                    nj...@pasteur.fr
 Nicolas Thiery                  nthi...@icare.mines.edu
 NightStrike                     nightstr...@gmail.com
 Nik A. Melchior                 n...@cse.wustl.edu
+Nikolai Weibull                 n...@bitwi.se
 NISHIDA Keisuke                 knish...@nn.iij4u.or.jp
 Noah Friedman                   fried...@gnu.ai.mit.edu
 Norman Gray                     nor...@astro.gla.ac.uk
diff --git a/lib/ylwrap b/lib/ylwrap
index 8a20288..6879d8d 100755
--- a/lib/ylwrap
+++ b/lib/ylwrap
@@ -79,6 +79,8 @@ quote_for_sed ()
 # The input.
 input="$1"
 shift
+# We'll later need for a correct munging of "#line" directives.
+input_sub_rx=`get_dirname "$input" | quote_for_sed`
 case "$input" in
   [\\/]* | ?:[\\/]*)
     # Absolute path; do nothing.
@@ -170,15 +172,11 @@ if test $ret -eq 0; then
         realtarget="$target"
         target="tmp-`echo $target | sed s/.*[\\/]//g`"
       fi
-      # Edit out '#line' or '#' directives.
-      #
+      # Munge "#line" or "#" directives.
       # We don't want the resulting debug information to point at
-      # an absolute srcdir; it is better for it to just mention the
-      # .y file with no path.
-      #
+      # an absolute srcdir.
       # We want to use the real output file name, not yy.lex.c for
       # instance.
-      #
       # We want the include guards to be adjusted too.
       FROM=`echo "$from" | sed \
             -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
@@ -187,7 +185,7 @@ if test $ret -eq 0; then
             -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
             -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
 
-      sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \
+      sed -e "/^#/!b" -e "s,$input_rx,$input_sub_rx," -e "s,$from,$2," \
           -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$?
 
       # Check whether header files must be updated.
diff --git a/t/yacc-line.sh b/t/yacc-line.sh
index 090b72b..62e19e4 100755
--- a/t/yacc-line.sh
+++ b/t/yacc-line.sh
@@ -94,18 +94,29 @@ for vpath in : false; do
 
   # For debugging,
   ls -l . sub sub/dir
-  $FGREP '.y' $c_outputs
+  $EGREP 'line|\.y' $c_outputs
 
   # Adjusted "#line" should not contain reference to the builddir.
-  $EGREP '#.*line.*(build|\.\.).*\.y' $c_outputs && Exit 1
+  grep '#.*line.*build.*\.y' $c_outputs && Exit 1
+  # Adjusted "#line" should not contain reference to the absolute
+  # srcdir.
+  $EGREP '#.*line *"?/.*\.y' $c_outputs && Exit 1
   # Adjusted "#line" should not contain reference to the default
   # output file names, e.g., 'y.tab.c' and 'y.tab.h'.
-  $EGREP '#.*line.*y\.tab\.' $c_outputs && Exit 1
-  # Don't be excessively strict in grepping, to avoid spurious failures.
-  grep '#.*line.*zardoz\.y' zardoz.c
-  grep '#.*line.*quux\.y' bar-quux.c
-  grep '#.*line.*zardoz\.y' sub/foo-zardoz.c
-  grep '#.*line.*quux\.y' sub/dir/quux.c
+  grep '#.*line.*y\.tab\.' $c_outputs && Exit 1
+  # Look out for a silly regression.
+  grep "#.*\.y.*\.y" $c_outputs && Exit 1
+  if $vpath; then
+    grep '#.*line.*"\.\./zardoz\.y"' zardoz.c
+    grep '#.*line.*"\.\./dir/quux\.y"' bar-quux.c
+    grep '#.*line.*"\.\./\.\./sub/zardoz\.y"' sub/foo-zardoz.c
+    grep '#.*line.*"\.\./\.\./sub/dir/quux\.y"' sub/dir/quux.c
+  else
+    grep '#.*line.*"zardoz\.y"' zardoz.c
+    grep '#.*line.*"dir/quux\.y"' bar-quux.c
+    grep '#.*line.*"zardoz\.y"' sub/foo-zardoz.c
+    grep '#.*line.*"dir/quux\.y"' sub/dir/quux.c
+  fi
   cd $srcdir
 
 done
-- 
1.7.9.5

Reply via email to