Commit f0ce61e5 authored by Akim Demaille's avatar Akim Demaille Committed by Roland Levillain
Browse files

maint: upgrade bison++.



	* build-aux/bin/fuse-switch: New.
	* build-aux/bin/bison++.in: Upgrade: use fuse-switch (does not
	make any difference in the case of tc), support more options,
	support verbosity levels.
	* src/parse/Makefile.am: Fix the bison++ regeneration.
	(BISONXXFLAGS, AM_BISONFLAGS): New.
	(FROM_PARSETIGER_YY): Rename as...
	(SOURCES_PARSETIGER_YY): this, for clarity.
Signed-off-by: Roland Levillain's avatarRoland Levillain <roland@lrde.epita.fr>
parent a3d879cd
2012-02-20 Akim Demaille <demaille@gostai.com>
maint: upgrade bison++.
* build-aux/bin/fuse-switch: New.
* build-aux/bin/bison++.in: Upgrade: use fuse-switch (does not
make any difference in the case of tc), support more options,
support verbosity levels.
* src/parse/Makefile.am: Fix the bison++ regeneration.
(BISONXXFLAGS, AM_BISONFLAGS): New.
(FROM_PARSETIGER_YY): Rename as...
(SOURCES_PARSETIGER_YY): this, for clarity.
2012-02-17 Akim Demaille <demaille@gostai.com>
move-if-change: in colors (no 3d available).
......
#! /bin/sh
set -x
# Exit status.
status=0
# Any tool failure is a failure of the script.
set -e
: ${BISON=@BISON@}
: ${BISON='@BISON@'}
stderr ()
{
local i
for i
do
echo "$i"
done | sed >&2 -e "s/^/$me: /"
}
verbose ()
{
if "$verbose"; then
stderr "$@"
fi
}
fatal ()
{
stderr "$@"
exit 1
}
usage ()
{
cat <<EOF
usage: bison++ OPTIONS... -- INPUT OUTPUT BISON-OPTIONS
# bison++ INPUT OUTPUT OPTIONS
# ----------------------------
Options:
-h, --help display this message and exit successfully
--location-dir=DIR where to install position.hh and location.hh.
E.g., "\$(top_srcdir)/include/foo"
--location-prefix=DIR where #include must look for these headers.
E.g., "foo"
--verbose display diffs
EOF
exit 0
}
me=$(basename $0)
move_if_change='@abs_srcdir@/move-if-change'
fuse_switch='@abs_srcdir@/fuse-switch'
move_if_change='@abs_srcdir@/move-if-change --color'
verbose=false
## ---------------------- ##
## Command line parsing. ##
## ---------------------- ##
get_options ()
{
while test $# != 0
do
# Handle --option=value by splitting apart and putting back on argv.
case $1 in
(--*=*)
opt=$(echo "$1" | sed -e 's/=.*//')
val=$(echo "$1" | sed -e 's/[^=]*=//')
shift
set dummy "$opt" "$val" ${1+"$@"}; shift
;;
esac
case $1 in
(-h | --help ) usage;;
(--location-dir) shift; location_dir=$1;;
(--location-prefix) shift; location_prefix=$1/;;
(--verbose) verbose=:
move_if_change="$move_if_change --verbose";;
(--) shift; break;;
(*) fatal "invalid argument: $1";;
esac
shift
done
input=$1
shift
output=$1
shift
bisonflags="$@"
}
## ------ ##
## Main. ##
## ------ ##
get_options "$@"
input=$1
input_base=$(basename "$input")
shift
output=$1
input_dir=$(dirname "$input")
output_base=$(basename "$output")
output_base_noext=$(echo "$output_base" | sed -e 's/\.[^.]*//')
output_dir=$(dirname "$output")
shift
options="$@"
: ${location_dir=$output_dir}
# The namespace we are in.
# FIXME: We need $srcdir to be able to compute it.
namespace=parse
if $BISON --xml --version >/dev/null 2>&1; then
options="$options --xml"
bisonflags="$bisonflags --xml"
fi
# Alexandre Duret-Lutz also notes that in VPATH-builds $(srcdir) can
# be an absolute path depending on how ./configure is called ...
# In that case
......@@ -48,7 +131,7 @@ mkdir $tmp
cp $input $tmp
cd $tmp
set +e
$BISON $options $input_base -o $output_base
$BISON $bisonflags $input_base -o $output_base
status=$?
set -e
......@@ -58,71 +141,157 @@ set -e
# Fixes in place.
fix_bison_output ()
{
# Fix doxygen tags.
perl -pi -e "s|\Q\\file $base\E\b|\\\\file parse/$base|g;" "$1"
local file="$1"
local base
base=$(basename "$file")
local base_noext
base_noext=$(echo "$file" | sed -e 's/\..*//')
perl -pi -e "
# Fix doxygen tags.
s|\Q\\file $base\E\b|\\\\file $namespace/$base|g;
# Fix sync lines for composite paths.
s|(^#line.*)$base_noext|\$1$input_dir/$base_noext|g
if '$input_dir' ne '$output_dir';
# In case position.hh and location.hh were moved.
s{include \"(position.hh|location.hh)\"}
{include <$location_prefix\$1>}g
if '$location_prefix' ne '';
# Kill trailing blanks.
s/[ \t]+\$//;
" "$1"
# Fuse the switches of the parser.
case $file in
(*.cc) $fuse_switch $file
# diff -uw $file.bak $file || true
;;
esac
}
# compile_xml_file XML XSL OUT-EXT
# --------------------------------
# By transforming XML = FILE.xml with XSL.xsl, create FILE.OUT-EXT if needed.
# "Needed" means FILE.OUT-EXT does not exist, or XML was updated.
compile_xml_file ()
{
local xml="$1"
local xsl="$2.xsl"
local out
out=$(basename "$xml" ".xml").$3
# "cmp NON-EXISTENT FILE" does what we want: fail.
if ! cmp -s "$xml" "$(out "$xml")" \
|| test ! -f "$(out "$out")"; then
local compile="xsltproc $($BISON --print-datadir)/xslt/$xsl"
if ! $compile "$xml" >"$(tmp "$out")"; then
stderr "cannot convert $xml report to $out"
# Produce a stub for the HTML for sake of the Makefile.
cat >"$(tmp "$out")" <<EOF
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Cannot run xsltproc</title>
</head>
<body>
<p>Cannot run xsltproc</p>
</body>
</html>
EOF
fi
install "$out"
fi
}
# out FILE
# --------
# Return path name of FILE once installed in its destination directory.
out ()
{
local f
f=$(basename "$1")
case $f in
(position.hh|location.hh) echo "$location_dir/$f";;
(*) echo "$output_dir/$f";;
esac
}
# out FILE
# --------
# Return path name of FILE in the tmp directory.
tmp ()
{
echo "$tmp/$(basename "$1")"
}
# install FILE
# ------------
# Install FILE in its destination directory.
install ()
{
local dest
dest=$(out "$1")
local dir
dir=$(dirname "$dest")
mkdir -p "$dir" ||
fatal "cannot create $dir"
$move_if_change "$(tmp "$1")" "$dest"
}
# Go back to where we were and use relative paths instead of using
# absolute file names. The messages look nicer.
cd ..
case $status in
0)
for file in $tmp/*
do
base=$(basename $file)
base_noext=$(echo "$base" | sed -e 's/\.[^.]*//')
out=$output_dir/$base
case $base in
$input_base)
# Leave it here.
;;
*.xml)
# Computing the HTML is slow. Do it when the XML changed.
fix_bison_output "$file"
if ! test -r "$out" || ! cmp -s "$file" "$out"; then
xml2html="xsltproc $($BISON --print-datadir)/xslt/xml2xhtml.xsl"
if $xml2html "$file" >$tmp/$base_noext.html; then
$move_if_change "$tmp/$base_noext.html" \
"$output_dir/$base_noext.html"
else
echo >&2 "$0: cannot convert XML report to HTML"
rm $tmp/$base_noext.html
fi
fi
$move_if_change "$file" "$out"
;;
*.hh)
fix_bison_output "$file"
# To save cycles, if the file differs only on sync lines,
# update it (to be right), but keep the original timestamps.
if test -r "$out" &&
diff -I '^#line' -I '/\* Line .* of .* \*/' -q "$file" "$out"; then
touch -r "$out" "$file"
cp "$out" "$out.bak"
echo >&2 "$0: kept the stamps of $file"
fi
$move_if_change "$file" "$out"
;;
*)
fix_bison_output "$file"
$move_if_change "$file" "$out"
;;
esac
done
;;
*) # We really want to keep the *.output files.
for file in $(ls $tmp/*.output $tmp/*.xml $tmp/*.html 2>/dev/null)
do
$move_if_change "$file" "$output_dir/$(basename $file)"
done
;;
esac
for file in $tmp/*
do
base=$(basename $file)
base_noext=$(echo "$base" | sed -e 's/\.[^.]*//')
case $status:$base in
(*:$input_base)
# Leave it here.
;;
# Success or not, install it.
(*:*.xml)
# Computing the HTML is slow. Do it when the XML changed.
fix_bison_output "$file"
compile_xml_file "$file" "xml2xhtml" "html"
# Compiling the dot output is quite long, it would be better
# to do that from the Makefile, so that -j applies.
# compile_xml_file "$file" "xml2dot" "dot"
install "$file"
;;
(0:*.hh)
fix_bison_output "$file"
# To save cycles, if the file differs only on sync lines,
# update it (to be right), but keep the original timestamps.
if test -r "$(out "$file")" &&
diff -I '^#line' -I '/\* Line .* of .* \*/' -q \
"$file" "$(out "$file")"
then
touch -r "$(out "$file")" "$file"
cp "$(out "$file")" "$(out "$file").bak"
verbose "kept the stamps of $file"
fi
install "$file"
;;
(*:*.output)
install "$file"
;;
(0:*)
fix_bison_output "$file"
install "$file"
;;
esac
done
# Get rid of the tmp dir.
rm -rf $tmp
# rm -rf $tmp
exit $status
#! /usr/bin/perl -w
# This script *tries* to fuse consecutive "switches" that have the
# same body.
#
# Usage: $0 FILES
#
# Leaves a copy of the input files as FILE.bak.
use strict;
my $case_re = '^\s*(case\b.*|default)\s*:';
# Return the block of code with all the ignored parts removed.
sub code ($)
{
local ($_) = @_;
# print STDERR "CODE IN: $_";
s,//.*,,gm;
s,/\*.*?.*\*/,,gm;
s/#line .*//gm;
# print STDERR "CODE OUT: $_";
return $_;
}
# Compare two case blocks against equality, ignoring the case label.
sub case_eq($$)
{
my ($b1, $b2) = @_;
return case_body(code($b1)) eq case_body(code($b2));
}
# Return the line which contains the "case" this block of code.
sub case_label($)
{
my ($case) = @_;
my $res = '';
for my $line (split "\n", $case)
{
# We put no space at the end of '//-' not to introduce trailing
# spaces.
$res .= ($line !~ /$case_re/ && '//-') . $line . "\n"
}
return $res;
}
# Return the case-block without its case line.
sub case_body($)
{
local ($_) = @_;
# print STDERR "BODY IN: $_";
s/^.*$case_re.*\n//mg;
# print STDERR "BODY OUT: $_";
return $_;
}
sub fuse($$)
{
my ($input, $output) = @_;
use IO::File;
my $in = new IO::File($input) or die;
my $out = new IO::File(">$output") or die;
# Something before the next $case.
my $pre_case = '';
# The body of the case: from case/default to the next break;
# There must be no break inside.
my $case = '';
my $previous_case = '';
# Whether we are in the switch {}.
my $in_switch = 0;
while ($_ = $in->getline)
{
# print STDERR "\$_ = $_";
if (!$in_switch)
{
if (/^\s*switch\b/)
{
$in_switch = 1;
}
}
else
{
# in switch.
#
# The "default: break" one a single line is output by
# bison's lalr1.cc..
if (m/$case_re/ .. m/^\s*(?:default:\s*)?break/)
{
# Register the current case.
$case .= $_;
if (/break/)
{
if (case_eq($previous_case, $case))
{
# print STDERR "== {{$previous_case}} {{$case}}\n";
$_ = case_label ($previous_case);
}
else
{
# The previous case is needed.
# print STDERR "!= {{$previous_case}} {{$case}}\n";
$_ = $previous_case;
}
$previous_case = $case;
$case = "";
$_ .= $pre_case;
$pre_case = '';
}
else
{
# Print nothing.
$_ = "";
}
}
elsif (m/}/)
{
# The closing brace of the switch.
$_ = $previous_case . $pre_case . $_;
$pre_case = '';
$previous_case = '';
$in_switch = 0;
}
else
{
# Something in a switch, but not in a case. Keep it,
# and output it before the forth coming output. Don't
# put it in $case though, as it would be commented out,
# which might be wrong (e.g., pragmas, or cpp
# directives).
$pre_case .= $_;
$_ = '';
}
}
print $out $_;
}
die "could not insert $pre_case"
if $pre_case;
}
use File::Copy;
for my $file (@ARGV)
{
copy ($file, "$file.bak") or die;
fuse("$file.bak", "$file");
}
### Setup "GNU" style for perl-mode and cperl-mode.
## Local Variables:
## perl-indent-level: 2
## perl-continued-statement-offset: 2
## perl-continued-brace-offset: 0
## perl-brace-offset: 0
## perl-brace-imaginary-offset: 0
## perl-label-offset: -2
## cperl-indent-level: 2
## cperl-brace-offset: 0
## cperl-continued-brace-offset: 0
## cperl-label-offset: -2
## cperl-extra-newline-before-brace: t
## cperl-merge-trailing-else: nil
## cperl-continued-statement-offset: 2
## End:
# From LRDE's TC's src/parse/Makefile.am:
# "[asm-parse.cc] is not part of [FROM_ASM_PARSE_YY] to prevent
# "[asm-parse.cc] is not part of [SOURCES_ASM_PARSE_YY] to prevent
# [asm-parse.cc] from occuring twice in libparse_a_SOURCES to avoid
# double inclusion of [asm-parse.o]."
FROM_ASM_PARSE_YY = \
SOURCES_ASM_PARSE_YY = \
$(srcdir)/stack.hh $(srcdir)/position.hh $(srcdir)/location.hh \
$(srcdir)/asm-parse.hh
BUILT_SOURCES = \
asm-scan.ll asm-scan.ll.stamp \
asm-parse.yy asm-parse.yy.stamp \
$(FROM_ASM_PARSE_YY)
$(SOURCES_ASM_PARSE_YY)
# This code comes from "Handling Tools that Produce Many Outputs",
# from the Automake documentation.
......@@ -34,25 +34,33 @@ $(srcdir)/asm-parse.yy: asm-parse.yy.stamp
BISONXX = $(top_builddir)/build-aux/bin/bison++
BISONXX_IN = $(top_srcdir)/build-aux/bin/bison++.in
$(BISONXX): $(BISONXX_IN)
cd $(top_builddir)/build-aux && $(MAKE) $(AM_MAKEFLAGS) bin/bison++
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) build-aux/bin/bison++
BISONXXFLAGS = \
--verbose
AM_BISONFLAGS = \
--report=all
EXTRA_DIST += $(srcdir)/bison++.stamp $(srcdir)/asm-parse.yy
$(srcdir)/bison++.stamp: $(srcdir)/asm-parse.yy $(BISONXX_IN)
$(MAKE) $(AM_MAKEFLAGS) $(BISONXX)
@rm -rf bison++.stamp.tmp
@touch bison++.stamp.tmp
$(BISONXX) $(srcdir)/asm-parse.yy $(srcdir)/asm-parse.cc -d -ra
@mv -f bison++.stamp.tmp $@
mkdir -p $(@D)
rm -f $@ $@.tmp
echo '$@ rebuilt because of: $?' >$@.tmp
$(MAKE) $(BISONXX)
$(BISONXX) $(BISONXXFLAGS) -- \
$< $(srcdir)/asm-parse.cc \
$(AM_BISONFLAGS) $(BISONFLAGS)
mv -f $@.tmp $@
# Run bison if a file that can be created by it is missing:
$(srcdir)/asm-parse.cc $(FROM_ASM_PARSE_YY): $(srcdir)/bison++.stamp
$(srcdir)/asm-parse.cc $(SOURCES_ASM_PARSE_YY): $(srcdir)/bison++.stamp
@if test ! -f $@; then \
rm -f $(srcdir)/bison++.stamp; \
$(MAKE) $(AM_MAKEFLAGS) $(srcdir)/bison++.stamp; \
fi
MAINTAINERCLEANFILES = asm-scan.ll asm-scan.yy $(FROM_ASM_PARSE_YY)
MAINTAINERCLEANFILES = asm-scan.ll asm-scan.yy $(SOURCES_ASM_PARSE_YY)
noinst_LTLIBRARIES = libparse.la
......@@ -60,6 +68,6 @@ libparse_la_CPPFLAGS = -I $(top_srcdir)/src -I $(top_builddir)/src
libparse_la_SOURCES = \
fwd.hh \
asm-parse.cc asm-parse.yy.stamp \
$(FROM_ASM_PARSE_YY) \
$(SOURCES_ASM_PARSE_YY) \
asm-scan.ll asm-scan.hh asm-scan.ll.stamp \
libparse.hh libparse.cc
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment