]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Add m4_curry.
authorEric Blake <ebb9@byu.net>
Wed, 15 Oct 2008 17:55:45 +0000 (11:55 -0600)
committerEric Blake <ebb9@byu.net>
Fri, 17 Oct 2008 22:32:27 +0000 (16:32 -0600)
* lib/m4sugar/m4sugar.m4 (m4_curry, _m4_curry): New macros.
* tests/m4sugar.at (m4@&t@_map_args): Rename...
(m4@&t@_map_args and m4@&t@_curry): ...and add currying tests.
* doc/autoconf.texi (Looping constructs) <m4_map_args>: Document
currying as a way to add parameters.
(Evaluation Macros) <m4_curry>: Document the new macro.
* NEWS: Likewise.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
NEWS
doc/autoconf.texi
lib/m4sugar/m4sugar.m4
tests/m4sugar.at

index 4e4127d4043455568d5777949d51832e91432873..79100bc2219484ff998e1daa29e4acade4f74c6a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2008-10-17  Eric Blake  <ebb9@byu.net>
 
+       Add m4_curry.
+       * lib/m4sugar/m4sugar.m4 (m4_curry, _m4_curry): New macros.
+       * tests/m4sugar.at (m4@&t@_map_args): Rename...
+       (m4@&t@_map_args and m4@&t@_curry): ...and add currying tests.
+       * doc/autoconf.texi (Looping constructs) <m4_map_args>: Document
+       currying as a way to add parameters.
+       (Evaluation Macros) <m4_curry>: Document the new macro.
+       * NEWS: Likewise.
+
        Improve suggested test filtering.
        * lib/m4sugar/m4sh.m4 (_AS_DETECT_SUGGESTED_PRUNE): New macro,
        extracted from...
diff --git a/NEWS b/NEWS
index 1ba23cc5ffc56fdce282571b2a3f4f7965dc292b..147639b39cd6af68fc89df6df6dc1fa254cc3c40 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,8 @@ GNU Autoconf NEWS - User visible changes.
 ** Configure scripts now use shell functions.
 
 ** The following m4sugar macros are new:
-   m4_default_quoted  m4_map_args  m4_map_args_pair  m4_set_map
+   m4_curry  m4_default_quoted  m4_map_args  m4_map_args_pair
+   m4_set_map
 
 ** The following documented m4sh macros are new:
    AS_LINENO_PREPARE  AS_ME_PREPARE  AS_VAR_COPY
index d539329eaa73abf7c67ccf0cfe175e183f34cbe3..3078869a33691d67805fc90ed573841e756e4958 100644 (file)
@@ -10930,7 +10930,7 @@ m4_count(m4_map_sep([m4_echo], [[,]], [[[a]], [[b]]]))
 
 @defmac m4_map_args (@var{macro}, @var{arg}@dots{})
 @msindex{map_args}
-Repeatedly invoke @var{macro} with each successive @var{arg} as its
+Repeatedly invoke @var{macro} with each successive @var{arg} as its only
 argument.  In the following example, three solutions are presented with
 the same expansion; the solution using @code{m4_map_args} is the most
 efficient.
@@ -10943,6 +10943,30 @@ m4_map([ m4_echo], [[[plain]], [[active]]])
 m4_map_args([ m4_echo], [plain], [active])
 @result{} plain active
 @end example
+
+In cases where it is useful to operate on additional parameters besides
+the list elements, the macro @code{m4_curry} can be used in @var{macro}
+to supply the argument currying necessary to generate the desired
+argument list.  In the following example, @code{list_add_n} is more
+efficient than @code{list_add_x}.
+
+@example
+m4_define([list], [[1], [2], [3]])dnl
+m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
+dnl list_add_n(N, ARG...)
+dnl Output a list consisting of each ARG added to N
+m4_define([list_add_n],
+[m4_shift(m4_map_args([,m4_curry([add], [$1])], m4_shift($@@)))])dnl
+list_add_n([1], list)
+@result{}2,3,4
+list_add_n([2], list)
+@result{}3,4,5
+m4_define([list_add_x],
+[m4_shift(m4_foreach([var], m4_dquote(m4_shift($@@)),
+  [,add([$1],m4_defn([var]))]))])dnl
+list_add_x([1], list)
+@result{}2,3,4
+@end example
 @end defmac
 
 @defmac m4_map_args_pair (@var{macro}, @dvar{macro-end, macro}, @
@@ -11010,6 +11034,19 @@ This macro returns the decimal count of the number of arguments it was
 passed.
 @end defmac
 
+@defmac m4_curry (@var{macro}, @var{arg}@dots{})
+@msindex{curry}
+This macro performs argument currying.  The expansion of this macro is
+another macro name that expects exactly one argument; that argument is
+then appended to the @var{arg} list, and then @var{macro} is expanded
+with the resulting argument list.
+
+@example
+m4_curry([m4_curry], [m4_reverse], [1])([2])([3])
+@result{}3, 2, 1
+@end example
+@end defmac
+
 @defmac m4_do (@var{arg}, @dots{})
 @msindex{do}
 This macro loops over its arguments and expands each @var{arg} in
index 2d50230d80bfbcebf9d10a2bd9d76f59235a1f13..ee8ee63e3f656eed6d022dc268048c51b8cbf3f2 100644 (file)
@@ -726,6 +726,20 @@ m4_define([_m4_apply],
 m4_define([m4_count], [$#])
 
 
+# m4_curry(MACRO, ARG...)
+# -----------------------
+# Perform argument currying.  The expansion of this macro is another
+# macro that takes exactly one argument, appends it to the end of the
+# original ARG list, then invokes MACRO.  For example:
+#   m4_curry([m4_curry], [m4_reverse], [1])([2])([3]) => 3, 2, 1
+# Not quite as practical as m4_incr, but you could also do:
+#   m4_define([add], [m4_eval(([$1]) + ([$2]))])
+#   m4_define([add_one], [m4_curry([add], [1])])
+#   add_one()([2]) => 3
+m4_define([m4_curry], [$1(m4_shift($@,)_$0])
+m4_define([_m4_curry],               [[$1])])
+
+
 # m4_do(STRING, ...)
 # ------------------
 # This macro invokes all its arguments (in sequence, of course).  It is
index d6f40a7abd88875849913fc1bc0f057b24dcafe3..f34bca36d5e06321dd40b95652eca76362608196 100644 (file)
@@ -37,21 +37,6 @@ AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
 ])# AT_CHECK_M4SUGAR_TEXT
 
 
-# Order of the tests:
-# - m4_warn
-#
-# - m4_require
-# uses warn/error code.
-#
-# - m4_split
-#
-# - m4_append
-#
-# - m4_join
-#
-# - m4_text_wrap
-# uses m4_split code.
-
 ## --------- ##
 ## m4_defn.  ##
 ## --------- ##
@@ -866,13 +851,27 @@ hi
 AT_CLEANUP
 
 
-## --------------------- ##
-## m4_map_args{,_pair}.  ##
-## --------------------- ##
+## ---------------------------------- ##
+## m4_map_args{,_pair} and m4_curry.  ##
+## ---------------------------------- ##
 
-AT_SETUP([m4@&t@_map_args])
+AT_SETUP([m4@&t@_map_args and m4@&t@_curry])
 AT_KEYWORDS([m4@&t@_map_args_pair m4@&t@_reverse])
 
+dnl First, make sure we can curry in isolation.
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_curry([m4_echo])([1])
+m4_curry([m4_curry], [m4_reverse], [1])([2])([3])
+m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
+m4_define([add_one], [m4_curry([add], [1])])dnl
+add_one()([4])
+]],
+[[1
+3, 2, 1
+5
+]])
+
+dnl Now, check that we can map a list of arguments.
 AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnl
 m4_map_args([ m4_echo])
 m4_map_args([ m4_echo], [plain], [active])
@@ -901,6 +900,21 @@ plainACTIVE
 , 2, 1, 4, 3
 ]])
 
+dnl Finally, put the two concepts together, to show the real power of the API.
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
+m4_define([list], [[-1], [0], [1]])dnl
+dnl list_add_n(value, arg...)
+dnl add VALUE to each ARG and output the resulting list
+m4_define([list_add_n],
+  [m4_shift(m4_map_args([,m4_curry([add], [$1])], m4_shift($@)))])
+list_add_n([1], list)
+list_add_n([2], list)
+]], [[
+0,1,2
+1,2,3
+]])
+
 AT_CLEANUP