1# -*- Autotest -*- 2 3AT_BANNER([M4sugar.]) 4 5# Copyright (C) 2000-2002, 2005-2012 Free Software Foundation, Inc. 6# 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20 21# AT_CHECK_M4SUGAR_TEXT(CODE, STDOUT, STDERR) 22# ------------------------------------------- 23# Check that m4sugar CODE expands to STDOUT and emits STDERR. 24m4_define([AT_CHECK_M4SUGAR_TEXT], 25[ 26AT_DATA_M4SUGAR([script.4s], 27[[m4_init 28m4_divert_push([])[]dnl 29]$1[[]dnl 30m4_divert_pop([]) 31]]) 32 33AT_CHECK_M4SUGAR([-o-],, [$2], [$3]) 34])# AT_CHECK_M4SUGAR_TEXT 35 36 37## ------------------ ## 38## m4_stack_foreach. ## 39## ------------------ ## 40 41AT_SETUP([m4@&t@_stack]) 42 43AT_KEYWORDS([m4@&t@_stack_foreach m4@&t@_stack_foreach_lifo]) 44AT_KEYWORDS([m4@&t@_stack_foreach_sep m4@&t@_stack_foreach_sep_lifo]) 45AT_KEYWORDS([m4@&t@_copy m4@&t@_n]) 46 47# Test the semantics of macros to walk stacked macro definitions. 48AT_CHECK_M4SUGAR_TEXT([[dnl 49m4_pushdef([abc], [def])dnl 50m4_pushdef([abc], [ghi])dnl 51m4_pushdef([abc], [jkl])dnl 52m4_stack_foreach([abc], [m4_n]) 53abc 54m4_stack_foreach_lifo([abc], [m4_n]) 55m4_stack_foreach([abc], [m4_n]) 56m4_copy([abc], [foo])dnl 57m4_stack_foreach([foo], [m4_n]) 58m4_stack_foreach_lifo([foo], [m4_n]) 59m4_stack_foreach_sep([abc], [ m4_index([abcdefghijkl],], [)]) 60m4_define([colon], [:])m4_define([lt], [<])m4_define([gt], [>])dnl 61m4_stack_foreach_sep_lifo([abc], [lt], [gt], [colon]) 62m4_pushdef([xyz], [123])dnl 63m4_pushdef([xyz], [456])dnl 64m4_define([doit], [[$1](m4_stack_foreach_sep([xyz], [m4_dquote(], [)], [,])) 65])dnl 66m4_stack_foreach([abc], [doit])]], 67[[def 68ghi 69jkl 70 71jkl 72jkl 73ghi 74def 75 76def 77ghi 78jkl 79 80def 81ghi 82jkl 83 84jkl 85ghi 86def 87 88 3 6 9 89<jkl>:<ghi>:<def> 90def([123],[456]) 91ghi([123],[456]) 92jkl([123],[456]) 93]]) 94 95AT_CLEANUP 96 97 98## --------- ## 99## m4_defn. ## 100## --------- ## 101 102AT_SETUP([m4@&t@_defn]) 103 104AT_KEYWORDS([m4@&t@_popdef m4@&t@_undefine m4@&t@_copy m4@&t@_rename 105m4@&t@_copy_force m4@&t@_rename_force]) 106 107# Ensure that m4sugar dies when dereferencing undefined macros, whether 108# this is provided by m4 natively or faked by wrappers in m4sugar. 109 110AT_DATA_M4SUGAR([script.4s], 111[[m4_define([good]) 112m4_defn([good], [oops]) 113]]) 114 115AT_CHECK_M4SUGAR([-o-], 1, [], [stderr]) 116AT_CHECK([grep good stderr], [1]) 117AT_CHECK([grep 'm4@&t@_defn: undefined.*oops' stderr], [0], [ignore]) 118 119AT_DATA_M4SUGAR([script.4s], 120[[m4_define([good]) 121m4_popdef([good], [oops]) 122]]) 123 124AT_CHECK_M4SUGAR([-o-], 1, [], [stderr]) 125AT_CHECK([grep good stderr], [1]) 126AT_CHECK([grep 'm4@&t@_popdef: undefined.*oops' stderr], [0], [ignore]) 127 128AT_DATA_M4SUGAR([script.4s], 129[[m4_define([good]) 130m4_undefine([good], [oops]) 131]]) 132 133AT_CHECK_M4SUGAR([-o-], 1, [], [stderr]) 134AT_CHECK([grep good stderr], [1]) 135AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore]) 136 137# Cannot rename an undefined macro. 138AT_DATA_M4SUGAR([script.4s], 139[[m4_rename([oops], [good]) 140]]) 141 142AT_CHECK_M4SUGAR([-o-], 1, [], [stderr]) 143AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore]) 144 145# Check that pushdef stacks can be renamed. 146AT_CHECK_M4SUGAR_TEXT([[m4_pushdef([a], [1])dnl 147m4_pushdef([a], [2])dnl 148m4_pushdef([a], m4_defn([m4_divnum]))dnl 149a b c 150m4_rename([a], [b])dnl 151a b c 152m4_copy([b], [c])dnl 153a b c 154m4_popdef([b], [c])dnl 155a b c 156m4_popdef([b], [c])dnl 157a b c 158m4_popdef([b], [c])dnl 159a b c 160dnl m4_copy is intentionally a no-op on undefined source 161m4_copy([oops], [dummy])m4_ifdef([dummy], [[oops]])dnl 162dnl allow forceful overwrites 163m4_define([d], [4])m4_define([e], [5])m4_define([f], [6])dnl 164m4_copy_force([d], [e])dnl 165m4_rename_force([d], [f])dnl 166d e f 167m4_popdef([e], [f])dnl 168d e f 169]], [[0 b c 170a 0 c 171a 0 0 172a 2 2 173a 1 1 174a b c 175d 4 4 176d e f 177]]) 178 179AT_CLEANUP 180 181 182## ------------ ## 183## m4_dumpdef. ## 184## ------------ ## 185 186AT_SETUP([m4@&t@_dumpdef]) 187 188AT_KEYWORDS([m4@&t@_dumpdefs]) 189 190# Ensure that m4sugar dies when dereferencing undefined macros. 191 192AT_DATA_M4SUGAR([script.4s], 193[[m4_define([good], [yep]) 194m4_dumpdef([good], [oops]) 195]]) 196 197AT_CHECK_M4SUGAR([-o-], 1, [], [stderr]) 198AT_CHECK([grep '^good: \[[yep\]]$' stderr], [0], [ignore]) 199AT_CHECK([grep 'm4@&t@_dumpdef: undefined.*oops' stderr], [0], [ignore]) 200 201# Check that pushdef stacks can be dumped. 202AT_CHECK_M4SUGAR_TEXT([[m4_divert_push([KILL]) 203m4_pushdef([a], [1]) 204m4_pushdef([a], [2]) 205m4_dumpdef([a]) 206m4_dumpdefs([oops], [a]) 207m4_divert_pop([KILL])dnl 208]], [], 209[[a: [2] 210a: [2] 211a: [1] 212]]) 213 214# Check behavior when dumping builtins. Unfortunately, when using M4 1.4.x 215# (or more precisely, when __m4_version__ is undefined), builtins get 216# flattened to an empty string. It takes M4 1.6 to work around this. 217AT_DATA_M4SUGAR([script.4s], 218[[m4_ifdef([__m4_version__], [_m4_undefine([__m4_version__])]) 219m4_init 220m4_dumpdef([m4_define]) 221]]) 222 223AT_CHECK_M4SUGAR([-o-], [0], [], 224[[m4_define: [] 225]]) 226 227AT_DATA_M4SUGAR([script.4s], 228[[m4_init 229m4_ifdef([__m4_version__], 230[m4_dumpdef([m4_define])], 231[m4_errprintn([m4_define: <define>])]) 232]]) 233 234AT_CHECK_M4SUGAR([-o-], [0], [], 235[[m4_define: <define> 236]]) 237 238AT_CLEANUP 239 240 241## --------- ## 242## m4_warn. ## 243## --------- ## 244 245AT_SETUP([m4@&t@_warn]) 246 247AT_DATA_M4SUGAR([script.4s], 248[[m4_init 249m4_defun([cross_warning], [m4_warn([cross], [cross])]) 250 251m4_divert([0])dnl 252m4_warn([obsolete], [obsolete])dnl 253cross_warning[]dnl 254m4_warn([syntax], [syntax])dnl 255cross_warning[]dnl 256m4_warn([syntax], [syntax])dnl 257]]) 258 259AT_CHECK_M4SUGAR([-o-], 0, [], 260[script.4s:4: warning: prefer named diversions 261script.4s:7: warning: syntax 262script.4s:9: warning: syntax 263]) 264 265AT_CHECK_M4SUGAR([-o- -Wall], 0, [], 266[script.4s:4: warning: prefer named diversions 267script.4s:5: warning: obsolete 268script.4s:6: warning: cross 269script.4s:2: cross_warning is expanded from... 270script.4s:6: the top level 271script.4s:7: warning: syntax 272script.4s:8: warning: cross 273script.4s:2: cross_warning is expanded from... 274script.4s:8: the top level 275script.4s:9: warning: syntax 276]) 277 278AT_CHECK_M4SUGAR([-o- -Wnone,cross], 0, [], 279[script.4s:6: warning: cross 280script.4s:2: cross_warning is expanded from... 281script.4s:6: the top level 282script.4s:8: warning: cross 283script.4s:2: cross_warning is expanded from... 284script.4s:8: the top level 285]) 286 287AT_CHECK_M4SUGAR([-o- -Wnone,cross,error], 1, [], 288[[script.4s:6: warning: cross 289script.4s:2: cross_warning is expanded from... 290script.4s:6: the top level 291script.4s:8: warning: cross 292script.4s:2: cross_warning is expanded from... 293script.4s:8: the top level 294]]) 295 296AT_CLEANUP 297 298 299## ----------------- ## 300## m4_divert_stack. ## 301## ----------------- ## 302 303AT_SETUP([m4@&t@_divert_stack]) 304AT_KEYWORDS([m4@&t@_divert m4@&t@_divert_push m4@&t@_divert_pop 305m4@&t@_undivert m4@&t@_cleardivert m4@&t@_divert_text]) 306 307dnl This test names some diversions to avoid a warning. 308AT_CHECK_M4SUGAR_TEXT([[m4_define([_m4_divert(ten)], [10])dnl 309m4_define([_m4_divert(twenty)], [20])dnl 310m4_define([_m4_divert(thirty)], [30])dnl 3111.m4_divert_stack 312m4_divert_push([ten])2.m4_divert_stack 313m4_divert_text([twenty], [3.m4_divert_stack])dnl 314m4_divert([thirty])4.m4_divert_stack 315m4_divert_pop([thirty])dnl 3165.m4_undivert([twenty], [thirty]) 317m4_pattern_allow([^m4_divert])dnl 318]], [[1.script.4s:2: m4@&t@_divert_push: 319script.4s:1: m4@&t@_divert: KILL 3205.3.script.4s:8: m4@&t@_divert_push: twenty 321script.4s:7: m4@&t@_divert_push: ten 322script.4s:2: m4@&t@_divert_push: 323script.4s:1: m4@&t@_divert: KILL 3244.script.4s:9: m4@&t@_divert: thirty 325script.4s:2: m4@&t@_divert_push: 326script.4s:1: m4@&t@_divert: KILL 327 3282.script.4s:7: m4@&t@_divert_push: ten 329script.4s:2: m4@&t@_divert_push: 330script.4s:1: m4@&t@_divert: KILL 331]]) 332 333AT_CHECK_M4SUGAR_TEXT([[dnl 334m4_divert_text([3], [three])dnl 335m4_divert_text([4], [four])dnl 336m4_divert_text([1], [one])dnl 337m4_divert_text([2], [two])dnl 338m4_cleardivert([2], [3])dnl 339]], 340[[one 341four 342]], 343[[script.4s:4: warning: prefer named diversions 344script.4s:5: warning: prefer named diversions 345script.4s:6: warning: prefer named diversions 346script.4s:7: warning: prefer named diversions 347script.4s:8: warning: prefer named diversions 348]]) 349 350AT_DATA_M4SUGAR([script.4s], 351[[m4_divert_pop 352]]) 353AT_CHECK_M4SUGAR([-o-], [1], [], 354[[script.4s:1: error: too many m4@&t@_divert_pop 355script.4s:1: the top level 356autom4te: m4 failed with exit status: 1 357]]) 358 359AT_DATA_M4SUGAR([script.4s], 360[[m4_init 361m4_divert_push([1]) 362m4_divert_pop([2]) 363]]) 364AT_CHECK_M4SUGAR([-o-], [1], [], 365[[script.4s:3: error: m4@&t@_divert_pop(2): diversion mismatch: 366script.4s:2: m4@&t@_divert_push: 1 367script.4s:1: m4@&t@_divert: KILL 368script.4s:3: the top level 369autom4te: m4 failed with exit status: 1 370]]) 371 372AT_DATA_M4SUGAR([script.4s], 373[[m4_divert([1]) 374m4_init 375m4_divert_push([2]) 376]]) 377AT_CHECK_M4SUGAR([-o-], [1], [], 378[[script.4s:2: error: m4@&t@_init: unbalanced m4@&t@_divert_push: 379script.4s:3: m4@&t@_divert_push: 2 380script.4s:2: m4@&t@_divert: KILL 381script.4s:2: the top level 382autom4te: m4 failed with exit status: 1 383]]) 384 385AT_CLEANUP 386 387 388## -------------------- ## 389## m4_expansion_stack. ## 390## -------------------- ## 391 392AT_SETUP([m4@&t@_expansion_stack]) 393 394AT_CHECK_M4SUGAR_TEXT([[1.m4_expansion_stack 395m4_defun([a], [b])dnl 396m4_define([c], [d])dnl 397m4_defun([d], [2.m4_expansion_stack])dnl 398m4_defun([b], [c])dnl 399a 4003.m4_ifdef([_m4_expansion_stack], [m4_expansion_stack]) 401]], [[1.script.4s:3: the top level 4022.script.4s:6: d is expanded from... 403script.4s:7: b is expanded from... 404script.4s:4: a is expanded from... 405script.4s:8: the top level 4063. 407]]) 408 409AT_CLEANUP 410 411 412## --------------------------- ## 413## m4_require: error message. ## 414## --------------------------- ## 415 416AT_SETUP([m4@&t@_require: error message]) 417AT_KEYWORDS([m4@&t@_require]) 418 419AT_DATA_M4SUGAR([script.4s], 420[[m4_defun([foo], [FOO]) 421m4_require([foo]) 422]]) 423 424AT_CHECK_M4SUGAR([], 1, [], 425[[script.4s:2: error: m4@&t@_require(foo): cannot be used outside of an m4_defun'd macro 426script.4s:2: the top level 427autom4te: m4 failed with exit status: 1 428]]) 429AT_CLEANUP 430 431 432## ----------------------------------- ## 433## m4_require: circular dependencies. ## 434## ----------------------------------- ## 435 436AT_SETUP([m4@&t@_require: circular dependencies]) 437AT_KEYWORDS([m4@&t@_require]) 438 439AT_DATA_M4SUGAR([script.4s], 440[[m4_defun([foo], [m4_require([bar])]) 441 442m4_defun([bar], [m4_require([foo])]) 443 444m4_defun([baz], [m4_require([foo])]) 445 446m4_init 447m4_divert([0])dnl 448baz 449]]) 450 451AT_CHECK_M4SUGAR([], 1, [], 452[[script.4s:9: error: m4@&t@_require: circular dependency of foo 453script.4s:3: bar is expanded from... 454script.4s:1: foo is expanded from... 455script.4s:5: baz is expanded from... 456script.4s:9: the top level 457autom4te: m4 failed with exit status: 1 458]]) 459AT_CLEANUP 460 461 462## ---------------------- ## 463## m4_require: one-shot. ## 464## ---------------------- ## 465 466AT_SETUP([m4@&t@_require: one-shot initialization]) 467AT_KEYWORDS([m4@&t@_require]) 468AT_KEYWORDS([m4@&t@_defun_init m4@&t@_copy m4@&t@_defun_once]) 469 470dnl check out m4_defun_init, m4_copy, and odd macro names 471AT_CHECK_M4SUGAR_TEXT([[ 472m4_define([t], [text])dnl 473m4_defun_init([a], [[init a 474]], [[common a] t])dnl 475m4_defun([b], [[b]m4_require([a])])dnl 476m4_defun([c], [[c]m4_require([a])])dnl 477b 478c 479a()dnl 480 481m4_defun_init([-], [hello, ], [m4_if([$#], [0], [world], [[$1]])])dnl 482m4_copy([-], [.])dnl 483m4_indir([.]) 484m4_indir([.], [goodbye]) 485m4_indir([-], [again]) 486]], [[ 487init a 488common a text 489b 490c 491common a text 492hello, world 493goodbye 494hello, again 495]]) 496 497dnl Check m4_defun_once behavior 498AT_CHECK_M4SUGAR_TEXT([[ 499m4_defun_once([a], [[a]])dnl 500m4_defun([b], [[b]m4_require([a])])dnl 501m4_defun([c], [[c]a[]m4_require([b])])dnl 502c 503a 504m4_defun_once([d], [[d]m4_require([a])])dnl 505d 506m4_defun_once([e], [[e]])dnl 507m4_defun([f], [[f]m4_require([e])e])dnl 508f 509]], [[ 510a 511b 512c 513 514d 515e 516f 517]]) 518 519 520AT_CLEANUP 521 522 523## -------------------- ## 524## m4_require: nested. ## 525## -------------------- ## 526 527AT_SETUP([m4@&t@_require: nested]) 528AT_KEYWORDS([m4@&t@_require m4@&t@_defun]) 529 530dnl From the m4sugar.m4 discourse: Require chains, top level 531AT_CHECK_M4SUGAR_TEXT([[dnl 532m4_defun([a], [[a]])dnl aka TEST2a 533m4_defun([b], [[b]m4_require([a])])dnl aka TEST3 534m4_defun([c], [[c]m4_require([b])])dnl aka TEST2b 535m4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1 536pre 537d 538d 539post 540]], 541[[pre 542a 543b 544c 545d 546d 547post 548]]) 549 550dnl From the m4sugar.m4 discourse: Require chains, nested 551AT_CHECK_M4SUGAR_TEXT([[dnl 552m4_defun([a], [[a]])dnl aka TEST2a 553m4_defun([b], [[b]m4_require([a])])dnl aka TEST3 554m4_defun([c], [[c]m4_require([b])])dnl aka TEST2b 555m4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1 556m4_defun([wrap], 557[pre 558d 559d 560post])dnl 561wrap 562]], 563[[a 564b 565c 566pre 567d 568d 569post 570]]) 571 572dnl Direct invocation, nested requires, top level 573AT_CHECK_M4SUGAR_TEXT([[dnl 574m4_defun([a], [[a]])dnl 575m4_defun([b], [[b]m4_require([a])])dnl 576m4_defun([c], [[c]m4_require([b])])dnl 577pre 578a 579c 580a 581c 582post 583]], 584[[pre 585a 586b 587c 588a 589c 590post 591]]) 592 593dnl Direct invocation, nested requires, nested defun. This is an example 594dnl of expansion before requirement, such that b occurs before its 595dnl prerequisite a. This indicates a bug in the macros (but not in 596dnl autoconf), so we should be emitting a warning. 597AT_CHECK_M4SUGAR_TEXT([[dnl 598m4_defun([a], [[a]])dnl 599m4_defun([b], [[b]m4_require([a])])dnl 600m4_defun([c], [[c]m4_require([b])])dnl 601dnl the extra macro layer works around line number differences in older m4 602m4_define([foo], [m4_defun([outer], 603[pre 604a 605c 606a 607c 608post])])foo[]dnl 609outer 610]], 611[[a 612b 613pre 614a 615c 616a 617c 618post 619]], 620[[script.4s:15: warning: m4@&t@_require: `a' was expanded before it was required 621script.4s:15: http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required 622script.4s:5: b is expanded from... 623script.4s:6: c is expanded from... 624script.4s:14: outer is expanded from... 625script.4s:15: the top level 626]]) 627 628dnl Direct invocation, expand-before-require but no nested require. As this 629dnl is common in real life, but does not result in out-of-order expansion, 630dnl we silently permit this. 631AT_CHECK_M4SUGAR_TEXT([[dnl 632m4_defun([a], [[a]])dnl 633m4_defun([b], [[b]m4_require([a])])dnl 634m4_defun([c], [[c]])dnl 635m4_defun([d], [[d]m4_require([c])])dnl 636pre1 637a 638b 639a 640b 641post1 642m4_defun([outer], 643[pre2 644c 645d 646c 647d 648post2])dnl 649outer 650m4_defun([e], [[e]])dnl 651m4_defun([f], [[f]m4_require([e])])dnl 652m4_defun([g], [[g] 653e 654f])dnl 655m4_defun([h], [[h]m4_require([g])])dnl 656h 657m4_defun([i], [[i]])dnl 658m4_defun([j], [[j] 659i])dnl 660m4_defun([k], [[k]m4_require([i])])dnl 661m4_defun([l], [[l]m4_require([k])])dnl 662m4_defun([m], [[m]m4_require([j])m4_require([l])])dnl 663m 664]], 665[[pre1 666a 667b 668a 669b 670post1 671pre2 672c 673d 674c 675d 676post2 677g 678e 679f 680h 681j 682i 683k 684l 685m 686]]) 687 688AT_CLEANUP 689 690 691## ------------------------------------------------- ## 692## m4_ifval, m4_ifblank, m4_ifset, m4_default, etc. ## 693## ------------------------------------------------- ## 694 695AT_SETUP([m4sugar shorthand conditionals]) 696AT_KEYWORDS([m4@&t@_ifval m4@&t@_ifblank m4@&t@_ifnblank m4@&t@_ifset 697m4@&t@_default m4@&t@_default_quoted m4@&t@_default_nblank 698m4@&t@_default_nblank_quoted]) 699 700AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])m4_define([empty]) 701m4_ifval([active], [yes], [no]) 702m4_ifval([empty], [yes], [no]) 703m4_ifval([ ], [yes], [no]) 704m4_ifval([], [yes], [no]) 705m4_ifblank([active], [yes], [no]) 706m4_ifblank([empty], [yes], [no]) 707m4_ifblank([ ], [yes], [no]) 708m4_ifblank([], [yes], [no]) 709m4_ifnblank([active], [yes], [no]) 710m4_ifnblank([empty], [yes], [no]) 711m4_ifnblank([ ], [yes], [no]) 712m4_ifnblank([], [yes], [no]) 713m4_ifset([active], [yes], [no]) 714m4_ifset([empty], [yes], [no]) 715m4_ifset([ ], [yes], [no]) 716m4_ifset([], [yes], [no]) 717--- 718m4_define([demo1], [m4_default([$1], [$2])])dnl 719m4_define([demo2], [m4_default_quoted([$1], [$2])])dnl 720m4_define([demo3], [m4_default_nblank([$1], [$2])])dnl 721m4_define([demo4], [m4_default_nblank_quoted([$1], [$2])])dnl 722demo1([active], [default]) 723demo1([], [active]) 724demo1([empty], [text]) 725-demo1([ ], [active])- 726demo2([active], [default]) 727demo2([], [active]) 728demo2([empty], [text]) 729-demo2([ ], [active])- 730demo3([active], [default]) 731demo3([], [active]) 732demo3([empty], [text]) 733-demo3([ ], [active])- 734demo4([active], [default]) 735demo4([], [active]) 736demo4([empty], [text]) 737-demo4([ ], [active])- 738]], [[ 739yes 740yes 741yes 742no 743no 744no 745yes 746yes 747yes 748yes 749no 750no 751yes 752no 753no 754no 755--- 756ACTIVE 757ACTIVE 758 759- - 760active 761active 762empty 763- - 764ACTIVE 765ACTIVE 766 767-ACTIVE- 768active 769active 770empty 771-active- 772]]) 773 774AT_CLEANUP 775 776## --------- ## 777## m4_cond. ## 778## --------- ## 779 780AT_SETUP([m4@&t@_cond]) 781 782AT_CHECK_M4SUGAR_TEXT([[m4_define([side], [m4_errprintn([$1])$1]) 783m4_cond([side(1)], [1], [a], 784 [side(1)], [1], [b], 785 [side(1)], [2], [c]) 786m4_cond([side(2)], [1], [a], 787 [side(2)], [1], [b], 788 [side(2)], [2], [c], 789 [side(2)]) 790m4_cond([side(3)], [1], [a], 791 [side(3)], [1], [b], 792 [side(3)], [2], [c], 793 [side(3)]) 794m4_cond([a,a], [a,a], [yes], [no]) 795m4_cond([[a,a]], [a,a], [yes]) 796m4_cond([a,a], [a,b], [yes], [no]) 797m4_cond([a,a], [a,b], [yes]) 798m4_cond([m4_eval([0xa])]) 799m4_define([ab], [AB])dnl 800m4_cond([a])b 801m4_cond([1], [1], [a])b 802m4_cond([1], [2], [3], [a])b 803]], [[ 804a 805c 8063 807yes 808yes 809no 810 81110 812AB 813AB 814AB 815]], [[1 8162 8172 8182 8193 8203 8213 8223 823]]) 824 825AT_CLEANUP 826 827 828## ---------- ## 829## m4 lists. ## 830## ---------- ## 831 832AT_SETUP([m4 lists]) 833 834AT_KEYWORDS([m4@&t@_car m4@&t@_cdr m4@&t@_argn _m4@&t_cdr]) 835 836AT_CHECK_M4SUGAR_TEXT([[dnl 837m4_define([a], [A])m4_define([b], [B])m4_define([c], [C]) 838m4_argn([1], [a], [b], [c]) 839m4_argn([2], [a], [b], [c]) 840m4_argn([3], [a], [b], [c]) 841m4_argn([4], [a], [b], [c]) 842m4_car([a], [b], [c]) 843m4_cdr([a], [b], [c]) 844m4_cdr([a], [b]) 845m4_cdr([a]) 846_m4_cdr([a], [b], [c]) 847_m4_cdr([a], [b]) 848_m4_cdr([a]) 849m4_if(m4_cdr([], []), [[]], [good], [bad]) 850m4_if(m4_cdr([]), [], [good], [bad]) 851]], [[ 852a 853b 854c 855 856a 857[b],[c] 858[b] 859 860, [b],[c] 861, [b] 862 863good 864good 865]]) 866 867AT_DATA_M4SUGAR([script.4s], 868[[m4_init 869m4_argn([0], [a], [b], [c]) 870]]) 871AT_CHECK_M4SUGAR([-o-], [1], [], 872[[script.4s:2: error: assert failed: 0 < 0 873script.4s:2: the top level 874autom4te: m4 failed with exit status: 1 875]]) 876 877AT_CLEANUP 878 879 880## ---------- ## 881## m4_split. ## 882## ---------- ## 883 884AT_SETUP([m4@&t@_split]) 885 886AT_CHECK_M4SUGAR_TEXT( 887[[m4_define([active], [ACT, IVE])m4_define([bd], [oops]) 888m4_split 889m4_split([[]]) 890m4_split([ ]) 891m4_split([active]) 892m4_split([ active active ])end 893m4_split([ ], [ ]) 894m4_split([active], [ ]) 895m4_split([ active active ], [ ])end 896m4_split([abcde], [bd]) 897m4_split([abcde], [[bd]]) 898m4_split([foo=`` bar='']) 899m4_split([foo='' bar=``]) 900dnl these next two are from the manual; keep this in sync if the internal 901dnl quoting strings in m4_split are changed 902m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl 903m4_split([a )}>=- b -=<{( c]) 904m4_split([a )}@&t@>=- b -=<@&t@{( c]) 905]], 906[[ 907 908[[]] 909[], [] 910[active] 911[], [active], [active], []end 912[], [] 913[active] 914[], [active active], []end 915[abcde] 916[a], [c], [e] 917[foo=``], [bar=''] 918[foo=''], [bar=``] 919[a], [], [B], [], [c] 920[a], [)}>=@&t@-], [b], [-@&t@=<{(], [c] 921]]) 922 923AT_CLEANUP 924 925 926## ------- ## 927## m4_do. ## 928## ------- ## 929 930AT_SETUP([m4@&t@_do]) 931 932AT_CHECK_M4SUGAR_TEXT( 933[[m4_define([ab], [1])m4_define([bc], [2])m4_define([abc], [3])dnl 934m4_define([AB], [4])m4_define([BC], [5])m4_define([ABC], [6])dnl 935m4_do 936m4_do([a]) 937m4_do([a], [b])c 938m4_unquote(m4_join([], [a], [b]))c 939m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl 940m4_do([a], [b])c 941m4_unquote(m4_join([], [a], [b]))c 942]], 943[[ 944a 945abc 9463 947ABC 9483 949]]) 950 951AT_CLEANUP 952 953 954## ----------- ## 955## m4_append. ## 956## ----------- ## 957 958AT_SETUP([m4@&t@_append]) 959AT_KEYWORDS([m4@&t@_append_uniq m4@&t@_append_uniq_w]) 960 961AT_CHECK_M4SUGAR_TEXT( 962[[m4_define([active], [ACTIVE])dnl 963m4_append([sentence], [This is an])dnl 964m4_append([sentence], [ active ])dnl 965m4_append([sentence], [symbol.])dnl 966sentence 967m4_undefine([active])dnl 968sentence 969m4_define([active], [ACTIVE])dnl 970m4_append([hooks], [m4_define([act1], [act2])])dnl 971m4_append([hooks], [m4_define([act2], [active])])dnl 972m4_undefine([active])dnl 973act1 974hooks 975act1 976dnl Test for bug fixed in 2.62 when separator is active. 977m4_define([a], [A])dnl 978m4_append_uniq([foo], [-], [a])dnl 979m4_append_uniq([foo], [-], [a])dnl 980m4_append_uniq([bar], [-], [a])dnl 981m4_append_uniq([bar], [~], [a])dnl 982m4_append_uniq([bar], [-], [a])dnl 983m4_defn([foo]) 984m4_defn([bar]) 985foo 986bar 987m4_append_uniq([blah], [one], [, ], [new], [existing]) 988m4_append_uniq([blah], [two], [, ], [new], [existing]) 989m4_append_uniq([blah], [two], [, ], [new], [existing]) 990m4_append_uniq([blah], [three], [, ], [new], [existing]) 991m4_append([blah], [two], [, ])dnl 992blah 993m4_dquote(blah) 994m4_append([list], [one], [[, ]])dnl 995m4_append([list], [two], [[, ]])dnl 996m4_append([list], [three], [[, ]])dnl 997list 998m4_dquote(list) 999m4_append_uniq_w([numbers], [1 1 2])dnl 1000m4_append_uniq_w([numbers], [ 2 3 ])dnl 1001numbers 1002]], 1003[[This is an ACTIVE symbol. 1004This is an active symbol. 1005act1 1006 1007active 1008- 1009-a~ 1010- 1011-A~ 1012new 1013new 1014existing 1015new 1016one, two, three, two 1017[one],[two],[three],[two] 1018one, two, three 1019[one, two, three] 10201 2 3 1021]]) 1022 1023AT_DATA_M4SUGAR([script.4s], 1024[[m4_init[]dnl 1025m4_append_uniq([str], [a], [ ]) 1026m4_append_uniq([str], [a b], [ ]) 1027m4_divert([])dnl 1028str 1029]]) 1030 1031AT_CHECK_M4SUGAR([-o-], 0, [[a a b 1032]], [[script.4s:3: warning: m4@&t@_append_uniq: `a b' contains ` ' 1033]]) 1034 1035AT_CLEANUP 1036 1037 1038## --------- ## 1039## m4_join. ## 1040## --------- ## 1041 1042AT_SETUP([m4@&t@_join]) 1043 1044AT_KEYWORDS([m4@&t@_joinall]) 1045 1046AT_CHECK_M4SUGAR_TEXT( 1047[[m4_define([active], [ACTIVE]) 1048m4_join 1049m4_join([|]) 1050m4_join([, ], [one], [two]) 1051m4_dquote(m4_join([, ], [one], [two])) 1052m4_join([|], [active], [active]) 1053m4_join([|], ,,,[one]) 1054m4_join([|], [one],,,) 1055m4_join([], ,,,[two]) 1056m4_join([], [two],,,) 1057m4_join([ active ], [one], , [two]) 1058m4_join([], [one], [two]) 1059m4_joinall([-], [one], [], [two]) 1060m4_joinall([-], [], [], [three], [], []) 1061m4_joinall([], [one], [], [two]) 1062m4_joinall 1063m4_joinall([-]) 1064m4_joinall([-], [one]) 1065]], 1066[[ 1067 1068 1069one, two 1070[one, two] 1071active|active 1072one 1073one 1074two 1075two 1076one active two 1077onetwo 1078one--two 1079--three-- 1080onetwo 1081 1082 1083one 1084]]) 1085 1086AT_CLEANUP 1087 1088 1089## ----------- ## 1090## m4_expand. ## 1091## ----------- ## 1092 1093AT_SETUP([m4@&t@_expand]) 1094 1095AT_CHECK_M4SUGAR_TEXT( 1096[[m4_define([active], [ACTIVE])dnl 1097m4_expand([#active 1098active]) 1099m4_expand([[active]]) 1100dnl properly quoted case statements 1101m4_expand([case a in @%:@( 1102 *) echo active, ;; 1103esac 1104case b in 1105 *[)] echo active, ;; 1106esac]) 1107dnl unbalanced underquoted `)', but we manage anyway (gasp!) 1108m4_expand([case c in #( 1109 *) echo active, ;; 1110esac 1111case d in 1112 *) echo active, ;; 1113esac]) 1114dnl unterminated comment/dnl 1115m4_expand([active # active]) 1116m4_expand([a 1117dnl]) 1118m4_expand([a 1119-dnl]) 1120]], 1121[[#active 1122ACTIVE 1123active 1124case a in #( 1125 *) echo ACTIVE, ;; 1126esac 1127case b in 1128 *) echo ACTIVE, ;; 1129esac 1130case c in #( 1131 *) echo ACTIVE, ;; 1132esac 1133case d in 1134 *) echo ACTIVE, ;; 1135esac 1136ACTIVE # active 1137a 1138a 1139- 1140]]) 1141 1142AT_CLEANUP 1143 1144 1145## ------------- ## 1146## m4_text_box. ## 1147## ------------- ## 1148 1149AT_SETUP([m4@&t@_text_box]) 1150 1151AT_CHECK_M4SUGAR_TEXT([[ 1152m4_text_box([a $1 @&t@b]) 1153m4_text_box([a $1 @&t@b], [$]) 1154m4_text_box([a $1 @&t@b], [,]) 1155]], [[ 1156## ------ ## 1157## a $1 b ## 1158## ------ ## 1159## $$$$$$ ## 1160## a $1 b ## 1161## $$$$$$ ## 1162## ,,,,,, ## 1163## a $1 b ## 1164## ,,,,,, ## 1165]]) 1166 1167AT_CLEANUP 1168 1169## -------------- ## 1170## m4_text_wrap. ## 1171## -------------- ## 1172 1173AT_SETUP([m4@&t@_text_wrap]) 1174AT_KEYWORDS([m4@&t@_escape]) 1175 1176# m4_text_wrap is used to display the help strings. Also, check that 1177# commas and $ are not swallowed. This can easily happen because of 1178# m4-listification. 1179 1180AT_DATA_M4SUGAR([script.4s], 1181[[m4_init[]m4_divert([])dnl 1182m4_define([a], [OOPS])dnl 1183m4_escape([a[b $c#]d]) 1184m4_if(m4_escape([a[b $c#]d]), [a[b $c#]d], [oops], 1185 m4_escape([a[b $c#]d]), [a@<:@b @S|@c@%:@@:>@d], [pass], [oops]) 1186 1187m4_text_wrap([Short string */], [ ], [/* ], 20) 1188 1189m4_text_wrap([Much longer string */], [ ], [/* ], 20) 1190 1191m4_text_wrap([Short doc.], [ ], [ --short ], 30) 1192 1193m4_text_wrap([Short doc.], [ ], [ --too-wide], 30) 1194 1195m4_text_wrap([Super long documentation.], [ ], [ --too-wide], 30) 1196 1197m4_text_wrap([First, second , third, [,quoted space]]) 1198m4_define([xfff], [oops]) 1199m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20]) 1200]]) 1201 1202AT_DATA([expout], 1203[[a[b $c#]d 1204pass 1205 1206/* Short string */ 1207 1208/* Much longer 1209 string */ 1210 1211 --short Short doc. 1212 1213 --too-wide 1214 Short doc. 1215 1216 --too-wide 1217 Super long 1218 documentation. 1219 1220First, second , third, [,quoted space] 1221 1222 $@ Some $1 $2 $3 1223 $* $4 embedded 1224 $* dollars. 1225]]) 1226 1227AT_CHECK_M4SUGAR([-o-], 0, [expout]) 1228 1229AT_CLEANUP 1230 1231## -------------------- ## 1232## m4_version_compare. ## 1233## -------------------- ## 1234 1235AT_SETUP([m4@&t@_version_compare]) 1236 1237AT_KEYWORDS([m4@&t@_list_cmp]) 1238 1239AT_CHECK_M4SUGAR_TEXT( 1240[[m4_version_compare([1.1], [2.0]) 1241m4_version_compare([2.0b], [2.0a]) 1242m4_version_compare([2.0z], [2.0y]) 1243m4_version_compare([1.1.1], [1.1.1a]) 1244m4_version_compare([1.2], [1.1.1a]) 1245m4_version_compare([1.0], [1]) 1246m4_version_compare([1.0a], [1.0a]) 1247m4_version_compare([1.1a], [1.1a.1]) 1248m4_version_compare([1.10], [1.1a]) 1249m4_version_compare([1-1a], [1,1A]) 1250m4_define([a], [oops])dnl 1251m4_version_compare([1.1a], [1.1A]) 1252m4_version_compare([1z], [1aa]) 1253m4_version_compare([2.61a], [2.61a-248-dc51]) 1254m4_version_compare([2.61b], [2.61a-248-dc51]) 1255m4_version_compare([08], [09]) 1256m4_version_compare([010], [8]) 1257dnl Test that side effects to m4_list_cmp occur exactly once 1258m4_list_cmp([[0], [0], [0]m4_errprintn([hi])], 1259 [[0], [0], [0]m4_errprintn([hi])]) 1260m4_list_cmp([[0], [0], [0]m4_errprintn([hi])], 1261 [[0], [0], [0]m4_errprintn([bye])]) 1262]], 1263[[-1 12641 12651 1266-1 12671 12680 12690 1270-1 12711 12720 12730 1274-1 1275-1 12761 1277-1 12781 12790 12800 1281]], [[hi 1282hi 1283hi 1284bye 1285]]) 1286 1287AT_CLEANUP 1288 1289## ------------------------------ ## 1290## Standard regular expressions. ## 1291## ------------------------------ ## 1292 1293AT_SETUP([Standard regular expressions]) 1294 1295# AT_CHECK_M4RE(RE-NAME, TEXT, INTENT = `ok' | `') 1296# ------------------------------------------------ 1297# Check whether RE-NAME (a macro whose definition is a regular expression) 1298# matches TEXT. INTENT = `ok' if the match should succeed or else empty. 1299m4_define([AT_CHECK_M4RE], 1300[AT_CHECK_M4SUGAR_TEXT( 1301[[m4_bregexp([$2], ^m4_defn([$1])$, [ok]) 1302]], [$3 1303])]) 1304 1305AT_CHECK_M4RE([m4_re_word], [ab9_c], [ok]) 1306AT_CHECK_M4RE([m4_re_word], [_9abc], [ok]) 1307AT_CHECK_M4RE([m4_re_word], [9ab_c]) 1308 1309AT_CHECK_M4RE([m4_re_string], [ab9_c], [ok]) 1310AT_CHECK_M4RE([m4_re_string], [_9abc], [ok]) 1311AT_CHECK_M4RE([m4_re_string], [9ab_c], [ok]) 1312AT_CHECK_M4RE([m4_re_string], [9a@_c]) 1313 1314AT_CLEANUP 1315 1316## ----------- ## 1317## m4_bmatch. ## 1318## ----------- ## 1319 1320AT_SETUP([m4@&t@_bmatch]) 1321 1322AT_CHECK_M4SUGAR_TEXT( 1323[[m4_bmatch([abc], [default\]) 1324m4_bmatch([abc], [^a], [yes]) 1325m4_bmatch([abc], [^a], [yes], [no]) 1326m4_bmatch([abc], [^.a], [yes]) 1327m4_bmatch([abc], [^.a], [yes], [no\]) 1328m4_bmatch([abc], [a], [1], [b], [2]) 1329m4_bmatch([abc], [A], [1], [b], [2]) 1330m4_define([ab], [AB])dnl 1331m4_bmatch([$*], [a])b 1332m4_bmatch([$*], [\*], [a])b 1333m4_bmatch([$*], [1], [2], [a])b 1334]], [[default\ 1335yes 1336yes 1337 1338no\ 13391 13402 1341AB 1342AB 1343AB 1344]]) 1345 1346AT_CLEANUP 1347 1348## ------------------------ ## 1349## m4_toupper, m4_tolower. ## 1350## ------------------------ ## 1351 1352AT_SETUP([m4@&t@_toupper and m4@&t@_tolower]) 1353 1354AT_CHECK_M4SUGAR_TEXT( 1355[[m4_define([abc], [hI])m4_define([ABC], [Hi]) 1356m4_toupper(abc aBc ABC) 1357m4_tolower(abc aBc ABC) 1358m4_toupper([abc aBc ABC]) 1359m4_tolower([abc aBc ABC]) 1360m4_echo(m4_toupper(abc aBc ABC)) 1361m4_echo(m4_tolower(abc aBc ABC)) 1362m4_echo(m4_toupper([abc aBc ABC])) 1363m4_echo(m4_tolower([abc aBc ABC])) 1364m4_do(m4_toupper(abc aBc ABC)) 1365m4_do(m4_tolower(abc aBc ABC)) 1366m4_do(m4_toupper([abc aBc ABC])) 1367m4_do(m4_tolower([abc aBc ABC])) 1368]], [[ 1369HI ABC HI 1370hi abc hi 1371ABC ABC ABC 1372abc abc abc 1373HI ABC HI 1374hi abc hi 1375ABC ABC ABC 1376abc abc abc 1377HI Hi HI 1378hi hI hi 1379Hi Hi Hi 1380hI hI hI 1381]]) 1382 1383AT_CLEANUP 1384 1385## --------------- ## 1386## m4_bpatsubsts. ## 1387## --------------- ## 1388 1389AT_SETUP([m4@&t@_bpatsubsts]) 1390 1391AT_CHECK_M4SUGAR_TEXT( 1392[[m4_bpatsubsts([11], [^..$]) 1393m4_bpatsubsts([11], [\(.\)1], [\12]) 1394m4_bpatsubsts([11], [^..$], [], [1], [2]) 1395m4_bpatsubsts([11], [\(.\)1], [\12], [1], [3]) 1396m4_define([a], [oops])m4_define([c], [oops])dnl 1397m4_define([AB], [good])m4_define([bc], [good])dnl 1398m4_bpatsubsts([abc], [a], [A], [b], [B], [c]) 1399m4_bpatsubsts([ab], [a])c 1400m4_bpatsubsts([ab], [c], [C], [a])c 1401m4_bpatsubsts([$1$*$@], [\$\*], [$#]) 1402]], [[11 140321 140422 140523 1406good 1407good 1408good 1409$1$#$@ 1410]]) 1411 1412AT_CLEANUP 1413 1414## -------------- ## 1415## m4_esyscmd_s. ## 1416## -------------- ## 1417 1418AT_SETUP([m4@&t@_esyscmd_s]) 1419AT_KEYWORDS([m4@&t@_chomp m4@&t@_chomp_all]) 1420 1421AT_CHECK_M4SUGAR_TEXT( 1422[[m4_define([world], [WORLD])dnl 1423m4_chomp([abc]) 1424m4_chomp([world 1425 1426]) 1427m4_esyscmd_s([echo hello world]) 1428m4_esyscmd_s([echo '[goodbye, 1429cruel world 1430 1431]']) 1432]], [[abc 1433world 1434 1435hello WORLD 1436goodbye, 1437cruel world 1438]]) 1439 1440AT_CLEANUP 1441 1442## ---------- ## 1443## M4 Loops. ## 1444## ---------- ## 1445 1446AT_SETUP([M4 loops]) 1447 1448AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w m4@&t@_map_args_w]) 1449 1450AT_CHECK_M4SUGAR_TEXT([[dnl 1451m4_define([myvar], [outer value])dnl 1452m4_for([myvar], 1, 3, 1, [ myvar]) 1453m4_for([myvar], 1, 3, , [ myvar]) 1454m4_for([myvar], 3, 1,-1, [ myvar]) 1455m4_for([myvar], 3, 1, , [ myvar]) 1456m4_for([myvar], 1, 3, 2, [ myvar]) 1457m4_for([myvar], 3, 1,-2, [ myvar]) 1458m4_for([myvar],-1,-3,-2, [ myvar]) 1459m4_for([myvar],-3,-1, 2, [ myvar]) 1460dnl Make sure we recalculate the bounds correctly: 1461m4_for([myvar], 1, 3, 3, [ myvar]) 1462m4_for([myvar], 1, 6, 3, [ myvar]) 1463m4_for([myvar],22,-7,-5, [ myvar]) 1464m4_for([myvar],-2,-7,-4, [ myvar]) 1465m4_for([myvar],-7,-2, 4, [ myvar]) 1466dnl Make sure we are not exposed to division truncation: 1467m4_for([myvar], 2, 5, 2, [ myvar]) 1468m4_for([myvar],-5,-2, 2, [ myvar]) 1469m4_for([myvar], 5, 2,-2, [ myvar]) 1470m4_for([myvar],-2,-5,-2, [ myvar]) 1471dnl Make sure we do not divide by zero: 1472m4_for([myvar], 1, 1, , [ myvar]) 1473m4_for([myvar], 1, 1,+2, [ myvar]) 1474m4_for([myvar], 1, 1,-2, [ myvar]) 1475dnl Make sure we do not loop endlessly 1476m4_for([myval], 1, 1, 0, [ myval]) 1477dnl Make sure to properly parenthesize 1478m4_for([myvar], 3-5, -2+8, , [ myvar]) 1479m4_for([myvar], -2+8, 3-5, , [ myvar]) 1480m4_for([myvar], 8, 16, 3 * 2, [ myvar]) 1481m4_for([myvar], 8, 16, -3 * -2, [ myvar]) 1482m4_for([myvar], [2<<2], [2<<3], [-3 * (-2)], [ myvar]) 1483dnl Modifying var does not affect the number of iterations 1484m4_for([myvar], 1, 5, , [ myvar[]m4_define([myvar], 5)]) 1485dnl Make sure we can do nameless iteration 1486m4_for(, 1, 10, , -) 1487dnl foreach tests 1488m4_foreach([myvar], [[a], [b, c], [d], [e 1489],[f]], [ myvar|]) 1490m4_foreach_w([myvar], [a b c, d,e f 1491g], [ myvar|]) 1492myvar 1493m4_map_args_w([a b c, d,e f 1494g], [ ], [|]) 1495m4_map_args_w([a b], [\1], [/]) 1496m4_define([dashes], [--])dnl 1497m4_map_args_w([a b c], [/], [\1], [dashes]) 1498dnl only one side effect expansion, prior to visiting list elements 1499m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnl 1500dnl shifting forms an important part of loops 1501m4_shift3:m4_shift3(1,2,3):m4_shift3(1,2,3,4) 1502m4_shiftn(3,1,2,3):m4_shiftn(3,1,2,3,4) 1503]], 1504[[ 1 2 3 1505 1 2 3 1506 3 2 1 1507 3 2 1 1508 1 3 1509 3 1 1510 -1 -3 1511 -3 -1 1512 1 1513 1 4 1514 22 17 12 7 2 -3 1515 -2 -6 1516 -7 -3 1517 2 4 1518 -5 -3 1519 5 3 1520 -2 -4 1521 1 1522 1 1523 1 1524 1 1525 -2 -1 0 1 2 3 4 5 6 1526 6 5 4 3 2 1 0 -1 -2 1527 8 14 1528 8 14 1529 8 14 1530 1 2 3 4 5 1531---------- 1532 a| b, c| d| e 1533| f| 1534 a| b| c,| d,e| f| g| 1535outer value 1536 a| b| c,| d,e| f| g| 1537\1a/\1b/ 1538/a\1--/b\1--/c\1 1539::4 1540:4 1541]], [[hi 15421 15432 15443 1545]]) 1546 1547dnl bounds checking in m4_for 1548AT_DATA_M4SUGAR([script.4s], 1549[[m4_init 1550m4_divert([0])dnl 1551m4_for([myvar], 1, 3,-1, [ myvar]) 1552]]) 1553AT_CHECK_M4SUGAR([], 1, [], 1554[[script.4s:3: error: assert failed: -1 > 0 1555script.4s:3: the top level 1556autom4te: m4 failed with exit status: 1 1557]]) 1558 1559AT_DATA_M4SUGAR([script.4s], 1560[[m4_init 1561m4_divert([0])dnl 1562m4_for([myvar], 1, 2, 0, [ myvar]) 1563]]) 1564AT_CHECK_M4SUGAR([], 1, [], 1565[[script.4s:3: error: assert failed: 0 > 0 1566script.4s:3: the top level 1567autom4te: m4 failed with exit status: 1 1568]]) 1569 1570AT_DATA_M4SUGAR([script.4s], 1571[[m4_init 1572m4_divert([0])dnl 1573m4_for([myvar], 2, 1, 0, [ myvar]) 1574]]) 1575AT_CHECK_M4SUGAR([], 1, [], 1576[[script.4s:3: error: assert failed: 0 < 0 1577script.4s:3: the top level 1578autom4te: m4 failed with exit status: 1 1579]]) 1580 1581dnl m4_shiftn also does bounds checking 1582AT_DATA_M4SUGAR([script.4s], 1583[[m4_init 1584m4_divert([0])dnl 1585m4_shiftn(3,1,2) 1586]]) 1587AT_CHECK_M4SUGAR([], 1, [], 1588[[script.4s:3: error: assert failed: 0 < 3 && 3 < 3 1589script.4s:3: the top level 1590autom4te: m4 failed with exit status: 1 1591]]) 1592 1593AT_CLEANUP 1594 1595 1596## --------------------- ## 1597## m4_map{,all}{,_sep}. ## 1598## --------------------- ## 1599 1600AT_SETUP([m4@&t@_map]) 1601AT_KEYWORDS([m4@&t@_apply m4@&t@_map_sep m4@&t@_mapall m4@&t@_mapall_sep]) 1602AT_KEYWORDS([m4@&t@_count]) 1603 1604AT_CHECK_M4SUGAR_TEXT([[dnl 1605m4_map([m4_count], []) 1606m4_map([ m4_count], [[], 1607 [[1]], 1608 [[1], [2]]]) 1609m4_mapall([ m4_count], [[], 1610 [[1]], 1611 [[1], [2]]]) 1612m4_map_sep([m4_eval], [,], [[[1+2]], 1613 [[10], [16]]]) 1614m4_count(m4_map_sep([m4_echo], [,], [[], [[1]], [[2]]])) 1615m4_count(m4_mapall_sep([m4_echo], [,], [[], [[1]], [[2]]])) 1616m4_map_sep([m4_eval], [[,]], [[[1+2]], 1617 [[10], [16]]]) 1618m4_count(m4_map_sep([m4_echo], [[,]], [[], [[1]], [[2]]])) 1619m4_count(m4_mapall_sep([m4_echo], [[,]], [[], [[1]], [[2]]])) 1620m4_map([-], [[]]) 1621m4_mapall([-], [[]]) 1622m4_map_sep([-], [:], [[]]) 1623m4_mapall_sep([-], [:], [[]]) 1624m4_define([a], [m4_if([$#], [0], [oops], [$1], [a], [pass], [oops])])dnl 1625m4_define([a1], [oops])dnl 1626m4_define([pass1], [oops])dnl 1627m4_map([a], [[[a]]])1 1628m4_map([m4_unquote([a])], [m4_dquote([a])]) 1629dnl only one side effect expansion, prior to visiting list elements 1630m4_map([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl 1631m4_map_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl 1632m4_mapall([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl 1633m4_mapall_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl 1634]], 1635[[ 1636 1 2 1637 0 1 2 16383,a 16392 16403 16413,a 16421 16431 1644 1645- 1646 1647- 1648pass1 1649pass 1650]], [[hi 16511 16522 16533 1654hi 16551 16562 16573 1658hi 16591 16602 16613 1662hi 16631 16642 16653 1666]]) 1667 1668AT_CLEANUP 1669 1670 1671## --------------------------------------- ## 1672## m4_map_args{,_sep,_pair} and m4_curry. ## 1673## --------------------------------------- ## 1674 1675AT_SETUP([m4@&t@_map_args and m4@&t@_curry]) 1676AT_KEYWORDS([m4@&t@_map_args_sep m4@&t@_map_args_pair m4@&t@_reverse 1677m4@&t@_map]) 1678 1679dnl First, make sure we can curry in isolation. 1680AT_CHECK_M4SUGAR_TEXT( 1681[[m4_curry([m4_echo])([1]) 1682m4_curry([m4_curry], [m4_reverse], [1])([2])([3]) 1683m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl 1684m4_define([add_one], [m4_curry([add], [1])])dnl 1685add_one()([4]) 1686]], 1687[[1 16883, 2, 1 16895 1690]]) 1691 1692dnl Now, check that we can map a list of arguments. 1693AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnl 1694m4_map_args([ m4_echo]) 1695m4_map_args([ m4_echo], [plain], [active]) 1696m4_map_args([m4_unquote], [plain], [active]) 1697m4_map_args_pair([, m4_reverse], []) 1698m4_map_args_pair([, m4_reverse], [], [1]) 1699m4_map_args_pair([, m4_reverse], [], [1], [2]) 1700m4_map_args_pair([, m4_reverse], [], [1], [2], [3]) 1701m4_map_args_pair([, m4_reverse], [], [1], [2], [3], [4]) 1702m4_map_args_pair([, m4_reverse], [, m4_dquote], [1]) 1703m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2]) 1704m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3]) 1705m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4]) 1706m4_map_args_sep([<], [>], [:], [1], [2], [3]) 1707m4_map_args_sep([m4_echo(], [)], [ ], [plain], [active]) 1708]], 1709[[ 1710 plain active 1711plainACTIVE 1712 1713, 1 1714, 2, 1 1715, 2, 1, 3 1716, 2, 1, 4, 3 1717, [1] 1718, 2, 1 1719, 2, 1, [3] 1720, 2, 1, 4, 3 1721<1>:<2>:<3> 1722plain active 1723]]) 1724 1725dnl Finally, put the two concepts together, to show the real power of the API. 1726AT_CHECK_M4SUGAR_TEXT( 1727[[m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl 1728m4_define([list], [[-1], [0], [1]])dnl 1729dnl list_add_n(value, arg...) 1730dnl add VALUE to each ARG and output the resulting list 1731m4_define([list_add_n], 1732 [m4_shift(m4_map_args([,m4_curry([add], [$1])], m4_shift($@)))]) 1733list_add_n([1], list) 1734list_add_n([2], list) 1735]], [[ 17360,1,2 17371,2,3 1738]]) 1739 1740AT_CLEANUP 1741 1742 1743## ------------ ## 1744## m4_combine. ## 1745## ------------ ## 1746 1747AT_SETUP([m4@&t@_combine]) 1748 1749AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl 1750m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3]) 1751m4_combine([, ], [[a], [b]], [-]) 1752m4_combine([, ], [[a], [b]], [-], []) 1753m4_combine([, ], [], [-], [a], [b]) 1754m4_combine([, ], [[]], [-], [a], [b]) 1755m4_combine([ a ], [[-], [+]], [a], [-], [+]) 1756m4_combine([$* ], [[$1], [$2]], [$#], [$@]) 1757]], 1758[[a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3 1759 1760a-, b- 1761 1762-a, -b 1763-a- a -a+ a +a- a +a+ 1764$1$#$@$* $2$#$@ 1765]], []) 1766 1767AT_CLEANUP 1768 1769 1770## -------------- ## 1771## m4_{max,min}. ## 1772## -------------- ## 1773 1774AT_SETUP([m4@&t@_max and m4@&t@_min]) 1775 1776AT_DATA_M4SUGAR([script.4s], 1777[[m4_max 1778]]) 1779 1780AT_CHECK_M4SUGAR([], 1, [], 1781[[script.4s:1: error: too few arguments to m4@&t@_max 1782script.4s:1: the top level 1783autom4te: m4 failed with exit status: 1 1784]]) 1785 1786AT_DATA_M4SUGAR([script.4s], 1787[[m4_min 1788]]) 1789 1790AT_CHECK_M4SUGAR([], 1, [], 1791[[script.4s:1: error: too few arguments to m4@&t@_min 1792script.4s:1: the top level 1793autom4te: m4 failed with exit status: 1 1794]]) 1795 1796AT_CHECK_M4SUGAR_TEXT([[dnl 1797m4_min(0) 1798m4_min(0xa) 1799m4_min(0, 0) 1800m4_min(0, 1) 1801m4_min(1, 0) 1802m4_min(0+1, 1+1) 1803m4_min(0+1, 1+0) 1804m4_min(0, 1, 2) 1805m4_min(2, 1, 0) 1806m4_min(1m4_for([i], 2, 100, , [,i])) 1807m4_min(m4_for([i], 100, 2, , [i,])1) 1808---- 1809m4_max(0) 1810m4_max(0xa) 1811m4_max(0, 0) 1812m4_max(0, 1) 1813m4_max(1, 0) 1814m4_max(1+0, 1+1) 1815m4_max(1+0, 1+0) 1816m4_max(0, 1, 2) 1817m4_max(2, 1, 0) 1818m4_max(1m4_for([i], 2, 100, , [,i])) 1819m4_max(m4_for([i], 100, 2, , [i,])1) 1820]], 1821[[0 182210 18230 18240 18250 18261 18271 18280 18290 18301 18311 1832---- 18330 183410 18350 18361 18371 18382 18391 18402 18412 1842100 1843100 1844]], []) 1845 1846AT_CLEANUP 1847 1848 1849## ----------- ## 1850## Recursion. ## 1851## ----------- ## 1852 1853AT_SETUP([recursion]) 1854 1855AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_cond 1856m4@&t@_bpatsubsts m4@&t@_shiftn m4@&t@_do m4@&t@_dquote_elt m4@&t@_reverse 1857m4@&t@_map m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min 1858m4@&t@_bmatch m4@&t@_map_args m4@&t@_map_args_pair]) 1859 1860dnl This test completes in a reasonable time if m4_foreach is linear, 1861dnl but thrashes if it is quadratic. If we are testing with m4 1.4.x, 1862dnl only the slower foreach.m4 implementation will work. But if we 1863dnl are testing with m4 1.6, we can rerun the test with __m4_version__ 1864dnl undefined to exercise the alternate code path. 1865AT_DATA_M4SUGAR([script.4s], 1866[[m4_init 1867m4_divert_push([])[]dnl 1868m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ])) 1869m4_shiftn(9998m4_for([i], [1], [10000], [], [,i])) 1870m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),)) 1871m4_len(m4_joinall([--], m4_map([, m4_echo], 1872 m4_dquote([1]m4_for([i], [2], [10000], [], [,i]))))) 1873m4_max(m4_min([1]m4_for([i], [2], [10000], [], 1874 [,i]))m4_for([i], [2], [10000], [], [,i])) 1875m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end]) 1876m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])), 1877 m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0])) 1878m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])]) 1879m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0]) 1880m4_for([i], [1], [10000], [], [m4_define(i)])dnl 1881m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl 1882m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A]) 1883m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$])) 1884m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl 1885m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j 1886m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i], 1887 [1], [10000], [], [,i])))) 1888m4_divert_pop([]) 1889]]) 1890 1891AT_CHECK_M4SUGAR([-o-], [0], [[48894 18929999,10000 189378896 189458894 189510000 1896end 18970 18980 18990 1900A 1901^9998$ 19029990 9990 19035001 1904]]) 1905 1906AT_DATA_M4SUGAR([script.4s], 1907[[m4_ifdef([__m4_version__], 1908[m4_undefine([__m4_version__])], 1909[m4_divert_push([])48894 19109999,10000 191178896 191258894 191310000 1914end 19150 19160 19170 1918A 1919^9998$ 19209990 9990 19215001 1922m4_exit([0])]) 1923m4_init 1924m4_divert_push([])[]dnl 1925m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ])) 1926m4_shiftn(9998m4_for([i], [1], [10000], [], [,i])) 1927m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),)) 1928m4_len(m4_joinall([--], m4_map([, m4_echo], 1929 m4_dquote([1]m4_for([i], [2], [10000], [], [,i]))))) 1930m4_max(m4_min([1]m4_for([i], [2], [10000], [], 1931 [,i]))m4_for([i], [2], [10000], [], [,i])) 1932m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end]) 1933m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])), 1934 m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0])) 1935m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])]) 1936m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0]) 1937m4_for([i], [1], [10000], [], [m4_define(i)])dnl 1938m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl 1939m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A]) 1940m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$])) 1941m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl 1942m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j 1943m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i], 1944 [1], [10000], [], [,i])))) 1945m4_divert_pop([]) 1946]]) 1947 1948AT_CHECK_M4SUGAR([-o-], [0], [[48894 19499999,10000 195078896 195158894 195210000 1953end 19540 19550 19560 1957A 1958^9998$ 19599990 9990 19605001 1961]]) 1962 1963AT_CLEANUP 1964 1965 1966## ---------- ## 1967## m4_set_*. ## 1968## ---------- ## 1969 1970AT_SETUP([m4@&t@_set]) 1971 1972AT_KEYWORDS([m4@&t@_set_add m4@&t@_set_add_all m4@&t@_set_contains 1973m4@&t@_set_contents m4@&t@_set_delete m4@&t@_set_difference m4@&t@_set_dump 1974m4@&t@_set_empty m4@&t@_set_foreach m4@&t@_set_intersection m4@&t@_set_list 1975m4@&t@_set_listc m4@&t@_set_map m4@&t@_set_remove m4@&t@_set_size 1976m4@&t@_set_union]) 1977 1978# Simple tests 1979AT_CHECK_M4SUGAR_TEXT([[m4_set_contains([a], [1], [yes], [no]) 1980m4_set_add([a], [1], [added], [dup]) 1981m4_set_contains([a], [1], [yes], [no]) 1982m4_set_add([a], [1], [added], [dup]) 1983m4_set_contents([a]) 1984m4_set_remove([a], [1], [removed], [missing]) 1985m4_set_contains([a], [1], [yes], [no]) 1986m4_set_remove([a], [1], [removed], [missing]) 1987m4_set_add([a], [2], [added], [dup]) 1988m4_set_empty([a], [yes], [no]) 1989m4_set_delete([a]) 1990m4_set_empty([a], [yes], [no]) 1991m4_set_add_all([c], [1], [2], [3]) 1992m4_set_add_all([a]m4_set_listc([c])) 1993m4_set_contents([c], [-]) 1994m4_set_dump([a], [-]) 1995m4_set_contents([a]) 1996m4_set_add_all([a], [1], [2], [3])m4_set_add_all([b], [3], [], [4]) 1997m4_set_difference([a], [b]) 1998m4_set_difference([b], [a]) 1999m4_set_intersection([a], [b]) 2000m4_set_union([a], [b]) 2001m4_define([printodd], [m4_if(m4_eval([$1 & 1]), [1], [:$1])])dnl 2002m4_set_map([a], [printodd]) 2003m4_set_foreach([a], [i], [m4_if(m4_eval(i & 1), [1], [m4_set_remove([a], i)])]) 2004m4_set_list([a]) 2005m4_set_add([a], []) 2006m4_set_list([a]) 2007m4_set_remove([a], [2]) 2008m4_dquote(m4_set_list([a])) 2009m4_set_listc([a]) 2010m4_set_size([a]) 2011m4_set_delete([a]) 2012m4_dquote(m4_set_list([a])) 2013m4_indir([m4_dquote]m4_set_listc([a])) 2014m4_set_listc([a]) 2015m4_set_size([a]) 2016]], [[no 2017added 2018yes 2019dup 20201 2021removed 2022no 2023missing 2024added 2025no 2026 2027yes 2028 2029 20301-2-3 20313-2-1 2032 2033 2034,1,2 2035,,4 2036,3 2037,1,2,3,,4 2038:1:3 2039 20402 2041 20422, 2043 2044[] 2045, 20461 2047 2048[] 2049 2050 20510 2052]]) 2053 2054# Stress tests - check for unusual names/values 2055AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl 2056m4_set_add([a], [a])dnl 2057m4_set_remove([a], [oops], [yes], [no]) 2058m4_set_add([a,b], [c])dnl 2059m4_set_add([a,b], [$*[]])dnl 2060m4_set_add_all([a], [b,c])dnl 2061m4_set_size([a]) 2062m4_count(m4_set_contents([a], [,])) 2063m4_count(m4_set_list([a], [,])) 2064m4_set_dump([a], [,]) 2065m4_set_contents([a,b], [,]) 2066m4_set_list([a,b]) 2067m4_set_foreach([$*[]], [$*[]], [oops]) 2068m4_set_add([$*[]], [])dnl 2069m4_set_remove([$*[]], [a], [yes], [no]) 2070m4_set_add([$*[]], [a])dnl 2071m4_set_foreach([$*[]], [$*[]], [-m4_defn([$*[]])m4_indir([$*[]])-]) 2072m4_set_remove([$*[]], [], [yes], [no]) 2073m4_set_add([c], [,])dnl 2074m4_set_foreach([a,b], [set], [:m4_set_listc(_m4_defn([set])):]) 2075]],[[no 20762 20771 20782 2079b,c,a 2080c,$*[] 2081c,$*[] 2082 2083no 2084---aoops- 2085yes 2086:,,::,a: 2087]]) 2088 2089# Stress tests - check for linear scaling (won't necessarily fail if 2090# quadratic, but hopefully users will complain if it appears to hang) 2091AT_CHECK_M4SUGAR_TEXT([[dnl 2092m4_for([i], [1], [10000], [], [m4_set_add([a], i)])dnl 2093m4_set_add_all([b]m4_for([i], [1], [10000], [], [,i]))dnl 2094m4_set_remove([a], [1])dnl 2095m4_set_remove([b], [10000])dnl 2096m4_set_add_all([a]m4_for([i], [1], [10000], [], [,i]))dnl 2097m4_for([i], [1], [10000], [], [m4_set_add([b], i)])dnl 2098m4_len(m4_set_contents([a])) 2099m4_len(m4_set_foreach([b], [b], [m4_if(m4_eval(b & 1), [1], 2100 [m4_set_remove([b], b, [-])])])) 2101m4_set_size([b]) 2102m4_define([prune3x], [m4_if(m4_eval([$1 % 3]), [0], 2103 [m4_set_remove([a], [$1], [-])])])dnl 2104m4_len(m4_set_map([a], [prune3x])) 2105m4_count(m4_shift(m4_set_intersection([a], [b]))) 2106]], [[38894 21075000 21085000 21093333 21103334 2111]]) 2112 2113AT_CLEANUP 2114 2115 2116## ---------------------- ## 2117## __file__ and __line__. ## 2118## ---------------------- ## 2119 2120AT_SETUP([[__file__ and __line__]]) 2121 2122# Check that __file__ and __line__ work. 2123# Check that m4__file__ and m4__line__ are not defined 2124# (and get them to pass by the undefined-macro check). 2125# Try to not assume too much about AT_CHECK_M4SUGAR_TEXT. 2126AT_CHECK_M4SUGAR_TEXT([[dnl 2127m4_pattern_allow([m4__file__])dnl 2128m4_pattern_allow([m4__line__])dnl 2129m4__file__ 2130m4__line__ 2131__file__ 2132m4_define([first], __line__)dnl 2133m4_define([second], __line__)dnl 2134m4_assert(first + 1 == second)dnl 2135]], [[m4@&t@__@&t@file__ 2136m4@&t@__@&t@line__ 2137script.4s 2138]]) 2139 2140AT_CLEANUP 2141