1db17cd6dSmrg#! /bin/sh
2db17cd6dSmrg# ylwrap - wrapper for lex/yacc invocations.
3db17cd6dSmrg
48bfe6addSmrgscriptversion=2024-06-19.01; # UTC
5db17cd6dSmrg
68bfe6addSmrg# Copyright (C) 1996-2024 Free Software Foundation, Inc.
7db17cd6dSmrg#
8db17cd6dSmrg# Written by Tom Tromey <tromey@cygnus.com>.
9db17cd6dSmrg#
10db17cd6dSmrg# This program is free software; you can redistribute it and/or modify
11db17cd6dSmrg# it under the terms of the GNU General Public License as published by
12db17cd6dSmrg# the Free Software Foundation; either version 2, or (at your option)
13db17cd6dSmrg# any later version.
14db17cd6dSmrg#
15db17cd6dSmrg# This program is distributed in the hope that it will be useful,
16db17cd6dSmrg# but WITHOUT ANY WARRANTY; without even the implied warranty of
17db17cd6dSmrg# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18db17cd6dSmrg# GNU General Public License for more details.
19db17cd6dSmrg#
20db17cd6dSmrg# You should have received a copy of the GNU General Public License
21a67f45c3Smrg# along with this program.  If not, see <https://www.gnu.org/licenses/>.
22db17cd6dSmrg
23db17cd6dSmrg# As a special exception to the GNU General Public License, if you
24db17cd6dSmrg# distribute this file as part of a program that contains a
25db17cd6dSmrg# configuration script generated by Autoconf, you may include it under
26db17cd6dSmrg# the same distribution terms that you use for the rest of that program.
27db17cd6dSmrg
28db17cd6dSmrg# This file is maintained in Automake, please report
29db17cd6dSmrg# bugs to <bug-automake@gnu.org> or send patches to
30db17cd6dSmrg# <automake-patches@gnu.org>.
31db17cd6dSmrg
329ff100acSmrgget_dirname ()
339ff100acSmrg{
349ff100acSmrg  case $1 in
359ff100acSmrg    */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
369ff100acSmrg    # Otherwise,  we want the empty string (not ".").
379ff100acSmrg  esac
389ff100acSmrg}
399ff100acSmrg
409ff100acSmrg# guard FILE
419ff100acSmrg# ----------
429ff100acSmrg# The CPP macro used to guard inclusion of FILE.
439ff100acSmrgguard ()
449ff100acSmrg{
459ff100acSmrg  printf '%s\n' "$1"                                                    \
469ff100acSmrg    | sed                                                               \
479ff100acSmrg        -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'   \
489ff100acSmrg        -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'                        \
499ff100acSmrg        -e 's/__*/_/g'
509ff100acSmrg}
519ff100acSmrg
529ff100acSmrg# quote_for_sed [STRING]
539ff100acSmrg# ----------------------
549ff100acSmrg# Return STRING (or stdin) quoted to be used as a sed pattern.
559ff100acSmrgquote_for_sed ()
569ff100acSmrg{
579ff100acSmrg  case $# in
589ff100acSmrg    0) cat;;
599ff100acSmrg    1) printf '%s\n' "$1";;
609ff100acSmrg  esac \
619ff100acSmrg    | sed -e 's|[][\\.*]|\\&|g'
629ff100acSmrg}
639ff100acSmrg
64db17cd6dSmrgcase "$1" in
65db17cd6dSmrg  '')
669ff100acSmrg    echo "$0: No files given.  Try '$0 --help' for more information." 1>&2
67db17cd6dSmrg    exit 1
68db17cd6dSmrg    ;;
69db17cd6dSmrg  -h|--h*)
70db17cd6dSmrg    cat <<\EOF
71db17cd6dSmrgUsage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
72db17cd6dSmrg
73db17cd6dSmrgWrapper for lex/yacc invocations, renaming files as desired.
74db17cd6dSmrg
75db17cd6dSmrg  INPUT is the input file
76db17cd6dSmrg  OUTPUT is one file PROG generates
77db17cd6dSmrg  DESIRED is the file we actually want instead of OUTPUT
78db17cd6dSmrg  PROGRAM is program to run
79db17cd6dSmrg  ARGS are passed to PROG
80db17cd6dSmrg
81db17cd6dSmrgAny number of OUTPUT,DESIRED pairs may be used.
82db17cd6dSmrg
83db17cd6dSmrgReport bugs to <bug-automake@gnu.org>.
848bfe6addSmrgGNU Automake home page: <https://www.gnu.org/software/automake/>.
858bfe6addSmrgGeneral help using GNU software: <https://www.gnu.org/gethelp/>.
86db17cd6dSmrgEOF
87db17cd6dSmrg    exit $?
88db17cd6dSmrg    ;;
89db17cd6dSmrg  -v|--v*)
908bfe6addSmrg    echo "ylwrap (GNU Automake) $scriptversion"
91db17cd6dSmrg    exit $?
92db17cd6dSmrg    ;;
93db17cd6dSmrgesac
94db17cd6dSmrg
95db17cd6dSmrg
96db17cd6dSmrg# The input.
979ff100acSmrginput=$1
98db17cd6dSmrgshift
999ff100acSmrg# We'll later need for a correct munging of "#line" directives.
1009ff100acSmrginput_sub_rx=`get_dirname "$input" | quote_for_sed`
1019ff100acSmrgcase $input in
102db17cd6dSmrg  [\\/]* | ?:[\\/]*)
103db17cd6dSmrg    # Absolute path; do nothing.
104db17cd6dSmrg    ;;
105db17cd6dSmrg  *)
106db17cd6dSmrg    # Relative path.  Make it absolute.
1079ff100acSmrg    input=`pwd`/$input
108db17cd6dSmrg    ;;
109db17cd6dSmrgesac
1109ff100acSmrginput_rx=`get_dirname "$input" | quote_for_sed`
1119ff100acSmrg
1129ff100acSmrg# Since DOS filename conventions don't allow two dots,
1139ff100acSmrg# the DOS version of Bison writes out y_tab.c instead of y.tab.c
1149ff100acSmrg# and y_tab.h instead of y.tab.h. Test to see if this is the case.
1159ff100acSmrgy_tab_nodot=false
1169ff100acSmrgif test -f y_tab.c || test -f y_tab.h; then
1179ff100acSmrg  y_tab_nodot=true
1189ff100acSmrgfi
1199ff100acSmrg
1209ff100acSmrg# The parser itself, the first file, is the destination of the .y.c
1219ff100acSmrg# rule in the Makefile.
1229ff100acSmrgparser=$1
1239ff100acSmrg
1249ff100acSmrg# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
1259ff100acSmrg# instance, we rename #include "y.tab.h" into #include "parse.h"
1269ff100acSmrg# during the conversion from y.tab.c to parse.c.
1279ff100acSmrgsed_fix_filenames=
128db17cd6dSmrg
1299ff100acSmrg# Also rename header guards, as Bison 2.7 for instance uses its header
1309ff100acSmrg# guard in its implementation file.
1319ff100acSmrgsed_fix_header_guards=
1329ff100acSmrg
1339ff100acSmrgwhile test $# -ne 0; do
1349ff100acSmrg  if test x"$1" = x"--"; then
135db17cd6dSmrg    shift
136db17cd6dSmrg    break
137db17cd6dSmrg  fi
1389ff100acSmrg  from=$1
1399ff100acSmrg  # Handle y_tab.c and y_tab.h output by DOS
1409ff100acSmrg  if $y_tab_nodot; then
1419ff100acSmrg    case $from in
1429ff100acSmrg      "y.tab.c") from=y_tab.c;;
1439ff100acSmrg      "y.tab.h") from=y_tab.h;;
1449ff100acSmrg    esac
1459ff100acSmrg  fi
146db17cd6dSmrg  shift
1479ff100acSmrg  to=$1
1489ff100acSmrg  shift
1499ff100acSmrg  sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
1509ff100acSmrg  sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
151db17cd6dSmrgdone
152db17cd6dSmrg
153db17cd6dSmrg# The program to run.
1549ff100acSmrgprog=$1
155db17cd6dSmrgshift
156db17cd6dSmrg# Make any relative path in $prog absolute.
1579ff100acSmrgcase $prog in
158db17cd6dSmrg  [\\/]* | ?:[\\/]*) ;;
1599ff100acSmrg  *[\\/]*) prog=`pwd`/$prog ;;
160db17cd6dSmrgesac
161db17cd6dSmrg
162db17cd6dSmrgdirname=ylwrap$$
1639ff100acSmrgdo_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
1649ff100acSmrgtrap "ret=129; $do_exit" 1
1659ff100acSmrgtrap "ret=130; $do_exit" 2
1669ff100acSmrgtrap "ret=141; $do_exit" 13
1679ff100acSmrgtrap "ret=143; $do_exit" 15
168db17cd6dSmrgmkdir $dirname || exit 1
169db17cd6dSmrg
170db17cd6dSmrgcd $dirname
171db17cd6dSmrg
172db17cd6dSmrgcase $# in
173db17cd6dSmrg  0) "$prog" "$input" ;;
174db17cd6dSmrg  *) "$prog" "$@" "$input" ;;
175db17cd6dSmrgesac
176db17cd6dSmrgret=$?
177db17cd6dSmrg
178db17cd6dSmrgif test $ret -eq 0; then
1799ff100acSmrg  for from in *
1809ff100acSmrg  do
1819ff100acSmrg    to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
182db17cd6dSmrg    if test -f "$from"; then
183db17cd6dSmrg      # If $2 is an absolute path name, then just use that,
1849ff100acSmrg      # otherwise prepend '../'.
1859ff100acSmrg      case $to in
1869ff100acSmrg        [\\/]* | ?:[\\/]*) target=$to;;
1879ff100acSmrg        *) target=../$to;;
188db17cd6dSmrg      esac
189db17cd6dSmrg
1909ff100acSmrg      # Do not overwrite unchanged header files to avoid useless
1919ff100acSmrg      # recompilations.  Always update the parser itself: it is the
1929ff100acSmrg      # destination of the .y.c rule in the Makefile.  Divert the
1939ff100acSmrg      # output of all other files to a temporary file so we can
1949ff100acSmrg      # compare them to existing versions.
1959ff100acSmrg      if test $from != $parser; then
1969ff100acSmrg        realtarget=$target
1979ff100acSmrg        target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'`
198db17cd6dSmrg      fi
1999ff100acSmrg
2009ff100acSmrg      # Munge "#line" or "#" directives.  Don't let the resulting
2019ff100acSmrg      # debug information point at an absolute srcdir.  Use the real
2029ff100acSmrg      # output file name, not yy.lex.c for instance.  Adjust the
2039ff100acSmrg      # include guards too.
2049ff100acSmrg      sed -e "/^#/!b"                           \
2059ff100acSmrg          -e "s|$input_rx|$input_sub_rx|"       \
2069ff100acSmrg          -e "$sed_fix_filenames"               \
2079ff100acSmrg          -e "$sed_fix_header_guards"           \
2089ff100acSmrg        "$from" >"$target" || ret=$?
2099ff100acSmrg
2109ff100acSmrg      # Check whether files must be updated.
2119ff100acSmrg      if test "$from" != "$parser"; then
2129ff100acSmrg        if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
2139ff100acSmrg          echo "$to is unchanged"
2149ff100acSmrg          rm -f "$target"
2159ff100acSmrg        else
2169ff100acSmrg          echo "updating $to"
217db17cd6dSmrg          mv -f "$target" "$realtarget"
218db17cd6dSmrg        fi
219db17cd6dSmrg      fi
220db17cd6dSmrg    else
2219ff100acSmrg      # A missing file is only an error for the parser.  This is a
2229ff100acSmrg      # blatant hack to let us support using "yacc -d".  If -d is not
2239ff100acSmrg      # specified, don't fail when the header file is "missing".
2249ff100acSmrg      if test "$from" = "$parser"; then
225db17cd6dSmrg        ret=1
226db17cd6dSmrg      fi
227db17cd6dSmrg    fi
228db17cd6dSmrg  done
229db17cd6dSmrgfi
230db17cd6dSmrg
231db17cd6dSmrg# Remove the directory.
232db17cd6dSmrgcd ..
233db17cd6dSmrgrm -rf $dirname
234db17cd6dSmrg
235db17cd6dSmrgexit $ret
236db17cd6dSmrg
237db17cd6dSmrg# Local Variables:
238db17cd6dSmrg# mode: shell-script
239db17cd6dSmrg# sh-indentation: 2
240a67f45c3Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
241db17cd6dSmrg# time-stamp-start: "scriptversion="
242db17cd6dSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
243a67f45c3Smrg# time-stamp-time-zone: "UTC0"
244db17cd6dSmrg# time-stamp-end: "; # UTC"
245db17cd6dSmrg# End:
246