mirror of
git://git.sv.gnu.org/autoconf
synced 2025-02-11 11:22:25 +08:00
* 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>
1292 lines
27 KiB
Plaintext
1292 lines
27 KiB
Plaintext
# -*- Autotest -*-
|
|
|
|
AT_BANNER([M4sugar.])
|
|
|
|
# Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008 Free Software
|
|
# Foundation, Inc.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2, or (at your option)
|
|
# any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
# 02110-1301, USA.
|
|
|
|
|
|
# AT_CHECK_M4SUGAR_TEXT(CODE, STDOUT, STDERR)
|
|
# -------------------------------------------
|
|
# Check that m4sugar CODE expands to STDOUT and emits STDERR.
|
|
m4_define([AT_CHECK_M4SUGAR_TEXT],
|
|
[
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_init
|
|
m4_divert_push(0)[]dnl
|
|
]$1[[]dnl
|
|
m4_divert_pop(0)
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
|
|
])# AT_CHECK_M4SUGAR_TEXT
|
|
|
|
|
|
## --------- ##
|
|
## m4_defn. ##
|
|
## --------- ##
|
|
|
|
AT_SETUP([m4@&t@_defn])
|
|
|
|
AT_KEYWORDS([m4@&t@_popdef m4@&t@_undefine])
|
|
|
|
# Ensure that m4sugar dies when dereferencing undefined macros, whether
|
|
# this is provided by m4 natively or faked by wrappers in m4sugar.
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_define([good])
|
|
m4_defn([good], [oops])
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
|
|
AT_CHECK([grep good stderr], [1])
|
|
AT_CHECK([grep 'm4@&t@_defn: undefined.*oops' stderr], [0], [ignore])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_define([good])
|
|
m4_popdef([good], [oops])
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
|
|
AT_CHECK([grep good stderr], [1])
|
|
AT_CHECK([grep 'm4@&t@_popdef: undefined.*oops' stderr], [0], [ignore])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_define([good])
|
|
m4_undefine([good], [oops])
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
|
|
AT_CHECK([grep good stderr], [1])
|
|
AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------- ##
|
|
## m4_warn. ##
|
|
## --------- ##
|
|
|
|
AT_SETUP([m4@&t@_warn])
|
|
|
|
# m4_text_wrap is used to display the help strings. Also, check that
|
|
# commas are not swallowed. This can easily happen because of
|
|
# m4-listification.
|
|
|
|
# FIXME: For the time being we use -f to make sure we do issue the
|
|
# warnings. But maybe autom4te should handle that by itself?
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_init
|
|
m4_defun([cross_warning], [m4_warn([cross], [cross])])
|
|
|
|
m4_divert([0])dnl
|
|
m4_warn([obsolete], [obsolete])dnl
|
|
cross_warning[]dnl
|
|
m4_warn([syntax], [syntax])dnl
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], 0, [],
|
|
[script.4s:7: warning: syntax
|
|
])
|
|
|
|
AT_CHECK_M4SUGAR([-o- -Wall -f], 0, [],
|
|
[script.4s:5: warning: obsolete
|
|
script.4s:6: warning: cross
|
|
script.4s:2: cross_warning is expanded from...
|
|
script.4s:6: the top level
|
|
script.4s:7: warning: syntax
|
|
])
|
|
|
|
AT_CHECK_M4SUGAR([-o- -Wnone,cross -f], 0, [],
|
|
[script.4s:6: warning: cross
|
|
script.4s:2: cross_warning is expanded from...
|
|
script.4s:6: the top level
|
|
])
|
|
|
|
AT_CHECK_M4SUGAR([-o- -Wnone,cross,error -f], 1, [],
|
|
[[script.4s:6: warning: cross
|
|
script.4s:2: cross_warning is expanded from...
|
|
script.4s:6: the top level
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------------------------- ##
|
|
## m4_require: error message. ##
|
|
## --------------------------- ##
|
|
|
|
AT_SETUP([m4@&t@_require: error message])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_defun([foo], [FOO])
|
|
m4_require([foo])
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:2: error: m4@&t@_require(foo): cannot be used outside of an m4_defun'd macro
|
|
script.4s:2: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
AT_CLEANUP
|
|
|
|
|
|
## ----------------------------------- ##
|
|
## m4_require: circular dependencies. ##
|
|
## ----------------------------------- ##
|
|
|
|
AT_SETUP([m4@&t@_require: circular dependencies])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_defun([foo], [m4_require([bar])])
|
|
|
|
m4_defun([bar], [m4_require([foo])])
|
|
|
|
m4_defun([baz], [m4_require([foo])])
|
|
|
|
m4_init
|
|
m4_divert([0])dnl
|
|
baz
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:9: error: m4@&t@_require: circular dependency of foo
|
|
script.4s:3: bar is expanded from...
|
|
script.4s:1: foo is expanded from...
|
|
script.4s:5: baz is expanded from...
|
|
script.4s:9: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------- ##
|
|
## m4_cond. ##
|
|
## --------- ##
|
|
|
|
AT_SETUP([m4@&t@_cond])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT([[m4_define([side], [m4_errprintn([$1])$1])
|
|
m4_cond([side(1)], [1], [a],
|
|
[side(1)], [1], [b],
|
|
[side(1)], [2], [c])
|
|
m4_cond([side(2)], [1], [a],
|
|
[side(2)], [1], [b],
|
|
[side(2)], [2], [c],
|
|
[side(2)])
|
|
m4_cond([side(3)], [1], [a],
|
|
[side(3)], [1], [b],
|
|
[side(3)], [2], [c],
|
|
[side(3)])
|
|
m4_cond([a,a], [a,a], [yes], [no])
|
|
m4_cond([[a,a]], [a,a], [yes])
|
|
m4_cond([a,a], [a,b], [yes], [no])
|
|
m4_cond([a,a], [a,b], [yes])
|
|
m4_cond([m4_eval([0xa])])
|
|
m4_define([ab], [AB])dnl
|
|
m4_cond([a])b
|
|
m4_cond([1], [1], [a])b
|
|
m4_cond([1], [2], [3], [a])b
|
|
]], [[
|
|
a
|
|
c
|
|
3
|
|
yes
|
|
yes
|
|
no
|
|
|
|
10
|
|
AB
|
|
AB
|
|
AB
|
|
]], [[1
|
|
2
|
|
2
|
|
2
|
|
3
|
|
3
|
|
3
|
|
3
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ---------- ##
|
|
## m4_split. ##
|
|
## ---------- ##
|
|
|
|
AT_SETUP([m4@&t@_split])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
|
|
m4_split
|
|
m4_split([[]])
|
|
m4_split([ ])
|
|
m4_split([active])
|
|
m4_split([ active active ])end
|
|
m4_split([ ], [ ])
|
|
m4_split([active], [ ])
|
|
m4_split([ active active ], [ ])end
|
|
m4_split([abcde], [bd])
|
|
m4_split([abcde], [[bd]])
|
|
m4_split([foo=`` bar=''])
|
|
m4_split([foo='' bar=``])
|
|
dnl these next two are from the manual; keep this in sync if the internal
|
|
dnl quoting strings in m4_split are changed
|
|
m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
|
|
m4_split([a )}>=- b -=<{( c])
|
|
m4_split([a )}@&t@>=- b -=<@&t@{( c])
|
|
]],
|
|
[[
|
|
|
|
[[]]
|
|
[], []
|
|
[active]
|
|
[], [active], [active], []end
|
|
[], []
|
|
[active]
|
|
[], [active active], []end
|
|
[abcde]
|
|
[a], [c], [e]
|
|
[foo=``], [bar='']
|
|
[foo=''], [bar=``]
|
|
[a], [], [B], [], [c]
|
|
[a], [)}>=-], [b], [-=<{(], [c]
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ------- ##
|
|
## m4_do. ##
|
|
## ------- ##
|
|
|
|
AT_SETUP([m4@&t@_do])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_define([ab], [1])m4_define([bc], [2])m4_define([abc], [3])dnl
|
|
m4_define([AB], [4])m4_define([BC], [5])m4_define([ABC], [6])dnl
|
|
m4_do
|
|
m4_do([a])
|
|
m4_do([a], [b])c
|
|
m4_unquote(m4_join([], [a], [b]))c
|
|
m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
|
|
m4_do([a], [b])c
|
|
m4_unquote(m4_join([], [a], [b]))c
|
|
]],
|
|
[[
|
|
a
|
|
abc
|
|
3
|
|
ABC
|
|
3
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ----------- ##
|
|
## m4_append. ##
|
|
## ----------- ##
|
|
|
|
AT_SETUP([m4@&t@_append])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_define([active], [ACTIVE])dnl
|
|
m4_append([sentence], [This is an])dnl
|
|
m4_append([sentence], [ active ])dnl
|
|
m4_append([sentence], [symbol.])dnl
|
|
sentence
|
|
m4_undefine([active])dnl
|
|
sentence
|
|
m4_define([active], [ACTIVE])dnl
|
|
m4_append([hooks], [m4_define([act1], [act2])])dnl
|
|
m4_append([hooks], [m4_define([act2], [active])])dnl
|
|
m4_undefine([active])dnl
|
|
act1
|
|
hooks
|
|
act1
|
|
dnl Test for bug fixed in 2.62 when separator is active.
|
|
m4_define([a], [A])dnl
|
|
m4_append_uniq([foo], [-], [a])dnl
|
|
m4_append_uniq([foo], [-], [a])dnl
|
|
m4_append_uniq([bar], [-], [a])dnl
|
|
m4_append_uniq([bar], [~], [a])dnl
|
|
m4_append_uniq([bar], [-], [a])dnl
|
|
m4_defn([foo])
|
|
m4_defn([bar])
|
|
foo
|
|
bar
|
|
m4_append_uniq([blah], [one], [, ], [new], [existing])
|
|
m4_append_uniq([blah], [two], [, ], [new], [existing])
|
|
m4_append_uniq([blah], [two], [, ], [new], [existing])
|
|
m4_append_uniq([blah], [three], [, ], [new], [existing])
|
|
m4_append([blah], [two], [, ])dnl
|
|
blah
|
|
m4_dquote(blah)
|
|
m4_append([list], [one], [[, ]])dnl
|
|
m4_append([list], [two], [[, ]])dnl
|
|
m4_append([list], [three], [[, ]])dnl
|
|
list
|
|
m4_dquote(list)
|
|
m4_append_uniq_w([numbers], [1 1 2])dnl
|
|
m4_append_uniq_w([numbers], [ 2 3 ])dnl
|
|
numbers
|
|
]],
|
|
[[This is an ACTIVE symbol.
|
|
This is an active symbol.
|
|
act1
|
|
|
|
active
|
|
-
|
|
-a~
|
|
-
|
|
-A~
|
|
new
|
|
new
|
|
existing
|
|
new
|
|
one, two, three, two
|
|
[one],[two],[three],[two]
|
|
one, two, three
|
|
[one, two, three]
|
|
1 2 3
|
|
]])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_append_uniq([str], [a], [ ])
|
|
m4_append_uniq([str], [a b], [ ])
|
|
m4_divert([0])dnl
|
|
str
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], 0, [[a a b
|
|
]], [[script.4s:2: warning: m4@&t@_append_uniq: `a b' contains ` '
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------- ##
|
|
## m4_join. ##
|
|
## --------- ##
|
|
|
|
AT_SETUP([m4@&t@_join])
|
|
|
|
AT_KEYWORDS([m4@&t@_joinall])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_define([active], [ACTIVE])
|
|
m4_join
|
|
m4_join([|])
|
|
m4_join([, ], [one], [two])
|
|
m4_dquote(m4_join([, ], [one], [two]))
|
|
m4_join([|], [active], [active])
|
|
m4_join([|], ,,,[one])
|
|
m4_join([|], [one],,,)
|
|
m4_join([], ,,,[two])
|
|
m4_join([], [two],,,)
|
|
m4_join([ active ], [one], , [two])
|
|
m4_join([], [one], [two])
|
|
m4_joinall([-], [one], [], [two])
|
|
m4_joinall([-], [], [], [three], [], [])
|
|
m4_joinall([], [one], [], [two])
|
|
m4_joinall
|
|
m4_joinall([-])
|
|
m4_joinall([-], [one])
|
|
]],
|
|
[[
|
|
|
|
|
|
one, two
|
|
[one, two]
|
|
active|active
|
|
one
|
|
one
|
|
two
|
|
two
|
|
one active two
|
|
onetwo
|
|
one--two
|
|
--three--
|
|
onetwo
|
|
|
|
|
|
one
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## -------------- ##
|
|
## m4_text_wrap. ##
|
|
## -------------- ##
|
|
|
|
AT_SETUP([m4@&t@_text_wrap])
|
|
|
|
# m4_text_wrap is used to display the help strings. Also, check that
|
|
# commas and $ are not swallowed. This can easily happen because of
|
|
# m4-listification.
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_divert([0])dnl
|
|
m4_text_wrap([Short string */], [ ], [/* ], 20)
|
|
|
|
m4_text_wrap([Much longer string */], [ ], [/* ], 20)
|
|
|
|
m4_text_wrap([Short doc.], [ ], [ --short ], 30)
|
|
|
|
m4_text_wrap([Short doc.], [ ], [ --too-wide], 30)
|
|
|
|
m4_text_wrap([Super long documentation.], [ ], [ --too-wide], 30)
|
|
|
|
m4_text_wrap([First, second , third, [,quoted]])
|
|
m4_define([xfff], [oops])
|
|
m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20])
|
|
]])
|
|
|
|
AT_DATA([expout],
|
|
[[/* Short string */
|
|
|
|
/* Much longer
|
|
string */
|
|
|
|
--short Short doc.
|
|
|
|
--too-wide
|
|
Short doc.
|
|
|
|
--too-wide
|
|
Super long
|
|
documentation.
|
|
|
|
First, second , third, [,quoted]
|
|
|
|
$@ Some $1 $2 $3
|
|
$* $4 embedded
|
|
$* dollars.
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], 0, [expout])
|
|
|
|
AT_CLEANUP
|
|
|
|
## -------------------- ##
|
|
## m4_version_compare. ##
|
|
## -------------------- ##
|
|
|
|
AT_SETUP([m4@&t@_version_compare])
|
|
|
|
AT_KEYWORDS([m4@&t@_list_cmp])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_version_compare([1.1], [2.0])
|
|
m4_version_compare([2.0b], [2.0a])
|
|
m4_version_compare([2.0z], [2.0y])
|
|
m4_version_compare([1.1.1], [1.1.1a])
|
|
m4_version_compare([1.2], [1.1.1a])
|
|
m4_version_compare([1.0], [1])
|
|
m4_version_compare([1.0a], [1.0a])
|
|
m4_version_compare([1.1a], [1.1a.1])
|
|
m4_version_compare([1.10], [1.1a])
|
|
m4_version_compare([1-1a], [1,1A])
|
|
m4_define([a], [oops])dnl
|
|
m4_version_compare([1.1a], [1.1A])
|
|
m4_version_compare([1z], [1aa])
|
|
m4_version_compare([2.61a], [2.61a-248-dc51])
|
|
m4_version_compare([2.61b], [2.61a-248-dc51])
|
|
dnl Test that side effects to m4_list_cmp occur exactly once
|
|
m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
|
|
[[0], [0], [0]m4_errprintn([hi])])
|
|
m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
|
|
[[0], [0], [0]m4_errprintn([bye])])
|
|
]],
|
|
[[-1
|
|
1
|
|
1
|
|
-1
|
|
1
|
|
0
|
|
0
|
|
-1
|
|
1
|
|
0
|
|
0
|
|
-1
|
|
-1
|
|
1
|
|
0
|
|
0
|
|
]], [[hi
|
|
hi
|
|
hi
|
|
bye
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
## ------------------------------ ##
|
|
## Standard regular expressions. ##
|
|
## ------------------------------ ##
|
|
|
|
AT_SETUP([Standard regular expressions])
|
|
|
|
# AT_CHECK_M4RE(RE-NAME, TEXT, INTENT = `ok' | `')
|
|
# ------------------------------------------------
|
|
# Check whether RE-NAME (a macro whose definition is a regular expression)
|
|
# matches TEXT. INTENT = `ok' if the match should succeed or else empty.
|
|
m4_define([AT_CHECK_M4RE],
|
|
[AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_bregexp([$2], ^m4_defn([$1])$, [ok])
|
|
]], [$3
|
|
])])
|
|
|
|
AT_CHECK_M4RE([m4_re_word], [ab9_c], [ok])
|
|
AT_CHECK_M4RE([m4_re_word], [_9abc], [ok])
|
|
AT_CHECK_M4RE([m4_re_word], [9ab_c])
|
|
|
|
AT_CHECK_M4RE([m4_re_string], [ab9_c], [ok])
|
|
AT_CHECK_M4RE([m4_re_string], [_9abc], [ok])
|
|
AT_CHECK_M4RE([m4_re_string], [9ab_c], [ok])
|
|
AT_CHECK_M4RE([m4_re_string], [9a@_c])
|
|
|
|
AT_CLEANUP
|
|
|
|
## ----------- ##
|
|
## m4_bmatch. ##
|
|
## ----------- ##
|
|
|
|
AT_SETUP([m4@&t@_bmatch])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_bmatch([abc], [default\])
|
|
m4_bmatch([abc], [^a], [yes])
|
|
m4_bmatch([abc], [^a], [yes], [no])
|
|
m4_bmatch([abc], [^.a], [yes])
|
|
m4_bmatch([abc], [^.a], [yes], [no\])
|
|
m4_bmatch([abc], [a], [1], [b], [2])
|
|
m4_bmatch([abc], [A], [1], [b], [2])
|
|
m4_define([ab], [AB])dnl
|
|
m4_bmatch([$*], [a])b
|
|
m4_bmatch([$*], [\*], [a])b
|
|
m4_bmatch([$*], [1], [2], [a])b
|
|
]], [[default\
|
|
yes
|
|
yes
|
|
|
|
no\
|
|
1
|
|
2
|
|
AB
|
|
AB
|
|
AB
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
## --------------- ##
|
|
## m4_bpatsubsts. ##
|
|
## --------------- ##
|
|
|
|
AT_SETUP([m4@&t@_bpatsubsts])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT(
|
|
[[m4_bpatsubsts([11], [^..$])
|
|
m4_bpatsubsts([11], [\(.\)1], [\12])
|
|
m4_bpatsubsts([11], [^..$], [], [1], [2])
|
|
m4_bpatsubsts([11], [\(.\)1], [\12], [1], [3])
|
|
m4_define([a], [oops])m4_define([c], [oops])dnl
|
|
m4_define([AB], [good])m4_define([bc], [good])dnl
|
|
m4_bpatsubsts([abc], [a], [A], [b], [B], [c])
|
|
m4_bpatsubsts([ab], [a])c
|
|
m4_bpatsubsts([ab], [c], [C], [a])c
|
|
m4_bpatsubsts([$1$*$@], [\$\*], [$#])
|
|
]], [[11
|
|
21
|
|
22
|
|
23
|
|
good
|
|
good
|
|
good
|
|
$1$#$@
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
## ---------- ##
|
|
## M4 Loops. ##
|
|
## ---------- ##
|
|
|
|
AT_SETUP([M4 loops])
|
|
|
|
AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT([[dnl
|
|
m4_define([myvar], [outer value])dnl
|
|
m4_for([myvar], 1, 3, 1, [ myvar])
|
|
m4_for([myvar], 1, 3, , [ myvar])
|
|
m4_for([myvar], 3, 1,-1, [ myvar])
|
|
m4_for([myvar], 3, 1, , [ myvar])
|
|
m4_for([myvar], 1, 3, 2, [ myvar])
|
|
m4_for([myvar], 3, 1,-2, [ myvar])
|
|
m4_for([myvar],-1,-3,-2, [ myvar])
|
|
m4_for([myvar],-3,-1, 2, [ myvar])
|
|
dnl Make sure we recalculate the bounds correctly:
|
|
m4_for([myvar], 1, 3, 3, [ myvar])
|
|
m4_for([myvar], 1, 6, 3, [ myvar])
|
|
m4_for([myvar],22,-7,-5, [ myvar])
|
|
m4_for([myvar],-2,-7,-4, [ myvar])
|
|
m4_for([myvar],-7,-2, 4, [ myvar])
|
|
dnl Make sure we are not exposed to division truncation:
|
|
m4_for([myvar], 2, 5, 2, [ myvar])
|
|
m4_for([myvar],-5,-2, 2, [ myvar])
|
|
m4_for([myvar], 5, 2,-2, [ myvar])
|
|
m4_for([myvar],-2,-5,-2, [ myvar])
|
|
dnl Make sure we do not divide by zero:
|
|
m4_for([myvar], 1, 1, , [ myvar])
|
|
m4_for([myvar], 1, 1,+2, [ myvar])
|
|
m4_for([myvar], 1, 1,-2, [ myvar])
|
|
dnl Make sure we do not loop endlessly
|
|
m4_for([myval], 1, 1, 0, [ myval])
|
|
dnl Make sure to properly parenthesize
|
|
m4_for([myvar], 3-5, -2+8, , [ myvar])
|
|
m4_for([myvar], -2+8, 3-5, , [ myvar])
|
|
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 Modifying var does not affect the number of iterations
|
|
m4_for([myvar], 1, 5, , [ myvar[]m4_define([myvar], 5)])
|
|
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
|
|
g], [ myvar|])
|
|
myvar
|
|
dnl only one side effect expansion, prior to visiting list elements
|
|
m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnl
|
|
dnl shifting forms an important part of loops
|
|
m4_shift3:m4_shift3(1,2,3):m4_shift3(1,2,3,4)
|
|
m4_shiftn(3,1,2,3):m4_shiftn(3,1,2,3,4)
|
|
]],
|
|
[[ 1 2 3
|
|
1 2 3
|
|
3 2 1
|
|
3 2 1
|
|
1 3
|
|
3 1
|
|
-1 -3
|
|
-3 -1
|
|
1
|
|
1 4
|
|
22 17 12 7 2 -3
|
|
-2 -6
|
|
-7 -3
|
|
2 4
|
|
-5 -3
|
|
5 3
|
|
-2 -4
|
|
1
|
|
1
|
|
1
|
|
1
|
|
-2 -1 0 1 2 3 4 5 6
|
|
6 5 4 3 2 1 0 -1 -2
|
|
8 14
|
|
8 14
|
|
8 14
|
|
1 2 3 4 5
|
|
----------
|
|
a| b, c| d| e
|
|
| f|
|
|
a| b| c,| d,e| f| g|
|
|
outer value
|
|
::4
|
|
:4
|
|
]], [[hi
|
|
1
|
|
2
|
|
3
|
|
]])
|
|
|
|
dnl bounds checking in m4_for
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_init
|
|
m4_divert([0])dnl
|
|
m4_for([myvar], 1, 3,-1, [ myvar])
|
|
]])
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:3: error: assert failed: -1 > 0
|
|
script.4s:3: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_init
|
|
m4_divert([0])dnl
|
|
m4_for([myvar], 1, 2, 0, [ myvar])
|
|
]])
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:3: error: assert failed: 0 > 0
|
|
script.4s:3: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_init
|
|
m4_divert([0])dnl
|
|
m4_for([myvar], 2, 1, 0, [ myvar])
|
|
]])
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:3: error: assert failed: 0 < 0
|
|
script.4s:3: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
|
|
dnl m4_shiftn also does bounds checking
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_init
|
|
m4_divert([0])dnl
|
|
m4_shiftn(3,1,2)
|
|
]])
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:3: error: assert failed: 0 < 3 && 3 < 3
|
|
script.4s:3: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------------------- ##
|
|
## m4_map{,all}{,_sep}. ##
|
|
## --------------------- ##
|
|
|
|
AT_SETUP([m4@&t@_map])
|
|
AT_KEYWORDS([m4@&t@_apply m4@&t@_map_sep m4@&t@_mapall m4@&t@_mapall_sep])
|
|
AT_KEYWORDS([m4@&t@_count])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT([[dnl
|
|
m4_map([m4_count], [])
|
|
m4_map([ m4_count], [[],
|
|
[[1]],
|
|
[[1], [2]]])
|
|
m4_mapall([ m4_count], [[],
|
|
[[1]],
|
|
[[1], [2]]])
|
|
m4_map_sep([m4_eval], [,], [[[1+2]],
|
|
[[10], [16]]])
|
|
m4_count(m4_map_sep([m4_echo], [,], [[], [[1]], [[2]]]))
|
|
m4_count(m4_mapall_sep([m4_echo], [,], [[], [[1]], [[2]]]))
|
|
m4_map_sep([m4_eval], [[,]], [[[1+2]],
|
|
[[10], [16]]])
|
|
m4_count(m4_map_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
|
|
m4_count(m4_mapall_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
|
|
m4_map([-], [[]])
|
|
m4_mapall([-], [[]])
|
|
m4_map_sep([-], [:], [[]])
|
|
m4_mapall_sep([-], [:], [[]])
|
|
m4_define([a], [m4_if([$#], [0], [oops], [$1], [a], [pass], [oops])])dnl
|
|
m4_define([a1], [oops])dnl
|
|
m4_define([pass1], [oops])dnl
|
|
m4_map([a], [[[a]]])1
|
|
m4_map([m4_unquote([a])], [m4_dquote([a])])
|
|
dnl only one side effect expansion, prior to visiting list elements
|
|
m4_map([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
|
|
m4_map_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
|
|
m4_mapall([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
|
|
m4_mapall_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
|
|
]],
|
|
[[
|
|
1 2
|
|
0 1 2
|
|
3,a
|
|
2
|
|
3
|
|
3,a
|
|
1
|
|
1
|
|
|
|
-
|
|
|
|
-
|
|
pass1
|
|
pass
|
|
]], [[hi
|
|
1
|
|
2
|
|
3
|
|
hi
|
|
1
|
|
2
|
|
3
|
|
hi
|
|
1
|
|
2
|
|
3
|
|
hi
|
|
1
|
|
2
|
|
3
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ---------------------------------- ##
|
|
## m4_map_args{,_pair} and m4_curry. ##
|
|
## ---------------------------------- ##
|
|
|
|
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])
|
|
m4_map_args([m4_unquote], [plain], [active])
|
|
m4_map_args_pair([, m4_reverse], [])
|
|
m4_map_args_pair([, m4_reverse], [], [1])
|
|
m4_map_args_pair([, m4_reverse], [], [1], [2])
|
|
m4_map_args_pair([, m4_reverse], [], [1], [2], [3])
|
|
m4_map_args_pair([, m4_reverse], [], [1], [2], [3], [4])
|
|
m4_map_args_pair([, m4_reverse], [, m4_dquote], [1])
|
|
m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2])
|
|
m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3])
|
|
m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4])
|
|
]],
|
|
[[
|
|
plain active
|
|
plainACTIVE
|
|
|
|
, 1
|
|
, 2, 1
|
|
, 2, 1, 3
|
|
, 2, 1, 4, 3
|
|
, [1]
|
|
, 2, 1
|
|
, 2, 1, [3]
|
|
, 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
|
|
|
|
|
|
## ------------ ##
|
|
## m4_combine. ##
|
|
## ------------ ##
|
|
|
|
AT_SETUP([m4@&t@_combine])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
|
|
m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3])
|
|
m4_combine([, ], [[a], [b]], [-])
|
|
m4_combine([, ], [[a], [b]], [-], [])
|
|
m4_combine([, ], [], [-], [a], [b])
|
|
m4_combine([, ], [[]], [-], [a], [b])
|
|
m4_combine([ a ], [[-], [+]], [a], [-], [+])
|
|
m4_combine([$* ], [[$1], [$2]], [$#], [$@])
|
|
]],
|
|
[[a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
|
|
|
|
a-, b-
|
|
|
|
-a, -b
|
|
-a- a -a+ a +a- a +a+
|
|
$1$#$@$* $2$#$@
|
|
]], [])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## -------------- ##
|
|
## m4_{max,min}. ##
|
|
## -------------- ##
|
|
|
|
AT_SETUP([m4@&t@_max and m4@&t@_min])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_max
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:1: error: too few arguments to m4@&t@_max
|
|
script.4s:1: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_min
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([], 1, [],
|
|
[[script.4s:1: error: too few arguments to m4@&t@_min
|
|
script.4s:1: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR_TEXT([[dnl
|
|
m4_min(0)
|
|
m4_min(0xa)
|
|
m4_min(0, 0)
|
|
m4_min(0, 1)
|
|
m4_min(1, 0)
|
|
m4_min(0+1, 1+1)
|
|
m4_min(0+1, 1+0)
|
|
m4_min(0, 1, 2)
|
|
m4_min(2, 1, 0)
|
|
m4_min(1m4_for([i], 2, 100, , [,i]))
|
|
m4_min(m4_for([i], 100, 2, , [i,])1)
|
|
----
|
|
m4_max(0)
|
|
m4_max(0xa)
|
|
m4_max(0, 0)
|
|
m4_max(0, 1)
|
|
m4_max(1, 0)
|
|
m4_max(1+0, 1+1)
|
|
m4_max(1+0, 1+0)
|
|
m4_max(0, 1, 2)
|
|
m4_max(2, 1, 0)
|
|
m4_max(1m4_for([i], 2, 100, , [,i]))
|
|
m4_max(m4_for([i], 100, 2, , [i,])1)
|
|
]],
|
|
[[0
|
|
10
|
|
0
|
|
0
|
|
0
|
|
1
|
|
1
|
|
0
|
|
0
|
|
1
|
|
1
|
|
----
|
|
0
|
|
10
|
|
0
|
|
1
|
|
1
|
|
2
|
|
1
|
|
2
|
|
2
|
|
100
|
|
100
|
|
]], [])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ----------- ##
|
|
## Recursion. ##
|
|
## ----------- ##
|
|
|
|
AT_SETUP([recursion])
|
|
|
|
AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_cond
|
|
m4@&t@_bpatsubsts m4@&t@_shiftn m4@&t@_do m4@&t@_dquote_elt m4@&t@_reverse
|
|
m4@&t@_map m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min
|
|
m4@&t@_bmatch m4@&t@_map_args m4@&t@_map_args_pair])
|
|
|
|
dnl This test completes in a reasonable time if m4_foreach is linear,
|
|
dnl but thrashes if it is quadratic. If we are testing with m4 1.4.x,
|
|
dnl only the slower foreach.m4 implementation will work. But if we
|
|
dnl are testing with m4 1.6, we can rerun the test with __m4_version__
|
|
dnl undefined to exercise the alternate code path.
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_init
|
|
m4_divert_push(0)[]dnl
|
|
m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
|
|
m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
|
|
m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
|
|
m4_len(m4_joinall([--], m4_map([, m4_echo],
|
|
m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
|
|
m4_max(m4_min([1]m4_for([i], [2], [10000], [],
|
|
[,i]))m4_for([i], [2], [10000], [], [,i]))
|
|
m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
|
|
m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
|
|
m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
|
|
m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
|
|
m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
|
|
m4_for([i], [1], [10000], [], [m4_define(i)])dnl
|
|
m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
|
|
m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
|
|
m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
|
|
m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
|
|
m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
|
|
m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
|
|
[1], [10000], [], [,i]))))
|
|
m4_divert_pop(0)
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], [0], [[48894
|
|
9999,10000
|
|
78896
|
|
58894
|
|
10000
|
|
end
|
|
0
|
|
0
|
|
0
|
|
A
|
|
^9998$
|
|
9990 9990
|
|
5001
|
|
]])
|
|
|
|
AT_DATA_M4SUGAR([script.4s],
|
|
[[m4_ifdef([__m4_version__],
|
|
[m4_undefine([__m4_version__])],
|
|
[m4_divert_push(0)48894
|
|
9999,10000
|
|
78896
|
|
58894
|
|
10000
|
|
end
|
|
0
|
|
0
|
|
0
|
|
A
|
|
^9998$
|
|
9990 9990
|
|
5001
|
|
m4_exit([0])])
|
|
m4_init
|
|
m4_divert_push(0)[]dnl
|
|
m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
|
|
m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
|
|
m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
|
|
m4_len(m4_joinall([--], m4_map([, m4_echo],
|
|
m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
|
|
m4_max(m4_min([1]m4_for([i], [2], [10000], [],
|
|
[,i]))m4_for([i], [2], [10000], [], [,i]))
|
|
m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
|
|
m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
|
|
m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
|
|
m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
|
|
m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
|
|
m4_for([i], [1], [10000], [], [m4_define(i)])dnl
|
|
m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
|
|
m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
|
|
m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
|
|
m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
|
|
m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
|
|
m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
|
|
[1], [10000], [], [,i]))))
|
|
m4_divert_pop(0)
|
|
]])
|
|
|
|
AT_CHECK_M4SUGAR([-o-], [0], [[48894
|
|
9999,10000
|
|
78896
|
|
58894
|
|
10000
|
|
end
|
|
0
|
|
0
|
|
0
|
|
A
|
|
^9998$
|
|
9990 9990
|
|
5001
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ---------- ##
|
|
## m4_set_*. ##
|
|
## ---------- ##
|
|
|
|
AT_SETUP([m4@&t@_set])
|
|
|
|
AT_KEYWORDS([m4@&t@_set_add m4@&t@_set_add_all m4@&t@_set_contains
|
|
m4@&t@_set_contents m4@&t@_set_delete m4@&t@_set_difference m4@&t@_set_dump
|
|
m4@&t@_set_empty m4@&t@_set_foreach m4@&t@_set_intersection m4@&t@_set_list
|
|
m4@&t@_set_listc m4@&t@_set_map m4@&t@_set_remove m4@&t@_set_size
|
|
m4@&t@_set_union])
|
|
|
|
# Simple tests
|
|
AT_CHECK_M4SUGAR_TEXT([[m4_set_contains([a], [1], [yes], [no])
|
|
m4_set_add([a], [1], [added], [dup])
|
|
m4_set_contains([a], [1], [yes], [no])
|
|
m4_set_add([a], [1], [added], [dup])
|
|
m4_set_contents([a])
|
|
m4_set_remove([a], [1], [removed], [missing])
|
|
m4_set_contains([a], [1], [yes], [no])
|
|
m4_set_remove([a], [1], [removed], [missing])
|
|
m4_set_add([a], [2], [added], [dup])
|
|
m4_set_empty([a], [yes], [no])
|
|
m4_set_delete([a])
|
|
m4_set_empty([a], [yes], [no])
|
|
m4_set_add_all([c], [1], [2], [3])
|
|
m4_set_add_all([a]m4_set_listc([c]))
|
|
m4_set_contents([c], [-])
|
|
m4_set_dump([a], [-])
|
|
m4_set_contents([a])
|
|
m4_set_add_all([a], [1], [2], [3])m4_set_add_all([b], [3], [], [4])
|
|
m4_set_difference([a], [b])
|
|
m4_set_difference([b], [a])
|
|
m4_set_intersection([a], [b])
|
|
m4_set_union([a], [b])
|
|
m4_define([printodd], [m4_if(m4_eval([$1 & 1]), [1], [:$1])])dnl
|
|
m4_set_map([a], [printodd])
|
|
m4_set_foreach([a], [i], [m4_if(m4_eval(i & 1), [1], [m4_set_remove([a], i)])])
|
|
m4_set_list([a])
|
|
m4_set_add([a], [])
|
|
m4_set_list([a])
|
|
m4_set_remove([a], [2])
|
|
m4_dquote(m4_set_list([a]))
|
|
m4_set_listc([a])
|
|
m4_set_size([a])
|
|
m4_set_delete([a])
|
|
m4_dquote(m4_set_list([a]))
|
|
m4_indir([m4_dquote]m4_set_listc([a]))
|
|
m4_set_listc([a])
|
|
m4_set_size([a])
|
|
]], [[no
|
|
added
|
|
yes
|
|
dup
|
|
1
|
|
removed
|
|
no
|
|
missing
|
|
added
|
|
no
|
|
|
|
yes
|
|
|
|
|
|
1-2-3
|
|
3-2-1
|
|
|
|
|
|
,1,2
|
|
,,4
|
|
,3
|
|
,1,2,3,,4
|
|
:1:3
|
|
|
|
2
|
|
|
|
2,
|
|
|
|
[]
|
|
,
|
|
1
|
|
|
|
[]
|
|
|
|
|
|
0
|
|
]])
|
|
|
|
# Stress tests - check for unusual names/values
|
|
AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
|
|
m4_set_add([a], [a])dnl
|
|
m4_set_remove([a], [oops], [yes], [no])
|
|
m4_set_add([a,b], [c])dnl
|
|
m4_set_add([a,b], [$*[]])dnl
|
|
m4_set_add_all([a], [b,c])dnl
|
|
m4_set_size([a])
|
|
m4_count(m4_set_contents([a], [,]))
|
|
m4_count(m4_set_list([a], [,]))
|
|
m4_set_dump([a], [,])
|
|
m4_set_contents([a,b], [,])
|
|
m4_set_list([a,b])
|
|
m4_set_foreach([$*[]], [$*[]], [oops])
|
|
m4_set_add([$*[]], [])dnl
|
|
m4_set_remove([$*[]], [a], [yes], [no])
|
|
m4_set_add([$*[]], [a])dnl
|
|
m4_set_foreach([$*[]], [$*[]], [-m4_defn([$*[]])m4_indir([$*[]])-])
|
|
m4_set_remove([$*[]], [], [yes], [no])
|
|
m4_set_add([c], [,])dnl
|
|
m4_set_foreach([a,b], [set], [:m4_set_listc(_m4_defn([set])):])
|
|
]],[[no
|
|
2
|
|
1
|
|
2
|
|
b,c,a
|
|
c,$*[]
|
|
c,$*[]
|
|
|
|
no
|
|
---aoops-
|
|
yes
|
|
:,,::,a:
|
|
]])
|
|
|
|
# Stress tests - check for linear scaling (won't necessarily fail if
|
|
# quadratic, but hopefully users will complain if it appears to hang)
|
|
AT_CHECK_M4SUGAR_TEXT([[dnl
|
|
m4_for([i], [1], [10000], [], [m4_set_add([a], i)])dnl
|
|
m4_set_add_all([b]m4_for([i], [1], [10000], [], [,i]))dnl
|
|
m4_set_remove([a], [1])dnl
|
|
m4_set_remove([b], [10000])dnl
|
|
m4_set_add_all([a]m4_for([i], [1], [10000], [], [,i]))dnl
|
|
m4_for([i], [1], [10000], [], [m4_set_add([b], i)])dnl
|
|
m4_len(m4_set_contents([a]))
|
|
m4_len(m4_set_foreach([b], [b], [m4_if(m4_eval(b & 1), [1],
|
|
[m4_set_remove([b], b, [-])])]))
|
|
m4_set_size([b])
|
|
m4_define([prune3x], [m4_if(m4_eval([$1 % 3]), [0],
|
|
[m4_set_remove([a], [$1], [-])])])dnl
|
|
m4_len(m4_set_map([a], [prune3x]))
|
|
m4_count(m4_shift(m4_set_intersection([a], [b])))
|
|
]], [[38894
|
|
5000
|
|
5000
|
|
3333
|
|
3334
|
|
]])
|
|
|
|
AT_CLEANUP
|