From: Akim Demaille Date: Wed, 10 May 2000 16:16:31 +0000 (+0000) Subject: * libm4.m4 (m4_foreach): Rewritten so that it does not require X-Git-Tag: autoconf-2.50~936 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=87c43d275c3501186925b847e49ca6dc60e4d154;p=thirdparty%2Fautoconf.git * libm4.m4 (m4_foreach): Rewritten so that it does not require lists in between parens. (m4_foreach_quoted): new copy of the previous `m4_foreach' which is still used by `m4_wrap'. * acgeneral.m4 (AC_INCLUDE, AC_INCLUDES): Removed. (AC_FOREACH): Don't use parens with `m4_foreach'. (AC_CHECK_MEMBER, AC_CHECK_DECLS, AC_CHECK_TYPES): Adjust the description. * acspecific.m4 (AC_STRUCT_TIMEZONE, AC_STRUCT_ST_BLKSIZE, AC_STRUCT_ST_BLOCKS, AC_STRUCT_ST_RDEV): Adjust. * autoconf.texi (AC_CHECK_MEMBER, AC_CHECK_DECLS, AC_CHECK_TYPES): Adjust their documentation. (AC_INCLUDE): Undocument. * tests/semantics.m4: Adjust. * tests/actest.m4: Rename as... * tests/aclocal.m4: this. * tests/atspecific.m4: No longer include actest.m4. * tests/torture.m4: Likewise. * tests/Makefile.am: Adjust. --- diff --git a/ChangeLog b/ChangeLog index ef78ccfbd..77622047f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2000-05-10 Akim Demaille + + * libm4.m4 (m4_foreach): Rewritten so that it does not require + lists in between parens. + (m4_foreach_quoted): new copy of the previous `m4_foreach' which + is still used by `m4_wrap'. + * acgeneral.m4 (AC_INCLUDE, AC_INCLUDES): Removed. + (AC_FOREACH): Don't use parens with `m4_foreach'. + (AC_CHECK_MEMBER, AC_CHECK_DECLS, AC_CHECK_TYPES): Adjust the + description. + * acspecific.m4 (AC_STRUCT_TIMEZONE, AC_STRUCT_ST_BLKSIZE, + AC_STRUCT_ST_BLOCKS, AC_STRUCT_ST_RDEV): Adjust. + * autoconf.texi (AC_CHECK_MEMBER, AC_CHECK_DECLS, AC_CHECK_TYPES): + Adjust their documentation. + (AC_INCLUDE): Undocument. + * tests/semantics.m4: Adjust. + * tests/actest.m4: Rename as... + * tests/aclocal.m4: this. + * tests/atspecific.m4: No longer include actest.m4. + * tests/torture.m4: Likewise. + * tests/Makefile.am: Adjust. + 2000-05-10 Akim Demaille * doc/autoconf.texi (Obsolete Macros): Document `AU_DEFUN'. diff --git a/acgeneral.m4 b/acgeneral.m4 index 2262dc664..28f1c90b9 100644 --- a/acgeneral.m4 +++ b/acgeneral.m4 @@ -647,7 +647,7 @@ define(AC_TR_SH, # ive ], [-Var-])end # => -active--b--active-end define([AC_FOREACH], -[m4_foreach([$1], (m4_split(m4_strip(m4_join([$2])))), [$3])]) +[m4_foreach([$1], m4_split(m4_strip(m4_join([$2]))), [$3])]) @@ -1446,18 +1446,6 @@ fi])dnl ])# _AC_INIT_VERSION -# AC_INCLUDE(FILE) -# ---------------- -# Wrapper around m4_include. -define(AC_INCLUDE, -[m4_include([$1])]) - - -# AC_INCLUDES((FILE, ...)) -# ------------------------ -define(AC_INCLUDES, -[m4_foreach([File], [$1], [AC_INCLUDE(File)])]) - # _AC_INIT_PREPARE_ENVIRONMENT # ---------------------------- @@ -2412,13 +2400,11 @@ AC_VAR_POPDEF([ac_Member])dnl ])# AC_CHECK_MEMBER -# AC_CHECK_MEMBER((AGGREGATE.MEMBER, ...), +# AC_CHECK_MEMBER([AGGREGATE.MEMBER, ...], # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND] # [INCLUDES]) # -------------------------------------------------------- -# The first argument is an m4 list. First because we want to -# promote m4 lists, and second because anyway there can be spaces -# in some types (struct etc.). +# The first argument is an m4 list. AC_DEFUN(AC_CHECK_MEMBERS, [m4_foreach([AC_Member], [$1], [AC_SPECIALIZE([AC_CHECK_MEMBER], AC_Member, @@ -3081,13 +3067,13 @@ AC_VAR_POPDEF([ac_Symbol])dnl ])# AC_CHECK_DECL -# AC_CHECK_DECLS(SYMBOL, +# AC_CHECK_DECLS(SYMBOLS, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], # [INCLUDES]) # -------------------------------------------------------- # Defines HAVE_DECL_SYMBOL to 1 if declared, 0 otherwise. See the # documentation for a detailed explanation of this difference with -# other AC_CHECK_*S macros. +# other AC_CHECK_*S macros. SYMBOLS is an m4 list. AC_DEFUN([AC_CHECK_DECLS], [m4_foreach([AC_Symbol], [$1], [AC_SPECIALIZE([AC_CHECK_DECL], AC_Symbol, @@ -3322,11 +3308,11 @@ AC_VAR_POPDEF([ac_Type])dnl ])# _AC_CHECK_TYPE_NEW -# AC_CHECK_TYPES((TYPE, ...), +# AC_CHECK_TYPES(TYPES, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], # [INCLUDES]) # -------------------------------------------------------- -# TYPEs is an m4 list. There are no ambiguities here, we mean the newer +# TYPES is an m4 list. There are no ambiguities here, we mean the newer # AC_CHECK_TYPE. AC_DEFUN([AC_CHECK_TYPES], [m4_foreach([AC_Type], [$1], diff --git a/acspecific.m4 b/acspecific.m4 index 79b43f32f..e7649735e 100644 --- a/acspecific.m4 +++ b/acspecific.m4 @@ -1735,7 +1735,7 @@ fi # external array `tzname' is found, define `HAVE_TZNAME'. AC_DEFUN(AC_STRUCT_TIMEZONE, [AC_REQUIRE([AC_STRUCT_TM])dnl -AC_CHECK_MEMBERS((struct tm.tm_zone),,,[#include +AC_CHECK_MEMBERS([struct tm.tm_zone],,,[#include #include <$ac_cv_struct_tm> ]) if test "$ac_cv_member_struct_tm_tm_zone" = yes; then @@ -1773,7 +1773,7 @@ AU_DEFUN(AC_STRUCT_ST_BLKSIZE, your code should no longer depend upon `HAVE_ST_BLKSIZE', but `HAVE_STRUCT_STAT_ST_BLKSIZE'. Remove this AC_WARNING and the `AC_DEFINE' when you adjust the code.]) -AC_CHECK_MEMBERS((struct stat.st_blksize), +AC_CHECK_MEMBERS([struct stat.st_blksize], [AC_DEFINE(HAVE_ST_BLKSIZE, 1, [Define if your `struct stat' has `st_blksize'. Deprecated, use @@ -1793,13 +1793,13 @@ AC_CHECK_MEMBERS((struct stat.st_blksize), # this macro, so don't obsolete it right now. # # AC_OBSOLETE([$0], [; replace it with -# AC_CHECK_MEMBERS((struct stat.st_blocks), +# AC_CHECK_MEMBERS([struct stat.st_blocks], # [AC_LIBOBJ([fileblocks])]) # Please note that it will define `HAVE_STRUCT_STAT_ST_BLOCKS', # and not `HAVE_ST_BLOCKS'.])dnl # AC_DEFUN(AC_STRUCT_ST_BLOCKS, -[AC_CHECK_MEMBERS((struct stat.st_blocks), +[AC_CHECK_MEMBERS([struct stat.st_blocks], [AC_DEFINE(HAVE_ST_BLOCKS, 1, [Define if your `struct stat' has `st_blocks'. Deprecated, use @@ -1818,11 +1818,11 @@ AU_DEFUN(AC_STRUCT_ST_RDEV, your code should no longer depend upon `HAVE_ST_RDEV', but `HAVE_STRUCT_STAT_ST_RDEV'. Remove this AC_WARNING and the `AC_DEFINE' when you adjust the code.]) -AC_CHECK_MEMBERS((struct stat.st_rdev), - [AC_DEFINE(HAVE_ST_RDEV, 1, - [Define if your `struct stat' has `st_rdev'. - Deprecated, use - `HAVE_STRUCT_STAT_ST_RDEV' instead.])],, +AC_CHECK_MEMBERS([struct stat.st_rdev], + [AC_DEFINE(HAVE_ST_RDEV, 1, + [Define if your `struct stat' has `st_rdev'. + Deprecated, use `HAVE_STRUCT_STAT_ST_RDEV' + instead.])],, [#include #include ])dnl diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 949d45357..e40829b8e 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -1223,27 +1223,29 @@ with @samp{--srcdir}; this is a safety check. @xref{Invoking configure}, for more information. @end defmac -Small packages may store all their macros in @code{aclocal.m4}. As the -set of macros grows, or for maintenance reasons, a maintainer may prefer -to split the macros in several files. In this case, Autoconf must be -told which files to load, and in which order. - -@defmac AC_INCLUDE (@var{file}...) -@maindex INCLUDE -@c FIXME: There is no longer shell globbing. -Read the macro definitions that appear in the listed files. A list of -space-separated filenames or shell globbing patterns is expected. The -files will be read in the order they're listed. - -Because the order of definition of macros is important (only the last -definition of a macro is used), beware that it is @code{AC_INIT} that -loads @file{acsite.m4} and @file{aclocal.m4}. Note that -@code{AC_INCLUDE}ing a file before @code{AC_INIT} or within -@file{aclocal.m4} is different from doing so after @code{AC_INIT}: in -the latter case, non-macro lines from included files may end up in the -@file{configure} script, whereas in the former case, they'd be discarded -just like any text that appear before @code{AC_INIT}. -@end defmac +@c FIXME: Remove definitively once --install explained. +@c +@c Small packages may store all their macros in @code{aclocal.m4}. As the +@c set of macros grows, or for maintenance reasons, a maintainer may prefer +@c to split the macros in several files. In this case, Autoconf must be +@c told which files to load, and in which order. +@c +@c @defmac AC_INCLUDE (@var{file}...) +@c @maindex INCLUDE +@c @c FIXME: There is no longer shell globbing. +@c Read the macro definitions that appear in the listed files. A list of +@c space-separated filenames or shell globbing patterns is expected. The +@c files will be read in the order they're listed. +@c +@c Because the order of definition of macros is important (only the last +@c definition of a macro is used), beware that it is @code{AC_INIT} that +@c loads @file{acsite.m4} and @file{aclocal.m4}. Note that +@c @code{AC_INCLUDE}ing a file before @code{AC_INIT} or within +@c @file{aclocal.m4} is different from doing so after @code{AC_INIT}: in +@c the latter case, non-macro lines from included files may end up in the +@c @file{configure} script, whereas in the former case, they'd be discarded +@c just like any text that appear before @code{AC_INIT}. +@c @end defmac Packages that do manual configuration or use the @code{install} program might need to tell @code{configure} where to find some other shell @@ -2209,7 +2211,7 @@ underscore is mapped to an underscore. For instance @example -AC_CHECK_TYPES((struct $Expensive*)) +AC_CHECK_TYPES(struct $Expensive*) @end example @noindent @@ -3413,10 +3415,10 @@ r-value, not if it is really declared, because it is much safer to avoid introducing extra declarations when not needed. @end defmac -@defmac AC_CHECK_DECLS ((@var{symbol}, @dots{}), @ovar{action-if-found}, @ovar{action-if-not-found}, @ovar{includes}) +@defmac AC_CHECK_DECLS (@var{symbols}, @ovar{action-if-found}, @ovar{action-if-not-found}, @ovar{includes}) @maindex CHECK_DECLS @cvindex HAVE_DECL_@var{symbol} -For each given @var{symbol} (comma separated list), define +For each of the @var{symbols} (comma separated list), define @code{HAVE_DECL_@var{symbol}} (in all capitals) to @samp{1} if @var{symbol} is declared, otherwise to @samp{0}. If @var{action-if-not-found} is given, it is additional shell code to @@ -3425,8 +3427,9 @@ execute when one of the function declarations is needed, otherwise This macro uses an m4 list as first argument: @example -AC_CHECK_DECLS((strlen)) -AC_CHECK_DECLS((malloc, realloc, calloc, free)) +AC_CHECK_DECLS(strdup) +AC_CHECK_DECLS([strlen]) +AC_CHECK_DECLS([malloc, realloc, calloc, free]) @end example Unlike the other @samp{AC_CHECK_*S} macros, when a @var{symbol} is not @@ -3558,16 +3561,16 @@ AC_CHECK_MEMBER(struct passwd.pw_gecos,, @end example @end defmac -@defmac AC_CHECK_MEMBERS ((@var{aggregate}.@var{member}, @dots{}), @ovar{action-if-found}, @ovar{action-if-not-found}, @ovar{includes}) +@defmac AC_CHECK_MEMBERS (@var{members}, @ovar{action-if-found}, @ovar{action-if-not-found}, @ovar{includes}) @maindex CHECK_MEMBERS -Check for the existence of each aggregate members using the previous -macro. When @var{member} belong to @var{aggregate}, define -@code{HAVE_@var{aggregate}_@var{member}} (in all capitals, with spaces -and dot replaced by underscore). +Check for the existence of each @samp{@var{aggregate}.@var{member}} of +@var{members} using the previous macro. When @var{member} belong to +@var{aggregate}, define @code{HAVE_@var{aggregate}_@var{member}} (in all +capitals, with spaces and dot replaced by underscore). This macro uses m4 lists: @example -AC_CHECK_MEMBERS((struct stat.st_rdev, struct stat.st_blksize)) +AC_CHECK_MEMBERS([struct stat.st_rdev, struct stat.st_blksize]) @end example @end defmac @@ -3663,19 +3666,19 @@ or defined by the @ovar{includes} (@pxref{Default Includes}). @end defmac -@defmac AC_CHECK_TYPES ((@var{type}, @dots{}), @ovar{action-if-found}, @ovar{action-if-not-found}, @ovar{includes}) +@defmac AC_CHECK_TYPES (@var{types}, @ovar{action-if-found}, @ovar{action-if-not-found}, @ovar{includes}) @maindex CHECK_TYPES -For each defined @var{type} define @code{HAVE_@var{type}} (in all -capitals). If no @var{includes} are specified, the default includes are -used (@pxref{Default Includes}). If @var{action-if-found} is given, it -is additional shell code to execute when one of the types is found. If -@var{action-if-not-found} is given, it is executed when one of the types -is not found. +For each @var{type} of the @var{types} which is defined, define +@code{HAVE_@var{type}} (in all capitals). If no @var{includes} are +specified, the default includes are used (@pxref{Default Includes}). If +@var{action-if-found} is given, it is additional shell code to execute +when one of the types is found. If @var{action-if-not-found} is given, +it is executed when one of the types is not found. This macro uses m4 lists: @example -AC_CHECK_TYPES((ptrdiff_t)) -AC_CHECK_TYPES((unsigned long long, uintmax_t)) +AC_CHECK_TYPES(ptrdiff_t) +AC_CHECK_TYPES([unsigned long long, uintmax_t]) @end example @end defmac diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4 index 2262dc664..28f1c90b9 100644 --- a/lib/autoconf/general.m4 +++ b/lib/autoconf/general.m4 @@ -647,7 +647,7 @@ define(AC_TR_SH, # ive ], [-Var-])end # => -active--b--active-end define([AC_FOREACH], -[m4_foreach([$1], (m4_split(m4_strip(m4_join([$2])))), [$3])]) +[m4_foreach([$1], m4_split(m4_strip(m4_join([$2]))), [$3])]) @@ -1446,18 +1446,6 @@ fi])dnl ])# _AC_INIT_VERSION -# AC_INCLUDE(FILE) -# ---------------- -# Wrapper around m4_include. -define(AC_INCLUDE, -[m4_include([$1])]) - - -# AC_INCLUDES((FILE, ...)) -# ------------------------ -define(AC_INCLUDES, -[m4_foreach([File], [$1], [AC_INCLUDE(File)])]) - # _AC_INIT_PREPARE_ENVIRONMENT # ---------------------------- @@ -2412,13 +2400,11 @@ AC_VAR_POPDEF([ac_Member])dnl ])# AC_CHECK_MEMBER -# AC_CHECK_MEMBER((AGGREGATE.MEMBER, ...), +# AC_CHECK_MEMBER([AGGREGATE.MEMBER, ...], # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND] # [INCLUDES]) # -------------------------------------------------------- -# The first argument is an m4 list. First because we want to -# promote m4 lists, and second because anyway there can be spaces -# in some types (struct etc.). +# The first argument is an m4 list. AC_DEFUN(AC_CHECK_MEMBERS, [m4_foreach([AC_Member], [$1], [AC_SPECIALIZE([AC_CHECK_MEMBER], AC_Member, @@ -3081,13 +3067,13 @@ AC_VAR_POPDEF([ac_Symbol])dnl ])# AC_CHECK_DECL -# AC_CHECK_DECLS(SYMBOL, +# AC_CHECK_DECLS(SYMBOLS, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], # [INCLUDES]) # -------------------------------------------------------- # Defines HAVE_DECL_SYMBOL to 1 if declared, 0 otherwise. See the # documentation for a detailed explanation of this difference with -# other AC_CHECK_*S macros. +# other AC_CHECK_*S macros. SYMBOLS is an m4 list. AC_DEFUN([AC_CHECK_DECLS], [m4_foreach([AC_Symbol], [$1], [AC_SPECIALIZE([AC_CHECK_DECL], AC_Symbol, @@ -3322,11 +3308,11 @@ AC_VAR_POPDEF([ac_Type])dnl ])# _AC_CHECK_TYPE_NEW -# AC_CHECK_TYPES((TYPE, ...), +# AC_CHECK_TYPES(TYPES, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], # [INCLUDES]) # -------------------------------------------------------- -# TYPEs is an m4 list. There are no ambiguities here, we mean the newer +# TYPES is an m4 list. There are no ambiguities here, we mean the newer # AC_CHECK_TYPE. AC_DEFUN([AC_CHECK_TYPES], [m4_foreach([AC_Type], [$1], diff --git a/lib/autoconf/specific.m4 b/lib/autoconf/specific.m4 index 79b43f32f..e7649735e 100644 --- a/lib/autoconf/specific.m4 +++ b/lib/autoconf/specific.m4 @@ -1735,7 +1735,7 @@ fi # external array `tzname' is found, define `HAVE_TZNAME'. AC_DEFUN(AC_STRUCT_TIMEZONE, [AC_REQUIRE([AC_STRUCT_TM])dnl -AC_CHECK_MEMBERS((struct tm.tm_zone),,,[#include +AC_CHECK_MEMBERS([struct tm.tm_zone],,,[#include #include <$ac_cv_struct_tm> ]) if test "$ac_cv_member_struct_tm_tm_zone" = yes; then @@ -1773,7 +1773,7 @@ AU_DEFUN(AC_STRUCT_ST_BLKSIZE, your code should no longer depend upon `HAVE_ST_BLKSIZE', but `HAVE_STRUCT_STAT_ST_BLKSIZE'. Remove this AC_WARNING and the `AC_DEFINE' when you adjust the code.]) -AC_CHECK_MEMBERS((struct stat.st_blksize), +AC_CHECK_MEMBERS([struct stat.st_blksize], [AC_DEFINE(HAVE_ST_BLKSIZE, 1, [Define if your `struct stat' has `st_blksize'. Deprecated, use @@ -1793,13 +1793,13 @@ AC_CHECK_MEMBERS((struct stat.st_blksize), # this macro, so don't obsolete it right now. # # AC_OBSOLETE([$0], [; replace it with -# AC_CHECK_MEMBERS((struct stat.st_blocks), +# AC_CHECK_MEMBERS([struct stat.st_blocks], # [AC_LIBOBJ([fileblocks])]) # Please note that it will define `HAVE_STRUCT_STAT_ST_BLOCKS', # and not `HAVE_ST_BLOCKS'.])dnl # AC_DEFUN(AC_STRUCT_ST_BLOCKS, -[AC_CHECK_MEMBERS((struct stat.st_blocks), +[AC_CHECK_MEMBERS([struct stat.st_blocks], [AC_DEFINE(HAVE_ST_BLOCKS, 1, [Define if your `struct stat' has `st_blocks'. Deprecated, use @@ -1818,11 +1818,11 @@ AU_DEFUN(AC_STRUCT_ST_RDEV, your code should no longer depend upon `HAVE_ST_RDEV', but `HAVE_STRUCT_STAT_ST_RDEV'. Remove this AC_WARNING and the `AC_DEFINE' when you adjust the code.]) -AC_CHECK_MEMBERS((struct stat.st_rdev), - [AC_DEFINE(HAVE_ST_RDEV, 1, - [Define if your `struct stat' has `st_rdev'. - Deprecated, use - `HAVE_STRUCT_STAT_ST_RDEV' instead.])],, +AC_CHECK_MEMBERS([struct stat.st_rdev], + [AC_DEFINE(HAVE_ST_RDEV, 1, + [Define if your `struct stat' has `st_rdev'. + Deprecated, use `HAVE_STRUCT_STAT_ST_RDEV' + instead.])],, [#include #include ])dnl diff --git a/libm4.m4 b/libm4.m4 index 7f4346ae8..e349268ba 100644 --- a/libm4.m4 +++ b/libm4.m4 @@ -433,21 +433,23 @@ ifelse($1, [$2], [], # # The example in the documentation is: # -# | # foreach(x, (item_1, item_2, ..., item_n), stmt) -# | define(`foreach', -# | `pushdef(`$1', `')_foreach(`$1', `$2', `$3')popdef(`$1')') -# | define(`_arg1', `$1') -# | define(`_foreach', -# | `ifelse(`$2', `()', , -# | `define(`$1', _arg1$2)$3`'_foreach(`$1', (shift$2), `$3')')') +# | # foreach(VAR, (LIST), STMT) +# | define([foreach], +# | [pushdef([$1])_foreach([$1], [$2], [$3])popdef([$1])]) +# | define([_arg1], [$1]) +# | define([_foreach], +# | [ifelse([$2], [()], , +# | [define([$1], _arg1$2)$3[]_foreach([$1], +# | (shift$2), +# | [$3])])]) # # But then if you run # # | define(a, 1) # | define(b, 2) # | define(c, 3) -# | foreach(`f', `(`a', `(b', `c)')', `echo f -# | ') +# | foreach([f], [([a], [(b], [c)])], [echo f +# | ]) # # it gives # @@ -456,15 +458,20 @@ ifelse($1, [$2], [], # # which is not what is expected. # -# Once you understood this, you turn yourself into a quoting wizard, -# and come up with the following solution: -# -# | # foreach(x, (item_1, item_2, ..., item_n), stmt) -# | define(`foreach', `pushdef(`$1', `')_foreach($@)popdef(`$1')') -# | define(`_arg1', ``$1'') -# | define(`_foreach', -# | `ifelse($2, `()', , -# | `define(`$1', `_arg1$2')$3`'_foreach(`$1', `(shift$2)', `$3')')') +# Of course the problem is that many quotes are missing. So you add +# plenty of quotes at random places, until you reach the expected +# result. Alternatively, if you are a quoting wizard, you directly +# reach the following implementation (but if you really did, then +# apply to the maintenance of libm4!). +# +# | # foreach(VAR, (LIST), STMT) +# | define([foreach], [pushdef([$1])_foreach($@)popdef([$1])]) +# | define([_arg1], [[$1]]) +# | define([_foreach], +# | [ifelse($2, [()], , +# | [define([$1], [_arg1$2])$3[]_foreach([$1], +# | [(shift$2)], +# | [$3])])]) # # which this time answers # @@ -473,30 +480,59 @@ ifelse($1, [$2], [], # => echo c) # # Bingo! +# +# Well, not quite. +# +# With a better look, you realize that the parens are more a pain than +# a help: since anyway you need to quote properly the list, you end up +# with always using an outermost pair of parens and an outermost pair +# of quotes. Rejecting the parens both eases the implementation, and +# simplifies the use: +# +# | # foreach(VAR, (LIST), STMT) +# | define([foreach], [pushdef([$1])_foreach($@)popdef([$1])]) +# | define([_arg1], [$1]) +# | define([_foreach], +# | [ifelse($2, [], , +# | [define([$1], [_arg1($2)])$3[]_foreach([$1], +# | [shift($2)], +# | [$3])])]) +# +# +# Now, just replace the `$2' with `m4_quote($2)' in the outer `ifelse' +# to improve robustness, and you come up with a quite satisfactory +# implementation. # m4_foreach(VARIABLE, LIST, EXPRESSION) # -------------------------------------- -# Expand EXPRESSION assigning to VARIABLE each value of the LIST -# (LIST should have the form `[(item_1, item_2, ..., item_n)]'), -# i.e. the whole list should be *quoted*. Quote members too if -# you don't want them to be expanded. +# +# Expand EXPRESSION assigning each value of the LIST to VARIABLE. +# LIST should have the form `item_1, item_2, ..., item_n', i.e. the +# whole list must *quoted*. Quote members too if you don't want them +# to be expanded. # # This macro is robust to active symbols: -# define(active, ACTIVE) -# m4_foreach([Var], [([active], [b], [active])], [-Var-])end -# => -active--b--active-end -define(m4_foreach, -[pushdef([$1], [])_m4_foreach($@)popdef([$1])]) +# | define(active, [ACT, IVE]) +# | m4_foreach(Var, [active, active], [-Var-]) +# => -ACT--IVE--ACT--IVE- +# +# | m4_foreach(Var, [[active], [active]], [-Var-]) +# => -ACT, IVE--ACT, IVE- +# +# | m4_foreach(Var, [[[active]], [[active]]], [-Var-]) +# => -active--active- +define([m4_foreach], +[pushdef([$1])_m4_foreach($@)popdef([$1])]) # Low level macros used to define m4_foreach. # Use m4_define for temporaries. -define(m4_car, [[$1]]) -define(_m4_foreach, -[ifelse($2, [()], , - [m4_define([$1], [m4_car$2])$3[]_m4_foreach([$1], - [(m4_shift$2)], - [$3])])]) +define([m4_car], [$1]) +define([_m4_foreach], +[ifelse(m4_quote($2), [], [], + [m4_define([$1], [m4_car($2)])$3[]_m4_foreach([$1], + [m4_shift($2)], + [$3])])]) ## ----------------- ## @@ -663,6 +699,22 @@ ifdef([$1], [defn([$1]), ])[$2])]) ## Helping macros to display strings. ## ## ----------------------------------- ## +# m4_foreach_quoted(VARIABLE, LIST, EXPRESSION) +# --------------------------------------------- +# FIXME: This macro should not exists. Currently it's used only in +# m4_wrap, which needs to be rewritten. But it's godam hard. +define(m4_foreach_quoted, +[pushdef([$1], [])_m4_foreach_quoted($@)popdef([$1])]) + +# Low level macros used to define m4_foreach. +# Use m4_define for temporaries. +define(m4_car_quoted, [[$1]]) +define(_m4_foreach_quoted, +[ifelse($2, [()], , + [m4_define([$1], [m4_car_quoted$2])$3[]_m4_foreach_quoted([$1], + [(m4_shift$2)], + [$3])])]) + # m4_wrap(STRING, [PREFIX], [FIRST-PREFIX], [WIDTH]) # -------------------------------------------------- @@ -711,7 +763,7 @@ m4_Prefix1[]dnl ifelse(m4_eval(m4_Cursor > len(m4_Prefix)), 1, [define([m4_Cursor], len(m4_Prefix)) m4_Prefix])[]dnl -m4_foreach([m4_Word], (m4_split(m4_strip(m4_join([$1])))), +m4_foreach_quoted([m4_Word], (m4_split(m4_strip(m4_join([$1])))), [m4_define([m4_Cursor], m4_eval(m4_Cursor + len(m4_Word) + 1))dnl dnl New line if too long, else insert a space unless it is the first dnl of the words. diff --git a/tests/Makefile.am b/tests/Makefile.am index fc05744d2..e8259ee21 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,7 +24,7 @@ SUITE = torture.m4 semantics.m4 syntax.m4 base.m4 tools.m4 # We don't actually distribute the testsuite, since one only # needs m4 to build it, m4 being required anyway to install Autoconf. -EXTRA_DIST = atgeneral.m4 atspecific.m4 suite.m4 macros.m4 actest.m4 $(SUITE) +EXTRA_DIST = atgeneral.m4 atspecific.m4 suite.m4 macros.m4 aclocal.m4 $(SUITE) PERL = perl diff --git a/tests/Makefile.in b/tests/Makefile.in index 0825544d5..fb16c7bb2 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -69,7 +69,7 @@ SUITE = torture.m4 semantics.m4 syntax.m4 base.m4 tools.m4 # We don't actually distribute the testsuite, since one only # needs m4 to build it, m4 being required anyway to install Autoconf. -EXTRA_DIST = atgeneral.m4 atspecific.m4 suite.m4 macros.m4 actest.m4 $(SUITE) +EXTRA_DIST = atgeneral.m4 atspecific.m4 suite.m4 macros.m4 aclocal.m4 $(SUITE) PERL = perl diff --git a/tests/actest.m4 b/tests/aclocal.m4 similarity index 100% rename from tests/actest.m4 rename to tests/aclocal.m4 diff --git a/tests/atspecific.m4 b/tests/atspecific.m4 index a09d540b8..90566648a 100644 --- a/tests/atspecific.m4 +++ b/tests/atspecific.m4 @@ -84,8 +84,7 @@ AT_DEFINE(AT_TEST_MACRO, dnl Produce the configure.in AT_DATA(configure.in, -[AC_INCLUDE(actest.m4) -AC_INIT +[AC_INIT AC_CONFIG_AUX_DIR($top_srcdir) AC_CONFIG_HEADER(config.h:config.hin) AC_ENV_SAVE(expout) @@ -104,7 +103,7 @@ AT_CHECK([top_srcdir=$top_srcdir ./configure], 0, ignore, ignore) test -n "$at_verbose" && echo "--- config.log" && cat config.log dnl Some tests might exit prematurely when they find a problem, in -dnl which case `env-after is probably missing. Don't check it then. +dnl which case `env-after' is probably missing. Don't check it then. if test -f env-after; then AT_CHECK([cat env-after], 0, expout) fi diff --git a/tests/semantics.m4 b/tests/semantics.m4 index ce6c2aead..e87578316 100644 --- a/tests/semantics.m4 +++ b/tests/semantics.m4 @@ -31,8 +31,8 @@ AC_CHECK_LIB(m, cos,, exit 1)]) # Check that it performs the correct actions: # Must define NEED_NO_DECL, but not NEED_YES_DECL. AT_TEST_MACRO(AC_CHECK_DECLS, -[AC_CHECK_DECLS((yes, no),,, - [int yes = 1;])], +[[AC_CHECK_DECLS([yes, no],,, + [int yes = 1;])]], [AT_CHECK_DEFINES( [#define HAVE_DECL_NO 0 #define HAVE_DECL_YES 1 @@ -70,8 +70,8 @@ AT_TEST_MACRO(AC_CHECK_HEADERS, # Check that it performs the correct actions. # Must define HAVE_STRUCT_YES_S_YES, but not HAVE_STRUCT_YES_S_NO. AT_TEST_MACRO(AC_CHECK_MEMBERS, -[AC_CHECK_MEMBERS((struct yes_s.yes, struct yes_s.no),,, - [struct yes_s { int yes ;} ;])], +[[AC_CHECK_MEMBERS([struct yes_s.yes, struct yes_s.no],,, + [struct yes_s { int yes ;} ;])]], [AT_CHECK_DEFINES( [/* #undef HAVE_STRUCT_YES_S_NO */ #define HAVE_STRUCT_YES_S_YES 1 @@ -104,8 +104,8 @@ typedef struct # `int' and `struct yes_s' are both checked to test both the compiler # builtin types, and defined types. AT_TEST_MACRO(AC_CHECK_TYPES, -[AC_CHECK_TYPES((int, struct yes_s, struct no_s),,, - [struct yes_s { int yes ;} ;])], +[[AC_CHECK_TYPES([int, struct yes_s, struct no_s],,, + [struct yes_s { int yes ;} ;])]], [AT_CHECK_DEFINES( [#define HAVE_INT 1 /* #undef HAVE_STRUCT_NO_S */ diff --git a/tests/torture.m4 b/tests/torture.m4 index 70efdc97b..9d5416e22 100644 --- a/tests/torture.m4 +++ b/tests/torture.m4 @@ -59,8 +59,7 @@ AT_DATA(dummy.in, ])]) AT_DATA(configure.in, -[AC_INCLUDE(actest.m4) -AC_INIT +[AC_INIT AC_CONFIG_HEADERS(config.h:config.hin) AC_CONFIG_FILES(dummy) [define]([AC_DEFUBST_VALUE], Big_Value)