WIP: new m4sugar function m4_join_uniq.

This is intended to be a pure version of m4_append_uniq,
i.e. it does all its work by expansion and not by defining macros.
It will be used by the code in the next commit.

WIP: currently has severe bugs, foreach.m4 version still needed.

* lib/m4sugar/m4sugar.m4 (m4_join_uniq, _m4_join_uniq): New macros.
* doc/autoconf.texi: Document m4_join_uniq.
* tests/m4sugar.at: Test m4_join_uniq.
This commit is contained in:
Zack Weinberg 2024-06-26 14:40:15 -04:00
parent 4578ab146c
commit 4ffd73054a
3 changed files with 74 additions and 3 deletions

View File

@ -13299,13 +13299,16 @@ pairs, and replace all remaining newlines with a space. The result is
still a quoted string.
@end defmac
@defmac m4_join (@ovar{separator}, @var{args}@dots{})
@defmacx m4_joinall (@ovar{separator}, @var{args}@dots{})
@defmac m4_join (@var{separator}, @var{args}@dots{})
@defmacx m4_joinall (@var{separator}, @var{args}@dots{})
@defmacx m4_join_uniq (@var{separator}, @var{args}@dots{})
@msindex{join}
@msindex{joinall}
Concatenate each @var{arg}, separated by @var{separator}.
@code{joinall} uses every argument, while @code{join} omits empty
arguments so that there are no back-to-back separators in the output.
@code{join_uniq} omits empty arguments and also omits each argument
that is already included in the string so far.
The result is a quoted string.
@example
m4_define([active], [ACTIVE])dnl
@ -13313,11 +13316,20 @@ m4_join([|], [one], [], [active], [two])
@result{}one|active|two
m4_joinall([|], [one], [], [active], [two])
@result{}one||active|two
m4_join([|], [onethree], [one], [], [two])
@result{}onethree|one|two
m4_join_uniq([|], [onethree], [one], [], [two])
@result{}onethree|two
@end example
Note that if all you intend to do is join @var{args} with commas between
them, to form a quoted list suitable for @code{m4_foreach}, it is more
efficient to use @code{m4_dquote}.
@code{m4_join_uniq} was introduced in Autoconf 2.73.
Like @code{m4_append_uniq} it is inherently quadratic in the total
length of the @var{args}; when this is large it is more efficient to use
the @samp{m4_set_} functions instead (@pxref{Set manipulation Macros}).
@end defmac
@defmac m4_newline (@ovar{text})

View File

@ -2467,6 +2467,23 @@ m4_define([m4_joinall], [[$2]_$0([$1], m4_shift($@))])
m4_define([_m4_joinall],
[m4_if([$#], [2], [], [[$1$3]$0([$1], m4_shift2($@))])])
# m4_join_uniq(SEP, ARG1, ARG2...)
# ------------------------------------------
# Same as m4_join, but also if any argument is already a substring of the
# concatenation-so-far it is dropped. No expansion is performed on SEP
# or ARGS. See m4_join for implementation notes.
m4_define([m4_join_uniq],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], m4_index([$2], [$3]), [-1], [_], []
)$0([$1], [[$2]], m4_shift3($@))])])
m4_define([_m4_join_uniq],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], m4_index([$2], [$3]), [-1], [[$1$2]],
[])$0([$1], m4_shift2($@))])])
# m4_combine([SEPARATOR], PREFIX-LIST, [INFIX], SUFFIX...)
# --------------------------------------------------------
# Produce the pairwise combination of every element in the quoted,

View File

@ -1157,7 +1157,7 @@ AT_CLEANUP
AT_SETUP([m4@&t@_join])
AT_KEYWORDS([m4@&t@_joinall])
AT_KEYWORDS([m4@&t@_joinall m4@&t@_join_uniq])
AT_CHECK_M4SUGAR_TEXT(
[[m4_define([active], [ACTIVE])dnl
@ -1202,6 +1202,27 @@ m4_joinall([-], [one],,,)
m4_joinall([], ,,,[two])
m4_joinall([], [two],,,)
m4_joinall([-], [], [], [three], [], [])
----
m4_join_uniq
m4_join_uniq([-])
m4_join_uniq([/], [one])
m4_join_uniq([/], [one], [two])
m4_join_uniq([/], [one], [], [two])
m4_join_uniq([], [one], [two])
m4_join_uniq([], [one], [], [two])
m4_join_uniq([/], [one], [one], [two])
m4_join_uniq([/], [one], [two], [one])
m4_join_uniq([/], [one], [on], [two])
m4_join_uniq([, ], [one], [two])
m4_dquote(m4_join_uniq([, ], [one], [two]))
m4_join_uniq([/], [active], [active])
m4_join_uniq([/], [active], [], [active])
m4_join_uniq([ active ], [one], , [two])
m4_join_uniq([/], ,,,[one])
m4_join_uniq([/], [one],,,)
m4_join_uniq([], ,,,[two])
m4_join_uniq([], [two],,,)
m4_join_uniq([/], [], [], [three], [], [])dnl
]],
[[
@ -1244,6 +1265,27 @@ one---
two
two
--three--
----
one
one/two
one/two
onetwo
onetwo
one/two
one/two
one/two
one, two
[one, two]
active/active
active/active
one active two
one
one
two
two
three
]])
AT_CLEANUP