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