xref: /netbsd-src/external/bsd/am-utils/dist/ylwrap (revision 8bae5d409deb915cf7c8f0539fae22ff2cb8a313)
1a53f50b9Schristos#! /bin/sh
2a53f50b9Schristos# ylwrap - wrapper for lex/yacc invocations.
3a53f50b9Schristos
4*8bae5d40Schristosscriptversion=2013-01-12.17; # UTC
5a53f50b9Schristos
6*8bae5d40Schristos# Copyright (C) 1996-2013 Free Software Foundation, Inc.
7a53f50b9Schristos#
8a53f50b9Schristos# Written by Tom Tromey <tromey@cygnus.com>.
9a53f50b9Schristos#
10a53f50b9Schristos# This program is free software; you can redistribute it and/or modify
11a53f50b9Schristos# it under the terms of the GNU General Public License as published by
12a53f50b9Schristos# the Free Software Foundation; either version 2, or (at your option)
13a53f50b9Schristos# any later version.
14a53f50b9Schristos#
15a53f50b9Schristos# This program is distributed in the hope that it will be useful,
16a53f50b9Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
17a53f50b9Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18a53f50b9Schristos# GNU General Public License for more details.
19a53f50b9Schristos#
20a53f50b9Schristos# You should have received a copy of the GNU General Public License
21*8bae5d40Schristos# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22a53f50b9Schristos
23a53f50b9Schristos# As a special exception to the GNU General Public License, if you
24a53f50b9Schristos# distribute this file as part of a program that contains a
25a53f50b9Schristos# configuration script generated by Autoconf, you may include it under
26a53f50b9Schristos# the same distribution terms that you use for the rest of that program.
27a53f50b9Schristos
28a53f50b9Schristos# This file is maintained in Automake, please report
29a53f50b9Schristos# bugs to <bug-automake@gnu.org> or send patches to
30a53f50b9Schristos# <automake-patches@gnu.org>.
31a53f50b9Schristos
32*8bae5d40Schristosget_dirname ()
33*8bae5d40Schristos{
34*8bae5d40Schristos  case $1 in
35*8bae5d40Schristos    */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
36*8bae5d40Schristos    # Otherwise,  we want the empty string (not ".").
37*8bae5d40Schristos  esac
38*8bae5d40Schristos}
39*8bae5d40Schristos
40*8bae5d40Schristos# guard FILE
41*8bae5d40Schristos# ----------
42*8bae5d40Schristos# The CPP macro used to guard inclusion of FILE.
43*8bae5d40Schristosguard ()
44*8bae5d40Schristos{
45*8bae5d40Schristos  printf '%s\n' "$1"                                                    \
46*8bae5d40Schristos    | sed                                                               \
47*8bae5d40Schristos        -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'   \
48*8bae5d40Schristos        -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'                        \
49*8bae5d40Schristos        -e 's/__*/_/g'
50*8bae5d40Schristos}
51*8bae5d40Schristos
52*8bae5d40Schristos# quote_for_sed [STRING]
53*8bae5d40Schristos# ----------------------
54*8bae5d40Schristos# Return STRING (or stdin) quoted to be used as a sed pattern.
55*8bae5d40Schristosquote_for_sed ()
56*8bae5d40Schristos{
57*8bae5d40Schristos  case $# in
58*8bae5d40Schristos    0) cat;;
59*8bae5d40Schristos    1) printf '%s\n' "$1";;
60*8bae5d40Schristos  esac \
61*8bae5d40Schristos    | sed -e 's|[][\\.*]|\\&|g'
62*8bae5d40Schristos}
63*8bae5d40Schristos
64a53f50b9Schristoscase "$1" in
65a53f50b9Schristos  '')
66*8bae5d40Schristos    echo "$0: No files given.  Try '$0 --help' for more information." 1>&2
67a53f50b9Schristos    exit 1
68a53f50b9Schristos    ;;
69a53f50b9Schristos  --basedir)
70a53f50b9Schristos    basedir=$2
71a53f50b9Schristos    shift 2
72a53f50b9Schristos    ;;
73a53f50b9Schristos  -h|--h*)
74a53f50b9Schristos    cat <<\EOF
75a53f50b9SchristosUsage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
76a53f50b9Schristos
77a53f50b9SchristosWrapper for lex/yacc invocations, renaming files as desired.
78a53f50b9Schristos
79a53f50b9Schristos  INPUT is the input file
80a53f50b9Schristos  OUTPUT is one file PROG generates
81a53f50b9Schristos  DESIRED is the file we actually want instead of OUTPUT
82a53f50b9Schristos  PROGRAM is program to run
83a53f50b9Schristos  ARGS are passed to PROG
84a53f50b9Schristos
85a53f50b9SchristosAny number of OUTPUT,DESIRED pairs may be used.
86a53f50b9Schristos
87a53f50b9SchristosReport bugs to <bug-automake@gnu.org>.
88a53f50b9SchristosEOF
89a53f50b9Schristos    exit $?
90a53f50b9Schristos    ;;
91a53f50b9Schristos  -v|--v*)
92a53f50b9Schristos    echo "ylwrap $scriptversion"
93a53f50b9Schristos    exit $?
94a53f50b9Schristos    ;;
95a53f50b9Schristosesac
96a53f50b9Schristos
97a53f50b9Schristos
98a53f50b9Schristos# The input.
99*8bae5d40Schristosinput=$1
100a53f50b9Schristosshift
101*8bae5d40Schristos# We'll later need for a correct munging of "#line" directives.
102*8bae5d40Schristosinput_sub_rx=`get_dirname "$input" | quote_for_sed`
103*8bae5d40Schristoscase $input in
104a53f50b9Schristos  [\\/]* | ?:[\\/]*)
105a53f50b9Schristos    # Absolute path; do nothing.
106a53f50b9Schristos    ;;
107a53f50b9Schristos  *)
108a53f50b9Schristos    # Relative path.  Make it absolute.
109*8bae5d40Schristos    input=`pwd`/$input
110a53f50b9Schristos    ;;
111a53f50b9Schristosesac
112*8bae5d40Schristosinput_rx=`get_dirname "$input" | quote_for_sed`
113a53f50b9Schristos
114*8bae5d40Schristos# Since DOS filename conventions don't allow two dots,
115*8bae5d40Schristos# the DOS version of Bison writes out y_tab.c instead of y.tab.c
116*8bae5d40Schristos# and y_tab.h instead of y.tab.h. Test to see if this is the case.
117*8bae5d40Schristosy_tab_nodot=false
118*8bae5d40Schristosif test -f y_tab.c || test -f y_tab.h; then
119*8bae5d40Schristos  y_tab_nodot=true
120*8bae5d40Schristosfi
121*8bae5d40Schristos
122*8bae5d40Schristos# The parser itself, the first file, is the destination of the .y.c
123*8bae5d40Schristos# rule in the Makefile.
124*8bae5d40Schristosparser=$1
125*8bae5d40Schristos
126*8bae5d40Schristos# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
127*8bae5d40Schristos# instance, we rename #include "y.tab.h" into #include "parse.h"
128*8bae5d40Schristos# during the conversion from y.tab.c to parse.c.
129*8bae5d40Schristossed_fix_filenames=
130*8bae5d40Schristos
131*8bae5d40Schristos# Also rename header guards, as Bison 2.7 for instance uses its header
132*8bae5d40Schristos# guard in its implementation file.
133*8bae5d40Schristossed_fix_header_guards=
134*8bae5d40Schristos
135*8bae5d40Schristoswhile test $# -ne 0; do
136*8bae5d40Schristos  if test x"$1" = x"--"; then
137a53f50b9Schristos    shift
138a53f50b9Schristos    break
139a53f50b9Schristos  fi
140*8bae5d40Schristos  from=$1
141*8bae5d40Schristos  # Handle y_tab.c and y_tab.h output by DOS
142*8bae5d40Schristos  if $y_tab_nodot; then
143*8bae5d40Schristos    case $from in
144*8bae5d40Schristos      "y.tab.c") from=y_tab.c;;
145*8bae5d40Schristos      "y.tab.h") from=y_tab.h;;
146*8bae5d40Schristos    esac
147*8bae5d40Schristos  fi
148a53f50b9Schristos  shift
149*8bae5d40Schristos  to=$1
150*8bae5d40Schristos  shift
151*8bae5d40Schristos  sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
152*8bae5d40Schristos  sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
153a53f50b9Schristosdone
154a53f50b9Schristos
155a53f50b9Schristos# The program to run.
156*8bae5d40Schristosprog=$1
157a53f50b9Schristosshift
158a53f50b9Schristos# Make any relative path in $prog absolute.
159*8bae5d40Schristoscase $prog in
160a53f50b9Schristos  [\\/]* | ?:[\\/]*) ;;
161*8bae5d40Schristos  *[\\/]*) prog=`pwd`/$prog ;;
162a53f50b9Schristosesac
163a53f50b9Schristos
164*8bae5d40Schristosprefix=`echo $input | sed \
165*8bae5d40Schristos	-e 's,^.*/,,g' \
166*8bae5d40Schristos	-e 's/_gram.[yl]$/_/g' \
167*8bae5d40Schristos	-e 's/_lex.[yl]$/_/g' \
168*8bae5d40Schristos	-e 's/_parse.[yl]$/_/g' \
169*8bae5d40Schristos	-e 's/_tok.[yl]$/_/g'`
170*8bae5d40Schristos
171*8bae5d40Schristoscase "$prog" in
172*8bae5d40Schristos*lex)
173*8bae5d40Schristos	flags="-P${prefix}"
174*8bae5d40Schristos	out="mv lex.$prefix.c lex.yy.c"
175*8bae5d40Schristos	;;
176*8bae5d40Schristosyacc|bison)
177*8bae5d40Schristos	flags="-p $prefix";;
178*8bae5d40Schristosesac
179*8bae5d40Schristos
180a53f50b9Schristosdirname=ylwrap$$
181*8bae5d40Schristosdo_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
182*8bae5d40Schristostrap "ret=129; $do_exit" 1
183*8bae5d40Schristostrap "ret=130; $do_exit" 2
184*8bae5d40Schristostrap "ret=141; $do_exit" 13
185*8bae5d40Schristostrap "ret=143; $do_exit" 15
186a53f50b9Schristosmkdir $dirname || exit 1
187a53f50b9Schristos
188a53f50b9Schristoscd $dirname
189a53f50b9Schristos
190a53f50b9Schristoscase $# in
191*8bae5d40Schristos  0) "$prog" $flags "$input" ;;
192*8bae5d40Schristos  *) "$prog" $flags "$@" "$input" ;;
193a53f50b9Schristosesac
194a53f50b9Schristosret=$?
195*8bae5d40Schristosif [ -n "$out" ]; then
196*8bae5d40Schristos	eval $out
197*8bae5d40Schristosfi
198a53f50b9Schristos
199a53f50b9Schristosif test $ret -eq 0; then
200*8bae5d40Schristos  for from in *
201*8bae5d40Schristos  do
202*8bae5d40Schristos    to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
203a53f50b9Schristos    if test -f "$from"; then
204a53f50b9Schristos      # If $2 is an absolute path name, then just use that,
205*8bae5d40Schristos      # otherwise prepend '../'.
206*8bae5d40Schristos      case $to in
207*8bae5d40Schristos        [\\/]* | ?:[\\/]*) target=$to;;
208*8bae5d40Schristos        *) target=../$to;;
209a53f50b9Schristos      esac
210a53f50b9Schristos
211*8bae5d40Schristos      # Do not overwrite unchanged header files to avoid useless
212*8bae5d40Schristos      # recompilations.  Always update the parser itself: it is the
213*8bae5d40Schristos      # destination of the .y.c rule in the Makefile.  Divert the
214*8bae5d40Schristos      # output of all other files to a temporary file so we can
215*8bae5d40Schristos      # compare them to existing versions.
216*8bae5d40Schristos      if test $from != $parser; then
217*8bae5d40Schristos        realtarget=$target
218*8bae5d40Schristos        target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'`
219a53f50b9Schristos      fi
2204bcd344eSchristos
221*8bae5d40Schristos      # Munge "#line" or "#" directives.  Don't let the resulting
222*8bae5d40Schristos      # debug information point at an absolute srcdir.  Use the real
223*8bae5d40Schristos      # output file name, not yy.lex.c for instance.  Adjust the
224*8bae5d40Schristos      # include guards too.
225*8bae5d40Schristos      sed -e "/^#/!b"                           \
226*8bae5d40Schristos          -e "s|$input_rx|$input_sub_rx|"       \
227*8bae5d40Schristos          -e "$sed_fix_filenames"               \
228*8bae5d40Schristos          -e "$sed_fix_header_guards"           \
229*8bae5d40Schristos        "$from" >"$target" || ret=$?
230a53f50b9Schristos
231*8bae5d40Schristos      # Check whether files must be updated.
232*8bae5d40Schristos      if test "$from" != "$parser"; then
233a53f50b9Schristos        if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
234*8bae5d40Schristos          echo "$to is unchanged"
235a53f50b9Schristos          rm -f "$target"
236a53f50b9Schristos        else
237*8bae5d40Schristos          echo "updating $to"
238a53f50b9Schristos          mv -f "$target" "$realtarget"
239a53f50b9Schristos        fi
240a53f50b9Schristos      fi
241a53f50b9Schristos    else
242*8bae5d40Schristos      # A missing file is only an error for the parser.  This is a
243*8bae5d40Schristos      # blatant hack to let us support using "yacc -d".  If -d is not
244*8bae5d40Schristos      # specified, don't fail when the header file is "missing".
245*8bae5d40Schristos      if test "$from" = "$parser"; then
246a53f50b9Schristos        ret=1
247a53f50b9Schristos      fi
248a53f50b9Schristos    fi
249a53f50b9Schristos  done
250a53f50b9Schristosfi
251a53f50b9Schristos
252a53f50b9Schristos# Remove the directory.
253a53f50b9Schristoscd ..
254a53f50b9Schristosrm -rf $dirname
255a53f50b9Schristos
256a53f50b9Schristosexit $ret
257a53f50b9Schristos
258a53f50b9Schristos# Local Variables:
259a53f50b9Schristos# mode: shell-script
260a53f50b9Schristos# sh-indentation: 2
261a53f50b9Schristos# eval: (add-hook 'write-file-hooks 'time-stamp)
262a53f50b9Schristos# time-stamp-start: "scriptversion="
263a53f50b9Schristos# time-stamp-format: "%:y-%02m-%02d.%02H"
264*8bae5d40Schristos# time-stamp-time-zone: "UTC"
265*8bae5d40Schristos# time-stamp-end: "; # UTC"
266a53f50b9Schristos# End:
267