ylwrap revision 316068
134192Sjdp#! /bin/sh
234192Sjdp# ylwrap - wrapper for lex/yacc invocations.
334192Sjdp
434192Sjdpscriptversion=2013-01-12.17; # UTC
534192Sjdp
634192Sjdp# Copyright (C) 1996-2014 Free Software Foundation, Inc.
734192Sjdp#
834192Sjdp# Written by Tom Tromey <tromey@cygnus.com>.
934192Sjdp#
1034192Sjdp# This program is free software; you can redistribute it and/or modify
1134192Sjdp# it under the terms of the GNU General Public License as published by
1234192Sjdp# the Free Software Foundation; either version 2, or (at your option)
13262435Sbrueffer# any later version.
1434192Sjdp#
1534192Sjdp# This program is distributed in the hope that it will be useful,
1634192Sjdp# but WITHOUT ANY WARRANTY; without even the implied warranty of
1734192Sjdp# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1834192Sjdp# GNU General Public License for more details.
1934192Sjdp#
2034192Sjdp# You should have received a copy of the GNU General Public License
2134192Sjdp# along with this program.  If not, see <http://www.gnu.org/licenses/>.
2234192Sjdp
2334192Sjdp# As a special exception to the GNU General Public License, if you
2434192Sjdp# distribute this file as part of a program that contains a
2534192Sjdp# configuration script generated by Autoconf, you may include it under
2634192Sjdp# the same distribution terms that you use for the rest of that program.
2734192Sjdp
2834192Sjdp# This file is maintained in Automake, please report
2934192Sjdp# bugs to <bug-automake@gnu.org> or send patches to
3034192Sjdp# <automake-patches@gnu.org>.
3134192Sjdp
3250476Speterget_dirname ()
3334192Sjdp{
3434192Sjdp  case $1 in
3534192Sjdp    */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
3634192Sjdp    # Otherwise,  we want the empty string (not ".").
3734192Sjdp  esac
3834192Sjdp}
3934192Sjdp
4034192Sjdp# guard FILE
4134192Sjdp# ----------
4234192Sjdp# The CPP macro used to guard inclusion of FILE.
4334192Sjdpguard ()
4434192Sjdp{
4534192Sjdp  printf '%s\n' "$1"                                                    \
4634192Sjdp    | sed                                                               \
47211413Skib        -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'   \
4869793Sobrien        -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'                        \
49110803Skan        -e 's/__*/_/g'
50119255Simp}
51110803Skan
5234192Sjdp# quote_for_sed [STRING]
5334192Sjdp# ----------------------
5434192Sjdp# Return STRING (or stdin) quoted to be used as a sed pattern.
5534192Sjdpquote_for_sed ()
5634192Sjdp{
57225152Skib  case $# in
5834192Sjdp    0) cat;;
5934192Sjdp    1) printf '%s\n' "$1";;
6034192Sjdp  esac \
6134192Sjdp    | sed -e 's|[][\\.*]|\\&|g'
6234192Sjdp}
6334192Sjdp
6434192Sjdpcase "$1" in
6534192Sjdp  '')
6634192Sjdp    echo "$0: No files given.  Try '$0 --help' for more information." 1>&2
6734192Sjdp    exit 1
6834192Sjdp    ;;
6934192Sjdp  --basedir)
7034192Sjdp    basedir=$2
7134192Sjdp    shift 2
7234192Sjdp    ;;
7334192Sjdp  -h|--h*)
7434192Sjdp    cat <<\EOF
7534192SjdpUsage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
7634192Sjdp
7734192SjdpWrapper for lex/yacc invocations, renaming files as desired.
7834192Sjdp
7934192Sjdp  INPUT is the input file
8034192Sjdp  OUTPUT is one file PROG generates
8134192Sjdp  DESIRED is the file we actually want instead of OUTPUT
8234192Sjdp  PROGRAM is program to run
8334192Sjdp  ARGS are passed to PROG
8434192Sjdp
8534192SjdpAny number of OUTPUT,DESIRED pairs may be used.
8634192Sjdp
8734192SjdpReport bugs to <bug-automake@gnu.org>.
8834192SjdpEOF
8934192Sjdp    exit $?
9034192Sjdp    ;;
9134192Sjdp  -v|--v*)
9234192Sjdp    echo "ylwrap $scriptversion"
9334192Sjdp    exit $?
9434192Sjdp    ;;
9534192Sjdpesac
9634192Sjdp
9734192Sjdp
9834192Sjdp# The input.
9934192Sjdpinput=$1
10034192Sjdpshift
10134192Sjdp# We'll later need for a correct munging of "#line" directives.
10234192Sjdpinput_sub_rx=`get_dirname "$input" | quote_for_sed`
10334192Sjdpcase $input in
10434192Sjdp  [\\/]* | ?:[\\/]*)
10534192Sjdp    # Absolute path; do nothing.
10634192Sjdp    ;;
10734192Sjdp  *)
10834192Sjdp    # Relative path.  Make it absolute.
10934192Sjdp    input=`pwd`/$input
11034192Sjdp    ;;
11134192Sjdpesac
11234192Sjdpinput_rx=`get_dirname "$input" | quote_for_sed`
11334192Sjdp
11434192Sjdp# Since DOS filename conventions don't allow two dots,
11534192Sjdp# the DOS version of Bison writes out y_tab.c instead of y.tab.c
11634192Sjdp# and y_tab.h instead of y.tab.h. Test to see if this is the case.
11734192Sjdpy_tab_nodot=false
11834192Sjdpif test -f y_tab.c || test -f y_tab.h; then
11934192Sjdp  y_tab_nodot=true
12034192Sjdpfi
12134192Sjdp
12234192Sjdp# The parser itself, the first file, is the destination of the .y.c
12334192Sjdp# rule in the Makefile.
12434192Sjdpparser=$1
12534192Sjdp
12634192Sjdp# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
12734192Sjdp# instance, we rename #include "y.tab.h" into #include "parse.h"
12834192Sjdp# during the conversion from y.tab.c to parse.c.
12934192Sjdpsed_fix_filenames=
13034192Sjdp
13134192Sjdp# Also rename header guards, as Bison 2.7 for instance uses its header
13234192Sjdp# guard in its implementation file.
13334192Sjdpsed_fix_header_guards=
13434192Sjdp
13534192Sjdpwhile test $# -ne 0; do
13634192Sjdp  if test x"$1" = x"--"; then
13734192Sjdp    shift
13834192Sjdp    break
13934192Sjdp  fi
140225152Skib  from=$1
14134192Sjdp  # Handle y_tab.c and y_tab.h output by DOS
142281452Skib  if $y_tab_nodot; then
143281452Skib    case $from in
144281452Skib      "y.tab.c") from=y_tab.c;;
145281452Skib      "y.tab.h") from=y_tab.h;;
146281452Skib    esac
147281452Skib  fi
148281452Skib  shift
149281452Skib  to=$1
150211413Skib  shift
15134192Sjdp  sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
15234192Sjdp  sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
15334192Sjdpdone
15434192Sjdp
15534192Sjdp# The program to run.
15638816Sdfrprog=$1
15738816Sdfrshift
15834192Sjdp# Make any relative path in $prog absolute.
15934192Sjdpcase $prog in
16034192Sjdp  [\\/]* | ?:[\\/]*) ;;
16134192Sjdp  *[\\/]*) prog=`pwd`/$prog ;;
16234192Sjdpesac
16334192Sjdp
16434192Sjdpdirname=ylwrap$$
165281452Skibdo_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
16634192Sjdptrap "ret=129; $do_exit" 1
16734192Sjdptrap "ret=130; $do_exit" 2
16834192Sjdptrap "ret=141; $do_exit" 13
16938816Sdfrtrap "ret=143; $do_exit" 15
17034192Sjdpmkdir $dirname || exit 1
17134192Sjdp
17234192Sjdpcd $dirname
17334192Sjdp
17434192Sjdpcase $# in
17534192Sjdp  0) "$prog" "$input" ;;
17634192Sjdp  *) "$prog" "$@" "$input" ;;
177114625Sobrienesac
17834192Sjdpret=$?
17934192Sjdp
18034192Sjdpif test $ret -eq 0; then
18134192Sjdp  for from in *
18234192Sjdp  do
18334192Sjdp    to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
18434192Sjdp    if test -f "$from"; then
18534192Sjdp      # If $2 is an absolute path name, then just use that,
18634192Sjdp      # otherwise prepend '../'.
18734192Sjdp      case $to in
188114625Sobrien        [\\/]* | ?:[\\/]*) target=$to;;
18934192Sjdp        *) target=../$to;;
19034192Sjdp      esac
19134192Sjdp
19234192Sjdp      # Do not overwrite unchanged header files to avoid useless
19334192Sjdp      # recompilations.  Always update the parser itself: it is the
19434192Sjdp      # destination of the .y.c rule in the Makefile.  Divert the
19534192Sjdp      # output of all other files to a temporary file so we can
19634192Sjdp      # compare them to existing versions.
19734192Sjdp      if test $from != $parser; then
19834192Sjdp        realtarget=$target
19934192Sjdp        target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'`
20034192Sjdp      fi
20134192Sjdp
20234192Sjdp      # Munge "#line" or "#" directives.  Don't let the resulting
20334192Sjdp      # debug information point at an absolute srcdir.  Use the real
20434192Sjdp      # output file name, not yy.lex.c for instance.  Adjust the
20534192Sjdp      # include guards too.
20634192Sjdp      sed -e "/^#/!b"                           \
20734192Sjdp          -e "s|$input_rx|$input_sub_rx|"       \
20834192Sjdp          -e "$sed_fix_filenames"               \
20934192Sjdp          -e "$sed_fix_header_guards"           \
21034192Sjdp        "$from" >"$target" || ret=$?
21134192Sjdp
21234192Sjdp      # Check whether files must be updated.
21334192Sjdp      if test "$from" != "$parser"; then
21434192Sjdp        if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
21534192Sjdp          echo "$to is unchanged"
21634192Sjdp          rm -f "$target"
21734192Sjdp        else
21834192Sjdp          echo "updating $to"
21934192Sjdp          mv -f "$target" "$realtarget"
22034192Sjdp        fi
22134192Sjdp      fi
22234192Sjdp    else
22334192Sjdp      # A missing file is only an error for the parser.  This is a
22434192Sjdp      # blatant hack to let us support using "yacc -d".  If -d is not
22534192Sjdp      # specified, don't fail when the header file is "missing".
22634192Sjdp      if test "$from" = "$parser"; then
22734192Sjdp        ret=1
22834192Sjdp      fi
22934192Sjdp    fi
23034192Sjdp  done
23134192Sjdpfi
23234192Sjdp
23334192Sjdp# Remove the directory.
23434192Sjdpcd ..
235154248Sjasonerm -rf $dirname
236154248Sjasone
237154248Sjasoneexit $ret
238154248Sjasone
239154248Sjasone# Local Variables:
240154248Sjasone# mode: shell-script
241154248Sjasone# sh-indentation: 2
242154248Sjasone# eval: (add-hook 'write-file-hooks 'time-stamp)
243154248Sjasone# time-stamp-start: "scriptversion="
244154248Sjasone# time-stamp-format: "%:y-%02m-%02d.%02H"
245154248Sjasone# time-stamp-time-zone: "UTC"
246154248Sjasone# time-stamp-end: "; # UTC"
247154248Sjasone# End:
248154248Sjasone