From: Zack Weinberg Date: Wed, 26 Jun 2024 18:40:15 +0000 (-0400) Subject: WIP: new m4sugar function m4_join_uniq. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ffd73054a515af570168d98d97c8644b06f1951;p=thirdparty%2Fautoconf.git 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. --- diff --git a/doc/autoconf.texi b/doc/autoconf.texi index cb148398..a500de35 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -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}) diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index 67b31055..186a7b19 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -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, diff --git a/tests/m4sugar.at b/tests/m4sugar.at index c241ff07..f257e9d5 100644 --- a/tests/m4sugar.at +++ b/tests/m4sugar.at @@ -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