# --------------------------------------------------------
# Expand EXPRESSION defining VARIABLE to FROM, FROM + 1, ..., TO.
# Both limits are included, and bounds are checked for consistency.
+# The algorithm is robust to indirect VARIABLE names.
m4_define([m4_for],
[m4_pushdef([$1], m4_eval([$2]))dnl
-m4_if(m4_eval(([$3]) > $1), 1,
+m4_if(m4_eval(([$3]) > m4_defn([$1])), 1,
[m4_pushdef([_m4_step], m4_eval(m4_default([$4], 1)))dnl
m4_assert(_m4_step > 0)dnl
-_m4_for([$1], m4_eval((([$3]) - $1) / _m4_step * _m4_step + $1), _m4_step, [$5])],
- m4_eval(([$3]) < $1), 1,
+_m4_for([$1], m4_eval((([$3]) - m4_defn([$1]))
+ / _m4_step * _m4_step + m4_defn([$1])),
+ _m4_step, [$5])],
+ m4_eval(([$3]) < m4_defn([$1])), 1,
[m4_pushdef([_m4_step], m4_eval(m4_default([$4], -1)))dnl
m4_assert(_m4_step < 0)dnl
-_m4_for([$1], m4_eval(($1 - ([$3])) / -(_m4_step) * _m4_step + $1), _m4_step, [$5])],
+_m4_for([$1], m4_eval((m4_defn([$1]) - ([$3]))
+ / -(_m4_step) * _m4_step + m4_defn([$1])),
+ _m4_step, [$5])],
[m4_pushdef(_m4_step,[])dnl
$5])[]dnl
m4_popdef([_m4_step])dnl
# Core of the loop, no consistency checks, all arguments are plain numbers.
m4_define([_m4_for],
[$4[]dnl
-m4_if($1, [$2], [],
- [m4_define([$1], m4_eval($1+[$3]))_m4_for([$1], [$2], [$3], [$4])])])
+m4_if(m4_defn([$1]), [$2], [],
+ [m4_define([$1], m4_eval(m4_defn([$1])+[$3]))$0($@)])])
# Implementing `foreach' loops in m4 is much more tricky than it may
m4_for([myvar], 8, 16, 3 * 2, [ myvar])
m4_for([myvar], 8, 16, -3 * -2, [ myvar])
m4_for([myvar], [2<<2], [2<<3], [-3 * (-2)], [ myvar])
+dnl Make sure we can do nameless iteration
+m4_for(, 1, 10, , -)
+dnl foreach tests
m4_foreach([myvar], [[a], [b, c], [d], [e
],[f]], [ myvar|])
m4_foreach_w([myvar], [a b c, d,e f
8 14
8 14
8 14
+----------
a| b, c| d| e
| f|
a| b| c,| d,e| f| g|