nolimips nolimips-0.9-14-gf0ce61e 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 <roland@lrde.epita.fr> --- ChangeLog | 13 ++ build-aux/bin/bison++.in | 313 ++++++++++++++++++++++++++++++++++----------- build-aux/bin/fuse-switch | 168 ++++++++++++++++++++++++ src/parse/Makefile.am | 32 +++-- 4 files changed, 442 insertions(+), 84 deletions(-) create mode 100755 build-aux/bin/fuse-switch diff --git a/ChangeLog b/ChangeLog index 540c335..7eaa468 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +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). diff --git a/build-aux/bin/bison++.in b/build-aux/bin/bison++.in index bb11bca..1659e38 100755 --- a/build-aux/bin/bison++.in +++ b/build-aux/bin/bison++.in @@ -1,34 +1,117 @@ #! /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 diff --git a/build-aux/bin/fuse-switch b/build-aux/bin/fuse-switch new file mode 100755 index 0000000..0d48d41 --- /dev/null +++ b/build-aux/bin/fuse-switch @@ -0,0 +1,168 @@ +#! /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: diff --git a/src/parse/Makefile.am b/src/parse/Makefile.am index 7b50a34..f19a240 100644 --- a/src/parse/Makefile.am +++ b/src/parse/Makefile.am @@ -1,15 +1,15 @@ # 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 -- 1.7.2.5
participants (1)
-
Akim Demaille