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