* lib/m4sugar/m4sugar.m4 (m4_expand): New macro.
* lib/autotest/general.m4 (AT_SETUP): Use it to preserve
whitespace after single-quoted comma.
* tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Test this.
* NEWS: Revert caveat about semantics change on comma.
* doc/autoconf.texi (Programming in M4): Lighten the warning on
using m4sugar; it is stabilizing.
(Redefined M4 Macros): Touch up wording on M4 builtins.
(Evaluation Macros): Document m4_expand.
Signed-off-by: Eric Blake <ebb9@byu.net>
+2007-10-15 Eric Blake <ebb9@byu.net>
+
+ Fix 2007-10-03 regression with AT_SETUP([a, b]).
+ * lib/m4sugar/m4sugar.m4 (m4_expand): New macro.
+ (m4_text_box): Use it.
+ * lib/autotest/general.m4 (AT_SETUP): Use it.
+ * lib/m4sugar/m4sh.m4 (_AS_RUN): Use it.
+ * tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Test this.
+ * NEWS: Revert caveat about semantics change on comma.
+ * doc/autoconf.texi (Evaluation Macros): Document m4_expand.
+
2007-10-13 Eric Blake <ebb9@byu.net>
Change m4_join to match libtool's ltsugar semantics.
expanded libdir value of /usr/lib, not /usr//lib.
** AT_SETUP now handles macro expansions properly when calculating line
- length. However, as a side effect, any whitespace immediately
- following a single-quoted comma is lost. If you previously used
- AT_SETUP([a, b]), you could change to AT_SETUP([a,[] b]) to keep
- the space.
+ length.
** Autotest now determines $srcdir correctly.
be used to take action depending on whether anything was appended.
** The following m4sugar macros are new:
- m4_cond m4_ignore m4_max m4_min m4_newline m4_shift2
- m4_shift3 m4_unquote
+ m4_cond m4_expand m4_ignore m4_max m4_min m4_newline
+ m4_shift2 m4_shift3 m4_unquote
** Warnings are now generated by default when an installer invokes
'configure' with an unknown --enable-* or --with-* option.
level of quoting.
@end defmac
+@defmac m4_expand (@var{arg})
+@msindex{expand}
+Return the expansion of @var{arg} as a quoted string. Whereas
+@code{m4_quote} is designed to collect expanded text into a single
+argument, @code{m4_expand} is designed to perform one level of expansion
+on quoted text. The distinction is in the treatment of whitespace
+following a comma in the original @var{arg}. Any time multiple
+arguments are collected into one with @code{m4_quote}, the M4 argument
+collection rules discard the whitespace. But with @code{m4_quote},
+whitespace is discarded only if it results from unquoted commas in the
+expansion of macros contained in @var{arg}.
+
+@example
+m4_define([active], [ACT, IVE])dnl
+m4_define([active2], [[ACT, IVE]])dnl
+m4_quote(active, active)
+@result{}ACT,IVE,ACT,IVE
+m4_expand([active, active])
+@result{}ACT,IVE, ACT,IVE
+m4_quote(active2, active2)
+@result{}ACT, IVE,ACT, IVE
+m4_expand([active2, active2])
+@result{}ACT, IVE, ACT, IVE
+@end example
+@end defmac
+
@defmac m4_ignore (@dots{})
@msindex{ignore}
This macro was introduced in Autoconf 2.62. Expands to nothing,
series of quoted elements.
@end defmac
-The following example aims at emphasizing the difference between (i), not
-using these macros, (ii), using @code{m4_quote}, and (iii), using
-@code{m4_dquote}.
+The following example aims at emphasizing the difference between several
+scenarios: not using these macros, using @code{m4_defn}, using
+@code{m4_quote}, using @code{m4_dquote}, and using @code{m4_expand}.
@example
$ @kbd{cat example.m4}
# Overquote, so that quotes are visible.
m4_define([show], [$[]1 = [$1], $[]@@ = [$@@]])
-m4_define([mkargs], [1, 2, 3])
+m4_define([a], [A])
+m4_define([mkargs], [1, 2[,] 3])
m4_define([arg1], [[$1]])
-m4_divert(0)dnl
+m4_divert([0])dnl
show(a, b)
+show([a, b])
show(m4_quote(a, b))
show(m4_dquote(a, b))
+show(m4_expand([a, b]))
+
arg1(mkargs)
arg1([mkargs])
arg1(m4_defn([mkargs]))
arg1(m4_quote(mkargs))
arg1(m4_dquote(mkargs))
+arg1(m4_expand([mkargs]))
$ @kbd{autom4te -l m4sugar example.m4}
-$1 = a, $@@ = [a],[b]
-$1 = a,b, $@@ = [a,b]
-$1 = [a],[b], $@@ = [[a],[b]]
+$1 = A, $@@ = [A],[b]
+$1 = a, b, $@@ = [a, b]
+$1 = A,b, $@@ = [A,b]
+$1 = [A],[b], $@@ = [[A],[b]]
+$1 = A, b, $@@ = [A, b]
+
1
mkargs
-1, 2, 3
-1,2,3
-[1],[2],[3]
+1, 2[,] 3
+1,2, 3
+[1],[2, 3]
+1,2, 3
@end example
m4_define([AT_capture_files], [])
m4_define([AT_line], AT_LINE)
m4_define([AT_xfail], [at_xfail=no])
-m4_define([AT_description], m4_quote($1))
+m4_define([AT_description], m4_expand([$1]))
m4_define([AT_ordinal], m4_incr(AT_ordinal))
m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))
m4_divert_push([TEST_FUNCTIONS])dnl
$1
_ASEOF
}],
-[(eval "AS_ESCAPE(m4_quote($1))")])])
+[(eval "AS_ESCAPE(m4_expand([$1]))")])])
# _AS_DETECT_REQUIRED(TEST)
m4_define([m4_dquote], [[$@]])
+# m4_expand(ARG)
+# --------------
+# Return the expansion of ARG as a single string. Unlike m4_quote($1), this
+# correctly preserves whitespace following single-quoted commas that appeared
+# within ARG (however, it does not preserve whitespace after any unquoted
+# commas encountered in the expansion).
+#
+# m4_define([active], [ACT, IVE])
+# m4_define([active2], [[ACT, IVE]])
+# m4_quote(active, active2)
+# => ACT,IVE,ACT, IVE
+# m4_expand([active, active2])
+# => ACT,IVE, ACT, IVE
+#
+# Splitting a quoted ARG on `,' preserves space, but produces a quoted list.
+# Unquote the list, then expand each argument while preserving the leading
+# spaces; finally, collect each argument back into the final string.
+m4_define([m4_expand],
+[m4_quote(_$0(m4_unquote(m4_split([$1], [,]))))])
+
+# _m4_expand(ARGS)
+# ----------------
+# Return the expansion of each ARG, separated by `,'. Less efficient than
+# m4_unquote, but preserves quoted leading space in each ARG.
+m4_define([_m4_expand],
+[m4_if([$#], [0], [],
+ [$#], [1], [$1],
+ [$1,$0(m4_shift($@))])])
+
+
# m4_ignore(ARGS)
# ---------------
# Expands to nothing. Useful for conditionally ignoring an arbitrary
# using FRAME-CHARACTER in the border.
m4_define([m4_text_box],
[m4_pushdef([m4_Border],
- m4_translit(m4_format([%*s], m4_qlen(m4_quote($1)), []),
+ m4_translit(m4_format([%*s], m4_qlen(m4_expand([$1])), []),
[ ], m4_if([$2], [], [[-]], [[$2]])))dnl
@%:@@%:@ m4_Border @%:@@%:@
@%:@@%:@ $1 @%:@@%:@
AT_CHECK_AT_TITLE_CHAR([Brackets], [[[]]], [[]])
AT_CHECK_AT_TITLE_CHAR([Pound], [[#]], [#])
AT_CHECK_AT_TITLE_CHAR([Quoted comma],[[,]], [,])
-AT_CHECK_AT_TITLE_CHAR([Comma], [,[]], [,])
+AT_CHECK_AT_TITLE_CHAR([Comma], [,], [,])
AT_CHECK_AT_TITLE_CHAR([Quoted Macro], [[macro_name]], [macro_name])
AT_CHECK_AT_TITLE_CHAR([Macro], [macro_name], [macro_expanded])