Add optional argument to AS_LITERAL_IF.

* lib/m4sugar/m4sh.m4 (_AS_LITERAL_IF): Rewrite to generate macro
name, without using m4_cond.
(_AS_LITERAL_IF_, _AS_LITERAL_IF_YES, _AS_LITERAL_IF_NO): New
helpers.
(AS_LITERAL_IF, AS_LITERAL_WORD_IF, _AS_TR_SH, _AS_TR_CPP)
(_AS_VAR_PUSHDEF): Adjust callers.
* lib/autoconf/types.m4 (AC_CHECK_ALIGNOF): Relax restrictions on
invalid bytes, since this allows inline struct layouts.
(_AC_CHECK_ALIGNOF): New helper macro.
* tests/m4sh.at (AS@&t@_LITERAL_IF): Update test.
* doc/autoconf.texi (Polymorphic Variables) <AS_LITERAL_IF>:
Update documentation.

Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Eric Blake 2010-03-16 18:12:02 -06:00
parent 71972deac8
commit e960d7be02
5 changed files with 88 additions and 39 deletions

View File

@ -1,5 +1,19 @@
2010-07-02 Eric Blake <eblake@redhat.com>
Add optional argument to AS_LITERAL_IF.
* lib/m4sugar/m4sh.m4 (_AS_LITERAL_IF): Rewrite to generate macro
name, without using m4_cond.
(_AS_LITERAL_IF_, _AS_LITERAL_IF_YES, _AS_LITERAL_IF_NO): New
helpers.
(AS_LITERAL_IF, AS_LITERAL_WORD_IF, _AS_TR_SH, _AS_TR_CPP)
(_AS_VAR_PUSHDEF): Adjust callers.
* lib/autoconf/types.m4 (AC_CHECK_ALIGNOF): Relax restrictions on
invalid bytes, since this allows inline struct layouts.
(_AC_CHECK_ALIGNOF): New helper macro.
* tests/m4sh.at (AS@&t@_LITERAL_IF): Update test.
* doc/autoconf.texi (Polymorphic Variables) <AS_LITERAL_IF>:
Update documentation.
Use AS_LITERAL_WORD_IF as appropriate.
* lib/autoconf/autoheader.m4 (AH_VERBATIM): Use new macro.
* lib/autoconf/general.m4 (AC_REQUIRE_AUX_FILE, AC_CACHE_VAL)

View File

@ -13298,15 +13298,20 @@ names and output shell code appropriate for both use cases. Behavior is
undefined if expansion of an indirect variable does not result in a
literal variable name.
@defmac AS_LITERAL_IF (@var{expression}, @ovar{if-literal}, @ovar{if-not})
@defmacx AS_LITERAL_WORD_IF (@var{expression}, @ovar{if-literal})
@defmac AS_LITERAL_IF (@var{expression}, @ovar{if-literal}, @ovar{if-not}, @
@dvar{if-simple-ref, @var{if-not}})
@defmacx AS_LITERAL_WORD_IF (@var{expression}, @ovar{if-literal}, @
@ovar{if-not}, @dvar{if-simple-ref, @var{if-not}})
@asindex{LITERAL_IF}
@asindex{LITERAL_WORD_IF}
If the expansion of @var{expression} is definitely a shell literal,
expand @var{if-literal}. If the expansion of @var{expression} looks
like it might contain shell indirections (such as @code{$var} or
@code{`expr`}), then @var{if-not} is expanded.
@code{AS_LITERAL_WORD_IF} only expands
@code{`expr`}), then @var{if-not} is expanded. Sometimes, it is
possible to output optimized code if @var{expression} consists only of
shell variable expansions (such as @code{$@{var@}}), in which case
@var{if-simple-ref} can be provided; but defaulting to @var{if-not}
should always be safe. @code{AS_LITERAL_WORD_IF} only expands
@var{if-literal} if @var{expression} looks like a single shell word,
containing no whitespace; while @code{AS_LITERAL_IF} allows whitespace
in @var{expression}.
@ -13327,7 +13332,7 @@ which uses an additional @code{m4_translit} to convert @samp{.} to
@samp{_}).
This example shows how to read the contents of the shell variable
@code{bar}, exercising both arguments to @code{AS_LITERAL_IF}. It
@code{bar}, exercising all three arguments to @code{AS_LITERAL_IF}. It
results in a script that will output the line @samp{hello} three times.
@example
@ -13335,7 +13340,8 @@ AC_DEFUN([MY_ACTION],
[AS_LITERAL_IF([$1],
[echo "$$1"],
[AS_VAR_COPY([tmp], [$1])
echo "$tmp"])])
echo "$tmp"],
[eval 'echo "$'"$1"\"])])
foo=bar bar=hello
MY_ACTION([bar])
MY_ACTION([`echo bar`])

View File

@ -785,25 +785,32 @@ AC_DEFINE_UNQUOTED(AS_TR_CPP(sizeof_$1), $AS_TR_SH([ac_cv_sizeof_$1]),
# AC_CHECK_ALIGNOF(TYPE, [INCLUDES = DEFAULT-INCLUDES])
# -----------------------------------------------------
# TYPE can include braces and semicolon, which AS_TR_CPP and AS_TR_SH
# (correctly) recognize as potential shell metacharacters. So we
# have to flatten problematic characters ourselves to guarantee that
# AC_DEFINE_UNQUOTED will see a literal.
AC_DEFUN([AC_CHECK_ALIGNOF],
[AS_LITERAL_IF([$1], [],
[m4_if(m4_index(m4_translit([[$1]], [`\"], [$]), [$]), [-1], [],
[m4_fatal([$0: requires literal arguments])])]dnl
[_$0([$1], [$2], m4_translit([[$1]], [{;}], [___]))])
m4_define([_AC_CHECK_ALIGNOF],
[# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
_AC_CACHE_CHECK_INT([alignment of $1], [AS_TR_SH([ac_cv_alignof_$1])],
_AC_CACHE_CHECK_INT([alignment of $1], [AS_TR_SH([ac_cv_alignof_$3])],
[(long int) offsetof (ac__type_alignof_, y)],
[AC_INCLUDES_DEFAULT([$2])
#ifndef offsetof
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
#endif
typedef struct { char x; $1 y; } ac__type_alignof_;],
[if test "$AS_TR_SH([ac_cv_type_$1])" = yes; then
[if test "$AS_TR_SH([ac_cv_type_$3])" = yes; then
AC_MSG_FAILURE([cannot compute alignment of $1], 77)
else
AS_TR_SH([ac_cv_alignof_$1])=0
AS_TR_SH([ac_cv_alignof_$3])=0
fi])
AC_DEFINE_UNQUOTED(AS_TR_CPP(alignof_$1), $AS_TR_SH([ac_cv_alignof_$1]),
AC_DEFINE_UNQUOTED(AS_TR_CPP(alignof_$3), $AS_TR_SH([ac_cv_alignof_$3]),
[The normal alignment of `$1', in bytes.])
])# AC_CHECK_ALIGNOF
@ -878,7 +885,8 @@ AC_DEFUN([AC_CHECK_MEMBER],
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
[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

View File

@ -1517,10 +1517,14 @@ 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 no shell indirections ($var or `expr`), expand
# IF-LITERAL, else IF-NOT-LITERAL.
# 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
@ -1528,8 +1532,9 @@ m4_dquote(m4_dquote(m4_defn([m4_cr_symbols1])))[[))], [0], [-])])
# assumption that it will be flattened to _). 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
# literal, because it has different globbing. Note, however, that
# while `${a+b}' is neither a literal nor a simple ref, `a+b' is a
# literal. 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.
#
@ -1548,30 +1553,44 @@ m4_dquote(m4_dquote(m4_defn([m4_cr_symbols1])))[[))], [0], [-])])
# anything that might be in a macro name, as well as comments, commas,
# or unbalanced parentheses. Valid shell variable characters and
# unambiguous literal characters are deleted (`a.b'), and remaining
# characters are normalized into `$' if they are special to the
# shell or to m4 parsing, and left alone otherwise.
# characters are normalized into `$' if they can form simple refs
# (${a}), `+' if they can potentially form literals (a+b), ``' if they
# can interfere with m4 parsing, or left alone otherwise. If both `$'
# and `+' are left, it is treated as a complex reference (${a+b}),
# even though it could technically be a simple reference (${a}+b).
# _AS_LITERAL_IF_ only has to check for an empty string after removing
# the normalized characters.
# one of the two normalized characters.
#
# 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], [@S|@]) == -1)], [0], [],
[m4_index(m4_translit([$1], [[]`'\"$4,#()]]]dnl
m4_dquote(m4_dquote(m4_defn([m4_cr_symbols2])))[[, [$$$$$$$5]), [$])],
[-1], [-]), [-], [$2], [$3])])
[m4_if(m4_index([$1], [@S|@]), [-1], [$0_(m4_translit([$1],
[-:%/@{}[]#(),.$2]]]m4_dquote(m4_dquote(m4_defn([m4_cr_symbols2])))[[,
[+++++$$`````]))], [$0_NO])])
# AS_LITERAL_WORD_IF(EXPRESSION, IF-LITERAL, IF-NOT-LITERAL)
m4_define([_AS_LITERAL_IF_],
[m4_if(m4_translit([$1], [+]), [], [$0YES],
m4_translit([$1], [$]), [], [m4_default], [$0NO])])
m4_define([_AS_LITERAL_IF_YES], [$3])
m4_define([_AS_LITERAL_IF_NO], [$2])
# AS_LITERAL_WORD_IF(EXPRESSION, IF-LITERAL, IF-NOT-LITERAL,
# [IF-SIMPLE-REF = IF-NOT-LITERAL])
# ----------------------------------------------------------
# Like AS_LITERAL_IF, except that spaces and tabs in EXPRESSION
# are treated as non-literal.
m4_define([AS_LITERAL_WORD_IF],
[_AS_LITERAL_IF(m4_expand([$1]), [$2], [$3], [ ][
], [$$$])])
[_AS_LITERAL_IF(m4_expand([$1]))([$4], [$3], [$2])])
# AS_TMPDIR(PREFIX, [DIRECTORY = $TMPDIR [= /tmp]])
@ -1760,7 +1779,8 @@ 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]],
@ -1792,7 +1812,8 @@ 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],
@ -1994,10 +2015,10 @@ 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)

View File

@ -1085,8 +1085,8 @@ echo AS_LITERAL_IF([lit], [ok], [ERR]) 1
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], [ok], [fixme]) 5
echo AS_LITERAL_IF([l${it}], [ERR1], [ok], [fixme]) 6
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])
@ -1094,7 +1094,7 @@ 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]) 11
echo AS_LITERAL_IF([mac], [ERR1], [ok], [fixme]) 12
echo AS_LITERAL_IF([mac], [ERR1], [ERR2], [ok]) 12
m4_define([mac], [l``it])
echo AS_LITERAL_IF([mac], [ERR], [ok]) 13
echo AS_LITERAL_IF([mac], [ERR1], [ok], [ERR2]) 14