2004-09-23 Kelley Cook <kcook@gcc.gnu.org>
[gcc/gcc.git] / ylwrap
diff --git a/ylwrap b/ylwrap
index b5b6218..e66a95b 100755 (executable)
--- a/ylwrap
+++ b/ylwrap
@@ -1,6 +1,11 @@
 #! /bin/sh
 # ylwrap - wrapper for lex/yacc invocations.
-# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+scriptversion=2004-09-10.20
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004
+#   Free Software Foundation, Inc.
+#
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-# Usage:
-#     ylwrap PROGRAM INPUT [OUTPUT DESIRED]... -- [ARGS]...
-# * PROGRAM is program to run.
-# * INPUT is the input file
-# * OUTPUT is file PROG generates
-# * DESIRED is file we actually want
-# * ARGS are passed to PROG
-# Any number of OUTPUT,DESIRED pairs may be used.
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
 
-# The program to run.
-prog="$1"
-shift
-# Make any relative path in $prog absolute.
-case "$prog" in
- /*) ;;
- */*) prog="`pwd`/$prog" ;;
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case "$1" in
+  '')
+    echo "$0: No files given.  Try \`$0 --help' for more information." 1>&2
+    exit 1
+    ;;
+  --basedir)
+    basedir=$2
+    shift 2
+    ;;
+  -h|--h*)
+    cat <<\EOF
+Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
+
+Wrapper for lex/yacc invocations, renaming files as desired.
+
+  INPUT is the input file
+  OUTPUT is one file PROG generates
+  DESIRED is the file we actually want instead of OUTPUT
+  PROGRAM is program to run
+  ARGS are passed to PROG
+
+Any number of OUTPUT,DESIRED pairs may be used.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit 0
+    ;;
+  -v|--v*)
+    echo "ylwrap $scriptversion"
+    exit 0
+    ;;
 esac
 
+
 # The input.
 input="$1"
 shift
 case "$input" in
/*)
 [\\/]* | ?:[\\/]*)
     # Absolute path; do nothing.
     ;;
- *)
-    # Relative path.  Make it absolute.  Why?  Because otherwise any
-    # debugging info in the generated file will point to the wrong
-    # place.  This is really gross.
+  *)
+    # Relative path.  Make it absolute.
     input="`pwd`/$input"
     ;;
 esac
 
 pairlist=
 while test "$#" -ne 0; do
-   if test "$1" = "--"; then
-      shift
-      break
-   fi
-   pairlist="$pairlist $1"
-   shift
+  if test "$1" = "--"; then
+    shift
+    break
+  fi
+  pairlist="$pairlist $1"
+  shift
 done
 
+# The program to run.
+prog="$1"
+shift
+# Make any relative path in $prog absolute.
+case "$prog" in
+  [\\/]* | ?:[\\/]*) ;;
+  *[\\/]*) prog="`pwd`/$prog" ;;
+esac
+
 # FIXME: add hostname here for parallel makes that run commands on
 # other machines.  But that might take us over the 14-char limit.
 dirname=ylwrap$$
@@ -67,41 +104,119 @@ trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15
 mkdir $dirname || exit 1
 
 cd $dirname
-$prog ${1+"$@"} "$input"
-status=$?
-
-if test $status -eq 0; then
-   set X $pairlist
-   shift
-   first=yes
-   while test "$#" -ne 0; do
-      if test -f "$1"; then
-         # If $2 is an absolute path name, then just use that,
-         # otherwise prepend `../'.
-         case "$2" in
-          /*) target="$2";;
-          *) target="../$2";;
-        esac
-        mv "$1" "$target" || status=$?
+
+case $# in
+  0) $prog "$input" ;;
+  *) $prog "$@" "$input" ;;
+esac
+ret=$?
+
+if test $ret -eq 0; then
+  set X $pairlist
+  shift
+  first=yes
+  # Since DOS filename conventions don't allow two dots,
+  # the DOS version of Bison writes out y_tab.c instead of y.tab.c
+  # and y_tab.h instead of y.tab.h. Test to see if this is the case.
+  y_tab_nodot="no"
+  if test -f y_tab.c || test -f y_tab.h; 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'`
+
+  while test "$#" -ne 0; do
+    from="$1"
+    # Handle y_tab.c and y_tab.h output by DOS
+    if test $y_tab_nodot = "yes"; then
+      if test $from = "y.tab.c"; then
+       from="y_tab.c"
       else
-        # A missing file is only an error for the first file.  This
-        # is a blatant hack to let us support using "yacc -d".  If -d
-        # is not specified, we don't want an error when the header
-        # file is "missing".
-        if test $first = yes; then
-           status=1
-        fi
+       if test $from = "y.tab.h"; then
+         from="y_tab.h"
+       fi
       fi
-      shift
-      shift
-      first=no
-   done
+    fi
+    if test -f "$from"; then
+      # If $2 is an absolute path name, then just use that,
+      # otherwise prepend `../'.
+      case "$2" in
+       [\\/]* | ?:[\\/]*) target="$2";;
+       *) target="../$2";;
+      esac
+
+      # We do not want to overwrite a header file if it hasn't
+      # changed.  This avoid useless recompilations.  However the
+      # parser itself (the first file) should always be updated,
+      # because it is the destination of the .y.c rule in the
+      # Makefile.  Divert the output of all other files to a temporary
+      # file so we can compare them to existing versions.
+      if test $first = no; then
+       realtarget="$target"
+       target="tmp-`echo $target | sed s/.*[\\/]//g`"
+      fi
+      # Edit out `#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.
+      #
+      # 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/'\
+            -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
+      TARGET=`echo "$2" | sed \
+            -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
+            -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
+
+      sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \
+          -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$?
+
+      # Check whether header files must be updated.
+      if test $first = no; then
+       if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
+         echo "$2" is unchanged
+         rm -f "$target"
+       else
+          echo updating "$2"
+          mv -f "$target" "$realtarget"
+        fi
+      fi
+    else
+      # A missing file is only an error for the first file.  This
+      # is a blatant hack to let us support using "yacc -d".  If -d
+      # is not specified, we don't want an error when the header
+      # file is "missing".
+      if test $first = yes; then
+        ret=1
+      fi
+    fi
+    shift
+    shift
+    first=no
+  done
 else
-   status=$?
+  ret=$?
 fi
 
 # Remove the directory.
 cd ..
 rm -rf $dirname
 
-exit $status
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End: