From 22d46ebe6ddaeb128e2b4119add59dccecc28526 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 1 Mar 2010 17:17:40 -0700 Subject: [PATCH 1/3] Optimize AS_BOX. * lib/m4sugar/m4sh.m4 (AS_BOX): Use less m4 time. (_AS_BOX_LITERAL): Use fewer forks in the common case. * doc/autoconf.texi (Common Shell Constructs) : Document the macro. * NEWS: Mention it. Signed-off-by: Eric Blake --- ChangeLog | 7 +++++++ NEWS | 3 +++ doc/autoconf.texi | 11 +++++++++++ lib/m4sugar/m4sh.m4 | 9 +++------ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 523628e..ce31a7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2010-03-01 Eric Blake + Optimize AS_BOX. + * lib/m4sugar/m4sh.m4 (AS_BOX): Use less m4 time. + (_AS_BOX_LITERAL): Use fewer forks in the common case. + * doc/autoconf.texi (Common Shell Constructs) : Document + the macro. + * NEWS: Mention it. + Update file flow diagram to mention Automake. * doc/autoconf.texi (Making configure Scripts): Avoid confusion with listing Makefile.in twice on one line. Add a diagram showing diff --git a/NEWS b/NEWS index 207325e..c11d3a1 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,9 @@ GNU Autoconf NEWS - User visible changes. ** AC_PROG_INSTALL correctly uses `shtool' again. Regression introduced in 2.64. +** The following macros are now documented: + AS_BOX + * Major changes in Autoconf 2.65 (2009-11-21) [stable] Released by Eric Blake, based on git versions 2.64.*. diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 191a397..0c7c981 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -13047,6 +13047,17 @@ Common Shell Constructs @end defmac @end ignore address@hidden AS_BOX (@var{text}, @var{char, -}) address@hidden +Expand into shell code that will output @var{text} surrounded by a box +with @var{char} in the top and bottom border. @var{text} should not +contain a newline, but may contain shell expansions valid for unquoted +here-documents. @var{char} defaults to @samp{-}, but can be any +character except @samp{/}, @samp{'}, @samp{"}, @samp{\}, @samp{$}, address@hidden&}, or @samp{`}. This is useful for outputting a comment box into +log files to separate distinct phases of script operation. address@hidden defmac + @defmac AS_CASE (@var{word}, @ovar{pattern1}, @ovar{if-matched1}, @ @dots{}, @ovar{default}) @asindex{CASE} diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4 index 8160b3d..6a43f21 100644 --- a/lib/m4sugar/m4sh.m4 +++ b/lib/m4sugar/m4sh.m4 @@ -1378,17 +1378,14 @@ as_executable_p=$as_test_x # Output MESSAGE, a single line text, framed with FRAME-CHARACTER (which # must not be `/'). m4_define([AS_BOX], -[AS_LITERAL_IF([$1], - [_AS_BOX_LITERAL($@)], - [_AS_BOX_INDIR($@)])]) +[m4_if(m4_index(m4_translit([[$1]], [`\"], [$$$]), [$]), + [-1], [_$0_LITERAL], [_$0_INDIR])($@)]) # _AS_BOX_LITERAL(MESSAGE, [FRAME-CHARACTER = `-']) # ------------------------------------------------- m4_define([_AS_BOX_LITERAL], -[cat <<\_ASBOX -m4_text_box($@) -_ASBOX]) +[AS_ECHO("m4_text_box($@)")]) # _AS_BOX_INDIR(MESSAGE, [FRAME-CHARACTER = `-']) -- 1.6.6.1 From d679979e5f79926de13f1abf0bfecf5bb990e56f Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 27 Feb 2010 10:39:31 -0700 Subject: [PATCH 2/3] Add optional argument to AS_LITERAL_IF. * lib/m4sugar/m4sh.m4 (_AS_LITERAL_IF): Rewrite to generate macro name, without using m4_cond. Allow more control over whitespace. (_AS_LITERAL_IF_, _AS_LITERAL_IF_YES, _AS_LITERAL_IF_NO): New helpers. (AS_LITERAL_IF, _AS_TR_SH, _AS_TR_CPP, _AS_VAR_PUSHDEF): Adjust callers. * lib/autoconf/types.m4 (AC_CHECK_MEMBER): Don't hand space to AS_LITERAL_IF. * lib/autoconf/general.m4 (_AC_INIT_PACKAGE): Likewise. * tests/m4sh.at (AS@&address@hidden): Update test. Signed-off-by: Eric Blake --- ChangeLog | 12 ++++++++++ lib/autoconf/general.m4 | 3 +- lib/autoconf/types.m4 | 6 +++- lib/m4sugar/m4sh.m4 | 55 ++++++++++++++++++++++++++++++++-------------- tests/m4sh.at | 28 ++++++++++++++++++------ 5 files changed, 77 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce31a7e..230d20e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2010-03-01 Eric Blake + Add optional argument to AS_LITERAL_IF. + * lib/m4sugar/m4sh.m4 (_AS_LITERAL_IF): Rewrite to generate macro + name, without using m4_cond. Allow more control over whitespace. + (_AS_LITERAL_IF_, _AS_LITERAL_IF_YES, _AS_LITERAL_IF_NO): New + helpers. + (AS_LITERAL_IF, _AS_TR_SH, _AS_TR_CPP, _AS_VAR_PUSHDEF): Adjust + callers. + * lib/autoconf/types.m4 (AC_CHECK_MEMBER): Don't hand space to + AS_LITERAL_IF. + * lib/autoconf/general.m4 (_AC_INIT_PACKAGE): Likewise. + * tests/m4sh.at (AS@&address@hidden): Update test. + Optimize AS_BOX. * lib/m4sugar/m4sh.m4 (AS_BOX): Use less m4 time. (_AS_BOX_LITERAL): Use fewer forks in the common case. diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4 index 15640c8..396ec3d 100644 --- a/lib/autoconf/general.m4 +++ b/lib/autoconf/general.m4 @@ -229,7 +229,8 @@ AU_ALIAS([AC_HELP_STRING], [AS_HELP_STRING]) # _AC_INIT_PACKAGE(PACKAGE-NAME, VERSION, BUG-REPORT, [TARNAME], [URL]) # --------------------------------------------------------------------- m4_define([_AC_INIT_PACKAGE], -[AS_LITERAL_IF([$1], [], [m4_warn([syntax], [AC_INIT: not a literal: $1])]) +[AS_LITERAL_IF(m4_translit([[$1]], [ ], [__]), [], + [m4_warn([syntax], [AC_INIT: not a literal: $1])]) AS_LITERAL_IF([$2], [], [m4_warn([syntax], [AC_INIT: not a literal: $2])]) AS_LITERAL_IF([$3], [], [m4_warn([syntax], [AC_INIT: not a literal: $3])]) m4_ifndef([AC_PACKAGE_NAME], diff --git a/lib/autoconf/types.m4 b/lib/autoconf/types.m4 index 0e0e3f3..0774582 100644 --- a/lib/autoconf/types.m4 +++ b/lib/autoconf/types.m4 @@ -877,8 +877,10 @@ AC_DEFUN([AC_CHECK_MEMBER], [Tries to find if the field MEMBER exists in type AGGR, after including INCLUDES, setting cache variable VAR accordingly.])], [_$0_BODY])]dnl -[AS_LITERAL_IF([$1], [], [m4_fatal([$0: requires literal arguments])])]dnl -[m4_if(m4_index([$1], [.]), -1, [m4_fatal([$0: Did not see any dot in `$1'])])]dnl +[AS_LITERAL_IF(m4_translit([[$1]], [ ], [__]), [], + [m4_fatal([$0: requires literal arguments])])]dnl +[m4_if(m4_index([$1], [.]), [-1], + [m4_fatal([$0: Did not see any dot in `$1'])])]dnl [AS_VAR_PUSHDEF([ac_Member], [ac_cv_member_$1])]dnl [ac_fn_[]_AC_LANG_ABBREV[]_check_member "$LINENO" ]dnl [m4_bpatsubst([$1], [^\([^.]*\)\.\(.*\)], ["\1" "\2"]) "ac_Member" ]dnl diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4 index 6a43f21..52edba8 100644 --- a/lib/m4sugar/m4sh.m4 +++ b/lib/m4sugar/m4sh.m4 @@ -1515,17 +1515,28 @@ m4_dquote(m4_dquote(m4_defn([m4_cr_symbols2])))[[)) > 0)], [1], [], m4_dquote(m4_dquote(m4_defn([m4_cr_symbols1])))[[))], [0], [-])]) -# AS_LITERAL_IF(EXPRESSION, IF-LITERAL, IF-NOT-LITERAL) +# AS_LITERAL_IF(EXPRESSION, IF-LITERAL, IF-NOT-LITERAL, +# [IF-SIMPLE-REF = IF-NOT-LITERAL]) # ----------------------------------------------------- # If EXPRESSION has shell indirections ($var or `expr`), expand -# IF-LITERAL, else IF-NOT-LITERAL. -# This is an *approximation*: for instance EXPRESSION = `\$' is -# definitely a literal, but will not be recognized as such. +# IF-LITERAL, else IF-NOT-LITERAL. In some cases, IF-NOT-LITERAL +# must be complex to safely deal with ``, while a simpler +# expression IF-SIMPLE-REF can be used if the indirection +# involves only shell variable expansion (as in ${varname}). +# +# EXPRESSION is treated as a literal if it results in the same +# interpretation whether it is unquoted or contained within double +# quotes. Therefore, neither `\$' nor `a''b' is a literal, since both +# backslash and single quotes have different quoting behavior in the +# two contexts; and `a*' is not a literal, because it has different +# globbing. This macro is an *approximation*: it is possible that +# there are some EXPRESSIONs which the shell would treat as literals, +# but which this macro does not recognize. # # Why do we reject EXPRESSION expanding with `[' or `]' as a literal? # Because AS_TR_SH is MUCH faster if it can use m4_translit on literals # instead of m4_bpatsubst; but m4_translit is much tougher to do safely -# if `[' is translated. +# if `[' is translated. That, and file globbing matters. # # Note that the quadrigraph @S|@ can result in non-literals, but outright # rejecting all @ would make AC_INIT complain on its bug report address. @@ -1539,15 +1550,26 @@ m4_dquote(m4_dquote(m4_defn([m4_cr_symbols1])))[[))], [0], [-])]) # m4_index can scan the result. # # Rather than expand m4_defn every time AS_LITERAL_IF is expanded, we -# inline its expansion up front. +# inline its expansion up front. _AS_LITERAL_IF expands to the name +# of a macro that takes three arguments: IF-SIMPLE-REF, +# IF-NOT-LITERAL, IF-LITERAL. It also takes an optional argument of +# any additional characters to allow as literals (useful for AS_TR_SH +# and AS_TR_CPP to perform inline conversion of whitespace to _). The +# order of the arguments allows reuse of m4_default. m4_define([AS_LITERAL_IF], -[_$0(m4_expand([$1]), [$2], [$3])]) +[_$0(m4_expand([$1]))([$4], [$3], [$2])]) m4_define([_AS_LITERAL_IF], -[m4_if(m4_cond([m4_eval(m4_index([$1], address@hidden|@]) == -1)], [0], [], - [m4_index(m4_translit([$1], [[]`,#()]]]dnl -m4_dquote(m4_dquote(m4_defn([m4_cr_symbols2])))[[, [$$$]), [$])], - [-1], [-]), [-], [$2], [$3])]) +[m4_if(m4_index([$1], address@hidden|@]), [-1], [$0_(m4_translit([$1], [{}[]#()]]]dnl +m4_dquote(m4_dquote(m4_defn([m4_cr_symbols2])))[[[,address@hidden/$2-], +[$$``:::]))], [$0_NO])]) + +m4_define([_AS_LITERAL_IF_], +[m4_if([$1], [], [$0YES], + m4_translit([$1], [$]), [], [m4_default], [$0NO])]) + +m4_define([_AS_LITERAL_IF_YES], [$3]) +m4_define([_AS_LITERAL_IF_NO], [$2]) # AS_TMPDIR(PREFIX, [DIRECTORY = $TMPDIR [= /tmp]]) @@ -1736,7 +1758,7 @@ m4_defun_init([AS_TR_SH], [_$0(m4_expand([$1]))]) m4_define([_AS_TR_SH], -[_AS_LITERAL_IF([$1], [$0_LITERAL], [$0_INDIR])([$1])]) +[_AS_LITERAL_IF([$1], [ ])([], [$0_INDIR], [$0_LITERAL])([$1])]) m4_define([_AS_TR_SH_LITERAL], [m4_translit([[$1]], @@ -1768,7 +1790,7 @@ m4_defun_init([AS_TR_CPP], [_$0(m4_expand([$1]))]) m4_define([_AS_TR_CPP], -[_AS_LITERAL_IF([$1], [$0_LITERAL], [$0_INDIR])([$1])]) +[_AS_LITERAL_IF([$1], [ ])([], [$0_INDIR], [$0_LITERAL])([$1])]) m4_define([_AS_TR_CPP_LITERAL], [m4_translit([$1], @@ -1970,10 +1992,9 @@ m4_defun_init([AS_VAR_PUSHDEF], [_$0([$1], m4_expand([$2]))]) m4_define([_AS_VAR_PUSHDEF], -[_AS_LITERAL_IF([$2], - [m4_pushdef([$1], [_AS_TR_SH_LITERAL([$2])])], - [as_$1=_AS_TR_SH_INDIR([$2]) -m4_pushdef([$1], [$as_[$1]])])]) +[_AS_LITERAL_IF([$2], [ ])([], [as_$1=_AS_TR_SH_INDIR([$2]) +m4_pushdef([$1], [$as_[$1]])], +[m4_pushdef([$1], [_AS_TR_SH_LITERAL([$2])])])]) # AS_VAR_SET(VARIABLE, VALUE) diff --git a/tests/m4sh.at b/tests/m4sh.at index f34e6ba..6e3f8b3 100644 --- a/tests/m4sh.at +++ b/tests/m4sh.at @@ -1040,15 +1040,22 @@ AT_KEYWORDS([m4sh]) AT_DATA_M4SH([script.as], [[dnl AS_INIT echo AS_LITERAL_IF([lit], [ok], [ERR]) 1 -echo AS_LITERAL_IF([l$it], [ERR], [ok]) 2 -echo AS_LITERAL_IF([l`case a in b) ;; esac`it], [ERR], [ok]) 3 -m4_define([mac], [lit]) -echo AS_LITERAL_IF([mac], [ok], [ERR]) 4 -echo AS_LITERAL_IF([mac($, ``)], [ok], [ERR]) 5 +echo AS_LITERAL_IF([l-/.it], [ok], [ERR]) 2 +echo AS_LITERAL_IF([l''it], [ERR], [ok]) 3 +echo AS_LITERAL_IF([l$it], [ERR], [ok]) 4 +echo AS_LITERAL_IF([l$it], [ERR1], [ERR2], [ok]) 5 +echo AS_LITERAL_IF([l${it}], [ERR1], [ERR2], [ok]) 6 +echo AS_LITERAL_IF([l`case a in b) ;; esac`it], [ERR], [ok]) 7 +echo AS_LITERAL_IF([l`case a in b) ;; esac`it], [ERR1], [ok], [ERR2]) 8 +m4_define([mac], [l-/.it]) +echo AS_LITERAL_IF([mac], [ok], [ERR]) 9 +echo AS_LITERAL_IF([mac($, ``)], [ok], [ERR]) 10 m4_define([mac], [l$it]) -echo AS_LITERAL_IF([mac], [ERR], [ok]) 6 +echo AS_LITERAL_IF([mac], [ERR], [ok]) 11 +echo AS_LITERAL_IF([mac], [ERR1], [ERR2], [ok]) 12 m4_define([mac], [l``it]) -echo AS_LITERAL_IF([mac], [ERR], [ok]) 7 +echo AS_LITERAL_IF([mac], [ERR], [ok]) 13 +echo AS_LITERAL_IF([mac], [ERR1], [ok], [ERR2]) 14 ]]) AT_CHECK_M4SH @@ -1060,6 +1067,13 @@ ok 4 ok 5 ok 6 ok 7 +ok 8 +ok 9 +ok 10 +ok 11 +ok 12 +ok 13 +ok 14 ]]) AT_CLEANUP -- 1.6.6.1 From e8402265cfad0a2992a7c97a7fb7f5190e6c054d Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 27 Feb 2010 11:43:21 -0700 Subject: [PATCH 3/3] Use new AS_LITERAL_IF argument when appropriate. * lib/m4sugar/m4sh.m4 (AS_VAR_SET): Reduce m4 overhead. (AS_VAR_IF, AS_VAR_TEST_SET): Provide shorter variant for simple references. Suggested by Bruno Haible. Signed-off-by: Eric Blake --- ChangeLog | 8 ++++++++ lib/m4sugar/m4sh.m4 | 9 ++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 230d20e..7b082c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2010-03-01 Eric Blake + Use new AS_LITERAL_IF argument when appropriate. + * lib/m4sugar/m4sh.m4 (AS_VAR_SET): Reduce m4 overhead. + (AS_VAR_IF, AS_VAR_TEST_SET): Provide shorter variant for simple + references. + Suggested by Bruno Haible. + +2010-03-01 Eric Blake + Add optional argument to AS_LITERAL_IF. * lib/m4sugar/m4sh.m4 (_AS_LITERAL_IF): Rewrite to generate macro name, without using m4_cond. Allow more control over whitespace. diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4 index 52edba8..7552046 100644 --- a/lib/m4sugar/m4sh.m4 +++ b/lib/m4sugar/m4sh.m4 @@ -1941,7 +1941,9 @@ m4_define([AS_VAR_IF], [AS_LITERAL_IF([$1], [AS_IF([test "x$$1" = x""$2]], [AS_VAR_COPY([as_val], [$1]) - AS_IF([test "x$as_val" = x""$2]]), [$3], [$4])]) + AS_IF([test "x$as_val" = x""$2]], + [AS_IF([eval test \"x\$"$1"\" = x"_AS_ESCAPE([$2], [`], [\"$])"]]), +[$3], [$4])]) # AS_VAR_PUSHDEF and AS_VAR_POPDEF @@ -2005,7 +2007,7 @@ m4_pushdef([$1], [$as_[$1]])], m4_define([AS_VAR_SET], [AS_LITERAL_IF([$1], [$1=$2], - [eval "$1=AS_ESCAPE([$2])"])]) + [eval "$1=_AS_ESCAPE([$2], [`], [\"$])"])]) # AS_VAR_SET_IF(VARIABLE, IF-TRUE, IF-FALSE) @@ -2023,7 +2025,8 @@ m4_define([AS_VAR_SET_IF], m4_define([AS_VAR_TEST_SET], [AS_LITERAL_IF([$1], [test "${$1+set}" = set], - [{ as_var=$1; eval "test \"\${$as_var+set}\" = set"; }])]) + [{ as_var=$1; eval "test \"\${$as_var+set}\" = set"; }], + [eval "test \"\${$1+set}\"" = set])]) ## -------------------- ## -- 1.6.6.1