13e747e6dSmrg#! /bin/sh
23e747e6dSmrg# ylwrap - wrapper for lex/yacc invocations.
33e747e6dSmrg
46d8e82c3Smrgscriptversion=2018-03-07.03; # UTC
53e747e6dSmrg
66d8e82c3Smrg# Copyright (C) 1996-2021 Free Software Foundation, Inc.
73e747e6dSmrg#
83e747e6dSmrg# Written by Tom Tromey <tromey@cygnus.com>.
93e747e6dSmrg#
103e747e6dSmrg# This program is free software; you can redistribute it and/or modify
113e747e6dSmrg# it under the terms of the GNU General Public License as published by
123e747e6dSmrg# the Free Software Foundation; either version 2, or (at your option)
133e747e6dSmrg# any later version.
143e747e6dSmrg#
153e747e6dSmrg# This program is distributed in the hope that it will be useful,
163e747e6dSmrg# but WITHOUT ANY WARRANTY; without even the implied warranty of
173e747e6dSmrg# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
183e747e6dSmrg# GNU General Public License for more details.
193e747e6dSmrg#
203e747e6dSmrg# You should have received a copy of the GNU General Public License
216d8e82c3Smrg# along with this program.  If not, see <https://www.gnu.org/licenses/>.
223e747e6dSmrg
233e747e6dSmrg# As a special exception to the GNU General Public License, if you
243e747e6dSmrg# distribute this file as part of a program that contains a
253e747e6dSmrg# configuration script generated by Autoconf, you may include it under
263e747e6dSmrg# the same distribution terms that you use for the rest of that program.
273e747e6dSmrg
283e747e6dSmrg# This file is maintained in Automake, please report
293e747e6dSmrg# bugs to <bug-automake@gnu.org> or send patches to
303e747e6dSmrg# <automake-patches@gnu.org>.
313e747e6dSmrg
32c2535118Smrgget_dirname ()
33c2535118Smrg{
34c2535118Smrg  case $1 in
35c2535118Smrg    */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
36c2535118Smrg    # Otherwise,  we want the empty string (not ".").
37c2535118Smrg  esac
38c2535118Smrg}
39c2535118Smrg
40c2535118Smrg# guard FILE
41c2535118Smrg# ----------
42c2535118Smrg# The CPP macro used to guard inclusion of FILE.
43c2535118Smrgguard ()
44c2535118Smrg{
45c2535118Smrg  printf '%s\n' "$1"                                                    \
46c2535118Smrg    | sed                                                               \
47c2535118Smrg        -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'   \
48c2535118Smrg        -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'                        \
49c2535118Smrg        -e 's/__*/_/g'
50c2535118Smrg}
51c2535118Smrg
52c2535118Smrg# quote_for_sed [STRING]
53c2535118Smrg# ----------------------
54c2535118Smrg# Return STRING (or stdin) quoted to be used as a sed pattern.
55c2535118Smrgquote_for_sed ()
56c2535118Smrg{
57c2535118Smrg  case $# in
58c2535118Smrg    0) cat;;
59c2535118Smrg    1) printf '%s\n' "$1";;
60c2535118Smrg  esac \
61c2535118Smrg    | sed -e 's|[][\\.*]|\\&|g'
62c2535118Smrg}
63c2535118Smrg
643e747e6dSmrgcase "$1" in
653e747e6dSmrg  '')
66c2535118Smrg    echo "$0: No files given.  Try '$0 --help' for more information." 1>&2
673e747e6dSmrg    exit 1
683e747e6dSmrg    ;;
693e747e6dSmrg  --basedir)
703e747e6dSmrg    basedir=$2
713e747e6dSmrg    shift 2
723e747e6dSmrg    ;;
733e747e6dSmrg  -h|--h*)
743e747e6dSmrg    cat <<\EOF
753e747e6dSmrgUsage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
763e747e6dSmrg
773e747e6dSmrgWrapper for lex/yacc invocations, renaming files as desired.
783e747e6dSmrg
793e747e6dSmrg  INPUT is the input file
803e747e6dSmrg  OUTPUT is one file PROG generates
813e747e6dSmrg  DESIRED is the file we actually want instead of OUTPUT
823e747e6dSmrg  PROGRAM is program to run
833e747e6dSmrg  ARGS are passed to PROG
843e747e6dSmrg
853e747e6dSmrgAny number of OUTPUT,DESIRED pairs may be used.
863e747e6dSmrg
873e747e6dSmrgReport bugs to <bug-automake@gnu.org>.
883e747e6dSmrgEOF
893e747e6dSmrg    exit $?
903e747e6dSmrg    ;;
913e747e6dSmrg  -v|--v*)
923e747e6dSmrg    echo "ylwrap $scriptversion"
933e747e6dSmrg    exit $?
943e747e6dSmrg    ;;
953e747e6dSmrgesac
963e747e6dSmrg
973e747e6dSmrg
983e747e6dSmrg# The input.
99c2535118Smrginput=$1
1003e747e6dSmrgshift
101c2535118Smrg# We'll later need for a correct munging of "#line" directives.
102c2535118Smrginput_sub_rx=`get_dirname "$input" | quote_for_sed`
103c2535118Smrgcase $input in
1043e747e6dSmrg  [\\/]* | ?:[\\/]*)
1053e747e6dSmrg    # Absolute path; do nothing.
1063e747e6dSmrg    ;;
1073e747e6dSmrg  *)
1083e747e6dSmrg    # Relative path.  Make it absolute.
109c2535118Smrg    input=`pwd`/$input
1103e747e6dSmrg    ;;
1113e747e6dSmrgesac
112c2535118Smrginput_rx=`get_dirname "$input" | quote_for_sed`
113c2535118Smrg
114c2535118Smrg# Since DOS filename conventions don't allow two dots,
115c2535118Smrg# the DOS version of Bison writes out y_tab.c instead of y.tab.c
116c2535118Smrg# and y_tab.h instead of y.tab.h. Test to see if this is the case.
117c2535118Smrgy_tab_nodot=false
118c2535118Smrgif test -f y_tab.c || test -f y_tab.h; then
119c2535118Smrg  y_tab_nodot=true
120c2535118Smrgfi
121c2535118Smrg
122c2535118Smrg# The parser itself, the first file, is the destination of the .y.c
123c2535118Smrg# rule in the Makefile.
124c2535118Smrgparser=$1
125c2535118Smrg
126c2535118Smrg# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
127c2535118Smrg# instance, we rename #include "y.tab.h" into #include "parse.h"
128c2535118Smrg# during the conversion from y.tab.c to parse.c.
129c2535118Smrgsed_fix_filenames=
1303e747e6dSmrg
131c2535118Smrg# Also rename header guards, as Bison 2.7 for instance uses its header
132c2535118Smrg# guard in its implementation file.
133c2535118Smrgsed_fix_header_guards=
134c2535118Smrg
135c2535118Smrgwhile test $# -ne 0; do
136c2535118Smrg  if test x"$1" = x"--"; then
1373e747e6dSmrg    shift
1383e747e6dSmrg    break
1393e747e6dSmrg  fi
140c2535118Smrg  from=$1
141c2535118Smrg  # Handle y_tab.c and y_tab.h output by DOS
142c2535118Smrg  if $y_tab_nodot; then
143c2535118Smrg    case $from in
144c2535118Smrg      "y.tab.c") from=y_tab.c;;
145c2535118Smrg      "y.tab.h") from=y_tab.h;;
146c2535118Smrg    esac
147c2535118Smrg  fi
1483e747e6dSmrg  shift
149c2535118Smrg  to=$1
150c2535118Smrg  shift
151c2535118Smrg  sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
152c2535118Smrg  sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
1533e747e6dSmrgdone
1543e747e6dSmrg
1553e747e6dSmrg# The program to run.
156c2535118Smrgprog=$1
1573e747e6dSmrgshift
1583e747e6dSmrg# Make any relative path in $prog absolute.
159c2535118Smrgcase $prog in
1603e747e6dSmrg  [\\/]* | ?:[\\/]*) ;;
161c2535118Smrg  *[\\/]*) prog=`pwd`/$prog ;;
1623e747e6dSmrgesac
1633e747e6dSmrg
1643e747e6dSmrgdirname=ylwrap$$
165c2535118Smrgdo_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
166c2535118Smrgtrap "ret=129; $do_exit" 1
167c2535118Smrgtrap "ret=130; $do_exit" 2
168c2535118Smrgtrap "ret=141; $do_exit" 13
169c2535118Smrgtrap "ret=143; $do_exit" 15
1703e747e6dSmrgmkdir $dirname || exit 1
1713e747e6dSmrg
1723e747e6dSmrgcd $dirname
1733e747e6dSmrg
1743e747e6dSmrgcase $# in
1753e747e6dSmrg  0) "$prog" "$input" ;;
1763e747e6dSmrg  *) "$prog" "$@" "$input" ;;
1773e747e6dSmrgesac
1783e747e6dSmrgret=$?
1793e747e6dSmrg
1803e747e6dSmrgif test $ret -eq 0; then
181c2535118Smrg  for from in *
182c2535118Smrg  do
183c2535118Smrg    to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
1843e747e6dSmrg    if test -f "$from"; then
1853e747e6dSmrg      # If $2 is an absolute path name, then just use that,
186c2535118Smrg      # otherwise prepend '../'.
187c2535118Smrg      case $to in
188c2535118Smrg        [\\/]* | ?:[\\/]*) target=$to;;
189c2535118Smrg        *) target=../$to;;
1903e747e6dSmrg      esac
1913e747e6dSmrg
192c2535118Smrg      # Do not overwrite unchanged header files to avoid useless
193c2535118Smrg      # recompilations.  Always update the parser itself: it is the
194c2535118Smrg      # destination of the .y.c rule in the Makefile.  Divert the
195c2535118Smrg      # output of all other files to a temporary file so we can
196c2535118Smrg      # compare them to existing versions.
197c2535118Smrg      if test $from != $parser; then
198c2535118Smrg        realtarget=$target
199c2535118Smrg        target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'`
2003e747e6dSmrg      fi
201c2535118Smrg
202c2535118Smrg      # Munge "#line" or "#" directives.  Don't let the resulting
203c2535118Smrg      # debug information point at an absolute srcdir.  Use the real
204c2535118Smrg      # output file name, not yy.lex.c for instance.  Adjust the
205c2535118Smrg      # include guards too.
206c2535118Smrg      sed -e "/^#/!b"                           \
207c2535118Smrg          -e "s|$input_rx|$input_sub_rx|"       \
208c2535118Smrg          -e "$sed_fix_filenames"               \
209c2535118Smrg          -e "$sed_fix_header_guards"           \
210c2535118Smrg        "$from" >"$target" || ret=$?
211c2535118Smrg
212c2535118Smrg      # Check whether files must be updated.
213c2535118Smrg      if test "$from" != "$parser"; then
214c2535118Smrg        if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
215c2535118Smrg          echo "$to is unchanged"
216c2535118Smrg          rm -f "$target"
217c2535118Smrg        else
218c2535118Smrg          echo "updating $to"
2193e747e6dSmrg          mv -f "$target" "$realtarget"
2203e747e6dSmrg        fi
2213e747e6dSmrg      fi
2223e747e6dSmrg    else
223c2535118Smrg      # A missing file is only an error for the parser.  This is a
224c2535118Smrg      # blatant hack to let us support using "yacc -d".  If -d is not
225c2535118Smrg      # specified, don't fail when the header file is "missing".
226c2535118Smrg      if test "$from" = "$parser"; then
2273e747e6dSmrg        ret=1
2283e747e6dSmrg      fi
2293e747e6dSmrg    fi
2303e747e6dSmrg  done
2313e747e6dSmrgfi
2323e747e6dSmrg
2333e747e6dSmrg# Remove the directory.
2343e747e6dSmrgcd ..
2353e747e6dSmrgrm -rf $dirname
2363e747e6dSmrg
2373e747e6dSmrgexit $ret
2383e747e6dSmrg
2393e747e6dSmrg# Local Variables:
2403e747e6dSmrg# mode: shell-script
2413e747e6dSmrg# sh-indentation: 2
2426d8e82c3Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
2433e747e6dSmrg# time-stamp-start: "scriptversion="
2443e747e6dSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
2456d8e82c3Smrg# time-stamp-time-zone: "UTC0"
2467a2631fcSmrg# time-stamp-end: "; # UTC"
2473e747e6dSmrg# End:
248