| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140 | #							-*- Autotest -*-AT_BANNER([M4sugar.])# Copyright (C) 2000-2002, 2005-2012 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.# 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_initm4_divert_push([])[]dnl]$1[[]dnlm4_divert_pop([])]])AT_CHECK_M4SUGAR([-o-],, [$2], [$3])])# AT_CHECK_M4SUGAR_TEXT## ------------------ #### m4_stack_foreach.  #### ------------------ ##AT_SETUP([m4@&t@_stack])AT_KEYWORDS([m4@&t@_stack_foreach m4@&t@_stack_foreach_lifo])AT_KEYWORDS([m4@&t@_stack_foreach_sep m4@&t@_stack_foreach_sep_lifo])AT_KEYWORDS([m4@&t@_copy m4@&t@_n])# Test the semantics of macros to walk stacked macro definitions.AT_CHECK_M4SUGAR_TEXT([[dnlm4_pushdef([abc], [def])dnlm4_pushdef([abc], [ghi])dnlm4_pushdef([abc], [jkl])dnlm4_stack_foreach([abc], [m4_n])abcm4_stack_foreach_lifo([abc], [m4_n])m4_stack_foreach([abc], [m4_n])m4_copy([abc], [foo])dnlm4_stack_foreach([foo], [m4_n])m4_stack_foreach_lifo([foo], [m4_n])m4_stack_foreach_sep([abc], [ m4_index([abcdefghijkl],], [)])m4_define([colon], [:])m4_define([lt], [<])m4_define([gt], [>])dnlm4_stack_foreach_sep_lifo([abc], [lt], [gt], [colon])m4_pushdef([xyz], [123])dnlm4_pushdef([xyz], [456])dnlm4_define([doit], [[$1](m4_stack_foreach_sep([xyz], [m4_dquote(], [)], [,]))])dnlm4_stack_foreach([abc], [doit])]],[[defghijkljkljklghidefdefghijkldefghijkljklghidef 3 6 9<jkl>:<ghi>:<def>def([123],[456])ghi([123],[456])jkl([123],[456])]])AT_CLEANUP## --------- #### m4_defn.  #### --------- ##AT_SETUP([m4@&t@_defn])AT_KEYWORDS([m4@&t@_popdef m4@&t@_undefine m4@&t@_copy m4@&t@_renamem4@&t@_copy_force m4@&t@_rename_force])# 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])# Cannot rename an undefined macro.AT_DATA_M4SUGAR([script.4s],[[m4_rename([oops], [good])]])AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore])# Check that pushdef stacks can be renamed.AT_CHECK_M4SUGAR_TEXT([[m4_pushdef([a], [1])dnlm4_pushdef([a], [2])dnlm4_pushdef([a], m4_defn([m4_divnum]))dnla b cm4_rename([a], [b])dnla b cm4_copy([b], [c])dnla b cm4_popdef([b], [c])dnla b cm4_popdef([b], [c])dnla b cm4_popdef([b], [c])dnla b cdnl m4_copy is intentionally a no-op on undefined sourcem4_copy([oops], [dummy])m4_ifdef([dummy], [[oops]])dnldnl allow forceful overwritesm4_define([d], [4])m4_define([e], [5])m4_define([f], [6])dnlm4_copy_force([d], [e])dnlm4_rename_force([d], [f])dnld e fm4_popdef([e], [f])dnld e f]], [[0 b ca 0 ca 0 0a 2 2a 1 1a b cd 4 4d e f]])AT_CLEANUP## ------------ #### m4_dumpdef.  #### ------------ ##AT_SETUP([m4@&t@_dumpdef])AT_KEYWORDS([m4@&t@_dumpdefs])# Ensure that m4sugar dies when dereferencing undefined macros.AT_DATA_M4SUGAR([script.4s],[[m4_define([good], [yep])m4_dumpdef([good], [oops])]])AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])AT_CHECK([grep '^good:	\[[yep\]]$' stderr], [0], [ignore])AT_CHECK([grep 'm4@&t@_dumpdef: undefined.*oops' stderr], [0], [ignore])# Check that pushdef stacks can be dumped.AT_CHECK_M4SUGAR_TEXT([[m4_divert_push([KILL])m4_pushdef([a], [1])m4_pushdef([a], [2])m4_dumpdef([a])m4_dumpdefs([oops], [a])m4_divert_pop([KILL])dnl]], [],[[a:	[2]a:	[2]a:	[1]]])# Check behavior when dumping builtins.  Unfortunately, when using M4 1.4.x# (or more precisely, when __m4_version__ is undefined), builtins get# flattened to an empty string.  It takes M4 1.6 to work around this.AT_DATA_M4SUGAR([script.4s],[[m4_ifdef([__m4_version__], [_m4_undefine([__m4_version__])])m4_initm4_dumpdef([m4_define])]])AT_CHECK_M4SUGAR([-o-], [0], [],[[m4_define:	[]]])AT_DATA_M4SUGAR([script.4s],[[m4_initm4_ifdef([__m4_version__],[m4_dumpdef([m4_define])],[m4_errprintn([m4_define:	<define>])])]])AT_CHECK_M4SUGAR([-o-], [0], [],[[m4_define:	<define>]])AT_CLEANUP## --------- #### m4_warn.  #### --------- ##AT_SETUP([m4@&t@_warn])AT_DATA_M4SUGAR([script.4s],[[m4_initm4_defun([cross_warning], [m4_warn([cross], [cross])])m4_divert([0])dnlm4_warn([obsolete], [obsolete])dnlcross_warning[]dnlm4_warn([syntax], [syntax])dnlcross_warning[]dnlm4_warn([syntax], [syntax])dnl]])AT_CHECK_M4SUGAR([-o-], 0, [],[script.4s:4: warning: prefer named diversionsscript.4s:7: warning: syntaxscript.4s:9: warning: syntax])AT_CHECK_M4SUGAR([-o- -Wall], 0, [],[script.4s:4: warning: prefer named diversionsscript.4s:5: warning: obsoletescript.4s:6: warning: crossscript.4s:2: cross_warning is expanded from...script.4s:6: the top levelscript.4s:7: warning: syntaxscript.4s:8: warning: crossscript.4s:2: cross_warning is expanded from...script.4s:8: the top levelscript.4s:9: warning: syntax])AT_CHECK_M4SUGAR([-o- -Wnone,cross], 0, [],[script.4s:6: warning: crossscript.4s:2: cross_warning is expanded from...script.4s:6: the top levelscript.4s:8: warning: crossscript.4s:2: cross_warning is expanded from...script.4s:8: the top level])AT_CHECK_M4SUGAR([-o- -Wnone,cross,error], 1, [],[[script.4s:6: warning: crossscript.4s:2: cross_warning is expanded from...script.4s:6: the top levelscript.4s:8: warning: crossscript.4s:2: cross_warning is expanded from...script.4s:8: the top level]])AT_CLEANUP## ----------------- #### m4_divert_stack.  #### ----------------- ##AT_SETUP([m4@&t@_divert_stack])AT_KEYWORDS([m4@&t@_divert m4@&t@_divert_push m4@&t@_divert_popm4@&t@_undivert m4@&t@_cleardivert m4@&t@_divert_text])dnl This test names some diversions to avoid a warning.AT_CHECK_M4SUGAR_TEXT([[m4_define([_m4_divert(ten)], [10])dnlm4_define([_m4_divert(twenty)], [20])dnlm4_define([_m4_divert(thirty)], [30])dnl1.m4_divert_stackm4_divert_push([ten])2.m4_divert_stackm4_divert_text([twenty], [3.m4_divert_stack])dnlm4_divert([thirty])4.m4_divert_stackm4_divert_pop([thirty])dnl5.m4_undivert([twenty], [thirty])m4_pattern_allow([^m4_divert])dnl]], [[1.script.4s:2: m4@&t@_divert_push:script.4s:1: m4@&t@_divert: KILL5.3.script.4s:8: m4@&t@_divert_push: twentyscript.4s:7: m4@&t@_divert_push: tenscript.4s:2: m4@&t@_divert_push:script.4s:1: m4@&t@_divert: KILL4.script.4s:9: m4@&t@_divert: thirtyscript.4s:2: m4@&t@_divert_push:script.4s:1: m4@&t@_divert: KILL2.script.4s:7: m4@&t@_divert_push: tenscript.4s:2: m4@&t@_divert_push:script.4s:1: m4@&t@_divert: KILL]])AT_CHECK_M4SUGAR_TEXT([[dnlm4_divert_text([3], [three])dnlm4_divert_text([4], [four])dnlm4_divert_text([1], [one])dnlm4_divert_text([2], [two])dnlm4_cleardivert([2], [3])dnl]],[[onefour]],[[script.4s:4: warning: prefer named diversionsscript.4s:5: warning: prefer named diversionsscript.4s:6: warning: prefer named diversionsscript.4s:7: warning: prefer named diversionsscript.4s:8: warning: prefer named diversions]])AT_DATA_M4SUGAR([script.4s],[[m4_divert_pop]])AT_CHECK_M4SUGAR([-o-], [1], [],[[script.4s:1: error: too many m4@&t@_divert_popscript.4s:1: the top levelautom4te: m4 failed with exit status: 1]])AT_DATA_M4SUGAR([script.4s],[[m4_initm4_divert_push([1])m4_divert_pop([2])]])AT_CHECK_M4SUGAR([-o-], [1], [],[[script.4s:3: error: m4@&t@_divert_pop(2): diversion mismatch:script.4s:2: m4@&t@_divert_push: 1script.4s:1: m4@&t@_divert: KILLscript.4s:3: the top levelautom4te: m4 failed with exit status: 1]])AT_DATA_M4SUGAR([script.4s],[[m4_divert([1])m4_initm4_divert_push([2])]])AT_CHECK_M4SUGAR([-o-], [1], [],[[script.4s:2: error: m4@&t@_init: unbalanced m4@&t@_divert_push:script.4s:3: m4@&t@_divert_push: 2script.4s:2: m4@&t@_divert: KILLscript.4s:2: the top levelautom4te: m4 failed with exit status: 1]])AT_CLEANUP## -------------------- #### m4_expansion_stack.  #### -------------------- ##AT_SETUP([m4@&t@_expansion_stack])AT_CHECK_M4SUGAR_TEXT([[1.m4_expansion_stackm4_defun([a], [b])dnlm4_define([c], [d])dnlm4_defun([d], [2.m4_expansion_stack])dnlm4_defun([b], [c])dnla3.m4_ifdef([_m4_expansion_stack], [m4_expansion_stack])]], [[1.script.4s:3: the top level2.script.4s:6: d is expanded from...script.4s:7: b is expanded from...script.4s:4: a is expanded from...script.4s:8: the top level3.]])AT_CLEANUP## --------------------------- #### m4_require: error message.  #### --------------------------- ##AT_SETUP([m4@&t@_require: error message])AT_KEYWORDS([m4@&t@_require])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 macroscript.4s:2: the top levelautom4te: m4 failed with exit status: 1]])AT_CLEANUP## ----------------------------------- #### m4_require: circular dependencies.  #### ----------------------------------- ##AT_SETUP([m4@&t@_require: circular dependencies])AT_KEYWORDS([m4@&t@_require])AT_DATA_M4SUGAR([script.4s],[[m4_defun([foo], [m4_require([bar])])m4_defun([bar], [m4_require([foo])])m4_defun([baz], [m4_require([foo])])m4_initm4_divert([0])dnlbaz]])AT_CHECK_M4SUGAR([], 1, [],[[script.4s:9: error: m4@&t@_require: circular dependency of fooscript.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 levelautom4te: m4 failed with exit status: 1]])AT_CLEANUP## ---------------------- #### m4_require: one-shot.  #### ---------------------- ##AT_SETUP([m4@&t@_require: one-shot initialization])AT_KEYWORDS([m4@&t@_require])AT_KEYWORDS([m4@&t@_defun_init m4@&t@_copy m4@&t@_defun_once])dnl check out m4_defun_init, m4_copy, and odd macro namesAT_CHECK_M4SUGAR_TEXT([[m4_define([t], [text])dnlm4_defun_init([a], [[init a]], [[common a] t])dnlm4_defun([b], [[b]m4_require([a])])dnlm4_defun([c], [[c]m4_require([a])])dnlbca()dnlm4_defun_init([-], [hello, ], [m4_if([$#], [0], [world], [[$1]])])dnlm4_copy([-], [.])dnlm4_indir([.])m4_indir([.], [goodbye])m4_indir([-], [again])]], [[init acommon a textbccommon a texthello, worldgoodbyehello, again]])dnl Check m4_defun_once behaviorAT_CHECK_M4SUGAR_TEXT([[m4_defun_once([a], [[a]])dnlm4_defun([b], [[b]m4_require([a])])dnlm4_defun([c], [[c]a[]m4_require([b])])dnlcam4_defun_once([d], [[d]m4_require([a])])dnldm4_defun_once([e], [[e]])dnlm4_defun([f], [[f]m4_require([e])e])dnlf]], [[abcdef]])AT_CLEANUP## -------------------- #### m4_require: nested.  #### -------------------- ##AT_SETUP([m4@&t@_require: nested])AT_KEYWORDS([m4@&t@_require m4@&t@_defun])dnl From the m4sugar.m4 discourse: Require chains, top levelAT_CHECK_M4SUGAR_TEXT([[dnlm4_defun([a], [[a]])dnl aka TEST2am4_defun([b], [[b]m4_require([a])])dnl aka TEST3m4_defun([c], [[c]m4_require([b])])dnl aka TEST2bm4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1preddpost]],[[preabcddpost]])dnl From the m4sugar.m4 discourse: Require chains, nestedAT_CHECK_M4SUGAR_TEXT([[dnlm4_defun([a], [[a]])dnl aka TEST2am4_defun([b], [[b]m4_require([a])])dnl aka TEST3m4_defun([c], [[c]m4_require([b])])dnl aka TEST2bm4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1m4_defun([wrap],[preddpost])dnlwrap]],[[abcpreddpost]])dnl Direct invocation, nested requires, top levelAT_CHECK_M4SUGAR_TEXT([[dnlm4_defun([a], [[a]])dnlm4_defun([b], [[b]m4_require([a])])dnlm4_defun([c], [[c]m4_require([b])])dnlpreacacpost]],[[preabcacpost]])dnl Direct invocation, nested requires, nested defun.  This is an examplednl of expansion before requirement, such that b occurs before itsdnl prerequisite a.  This indicates a bug in the macros (but not indnl autoconf), so we should be emitting a warning.AT_CHECK_M4SUGAR_TEXT([[dnlm4_defun([a], [[a]])dnlm4_defun([b], [[b]m4_require([a])])dnlm4_defun([c], [[c]m4_require([b])])dnldnl the extra macro layer works around line number differences in older m4m4_define([foo], [m4_defun([outer],[preacacpost])])foo[]dnlouter]],[[abpreacacpost]],[[script.4s:15: warning: m4@&t@_require: `a' was expanded before it was requiredscript.4s:15: http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Requiredscript.4s:5: b is expanded from...script.4s:6: c is expanded from...script.4s:14: outer is expanded from...script.4s:15: the top level]])dnl Direct invocation, expand-before-require but no nested require.  As thisdnl is common in real life, but does not result in out-of-order expansion,dnl we silently permit this.AT_CHECK_M4SUGAR_TEXT([[dnlm4_defun([a], [[a]])dnlm4_defun([b], [[b]m4_require([a])])dnlm4_defun([c], [[c]])dnlm4_defun([d], [[d]m4_require([c])])dnlpre1ababpost1m4_defun([outer],[pre2cdcdpost2])dnlouterm4_defun([e], [[e]])dnlm4_defun([f], [[f]m4_require([e])])dnlm4_defun([g], [[g]ef])dnlm4_defun([h], [[h]m4_require([g])])dnlhm4_defun([i], [[i]])dnlm4_defun([j], [[j]i])dnlm4_defun([k], [[k]m4_require([i])])dnlm4_defun([l], [[l]m4_require([k])])dnlm4_defun([m], [[m]m4_require([j])m4_require([l])])dnlm]],[[pre1ababpost1pre2cdcdpost2gefhjiklm]])AT_CLEANUP## ------------------------------------------------- #### m4_ifval, m4_ifblank, m4_ifset, m4_default, etc.  #### ------------------------------------------------- ##AT_SETUP([m4sugar shorthand conditionals])AT_KEYWORDS([m4@&t@_ifval m4@&t@_ifblank m4@&t@_ifnblank m4@&t@_ifsetm4@&t@_default m4@&t@_default_quoted m4@&t@_default_nblankm4@&t@_default_nblank_quoted])AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])m4_define([empty])m4_ifval([active], [yes], [no])m4_ifval([empty], [yes], [no])m4_ifval([ ], [yes], [no])m4_ifval([], [yes], [no])m4_ifblank([active], [yes], [no])m4_ifblank([empty], [yes], [no])m4_ifblank([ ], [yes], [no])m4_ifblank([], [yes], [no])m4_ifnblank([active], [yes], [no])m4_ifnblank([empty], [yes], [no])m4_ifnblank([ ], [yes], [no])m4_ifnblank([], [yes], [no])m4_ifset([active], [yes], [no])m4_ifset([empty], [yes], [no])m4_ifset([ ], [yes], [no])m4_ifset([], [yes], [no])---m4_define([demo1], [m4_default([$1], [$2])])dnlm4_define([demo2], [m4_default_quoted([$1], [$2])])dnlm4_define([demo3], [m4_default_nblank([$1], [$2])])dnlm4_define([demo4], [m4_default_nblank_quoted([$1], [$2])])dnldemo1([active], [default])demo1([], [active])demo1([empty], [text])-demo1([ ], [active])-demo2([active], [default])demo2([], [active])demo2([empty], [text])-demo2([ ], [active])-demo3([active], [default])demo3([], [active])demo3([empty], [text])-demo3([ ], [active])-demo4([active], [default])demo4([], [active])demo4([empty], [text])-demo4([ ], [active])-]], [[yesyesyesnononoyesyesyesyesnonoyesnonono---ACTIVEACTIVE- -activeactiveempty- -ACTIVEACTIVE-ACTIVE-activeactiveempty-active-]])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])dnlm4_cond([a])bm4_cond([1], [1], [a])bm4_cond([1], [2], [3], [a])b]], [[ac3yesyesno10ABABAB]], [[12223333]])AT_CLEANUP## ---------- #### m4 lists.  #### ---------- ##AT_SETUP([m4 lists])AT_KEYWORDS([m4@&t@_car m4@&t@_cdr m4@&t@_argn _m4@&t_cdr])AT_CHECK_M4SUGAR_TEXT([[dnlm4_define([a], [A])m4_define([b], [B])m4_define([c], [C])m4_argn([1], [a], [b], [c])m4_argn([2], [a], [b], [c])m4_argn([3], [a], [b], [c])m4_argn([4], [a], [b], [c])m4_car([a], [b], [c])m4_cdr([a], [b], [c])m4_cdr([a], [b])m4_cdr([a])_m4_cdr([a], [b], [c])_m4_cdr([a], [b])_m4_cdr([a])m4_if(m4_cdr([], []), [[]], [good], [bad])m4_if(m4_cdr([]), [], [good], [bad])]], [[abca[b],[c][b], [b],[c], [b]goodgood]])AT_DATA_M4SUGAR([script.4s],[[m4_initm4_argn([0], [a], [b], [c])]])AT_CHECK_M4SUGAR([-o-], [1], [],[[script.4s:2: error: assert failed: 0 < 0script.4s:2: the top levelautom4te: m4 failed with exit status: 1]])AT_CLEANUP## ---------- #### m4_split.  #### ---------- ##AT_SETUP([m4@&t@_split])AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACT, IVE])m4_define([bd], [oops])m4_splitm4_split([[]])m4_split([ ])m4_split([active])m4_split([ active	active ])endm4_split([ ], [ ])m4_split([active], [ ])m4_split([ active	active ], [ ])endm4_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 internaldnl quoting strings in m4_split are changedm4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnlm4_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], [)}>=@&t@-], [b], [-@&t@=<{(], [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])dnlm4_define([AB], [4])m4_define([BC], [5])m4_define([ABC], [6])dnlm4_dom4_do([a])m4_do([a], [b])cm4_unquote(m4_join([], [a], [b]))cm4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnlm4_do([a], [b])cm4_unquote(m4_join([], [a], [b]))c]],[[aabc3ABC3]])AT_CLEANUP## ----------- #### m4_append.  #### ----------- ##AT_SETUP([m4@&t@_append])AT_KEYWORDS([m4@&t@_append_uniq m4@&t@_append_uniq_w])AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnlm4_append([sentence], [This is an])dnlm4_append([sentence], [ active ])dnlm4_append([sentence], [symbol.])dnlsentencem4_undefine([active])dnlsentencem4_define([active], [ACTIVE])dnlm4_append([hooks], [m4_define([act1], [act2])])dnlm4_append([hooks], [m4_define([act2], [active])])dnlm4_undefine([active])dnlact1hooksact1dnl Test for bug fixed in 2.62 when separator is active.m4_define([a], [A])dnlm4_append_uniq([foo], [-], [a])dnlm4_append_uniq([foo], [-], [a])dnlm4_append_uniq([bar], [-], [a])dnlm4_append_uniq([bar], [~], [a])dnlm4_append_uniq([bar], [-], [a])dnlm4_defn([foo])m4_defn([bar])foobarm4_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], [, ])dnlblahm4_dquote(blah)m4_append([list], [one], [[, ]])dnlm4_append([list], [two], [[, ]])dnlm4_append([list], [three], [[, ]])dnllistm4_dquote(list)m4_append_uniq_w([numbers], [1 1 2])dnlm4_append_uniq_w([numbers], [ 2 3 ])dnlnumbers]],[[This is an ACTIVE symbol.This is an active symbol.act1active--a~--A~newnewexistingnewone, two, three, two[one],[two],[three],[two]one, two, three[one, two, three]1 2 3]])AT_DATA_M4SUGAR([script.4s],[[m4_init[]dnlm4_append_uniq([str], [a], [ ])m4_append_uniq([str], [a b], [ ])m4_divert([])dnlstr]])AT_CHECK_M4SUGAR([-o-], 0, [[a a b]], [[script.4s:3: 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_joinm4_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_joinallm4_joinall([-])m4_joinall([-], [one])]],[[one, two[one, two]active|activeoneonetwotwoone active twoonetwoone--two--three--onetwoone]])AT_CLEANUP## ----------- #### m4_expand.  #### ----------- ##AT_SETUP([m4@&t@_expand])AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnlm4_expand([#activeactive])m4_expand([[active]])dnl properly quoted case statementsm4_expand([case a in @%:@(  *) echo active, ;;esaccase b in  *[)] echo active, ;;esac])dnl unbalanced underquoted `)', but we manage anyway (gasp!)m4_expand([case c in #(  *) echo active, ;;esaccase d in  *) echo active, ;;esac])dnl unterminated comment/dnlm4_expand([active # active])m4_expand([adnl])m4_expand([a-dnl])]],[[#activeACTIVEactivecase a in #(  *) echo ACTIVE, ;;esaccase b in  *) echo ACTIVE, ;;esaccase c in #(  *) echo ACTIVE, ;;esaccase d in  *) echo ACTIVE, ;;esacACTIVE # activeaa-]])AT_CLEANUP## ------------- #### m4_text_box.  #### ------------- ##AT_SETUP([m4@&t@_text_box])AT_CHECK_M4SUGAR_TEXT([[m4_text_box([a $1 @&t@b])m4_text_box([a $1 @&t@b], [$])m4_text_box([a $1 @&t@b], [,])]], [[## ------ #### a $1 b #### ------ #### $$$$$$ #### a $1 b #### $$$$$$ #### ,,,,,, #### a $1 b #### ,,,,,, ##]])AT_CLEANUP## -------------- #### m4_text_wrap.  #### -------------- ##AT_SETUP([m4@&t@_text_wrap])AT_KEYWORDS([m4@&t@_escape])# 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_init[]m4_divert([])dnlm4_define([a], [OOPS])dnlm4_escape([a[b $c#]d])m4_if(m4_escape([a[b $c#]d]), [a[b $c#]d], [oops],      m4_escape([a[b $c#]d]), [a@<:@b @S|@c@%:@@:>@d], [pass], [oops])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  space]])m4_define([xfff], [oops])m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20])]])AT_DATA([expout],[[a[b $c#]dpass/* Short string *//* Much longer   string */  --short Short doc.  --too-wide          Short doc.  --too-wide          Super long          documentation.First, second , third, [,quoted space] $@ 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])dnlm4_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])m4_version_compare([08], [09])m4_version_compare([010], [8])dnl Test that side effects to m4_list_cmp occur exactly oncem4_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])])]],[[-111-1100-1100-1-11-1100]], [[hihihibye]])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])dnlm4_bmatch([$*], [a])bm4_bmatch([$*], [\*], [a])bm4_bmatch([$*], [1], [2], [a])b]], [[default\yesyesno\12ABABAB]])AT_CLEANUP## ------------------------ #### m4_toupper, m4_tolower.  #### ------------------------ ##AT_SETUP([m4@&t@_toupper and m4@&t@_tolower])AT_CHECK_M4SUGAR_TEXT([[m4_define([abc], [hI])m4_define([ABC], [Hi])m4_toupper(abc aBc ABC)m4_tolower(abc aBc ABC)m4_toupper([abc aBc ABC])m4_tolower([abc aBc ABC])m4_echo(m4_toupper(abc aBc ABC))m4_echo(m4_tolower(abc aBc ABC))m4_echo(m4_toupper([abc aBc ABC]))m4_echo(m4_tolower([abc aBc ABC]))m4_do(m4_toupper(abc aBc ABC))m4_do(m4_tolower(abc aBc ABC))m4_do(m4_toupper([abc aBc ABC]))m4_do(m4_tolower([abc aBc ABC]))]], [[HI ABC HIhi abc hiABC ABC ABCabc abc abcHI ABC HIhi abc hiABC ABC ABCabc abc abcHI Hi HIhi hI hiHi Hi HihI hI hI]])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])dnlm4_define([AB], [good])m4_define([bc], [good])dnlm4_bpatsubsts([abc], [a], [A], [b], [B], [c])m4_bpatsubsts([ab], [a])cm4_bpatsubsts([ab], [c], [C], [a])cm4_bpatsubsts([$1$*$@], [\$\*], [$#])]], [[11212223goodgoodgood$1$#$@]])AT_CLEANUP## -------------- #### m4_esyscmd_s.  #### -------------- ##AT_SETUP([m4@&t@_esyscmd_s])AT_KEYWORDS([m4@&t@_chomp m4@&t@_chomp_all])AT_CHECK_M4SUGAR_TEXT([[m4_define([world], [WORLD])dnlm4_chomp([abc])m4_chomp([world])m4_esyscmd_s([echo hello world])m4_esyscmd_s([echo '[goodbye,cruel world]'])]], [[abcworldhello WORLDgoodbye,cruel world]])AT_CLEANUP## ---------- #### M4 Loops.  #### ---------- ##AT_SETUP([M4 loops])AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w m4@&t@_map_args_w])AT_CHECK_M4SUGAR_TEXT([[dnlm4_define([myvar], [outer value])dnlm4_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 endlesslym4_for([myval], 1, 1, 0, [ myval])dnl Make sure to properly parenthesizem4_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 iterationsm4_for([myvar], 1, 5, , [ myvar[]m4_define([myvar], 5)])dnl Make sure we can do nameless iterationm4_for(, 1, 10, , -)dnl foreach testsm4_foreach([myvar], [[a], [b, c], [d], [e],[f]], [ myvar|])m4_foreach_w([myvar], [a  b c, d,e fg], [ myvar|])myvarm4_map_args_w([a  b c, d,e fg], [ ], [|])m4_map_args_w([a b], [\1], [/])m4_define([dashes], [--])dnlm4_map_args_w([a b c], [/], [\1], [dashes])dnl only one side effect expansion, prior to visiting list elementsm4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnldnl shifting forms an important part of loopsm4_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 a| b| c,| d,e| f| g|\1a/\1b//a\1--/b\1--/c\1::4:4]], [[hi123]])dnl bounds checking in m4_forAT_DATA_M4SUGAR([script.4s],[[m4_initm4_divert([0])dnlm4_for([myvar], 1, 3,-1, [ myvar])]])AT_CHECK_M4SUGAR([], 1, [],[[script.4s:3: error: assert failed: -1 > 0script.4s:3: the top levelautom4te: m4 failed with exit status: 1]])AT_DATA_M4SUGAR([script.4s],[[m4_initm4_divert([0])dnlm4_for([myvar], 1, 2, 0, [ myvar])]])AT_CHECK_M4SUGAR([], 1, [],[[script.4s:3: error: assert failed: 0 > 0script.4s:3: the top levelautom4te: m4 failed with exit status: 1]])AT_DATA_M4SUGAR([script.4s],[[m4_initm4_divert([0])dnlm4_for([myvar], 2, 1, 0, [ myvar])]])AT_CHECK_M4SUGAR([], 1, [],[[script.4s:3: error: assert failed: 0 < 0script.4s:3: the top levelautom4te: m4 failed with exit status: 1]])dnl m4_shiftn also does bounds checkingAT_DATA_M4SUGAR([script.4s],[[m4_initm4_divert([0])dnlm4_shiftn(3,1,2)]])AT_CHECK_M4SUGAR([], 1, [],[[script.4s:3: error: assert failed: 0 < 3 && 3 < 3script.4s:3: the top levelautom4te: 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([[dnlm4_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])])dnlm4_define([a1], [oops])dnlm4_define([pass1], [oops])dnlm4_map([a], [[[a]]])1m4_map([m4_unquote([a])], [m4_dquote([a])])dnl only one side effect expansion, prior to visiting list elementsm4_map([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnlm4_map_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnlm4_mapall([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnlm4_mapall_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl]],[[ 1 2 0 1 23,a233,a11--pass1pass]], [[hi123hi123hi123hi123]])AT_CLEANUP## --------------------------------------- #### m4_map_args{,_sep,_pair} and m4_curry.  #### --------------------------------------- ##AT_SETUP([m4@&t@_map_args and m4@&t@_curry])AT_KEYWORDS([m4@&t@_map_args_sep m4@&t@_map_args_pair m4@&t@_reversem4@&t@_map])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]))])dnlm4_define([add_one], [m4_curry([add], [1])])dnladd_one()([4])]],[[13, 2, 15]])dnl Now, check that we can map a list of arguments.AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnlm4_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])m4_map_args_sep([<], [>], [:], [1], [2], [3])m4_map_args_sep([m4_echo(], [)], [ ], [plain], [active])]],[[ plain activeplainACTIVE, 1, 2, 1, 2, 1, 3, 2, 1, 4, 3, [1], 2, 1, 2, 1, [3], 2, 1, 4, 3<1>:<2>:<3>plain active]])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]))])dnlm4_define([list], [[-1], [0], [1]])dnldnl list_add_n(value, arg...)dnl add VALUE to each ARG and output the resulting listm4_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,21,2,3]])AT_CLEANUP## ------------ #### m4_combine.  #### ------------ ##AT_SETUP([m4@&t@_combine])AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnlm4_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-3a-, 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@_maxscript.4s:1: the top levelautom4te: 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@_minscript.4s:1: the top levelautom4te: m4 failed with exit status: 1]])AT_CHECK_M4SUGAR_TEXT([[dnlm4_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)]],[[010000110011----0100112122100100]], [])AT_CLEANUP## ----------- #### Recursion.  #### ----------- ##AT_SETUP([recursion])AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_condm4@&t@_bpatsubsts m4@&t@_shiftn m4@&t@_do m4@&t@_dquote_elt m4@&t@_reversem4@&t@_map m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_minm4@&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 wednl 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_initm4_divert_push([])[]dnlm4_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)])dnlm4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnlm4_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)dnlm4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) jm4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],  [1], [10000], [], [,i]))))m4_divert_pop([])]])AT_CHECK_M4SUGAR([-o-], [0], [[488949999,10000788965889410000end000A^9998$9990 99905001]])AT_DATA_M4SUGAR([script.4s],[[m4_ifdef([__m4_version__],[m4_undefine([__m4_version__])],[m4_divert_push([])488949999,10000788965889410000end000A^9998$9990 99905001m4_exit([0])])m4_initm4_divert_push([])[]dnlm4_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)])dnlm4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnlm4_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)dnlm4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) jm4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],  [1], [10000], [], [,i]))))m4_divert_pop([])]])AT_CHECK_M4SUGAR([-o-], [0], [[488949999,10000788965889410000end000A^9998$9990 99905001]])AT_CLEANUP## ---------- #### m4_set_*.  #### ---------- ##AT_SETUP([m4@&t@_set])AT_KEYWORDS([m4@&t@_set_add m4@&t@_set_add_all m4@&t@_set_containsm4@&t@_set_contents m4@&t@_set_delete m4@&t@_set_difference m4@&t@_set_dumpm4@&t@_set_empty m4@&t@_set_foreach m4@&t@_set_intersection m4@&t@_set_listm4@&t@_set_listc m4@&t@_set_map m4@&t@_set_remove m4@&t@_set_sizem4@&t@_set_union])# Simple testsAT_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])])dnlm4_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])]], [[noaddedyesdup1removednomissingaddednoyes1-2-33-2-1,1,2,,4,3,1,2,3,,4:1:322,[],1[]0]])# Stress tests - check for unusual names/valuesAT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnlm4_set_add([a], [a])dnlm4_set_remove([a], [oops], [yes], [no])m4_set_add([a,b], [c])dnlm4_set_add([a,b], [$*[]])dnlm4_set_add_all([a], [b,c])dnlm4_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([$*[]], [])dnlm4_set_remove([$*[]], [a], [yes], [no])m4_set_add([$*[]], [a])dnlm4_set_foreach([$*[]], [$*[]], [-m4_defn([$*[]])m4_indir([$*[]])-])m4_set_remove([$*[]], [], [yes], [no])m4_set_add([c], [,])dnlm4_set_foreach([a,b], [set], [:m4_set_listc(_m4_defn([set])):])]],[[no212b,c,ac,$*[]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([[dnlm4_for([i], [1], [10000], [], [m4_set_add([a], i)])dnlm4_set_add_all([b]m4_for([i], [1], [10000], [], [,i]))dnlm4_set_remove([a], [1])dnlm4_set_remove([b], [10000])dnlm4_set_add_all([a]m4_for([i], [1], [10000], [], [,i]))dnlm4_for([i], [1], [10000], [], [m4_set_add([b], i)])dnlm4_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], [-])])])dnlm4_len(m4_set_map([a], [prune3x]))m4_count(m4_shift(m4_set_intersection([a], [b])))]], [[388945000500033333334]])AT_CLEANUP## ---------------------- #### __file__ and __line__. #### ---------------------- ##AT_SETUP([[__file__ and __line__]])# Check that __file__ and __line__ work.# Check that m4__file__ and m4__line__ are not defined# (and get them to pass by the undefined-macro check).# Try to not assume too much about AT_CHECK_M4SUGAR_TEXT.AT_CHECK_M4SUGAR_TEXT([[dnlm4_pattern_allow([m4__file__])dnlm4_pattern_allow([m4__line__])dnlm4__file__m4__line____file__m4_define([first], __line__)dnlm4_define([second], __line__)dnlm4_assert(first + 1 == second)dnl]], [[m4@&t@__@&t@file__m4@&t@__@&t@line__script.4s]])AT_CLEANUP
 |