]> git.ipfire.org Git - thirdparty/automake.git/commitdiff
[ng] am.xargs-map: be usable with huge lists
authorStefano Lattarini <stefano.lattarini@gmail.com>
Sat, 7 Jul 2012 17:09:32 +0000 (19:09 +0200)
committerStefano Lattarini <stefano.lattarini@gmail.com>
Sat, 7 Jul 2012 20:33:31 +0000 (22:33 +0200)
The previous implementation could eat all memory if the given list was
really huge -- but this function will be needed to operate on potentially
huge lists! (i.e., list of tests or files which can exceed the command-line
length limit of the system).

As a drawback, the function cannot recursively invoke itself anymore (not
even indirectly), but this is an acceptable limitation for its intended
uses.

* lib/am/header-vars.am (am.xargs-map): Reimplemented.
(am.max-cmdline-args): Redefine, as its semantics have changed.
(am.max-cmdline-args+1): Remove, no more needed.

Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
lib/am/header-vars.am

index 812f2f6d576bd26c19e4e534f107f10f7462686e..d7afe6fac173e18c16cffa9d62fa43e9e422da81 100644 (file)
@@ -259,24 +259,39 @@ am__strip_suffixes = $(strip \
 # Helper variables and function to help in recipes that could exceed
 # the command line length limit.
 
-## FIXME: this is basically arbitrary.  In the long term, defining this
-## FIXME: after a configure-time test on the command-line length limits,
-## FIXME: or at least on a system-by-system basis, might be better.
-am.max-cmdline-args := 40
-am.max-cmdline-args+1 := 41
+## FIXME: Forty aguments; this is basically arbitrary.  In the long term,
+## FIXME: defining this after a configure-time test on the command-line
+## FIXME: length limits, or at least on a system-by-system basis, might
+## FIXME: be better.  But don't make it too big, or our implementation
+## FIXME: will likely suffer in performance and memory consumption.
+# And in the Information Age, we somehow managed to revert an abacus-like
+# counting.  Yay for us :-)
+am.max-cmdline-args := xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 
 # $(call am.xargs-map,FUNCTION,LIST)
 # ----------------------------------
 # Map the function $1 on the arguments $2, ensuring that each
 # call of $1 has at most 40 arguments.
+# This implementation is hacky, but the more elegant or "naive" ones
+# (based on recursion) proved to be ludicrously memory-hungry with
+# huge lists.
+# A drawback of this implementation is that am.xargs-map cannot be
+# recursively invoked, but that shouldn't matter for our use cases.
 # The extra $(strip) calls are only to allow clearer formatting.
 define am.xargs-map
 $(if $2,$(strip \
-  )$(call $1,$(wordlist 1,$(am.max-cmdline-args),$2))$(strip \
-  )$(call $0,$1,$(wordlist $(am.max-cmdline-args+1),$(words $2),$2)))
+  )$(eval $0.partial-args :=)$(strip \
+  )$(eval $0.counter :=)$(strip \
+  )$(foreach i,$2,$(strip \
+    )$(eval $0.counter := $$($0.counter)x)$(strip \
+    )$(eval $0.partial-args += $$i)$(strip \
+    )$(if $(filter $(am.max-cmdline-args),$($0.counter)),$(strip \
+      )$(call $1,$(strip $($0.partial-args)))$(strip \
+      )$(eval $0.partial-args :=)$(strip \
+      )$(eval $0.counter :=)))$(strip \
+  )$(if $($0.counter),$(call $1,$(strip $($0.partial-args)))))
 endef
 
-
 ## Some derived variables that have been found to be useful.
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@