#! /bin/sh # Rename yy.* identifiers to avoid name clashes. This file is part of Grecs. # Copyright (C) 2011-2012 Sergey Poznyakoff # # Grecs is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # Grecs is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Grecs. If not, see . # Usage: yyrename [-f "OUTFILE [OUTFILE...]"] COMMAND INFILE # Makefile.am: # LEXCOMPILE = yyrename -f $(LEX_OUTPUT_ROOT).c \ # '$(LEX) $(LFLAGS) $(AM_LFLAGS)' # YACCCOMPILE = yyrename '$(YACC) $(YFLAGS) $(AM_YFLAGS)' # # This script runs COMMAND with INFILE as its argument and scans # OUTFILEs for identifiers starting with 'yy'. It then renames these # identifiers by replacing 'yy' with the selected prefix. # # The prefix is looked up in the file yytrans, located in the INFILE's # directory. If this file does not exist, the prefix is constructed # by concatenating the string 'grecs_' and the ``root name''. The root # name is built by removing '-lex.l' or '-gram.y' from the base name. # If the latter does not end in any of these, the root name # is constructed by removing the suffix from the base name. # # The yytrans file is a line-oriented lookup table. Empty lines are # ignored, usual UNIX comment lines are honored. The remaining lines # shall consist of two words separated by any amount of whitespace. # The first word is a look-up key, the second one provides a translation # (yy replacement) for that key. # # Two look-ups are tried: first the base name and then the root name. # If both result in a non-empty replacement, the former is preferred # over the latter. # # The -f option supplies a list of output file names generated by COMMAND. # If not supplied, the following defaults are used: y.tab.c and y.tab.h, if # INFILE ends in '.y', and yy.lex.c, if it ends in '.l'. If INFILE does not # end in any of these suffixes, error is reported. # # BUGS: Any occurrence of 'yy' is replaced, not only 'yy' prefixes. # case $1 in -f) files=$2 shift shift esac if test $# -ne 2; then echo >&2 "usage: yyrename [-f "OUTFILE [OUTFILE...]"] COMMAND INFILE" exit 1 fi base=`expr "$2" : '.*/\(.*\)\.[ly]'` dir=`dirname "$2"` case $2 in *.y) test -z "$files" && files="y.tab.c y.tab.h" root=`expr "$2" : '.*/\(.*\)-gram\.y'`;; *.l) test -z "$files" && files=lex.yy.c root=`expr "$2" : '.*/\(.*\)-lex\.l'`;; *) if test -z "$files"; then echo >&2 "$0: suffix unknown, files must be given (use -f)" exit 1 fi root=$base esac if test -f $dir/yytrans; then pfx=`awk ' { sub(/#.*$/,"") } NF == 2 && $1=="'$base'" { exact=$2 } NF == 2 && $1=="'$root'" { root=$2 } { next } END { print exact ? exact : root ? root : "" }' $dir/yytrans` else pfx= fi if test -z "$pfx"; then pfx=grecs_`echo $root | tr .- __` fi eval $* || exit $? for file in $files do mv $file ${file}.tmp sed "/^#line/b;/^# *[0-9]/b;s/yy/$pfx/g" ${file}.tmp > $file done