diff options
28 files changed, 461 insertions, 306 deletions
diff --git a/configure.ac b/configure.ac index c8c8fb620..b0c551e4f 100644 --- a/configure.ac +++ b/configure.ac @@ -71,6 +71,9 @@ AC_SUBST(MU_LIB_COMMON_INCLUDES,'-I${top_builddir} -I${top_srcdir}/include -I${ AC_SUBST(MU_APP_COMMON_INCLUDES,'-I${srcdir} -I${top_srcdir}/include -I${top_srcdir}/lib -I${top_srcdir}/lib/gnu -I${top_builddir}/lib/gnu -I${top_builddir} -I${top_builddir}/include') +# Use our replacement for the ylwrap tool +AC_SUBST([MU_YLWRAP],'$(mu_aux_dir)/gylwrap --compatibility --') + dnl Check for programs AC_PROG_CC AM_PROG_CC_C_O diff --git a/libmailutils/base/.gitignore b/libmailutils/base/.gitignore index e3e0cf0d2..0b756b195 100644 --- a/libmailutils/base/.gitignore +++ b/libmailutils/base/.gitignore @@ -1 +1,2 @@ parsedate.c + diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am index 437dbbe0f..0936a2d19 100644 --- a/libmailutils/base/Makefile.am +++ b/libmailutils/base/Makefile.am @@ -54,7 +54,7 @@ libbase_la_SOURCES = \ observer.c\ onexit.c\ opool.c\ - parsedate.c\ + parsedate.y\ permstr.c\ registrar.c\ refcount.c\ @@ -82,17 +82,10 @@ AM_CPPFLAGS = \ -DLOCALEDIR=\"$(localedir)\" -YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap -AM_YFLAGS=-vt -AM_LFLAGS=-dp +YLWRAP = @MU_YLWRAP@ +EXTRA_DIST = gylwrap.conf +AM_YFLAGS= +AM_LFLAGS= -EXTRA_DIST = parsedate.y - -BUILT_SOURCES = parsedate.c - -parsedate.c: $(srcdir)/parsedate.y - $(YLWRAP) "$(YACC) $(AM_YFLAGS)" $< \ - y.tab.c parsedate.c y.output parsedate.y.output \ - -- -yy pd_yy diff --git a/libmailutils/base/gylwrap.conf b/libmailutils/base/gylwrap.conf new file mode 100644 index 000000000..33b8c123f --- /dev/null +++ b/libmailutils/base/gylwrap.conf @@ -0,0 +1,3 @@ +# Configuration settings for gylwrap. +# See ../../mu-aux/gylwrap --help, for details. +yyrepl = pd_yy diff --git a/libmailutils/cfg/.gitignore b/libmailutils/cfg/.gitignore index 8993e6040..97bc813a3 100644 --- a/libmailutils/cfg/.gitignore +++ b/libmailutils/cfg/.gitignore @@ -1,3 +1,4 @@ lexer.c parser.c parser.h +parser.output diff --git a/libmailutils/cfg/Makefile.am b/libmailutils/cfg/Makefile.am index 51f67de6b..eb299fae0 100644 --- a/libmailutils/cfg/Makefile.am +++ b/libmailutils/cfg/Makefile.am @@ -20,9 +20,8 @@ noinst_LTLIBRARIES = libcfg.la libcfg_la_SOURCES = \ driver.c\ format.c\ - lexer.c\ - parser.c\ - cfg.h + lexer.l\ + parser.y localedir = $(datadir)/locale AM_CPPFLAGS = \ @@ -30,25 +29,15 @@ AM_CPPFLAGS = \ -DSYSCONFDIR=\"$(sysconfdir)\"\ -DLOCALEDIR=\"$(localedir)\" - EXTRA_DIST = \ lexer.l\ parser.y\ - parser.h + parser.h\ + gylwrap.conf BUILT_SOURCES = parser.c parser.h lexer.c -YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap -AM_YFLAGS=-vt +YLWRAP = @MU_YLWRAP@ +AM_YFLAGS=-vdt AM_LFLAGS=-dp -parser.c parser.h: $(srcdir)/parser.y - $(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ - y.tab.c parser.c y.tab.h parser.h \ - y.output parser.y.output \ - -- -yy mu_cfg_yy - -lexer.c: $(srcdir)/lexer.l parser.h - $(AM_V_GEN)$(YLWRAP) "$(LEX) $(AM_LFLAGS) $(LFLAGS)" \ - $(srcdir)/lexer.l lex.yy.c lexer.c \ - -- -yy mu_cfg_yy diff --git a/libmailutils/cfg/cfg.h b/libmailutils/cfg/cfg.h deleted file mode 100644 index 3b0ae34c3..000000000 --- a/libmailutils/cfg/cfg.h +++ /dev/null @@ -1 +0,0 @@ -#include <mailutils/yyloc.h> diff --git a/libmailutils/cfg/gylwrap.conf b/libmailutils/cfg/gylwrap.conf new file mode 100644 index 000000000..4a93e6f83 --- /dev/null +++ b/libmailutils/cfg/gylwrap.conf @@ -0,0 +1,4 @@ +# Configuration settings for gylwrap. +# See ../../mu-aux/gylwrap --help, for details. + +yyrepl = mu_cfg_yy diff --git a/libmailutils/cfg/lexer.l b/libmailutils/cfg/lexer.l index d164a109f..046519649 100644 --- a/libmailutils/cfg/lexer.l +++ b/libmailutils/cfg/lexer.l @@ -41,7 +41,7 @@ #include <mailutils/locus.h> #include <mailutils/stream.h> #include <mailutils/stdstream.h> -#include "cfg.h" +#include <mailutils/yyloc.h> #include "parser.h" void _mu_line_begin (void); diff --git a/libmailutils/cfg/parser.y b/libmailutils/cfg/parser.y index b49dd0c11..e4654bc55 100644 --- a/libmailutils/cfg/parser.y +++ b/libmailutils/cfg/parser.y @@ -40,7 +40,7 @@ #include <mailutils/stream.h> #include <mailutils/stdstream.h> #include <mailutils/cidr.h> -#include "cfg.h" +#include <mailutils/yyloc.h> int mu_cfg_parser_verbose; static mu_list_t /* of mu_cfg_node_t */ parse_node_list; diff --git a/libmu_sieve/Makefile.am b/libmu_sieve/Makefile.am index 084211c0a..2954794a9 100644 --- a/libmu_sieve/Makefile.am +++ b/libmu_sieve/Makefile.am @@ -15,7 +15,7 @@ ## You should have received a copy of the GNU General Public License ## along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. -YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap +YLWRAP = @MU_YLWRAP@ AM_YFLAGS = -dtv #AM_LEXFLAGS=-dvp AM_CPPFLAGS =\ @@ -39,9 +39,8 @@ libmu_sieve_la_SOURCES = \ relational.c\ require.c\ runtime.c\ - sieve-gram.c\ - sieve-gram.h\ - sieve-lex.c\ + sieve-gram.y\ + sieve-lex.l\ strexp.c\ string.c\ tests.c\ @@ -50,24 +49,14 @@ libmu_sieve_la_SOURCES = \ libmu_sieve_la_LIBADD = ${MU_LIB_MAILUTILS} @LTDL_LIB@ libmu_sieve_la_LDFLAGS = -version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ -noinst_HEADERS = sieve-priv.h +noinst_HEADERS = sieve-priv.h sieve-gram.h BUILT_SOURCES = \ sieve-gram.c sieve-gram.h \ sieve-lex.c -MAINTAINERCLEANFILES=$(BUILT_SOURCES) - -EXTRA_DIST = sieve.y sieve.l +EXTRA_DIST=gylwrap.conf -sieve-lex.c: $(srcdir)/sieve.l sieve-gram.h - $(AM_V_GEN)$(YLWRAP) "$(LEX) $(AM_LEXFLAGS) $(LEXFLAGS)" \ - $(srcdir)/sieve.l lex.yy.c sieve-lex.c \ - -- -yy mu_sieve_yy - -sieve-gram.c sieve-gram.h: $(srcdir)/sieve.y - $(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS) $(YFLAGS)" $(srcdir)/sieve.y \ - y.tab.c sieve-gram.c y.tab.h sieve-gram.h y.output y.output \ - -- -yy mu_sieve_yy +MAINTAINERCLEANFILES=$(BUILT_SOURCES) diff --git a/libmu_sieve/gylwrap.conf b/libmu_sieve/gylwrap.conf new file mode 100644 index 000000000..3f574d74e --- /dev/null +++ b/libmu_sieve/gylwrap.conf @@ -0,0 +1,4 @@ +# Configuration settings for gylwrap. +# See ../mu-aux/gylwrap --help, for details. + +yyrepl=mu_sieve_yy diff --git a/libmu_sieve/sieve.y b/libmu_sieve/sieve-gram.y index 5499a5ece..5499a5ece 100644 --- a/libmu_sieve/sieve.y +++ b/libmu_sieve/sieve-gram.y diff --git a/libmu_sieve/sieve.l b/libmu_sieve/sieve-lex.l index a93245e70..a93245e70 100644 --- a/libmu_sieve/sieve.l +++ b/libmu_sieve/sieve-lex.l diff --git a/mail/Makefile.am b/mail/Makefile.am index 7c2cebc3c..b2061516f 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -15,6 +15,7 @@ ## You should have received a copy of the GNU General Public License ## along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. +YLWRAP = @MU_YLWRAP@ AM_YFLAGS=-vt AM_CPPFLAGS = \ @MU_APP_COMMON_INCLUDES@ @MU_AUTHINCS@\ diff --git a/mh/.gitignore b/mh/.gitignore index 4e2b87b96..99f999acf 100644 --- a/mh/.gitignore +++ b/mh/.gitignore @@ -14,8 +14,7 @@ forw inc install-mh mark -mh_alias.h -mh_alias_gram.c +mh_alias_gram.[ch] mh_alias_lex.c mh_fmtgram.c mhl diff --git a/mh/Makefile.am b/mh/Makefile.am index fdd23f827..d4c89a892 100644 --- a/mh/Makefile.am +++ b/mh/Makefile.am @@ -68,33 +68,33 @@ noinst_LIBRARIES = libmh.a libmh_a_SOURCES= \ compcommon.c\ mboxprop.c\ - mh_alias_gram.c\ - mh_alias_lex.c\ + mh_alias_gram.y\ + mh_alias_lex.l\ mh_getopt.c\ mh_global.c\ mh_format.c\ mh_init.c\ mh_list.c\ - mh_fmtgram.c\ + mh_fmtgram.y\ mh_msgset.c\ mh_sequence.c\ mh_stream.c\ mh_whatnow.c\ mh_whom.c\ whatnowenv.c -noinst_HEADERS = mh.h mh_alias.h mh_format.h mh_getopt.h +noinst_HEADERS = mh.h mh_alias_gram.h mh_format.h mh_getopt.h -BUILT_SOURCES= \ - mh_fmtgram.c \ - pick-gram.c \ - pick-gram.h \ - mh_alias_gram.c \ - mh_alias_lex.c \ - mh_alias.h +BUILT_SOURCES=\ + mh_fmtgram.c\ + pick-gram.c\ + pick-gram.h\ + mh_alias_gram.c\ + mh_alias_gram.h\ + mh_alias_lex.c MAINTAINERCLEANFILES=$(BUILT_SOURCES) -EXTRA_DIST = mh_fmtgram.y pick.y mh_alias.y mh_alias.l +EXTRA_DIST = gylwrap.conf mhlibdir = $(pkgdatadir)/mh @@ -119,9 +119,9 @@ mh_LIBS = \ @MU_COMMON_LIBRARIES@ LDADD = $(mh_LIBS) scan_LDADD = $(mh_LIBS) @CURSES_LIBS@ -pick_SOURCES = pick.c pick.h pick-gram.c pick-gram.h +pick_SOURCES = pick.c pick.h pick-gram.y pick-gram.h -YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap +YLWRAP = @MU_YLWRAP@ AM_YFLAGS=-vt inc_LDADD = \ @@ -144,29 +144,6 @@ inc_LDADD = \ ${MU_LIB_MAILUTILS}\ @MU_COMMON_LIBRARIES@ - -pick-gram.c pick-gram.h: $(srcdir)/pick.y - $(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ - y.tab.c pick-gram.c y.tab.h pick-gram.h \ - y.output pick.output \ - -- -yy pick_yy - -mh_fmtgram.c: $(srcdir)/mh_fmtgram.y - $(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS)" $< \ - y.tab.c mh_fmtgram.c y.output fmtgram.y.output \ - -- -yy fmt_yy - -mh_alias_gram.c mh_alias.h: $(srcdir)/mh_alias.y - $(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ - y.tab.c mh_alias_gram.c y.tab.h mh_alias.h \ - y.output mh_alias.output \ - -- -yy ali_yy - -mh_alias_lex.c: $(srcdir)/mh_alias.l mh_alias.h - $(AM_V_GEN)$(YLWRAP) "$(LEX) $(AM_LEXFLAGS) $(LEXFLAGS)" \ - $(srcdir)/mh_alias.l lex.yy.c mh_alias_lex.c \ - -- -yy ali_yy - install-exec-hook: @here=`pwd`; \ cd $(DESTDIR)$(bindir); \ diff --git a/mh/gylwrap.conf b/mh/gylwrap.conf new file mode 100644 index 000000000..995496232 --- /dev/null +++ b/mh/gylwrap.conf @@ -0,0 +1,13 @@ +# Configuration settings for gylwrap. +# See ../mu-aux/gylwrap --help, for details. + +[pick-gram.y] + yyrepl = pick_yy + flags = -d +[mh_fmtgram.y] + yyrepl = fmt_yy +[mh_alias_gram.y] + yyrepl = ali_yy + flags = -d +[mh_alias_lex.l] + yyrepl = ali_yy diff --git a/mh/mh_alias.y b/mh/mh_alias_gram.y index 0d6bffcc2..0d6bffcc2 100644 --- a/mh/mh_alias.y +++ b/mh/mh_alias_gram.y diff --git a/mh/mh_alias.l b/mh/mh_alias_lex.l index df81ce30f..0d854b46b 100644 --- a/mh/mh_alias.l +++ b/mh/mh_alias_lex.l @@ -23,7 +23,7 @@ %{ #include <mh.h> -#include <mh_alias.h> +#include <mh_alias_gram.h> #include <sys/stat.h> #include <mailutils/cctype.h> #include <mailutils/io.h> diff --git a/mh/pick.y b/mh/pick-gram.y index ef2bdaab0..ef2bdaab0 100644 --- a/mh/pick.y +++ b/mh/pick-gram.y diff --git a/mimeview/.gitignore b/mimeview/.gitignore index b18e41a81..cee470e87 100644 --- a/mimeview/.gitignore +++ b/mimeview/.gitignore @@ -3,11 +3,8 @@ .libs Makefile Makefile.in -lex.yy.c -mimetypes-decl.h -mimetypes-gram.c -mimetypes-lex.c -mimetypes.output +grammar.c +grammar.h +grammar.output +lexer.c mimeview -y.output -y.tab.c diff --git a/mimeview/Makefile.am b/mimeview/Makefile.am index 5334e40c0..039e2be9f 100644 --- a/mimeview/Makefile.am +++ b/mimeview/Makefile.am @@ -25,28 +25,15 @@ AM_CPPFLAGS = \ bin_PROGRAMS = mimeview mimeview_SOURCES = \ mimeview.c \ - mimetypes-gram.c \ - mimetypes-lex.c \ - mimetypes-decl.h \ - mimeview.h + grammar.y \ + lexer.l \ + mimeview.h\ + grammar.h -YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap -AM_YFLAGS=-vt +YLWRAP = @MU_YLWRAP@ +AM_YFLAGS=-vtd AM_LEXFLAGS=-d -EXTRA_DIST = mimetypes.y mimetypes.l - -mimetypes-gram.c mimetypes-decl.h: $(srcdir)/mimetypes.y - $(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ - y.tab.c mimetypes-gram.c y.tab.h mimetypes-decl.h \ - y.output mimetypes.output \ - -- -yy mimetypes_yy - -mimetypes-lex.c: $(srcdir)/mimetypes.l mimetypes-decl.h - $(AM_V_GEN)$(YLWRAP) "$(LEX) $(AM_LEXFLAGS) $(LEXFLAGS)" \ - $(srcdir)/mimetypes.l lex.yy.c mimetypes-lex.c \ - -- -yy mimetypes_yy - -BUILT_SOURCES = mimetypes-gram.c mimetypes-lex.c mimetypes-decl.h +EXTRA_DIST = gylwrap.conf mimeview_LDADD = \ ${MU_APP_LIBRARIES}\ diff --git a/mimeview/mimetypes.y b/mimeview/grammar.y index 6d6f0b432..cb36f3941 100644 --- a/mimeview/mimetypes.y +++ b/mimeview/grammar.y @@ -22,7 +22,7 @@ #include <mailutils/cctype.h> #include <mimeview.h> -#include <mimetypes-decl.h> +#include <grammar.h> #include <regex.h> static void diff --git a/mimeview/gylwrap.conf b/mimeview/gylwrap.conf new file mode 100644 index 000000000..cd41ab231 --- /dev/null +++ b/mimeview/gylwrap.conf @@ -0,0 +1,3 @@ +# Configuration settings for gylwrap. +# See ../mu-aux/gylwrap --help, for details. +yyrepl = mimetypes_yy diff --git a/mimeview/mimetypes.l b/mimeview/lexer.l index 5524ec4ea..71de5d721 100644 --- a/mimeview/mimetypes.l +++ b/mimeview/lexer.l @@ -26,7 +26,7 @@ #include <stdio.h> #include <sys/stat.h> #include <mimeview.h> -#include <mimetypes-decl.h> +#include <grammar.h> #include <mailutils/io.h> static mu_linetrack_t trk; diff --git a/mu-aux/gylwrap b/mu-aux/gylwrap index c91ab48c8..0fbd595ae 100755 --- a/mu-aux/gylwrap +++ b/mu-aux/gylwrap @@ -1,184 +1,376 @@ -#! /bin/sh -# ylwrap - wrapper for lex/yacc invocations. -# Copyright 1996-1999, 2007, 2010-2012, 2014-2017 Free Software -# Foundation, Inc. -# Written by Tom Tromey <tromey@cygnus.com>. -# -# This program 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. -# -# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - -# Usage: -# ylwrap PROGRAM [ARGS] INPUT [OUTPUT DESIRED]... -- [-yy repl] [ARGS]... -# * PROGRAM is program to run; options can follow but must start with `-'. -# * INPUT is the input file -# * OUTPUT is file PROG generates -# * DESIRED is file we actually want -# * ARGS are passed to PROG -# * Optional -yy introduces the sequence to replace yy prefixes with. -# Any number of OUTPUT,DESIRED pairs may be used. - -# The program to run. -prog="$1" -shift -# Make any relative path in $prog absolute. -case "$prog" in - /* | [A-Za-z]:*) ;; - */*) prog="`pwd`/$prog" ;; -esac - -# We also have to accept options here and append them to the program. -# Why? Suppose YACC is set to `bison -y'. Clearly nobody uses -# ylwrap, or this would have been discovered earlier! -while :; do - case "$1" in - -*) - prog="$prog $1" - shift - ;; - *) - break - ;; - esac -done - -# The input. -input="$1" -shift -case "$input" in - /* | [A-Za-z]:*) - # Absolute path; do nothing. - ;; - *) - # Relative path. Make it absolute. - input="`pwd`/$input" - ;; -esac - -# The directory holding the input. -input_dir="`echo $input | sed -e 's,/[^/]*$,,'`" -# Quote $INPUT_DIR so we can use it in a regexp. -# FIXME: really we should care about more than `.'. -input_rx="`echo $input_dir | sed -e 's,\.,\\\.,g'`" - -pairlist= -defout=$1 -while test "$#" -ne 0; do - if test "$1" = "--"; then - shift - break - fi - pairlist="$pairlist $1" - shift -done - -STDOUT="" -if [ $# -ne 0 ]; then - while test "$#" -ne 0; do - case "x$1" in - x-yy) - shift - if [ $# -eq 0 ]; then - echo "ylwrap: -yy requires an argument" - exit 1 - fi - YYREPL=$1 - shift;; - x-stdout) - shift - STDOUT=$defout - ;; - *) - break;; - esac - done -fi - -# FIXME: add hostname here for parallel makes that run commands on -# other machines. But that might take us over the 14-char limit. -dirname=ylwrap$$ -trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15 -mkdir $dirname || exit 1 - -cd $dirname - -if [ -n "$STDOUT" ]; then - $prog ${1+"$@"} "$input" > $STDOUT -else - $prog ${1+"$@"} "$input" -fi -status=$? - -if test $status -eq 0; then - set X $pairlist - shift - first=yes - # Since DOS filename conventions don't allow two dots, - # the DOS version of Bison writes out y_tab.c instead of y.tab.c - # and y_tab.h instead of y.tab.h. Test to see if this is the case. - y_tab_nodot="no" - if test -f y_tab.c || test -f y_tab.h; then - y_tab_nodot="yes" - fi - - while test "$#" -ne 0; do - from="$1" - # Handle y_tab.c and y_tab.h output by DOS - if test $y_tab_nodot = "yes"; then - if test $from = "y.tab.c"; then - from="y_tab.c" - else - if test $from = "y.tab.h"; then - from="y_tab.h" - fi - fi - fi - if test -f "$from"; then - # If $2 is an absolute path name, then just use that, - # otherwise prepend `../'. - case "$2" in - /* | [A-Za-z]:*) target="$2";; - *) target="../$2";; - esac - - # Edit out `#line' or `#' directives. We don't want the - # resulting debug information to point at an absolute srcdir; - # it is better for it to just mention the .y file with no - # path. - T=`basename $target` - EXPR="/^#/ s,$input_rx/,,;s,\"$from\",\"$T\"," - if [ ! -z "$YYREPL" ]; then - EXPR="$EXPR;s/yy/$YYREPL/g" - fi - sed -e "$EXPR" "$from" > "$target" || status=$? - else - # A missing file is only an error for the first file. This - # is a blatant hack to let us support using "yacc -d". If -d - # is not specified, we don't want an error when the header - # file is "missing". - if test $first = yes; then - status=1 - fi - fi - shift - shift - first=no - done -else - status=$? -fi - -# Remove the directory. -cd .. -rm -rf $dirname - -exit $status +eval '(exit $?0)' && eval 'exec perl -wS "$0" "$@"' + & eval 'exec perl -wS "$0" $argv:q' + if 0; + +use strict; +use warnings; +use Getopt::Long qw(:config gnu_getopt no_ignore_case require_order auto_version); +use File::Basename; +use File::Temp qw(tempdir); +use Pod::Man; +use Pod::Usage; +use Cwd 'abs_path'; +use List::Regexp; + +=head1 NAME + +gylwrap - wrapper for yacc, lex and similar programs + +=head1 SYNOPSIS + +B<gylwrap> +[B<-c?>] +[B<--compatibility>] +[B<--yyrepl=>I<PREFIX>] +[B<--yysym=>I<STRING>] +[B<--stdout>] +[B<--help>] +[B<--version>] +I<COMMAND> +I<INPUT> +I<OUTPUT> I<DESIRED>... + +B<ylwrap> +[B<-?>] +[B<--yyrepl=>I<PREFIX>] +[B<--yysym=>I<STRING>] +[B<--stdout>] +[B<--help>] +[B<--version>] +I<INPUT> +[I<OUTPUT> I<DESIRED>]... +B<--> I<PROGRAM> [I<ARGS>] + +=head1 DESCRIPTION + +Wraps B<lex> and B<yacc> invocations to rename their output files. +It also ensures that multiple I<COMMAND> instances can be invoked +in a single directory in parallel and allows for renaming global +symbols to avoid clashes when multiple parsers and/or lexers are +linked in a single executable. + +To achieve this, B<gylwrap> creates a temporary directory, changes +to it, and runs I<COMMAND> (which may contain arguments and options) +with I<INPUT> as its last argument. Upon successful exit, it processes +the I<OUTPUT> I<DESIRED> pairs. Each I<OUTPUT> file is then renamed +to the file I<DESIRED>, taking care to fix up any eventual B<#line> +directives. + +If B<--yyrepl=I<PREFIX>> is given, the global symbols that can cause +name clashes are renamed by replacing the initial B<yy> with I<PREFIX>. +For a list of symbols that are subject for replacement, inspect the +B<@sym> variable at the start of the script. Additional names can be +added to this list using the B<--yysym> option. + +If given the B<--compatibility> option or if invoked as B<ylwrap>, +the tool runs in compatibility mode, mimicking the behavior of the +standard B<ylwrap> utility from GNU Automake. Command line arguments +consist of two lists, separated by B<-->. The left-hand side list +supplies the I<OUTPUT>,I<DESIRED> pairs, and the right-hand side one +supplies the command and its arguments. + +In both modes, prior to running the command, the program looks for file +B<gylwrap.conf> in the same directory as the I<INPUT> file. If found, +the file is sourced. Empty lines and comments (introduced by the hash +sign) are ignored. Rest of lines are either option assignements, or +section headings. + +Option assignements have the form B<I<OPTION> = I<VALUE>>, and generally, +have the same meaning as the corresponding command line option without +the leading two dashes: + +=over 4 + +=item B<yyrepl => I<PREFIX> + +Replace the B<yy> prefix with I<PREFIX> in the identifiers. + +=item B<stdout = 1> + +Enable the B<--stdout> option. + +=item B<yysym => I<NAME> + +Add I<NAME> to the list of symbols suitable for prefix replacement. +This keyword can appear multiple times. + +=item B<flags => I<STRING> + +Add I<STRING> to the invocation of I<COMMAND>. This is useful, if you +have several parsers in the same directory, and some of them require +the B<-d> option, while others don't. + +=back + +Section headers have the form B<[I<FILE>]>. The settings under a +section header have effect only if I<FILE> is the same as the I<INPUT> +command line argument. + +=head1 OPTIONS + +=over 4 + +=item B<-c>, B<--compatibility> + +Run in compatibility mode. + +=item B<--stdout> + +Redirect I<COMMAND>'s standard output to the first I<OUTPUT>. + +=item B<--yyrepl=>I<PREFIX> + +Replace the B<yy> prefix in global symbols with I<PREFIX>. + +=item B<--yysym=>I<SYMBOL> + +Add I<SYMBOL> to the list of symbols subject for replacement. + +=item B<-?>, B<--help> + +Displays help text and exit + +=item B<--version> + +Displays program version and exits. + +=back + +=head1 NOTE + +This script is an improved version of the B<ylwrap> script, included +in the GNU Automake distribution. + +=cut + +# List of symbols suitable for prefix replacements. See the +# options --yyrepl and --yysym, and similar statements in the configuration +# file. +my @yysym = qw( + yymaxdepth + yyparse + yylex + yyerror + yylval + yychar + yydebug + yypact + yyr1 + yyr2 + yydef + yychk + yypgo + yyact + yyexca + yyerrflag + yynerrs + yyps + yypv + yys + yy_yys + yystate + yytmp + yyv + yy_yyv + yyval + yylloc + yyreds + yytoks + yylhs + yylen + yydefred + yydgoto + yysindex + yyrindex + yygindex + yytable + yycheck + yyname + yyrule +); + +our $VERSION = '1.00'; + +# If prefix replacement is requested, the list above is assembled into +# a single regular expression, stored here. +my $yyrx; + +# String to replace the "yy" prefix with. +my $yyrepl; + +# If set, redirect the stdout from the command to the first output file. +my $stdout; + +# Input directory with special characters escaped, for "#line" directive +# fixup. +my $input_rx; + +# Configuration settings from the "gylwrap.conf" file. Indexed by +# input file name. Default entry is ''. +my %config; + +# Name of the first output file. This is used in compatibility mode to +# avoid bailing out if one of the output files (except the principal one) +# does not exist. +my $parser; + +# Name this program was invoked as. +my $progname = basename($0); +my $compat = $progname eq 'ylwrap'; # True if running in compatibility mode + +# List of files created during the run, for cleanup purposes. +my @created; + +sub filter { + my ($from, $to) = @_; + my $target = basename($to); + my $ifd; + unless (open($ifd, '<', $from)) { + if ($compat) { + return if $from ne $parser; + } + die "can't open input file $from: $!"; + } + open(my $ofd, '>', $to) + or die "can't open output file $to: $!"; + push @created, $to; + while (<$ifd>) { + if (/^#/) { + s{$input_rx/}{}; + s{"$from"}{"$target"}; + } + if ($yyrx) { + s{\byy($yyrx)\b}{${yyrepl}$1}g; + } + print $ofd $_ + } + close $ifd; + close $ofd; +} + +sub readconf { + my $file = shift; + open(my $fd, '<', $file) + or die "can't open $file: $!"; + my $key = ''; + while (<$fd>) { + chomp; + s/^\s+//; + if (/^#/ || /^$/) { + next; + } elsif (/^\[(.+)\]/) { + $key = $1; + } elsif (m/(.+?)\s*=\s*(.+)$/) { |