1# Copyright 2011 Steven Watanabe. 2# Distributed under the Boost Software License, Version 1.0. 3# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 4 5# Tools 6 7passed = 0 ; 8failed = 0 ; 9 10rule show-result ( id : test-result ) 11{ 12 if ! ( --quiet in $(ARGV) ) 13 { 14 ECHO "$(test-result):" $(id) ; 15 } 16 $(test-result) = [ CALC $($(test-result)) + 1 ] ; 17} 18 19rule check-equal ( id : values * : expected * ) 20{ 21 local test-result ; 22 local location = [ BACKTRACE ] ; 23 location = $(location[5-6]) ; 24 location = "$(location[1]):$(location[2])" ; 25 if x$(values) = x$(expected) 26 { 27 test-result = passed ; 28 } 29 else 30 { 31 ECHO "error:" "[" $(values) "] != [" $(expected) "]" ; 32 test-result = failed ; 33 } 34 show-result "$(location):$(id)" : $(test-result) ; 35} 36 37rule mark-order ( id : result * ) 38{ 39 order += $(id) ; 40 return $(result) ; 41} 42 43rule check-order ( id : expected * ) 44{ 45 check-equal $(id) : $(order) : $(expected) ; 46 order = ; 47} 48 49# Check variable expansion 50 51{ 52 53local v1 = 1 2 3 ; 54local v2 = 4 5 6 ; 55local v3 = 0 1 2 3 4 5 6 7 8 9 10 ; 56local g = g1 g2 ; 57local v4 = String/With/Mixed/Case ; 58local v5 = path\\with\\backslashes ; 59local v6 = <grist>generic/path.txt(member.txt) ; 60local v7 = <Grist1>Dir1/File1.cpp(M1.c) <Grist2>Dir2/File2.hpp(M2.c) ; 61local v8 = <Grist3>Dir3/File3.c(M3.c) <Grist4>Dir4/File4.h(M4.c) ; 62local select1 = GU BL DBST ; 63local case1 = L U ; 64local vars = 7 8 ; 65local sub = 2 1 ; 66local p0 = name ; 67local p1 = dir/name ; 68local p2 = dir/sub/name ; 69local j1 = , - ; 70 71check-equal var-product : $(v1)$(v2) : 14 15 16 24 25 26 34 35 36 ; 72 73check-equal var-set-grist : $(v1:G=grist) : <grist>1 <grist>2 <grist>3 ; 74check-equal var-set-grist-multi : $(v1:G=$(g)) : <g1>1 <g1>2 <g1>3 <g2>1 <g2>2 <g2>3 ; 75 76check-equal var-lower : $(v4:L) : string/with/mixed/case ; 77check-equal var-upper : $(v4:U) : STRING/WITH/MIXED/CASE ; 78check-equal var-LU : $(v4:LU) : STRING/WITH/MIXED/CASE ; 79check-equal var-slashes : $(v5:T) : path/with/backslashes ; 80check-equal var-grist : $(v6:G) : <grist> ; 81check-equal var-grist-none : $(v1:G) : "" "" "" ; 82check-equal var-base : $(v6:B) : path ; 83check-equal var-suffix : $(v6:S) : .txt ; 84check-equal var-dir : $(v6:D) : generic ; 85check-equal var-member : $(v6:M) : (member.txt) ; 86check-equal var-multi : $(v6:$(select1)) : <GRIST> path generic/path.txt ; 87 88check-equal var-join-0 : $(:J=,) : ; 89check-equal var-join-1 : $(p0:J=,) : name ; 90check-equal var-join-3 : $(v1:J=,) : 1,2,3 ; 91check-equal var-set-grist-join : $(v1:G=grist:J=,) : <grist>1,<grist>2,<grist>3 ; 92# behavior change. In the past, a J= modifier would 93# cause only the last element of the other modifiers 94# to take effect. 95check-equal var-set-grist-multi-join : $(v1:G=$(g):J=,) : <g1>1,<g1>2,<g1>3 <g2>1,<g2>2,<g2>3 ; 96check-equal var-set-grist-multi-join-multi : $(v1:G=$(g):J=$(j1)) : <g1>1,<g1>2,<g1>3 <g1>1-<g1>2-<g1>3 <g2>1,<g2>2,<g2>3 <g2>1-<g2>2-<g2>3 ; 97 98check-equal var-D=-0 : name : $(p0:D=) ; 99check-equal var-D=-1 : name : $(p1:D=) ; 100check-equal var-D=-2 : name : $(p2:D=) ; 101check-equal var-D-0 : "" : $(p0:D) ; 102check-equal var-D-1 : dir : $(p1:D) ; 103check-equal var-D-2 : dir/sub : $(p2:D) ; 104check-equal var-S-1 : "" : $(p0:S) ; 105check-equal var-no-at-file-0 : ($(p0)) : [ MATCH ^@(.*) : "@($(p0))" ] ; 106check-equal var-no-at-file-1 : ($(p0)) : [ MATCH @(.*) : "--@($(p0))" ] ; 107 108if $(OS) = CYGWIN 109{ 110 local cyg-root = $(:WE=/) ; 111 local cyg1 = /cygdrive/c/path1.txt ; 112 check-equal cygwin-to-cygdrive : $(cyg1:W) : C:\\path1.txt ; 113 local cyg2 = /bin/bash ; 114 check-equal cygwin-to-windows : $(cyg2:W) : $(cyg-root)\\bin\\bash ; 115 check-equal cygwin-combine-WT : $(cyg2:WT) : $(cyg-root)\\bin\\bash ; 116 117 local cyg3 = /home/boost/devel/trunk/bin.v2/ ; # exactly 31 characters 118 local win3 = $(cyg-root)\\home\\boost\\devel\\trunk\\bin.v2\\ ; 119 # This is is the easiest way to demonstrate a bug 120 # that used to cause undefined behavior. Longer paths 121 # resulted in a use-after-free error, which happened 122 # to work most of the time. 123 check-equal cygwin-long-WU : $(cyg3:WU) : $(win3:U) ; 124 125 local cyg-grist = <grist>$(cyg1) ; 126 check-equal cygwin-grist : $(cyg-grist:W) : <grist>\\cygdrive\\c\\path1.txt ; 127 128 check-equal cygwin-WU : $(cyg2:WU) : $(cyg-root:U)\\BIN\\BASH ; 129 # behavior change: L now consistently applied after W. 130 # used to affect all except the drive letter. 131 check-equal cygwin-WL : $(cyg2:WL) : $(cyg-root:L)\\bin\\bash ; 132} 133 134# behavior change 135check-equal var-test1 : $(v7[2]:G:L) : <grist2> ; 136 137check-equal var-multi-product-smm : $(v$(vars)[$(sub)]:G=$(g):$(case1)) : 138 <g1>dir2/file2.hpp(m2.c) <G1>DIR2/FILE2.HPP(M2.C) 139 <g2>dir2/file2.hpp(m2.c) <G2>DIR2/FILE2.HPP(M2.C) 140 <g1>dir1/file1.cpp(m1.c) <G1>DIR1/FILE1.CPP(M1.C) 141 <g2>dir1/file1.cpp(m1.c) <G2>DIR1/FILE1.CPP(M1.C) 142 <g1>dir4/file4.h(m4.c) <G1>DIR4/FILE4.H(M4.C) 143 <g2>dir4/file4.h(m4.c) <G2>DIR4/FILE4.H(M4.C) 144 <g1>dir3/file3.c(m3.c) <G1>DIR3/FILE3.C(M3.C) 145 <g2>dir3/file3.c(m3.c) <G2>DIR3/FILE3.C(M3.C) 146; 147check-equal var-nopathmods : $(:E=//) : // ; 148 149# showcases all the idiosyncracies of indexing 150# key: h = high, l = low, p = positive, m = minus, e = end. 151 152check-equal var-subscript-one-p : $(v3[3]) : 2 ; 153check-equal var-subscript-one-m : $(v3[-3]) : 8 ; 154check-equal var-subscript-one-0 : $(v3[0]) : 0 ; 155check-equal var-subscript-one-h : $(v3[20]) : ; 156check-equal var-subscript-one-l : $(v3[-20]) : 0 ; 157check-equal var-subscript-range-pp : $(v3[2-4]) : 1 2 3 ; 158check-equal var-subscript-range-pm : $(v3[2--3]) : 1 2 3 4 5 6 7 8 ; 159check-equal var-subscript-range-pe : $(v3[2-]) : 1 2 3 4 5 6 7 8 9 10 ; 160check-equal var-subscript-range-ph : $(v3[2-20]) : 1 2 3 4 5 6 7 8 9 10 ; 161check-equal var-subscript-range-pl : $(v3[2--20]) : ; 162check-equal var-subscript-range-mp : $(v3[-3-10]) : 8 9 ; 163check-equal var-subscript-range-mm : $(v3[-4--2]) : 7 8 9 ; 164check-equal var-subscript-range-me : $(v3[-4-]) : 7 8 9 10 ; 165check-equal var-subscript-range-mh : $(v3[-4-20]) : 7 8 9 10 ; 166check-equal var-subscript-range-mh : $(v3[-4--20]) : ; 167check-equal var-subscript-range-0p : $(v3[0-2]) : 0 1 2 ; 168check-equal var-subscript-range-0m : $(v3[0--4]) : 0 1 2 3 4 5 6 7 8 ; 169check-equal var-subscript-range-0e : $(v3[0-]) : 0 1 2 3 4 5 6 7 8 9 10 ; 170check-equal var-subscript-range-0h : $(v3[0-20]) : 0 1 2 3 4 5 6 7 8 9 10 ; 171check-equal var-subscript-range-0l : $(v3[0--20]) : ; 172check-equal var-subscript-range-hp : $(v3[20-4]) : ; 173check-equal var-subscript-range-hm : $(v3[20--4]) : ; 174check-equal var-subscript-range-he : $(v3[20-]) : ; 175check-equal var-subscript-range-hh : $(v3[20-20]) : ; 176check-equal var-subscript-range-hl : $(v3[20--20]) : ; 177check-equal var-subscript-range-lp : $(v3[-13-4]) : 0 1 2 3 4 5 ; 178check-equal var-subscript-range-lm : $(v3[-13--4]) : 0 1 2 3 4 5 6 7 8 9 ; 179check-equal var-subscript-range-le : $(v3[-13-]) : 0 1 2 3 4 5 6 7 8 9 10 ; 180check-equal var-subscript-range-lh : $(v3[-13-20]) : 0 1 2 3 4 5 6 7 8 9 10 ; 181check-equal var-subscript-range-ll : $(v3[-13--13]) : 0 ; 182check-equal var-subscript-range-empty : $(v3[4-3]) : ; 183 184} 185 186# Check rules 187 188{ 189 190rule test-rule 191{ 192 return $(<) - $(>) - $(1) - $(2) - $(3) - $(4) - $(5) - $(6) - $(7) - $(8) - $(9) - $(10) - $(11) - $(12) - $(13) - $(14) - $(15) - $(16) - $(17) - $(18) - $(19) ; 193} 194 195check-equal rule-arguments-numbered : 196 [ test-rule a1 : a2 : a3 : a4 : a5 : a6 : a7 : a8 : a9 : a10 : a11 : a12 : a13 : a14 : a15 : a16 : a17 : a18 : a19 ] : 197 a1 - a2 - a1 - a2 - a3 - a4 - a5 - a6 - a7 - a8 - a9 - a10 - a11 - a12 - a13 - a14 - a15 - a16 - a17 - a18 - a19 ; 198 199rule test-rule 200{ 201 return $(<:L) - $(>:L) - $(1:L) - $(2:L) - $(3:L) - $(4:L) - $(5:L) - $(6:L) - $(7:L) - $(8:L) - $(9:L) - $(10:L) - $(11:L) - $(12:L) - $(13:L) - $(14:L) - $(15:L) - $(16:L) - $(17:L) - $(18:L) - $(19:L) ; 202} 203 204# behavior change 205check-equal rule-arguments-numbered-lower : 206 [ test-rule a1 : a2 : a3 : a4 : a5 : a6 : a7 : a8 : a9 : a10 : a11 : a12 : a13 : a14 : a15 : a16 : a17 : a18 : a19 ] : 207 a1 - a2 - a1 - a2 - a3 - a4 - a5 - a6 - a7 - a8 - a9 - a10 - a11 - a12 - a13 - a14 - a15 - a16 - a17 - a18 - a19 ; 208 209 210rule test-rule ( p1 : p2 : p3 : p4 : p5 : p6 : p7 : p8 : p9 : 211 p10 : p11 : p12 : p13 : p14 : p15 : p16 : p17 : p18 : p19 ) 212 213 214{ 215 return $(p1) - $(p2) - $(p3) - $(p4) - $(p5) - $(p6) - $(p7) - $(p8) - $(p9) - $(p10) - $(p11) - $(p12) - $(p13) - $(p14) - $(p15) - $(p16) - $(p17) - $(p18) - $(p19) ; 216} 217 218check-equal rule-arguments-named : 219 [ test-rule a1 : a2 : a3 : a4 : a5 : a6 : a7 : a8 : a9 : a10 : a11 : a12 : a13 : a14 : a15 : a16 : a17 : a18 : a19 ] : 220 a1 - a2 - a3 - a4 - a5 - a6 - a7 - a8 - a9 - a10 - a11 - a12 - a13 - a14 - a15 - a16 - a17 - a18 - a19 ; 221 222# 223# test rule indirection 224# 225rule select ( n list * ) 226{ 227 return $(list[$(n)]) ; 228} 229 230rule indirect1 ( rule + : args * ) 231{ 232 return [ $(rule) $(args) ] ; 233} 234 235check-equal rule-indirect-1 : [ indirect1 select 1 : a b c d e ] : a ; 236check-equal rule-indirect-2 : [ indirect1 select 2 : a b c d e ] : b ; 237 238x = reset ; 239rule reset-x ( new-value ) 240{ 241 x = $(new-value) ; 242} 243$(x)-x bar ; # invokes reset-x... 244check-equal rule-reset : $(x) : bar ; # which changes x 245 246rule bar-x ( new-value ) 247{ 248 mark-order r3 ; 249} 250 251# The arguments are evaluated in forward order 252# before the rule name 253$(x)-x [ mark-order r1 : [ reset-x reset ] ] : [ mark-order r2 ] ; 254check-order rule-order : r1 r2 ; 255 256# Cases that look like member calls 257rule looks.like-a-member ( args * ) 258{ 259 return $(args) ; 260} 261 262rule call-non-member ( rule + ) 263{ 264 return [ $(rule).like-a-member ] ; 265} 266 267rule call-non-member-with-args ( rule + ) 268{ 269 return [ $(rule).like-a-member a2 ] ; 270} 271 272check-equal rule-non-member : [ call-non-member looks ] : ; 273#check-equal rule-non-member-a1 : [ call-non-member looks a1 ] : looks.a1 ; 274check-equal rule-non-member-args : [ call-non-member-with-args looks ] : a2 ; 275#check-equal rule-non-member-args-a1 : [ call-non-member-with-args looks a1 ] : looks.a1 a2 ; 276 277} 278 279# Check append 280 281{ 282 283local value = [ mark-order r1 : v1 v2 ] [ mark-order r2 : v3 v4 ] ; 284check-equal append : $(value) : v1 v2 v3 v4 ; 285check-order append-order : r1 r2 ; 286 287} 288 289# Check foreach 290 291{ 292 293local v1 = 1 2 3 ; 294local x = old ; 295local result ; 296 297for local x in $(v1) 298{ 299 result += $(x) + ; 300} 301 302check-equal foreach-local-item : $(result) : 1 + 2 + 3 + ; 303check-equal foreach-local : $(x) : old ; 304 305result = ; 306 307for x in $(v1) 308{ 309 result += $(x) + ; 310} 311 312check-equal foreach-nonlocal-item : $(result) : 1 + 2 + 3 + ; 313check-equal foreach-nonlocal : $(x) : 3 ; 314 315rule call-foreach ( values * ) 316{ 317 for local x in $(values) 318 { 319 return $(x) ; 320 } 321} 322 323check-equal foreach-result : [ call-foreach 1 2 3 ] : 1 ; 324 325result = ; 326local varname = x ; 327x = old ; 328 329for local $(varname) in $(v1) 330{ 331 result += $(x) + ; 332} 333 334check-equal foreach-no-expand : $(result) : old + old + old + ; 335 336result = ; 337 338for local v1 in $(v1) 339{ 340 result += $(v1) + ; 341} 342 343check-equal foreach-order : $(result) : 1 + 2 + 3 + ; 344 345} 346 347# Check if 348 349{ 350 351if true 352{ 353 mark-order r1 ; 354} 355 356check-order if-true : r1 ; 357 358if $(false) 359{ 360 mark-order r1 ; 361} 362 363check-order if-false : ; 364 365if true 366{ 367 mark-order r1 ; 368} 369else 370{ 371 mark-order r2 ; 372} 373 374check-order if-else-true : r1 ; 375 376if $(false) 377{ 378 mark-order r1 ; 379} 380else 381{ 382 mark-order r2 ; 383} 384 385check-order if-else-false : r2 ; 386 387rule test-rule 388{ 389 if true 390 { 391 return result ; 392 } 393} 394 395check-equal if-true-result : [ test-rule ] : result ; 396 397rule test-rule 398{ 399 local idx = 1 2 ; 400 local values = true ; 401 while $(idx) 402 { 403 local v = $(values[$(idx[1])]) ; 404 idx = $(idx[2-]) ; 405 if $(v) 406 { 407 return result ; 408 } 409 } 410} 411 412check-equal if-false-result : [ test-rule ] : result ; 413 414rule test-rule 415{ 416 if true 417 { 418 return r1 ; 419 } 420 else 421 { 422 return r2 ; 423 } 424} 425 426check-equal if-else-true-result : [ test-rule ] : r1 ; 427 428rule test-rule 429{ 430 if $(false) 431 { 432 return r1 ; 433 } 434 else 435 { 436 return r2 ; 437 } 438} 439 440check-equal if-else-false-result : [ test-rule ] : r2 ; 441 442} 443 444# Check the evaluation of conditions 445 446{ 447 448local test-result ; 449local v1 = "" "" "" ; 450local v2 = ; 451local v3 = a b c ; 452local v4 = a b c d ; 453local v5 = a b d ; 454local v6 = "" "" "" d ; 455 456rule test-comparison ( id : equal less greater ) 457{ 458 check-equal $(id)-empty-1 : [ eval-$(id) $(v1) : $(v2) ] : $(equal) ; 459 check-equal $(id)-empty-2 : [ eval-$(id) $(v1) : $(v2) ] : $(equal) ; 460 check-equal $(id)-equal : [ eval-$(id) $(v3) : $(v3) ] : $(equal) ; 461 check-equal $(id)-less-1 : [ eval-$(id) $(v3) : $(v4) ] : $(less) ; 462 check-equal $(id)-less-2 : [ eval-$(id) $(v3) : $(v5) ] : $(less) ; 463 check-equal $(id)-less-3 : [ eval-$(id) $(v4) : $(v5) ] : $(less) ; 464 check-equal $(id)-greater-1 : [ eval-$(id) $(v4) : $(v3) ] : $(greater) ; 465 check-equal $(id)-greater-2 : [ eval-$(id) $(v5) : $(v3) ] : $(greater) ; 466 check-equal $(id)-greater-3 : [ eval-$(id) $(v5) : $(v4) ] : $(greater) ; 467} 468 469rule eval-lt ( lhs * : rhs * ) 470{ 471 if $(lhs) < $(rhs) { return true ; } 472 else { return false ; } 473} 474 475test-comparison lt : false true false ; 476 477rule eval-gt ( lhs * : rhs * ) 478{ 479 if $(lhs) > $(rhs) { return true ; } 480 else { return false ; } 481} 482 483test-comparison gt : false false true ; 484 485rule eval-le ( lhs * : rhs * ) 486{ 487 if $(lhs) <= $(rhs) { return true ; } 488 else { return false ; } 489} 490 491test-comparison le : true true false ; 492 493rule eval-ge ( lhs * : rhs * ) 494{ 495 if $(lhs) >= $(rhs) { return true ; } 496 else { return false ; } 497} 498 499test-comparison ge : true false true ; 500 501rule eval-eq ( lhs * : rhs * ) 502{ 503 if $(lhs) = $(rhs) { return true ; } 504 else { return false ; } 505} 506 507test-comparison eq : true false false ; 508 509rule eval-ne ( lhs * : rhs * ) 510{ 511 if $(lhs) != $(rhs) { return true ; } 512 else { return false ; } 513} 514 515test-comparison ne : false true true ; 516 517rule eval-not-lt ( lhs * : rhs * ) 518{ 519 if ! ( $(lhs) < $(rhs) ) { return true ; } 520 else { return false ; } 521} 522 523test-comparison not-lt : true false true ; 524 525rule eval-not-gt ( lhs * : rhs * ) 526{ 527 if ! ( $(lhs) > $(rhs) ) { return true ; } 528 else { return false ; } 529} 530 531test-comparison not-gt : true true false ; 532 533rule eval-not-le ( lhs * : rhs * ) 534{ 535 if ! ( $(lhs) <= $(rhs) ) { return true ; } 536 else { return false ; } 537} 538 539test-comparison not-le : false false true ; 540 541rule eval-not-ge ( lhs * : rhs * ) 542{ 543 if ! ( $(lhs) >= $(rhs) ) { return true ; } 544 else { return false ; } 545} 546 547test-comparison not-ge : false true false ; 548 549rule eval-not-eq ( lhs * : rhs * ) 550{ 551 if ! ( $(lhs) = $(rhs) ) { return true ; } 552 else { return false ; } 553} 554 555test-comparison not-eq : false true true ; 556 557rule eval-not-ne ( lhs * : rhs * ) 558{ 559 if ! ( $(lhs) != $(rhs) ) { return true ; } 560 else { return false ; } 561} 562 563test-comparison not-ne : true false false ; 564 565local v7 = a a a a a a ; 566local v8 = c b ; 567local v9 = c d b ; 568local v10 = c a b c c b a a a ; 569 570rule test-in ( id : subset not-subset ) 571{ 572 check-equal $(id)-0-0 : [ eval-$(id) $(v2) : $(v2) ] : $(subset) ; 573 check-equal $(id)-0-empty : [ eval-$(id) $(v2) : $(v1) ] : $(subset) ; 574 check-equal $(id)-empty-0 : [ eval-$(id) $(v1) : $(v2) ] : $(not-subset) ; 575 check-equal $(id)-equal : [ eval-$(id) $(v3) : $(v3) ] : $(subset) ; 576 check-equal $(id)-simple : [ eval-$(id) $(v3) : $(v4) ] : $(subset) ; 577 check-equal $(id)-extra : [ eval-$(id) $(v4) : $(v3) ] : $(not-subset) ; 578 check-equal $(id)-multiple : [ eval-$(id) $(v7) : $(v3) ] : $(subset) ; 579 check-equal $(id)-unordered : [ eval-$(id) $(v8) : $(v3) ] : $(subset) ; 580 check-equal $(id)-unordered-extra : [ eval-$(id) $(v9) : $(v3) ] : $(not-subset) ; 581 check-equal $(id)-unordered-multiple : [ eval-$(id) $(v10) : $(v3) ] : $(subset) ; 582} 583 584rule eval-in ( lhs * : rhs * ) 585{ 586 if $(lhs) in $(rhs) { return true ; } 587 else { return false ; } 588} 589 590test-in "in" : true false ; 591 592rule eval-not-in ( lhs * : rhs * ) 593{ 594 if ! ( $(lhs) in $(rhs) ) { return true ; } 595 else { return false ; } 596} 597 598test-in not-in : false true ; 599 600rule test-truth-table ( id : tt tf ft ff ) 601{ 602 check-equal $(id)-tt : [ eval-$(id) 1 : 1 ] : $(tt) ; 603 check-equal $(id)-tf : [ eval-$(id) 1 : ] : $(tf) ; 604 check-equal $(id)-ft : [ eval-$(id) : 1 ] : $(ft) ; 605 check-equal $(id)-ff : [ eval-$(id) : ] : $(ff) ; 606} 607 608rule eval-and ( lhs ? : rhs ? ) 609{ 610 if $(lhs) && $(rhs) { return true ; } 611 else { return false ; } 612} 613 614test-truth-table and : true false false false ; 615 616rule eval-or ( lhs ? : rhs ? ) 617{ 618 if $(lhs) || $(rhs) { return true ; } 619 else { return false ; } 620} 621 622test-truth-table or : true true true false ; 623 624rule eval-not-and ( lhs ? : rhs ? ) 625{ 626 if ! ( $(lhs) && $(rhs) ) { return true ; } 627 else { return false ; } 628} 629 630test-truth-table not-and : false true true true ; 631 632rule eval-not-or ( lhs ? : rhs ? ) 633{ 634 if ! ( $(lhs) || $(rhs) ) { return true ; } 635 else { return false ; } 636} 637 638test-truth-table not-or : false false false true ; 639 640if [ mark-order r1 : test1 ] < [ mark-order r2 : test2 ] { } 641check-order lt-order : r1 r2 ; 642if [ mark-order r1 : test1 ] > [ mark-order r2 : test2 ] { } 643check-order gt-order : r1 r2 ; 644if [ mark-order r1 : test1 ] <= [ mark-order r2 : test2 ] { } 645check-order le-order : r1 r2 ; 646if [ mark-order r1 : test1 ] >= [ mark-order r2 : test2 ] { } 647check-order ge-order : r1 r2 ; 648if [ mark-order r1 : test1 ] = [ mark-order r2 : test2 ] { } 649check-order eq-order : r1 r2 ; 650if [ mark-order r1 : test1 ] != [ mark-order r2 : test2 ] { } 651check-order ne-order : r1 r2 ; 652if [ mark-order r1 : test1 ] in [ mark-order r2 : test2 ] { } 653check-order in-order : r1 r2 ; 654 655if [ mark-order r1 : test1 ] && [ mark-order r2 : test2 ] { } 656check-order and-order : r1 r2 ; 657if [ mark-order r1 ] && [ mark-order r2 : test2 ] { } 658check-order and-order-short-circuit : r1 ; 659 660if [ mark-order r1 ] || [ mark-order r2 : test2 ] { } 661check-order or-order : r1 r2 ; 662if [ mark-order r1 : test1 ] || [ mark-order r2 : test2 ] { } 663check-order or-order-short-circuit : r1 ; 664 665} 666 667# Check include 668 669{ 670#FIXME: 671# plain include 672# include in module 673# include returns an empty list 674# rule arguments are available inside include 675} 676 677# Check local 678 679{ 680 681local v1 = a b c ; 682local v2 = f g h ; 683 684{ 685 local v1 ; 686 check-equal local-no-init : $(v1) : ; 687} 688 689check-equal local-restore : $(v1) : a b c ; 690 691{ 692 local v1 = d e f ; 693 check-equal local-init : $(v1) : d e f ; 694} 695 696check-equal local-restore-init : $(v1) : a b c ; 697 698{ 699 local v1 v2 ; 700 check-equal local-multiple-no-init : $(v1) - $(v2) : - ; 701} 702 703check-equal local-multiple-restore : $(v1) - $(v2) : a b c - f g h ; 704 705{ 706 local v1 v2 = d e f ; 707 check-equal local-multiple-init : $(v1) - $(v2) : d e f - d e f ; 708} 709 710{ 711 local v1 v1 = d e f ; 712 check-equal local-duplicate : $(v1) - $(v1) : d e f - d e f ; 713} 714 715check-equal local-duplicate-restore : $(v1) : a b c ; 716 717{ 718 local [ mark-order r1 : v1 ] = [ mark-order r2 : d e f ] ; 719 check-order local-order : r1 r2 ; 720} 721 722} 723 724# Check module 725 726{ 727 local var1 = root-module-var ; 728 module my_module 729 { 730 var1 = module-var ; 731 rule get ( ) 732 { 733 return $(var1) ; 734 } 735 local rule not_really ( ) { return nothing ; } 736 } 737 738 check-equal module-var-not-root : $(var1) : root-module-var ; 739 740 check-equal module-rulenames : [ RULENAMES my_module ] : get ; 741 742 IMPORT_MODULE my_module ; 743 check-equal module-rule-import-module : [ my_module.get ] : module-var ; 744 745 IMPORT my_module : get : : module-get ; 746 check-equal module-rule-imort : [ module-get ] : module-var ; 747 748 IMPORT my_module : get : : module-get : LOCALIZE ; 749 check-equal module-rule-imort-localize : [ module-get ] : root-module-var ; 750 751} 752 753# Check class 754{ 755#FIXME: 756# ... 757} 758 759# Check on 760 761{ 762 763local target1 = test-on-target1 ; 764local target2 = test-on-target2 ; 765local targets = $(target1) $(target2) ; 766local v1 v2 v3 ; 767 768VAR on $(target1) = value1 ; 769V2 on $(target2) = value2 ; 770 771check-equal on-return : [ on $(target1) return $(VAR) ] : value1 ; 772 773rule test-rule 774{ 775 return $(VAR) ; 776} 777 778check-equal on-rule : [ on $(target1) test-rule ] : value1 ; 779 780check-equal on-multiple : [ on $(targets) return $(V2) ] : ; 781 782rule test-rule 783{ 784 on $(target1) 785 { 786 return $(VAR) ; 787 } 788} 789 790check-equal on-block : [ test-rule ] : value1 ; 791 792# FIXME: crazy implementation artifacts: 793 794v1 on test-on-target3 = x1 ; 795on test-on-target3 796{ 797 v1 on test-on-target3 += x1 ; 798 v1 = y1 ; 799 v2 on test-on-target3 += x2 ; 800 v2 = y2 ; 801 v3 = y3 ; 802} 803 804check-equal on-swap-old1 : $(v1) : x1 ; 805check-equal on-swap-old2 : [ on test-on-target3 return $(v1) ] : y1 ; 806check-equal on-swap-new1 : $(v2) : x2 ; 807check-equal on-swap-new2 : [ on test-on-target3 return $(v2) ] : y2 ; 808check-equal on-no-swap : $(v3) : y3 ; 809 810} 811 812# Check rule 813 814{ 815#FIXME: 816# argument order 817# expand rule name 818} 819 820# Check rules 821 822{ 823#FIXME: 824} 825 826# Check set 827 828{ 829local v1 ; 830local v2 ; 831local v3 ; 832local vars = v1 v2 v3 ; 833 834v1 = x1 ; 835check-equal set-set-empty : $(v1) : x1 ; 836v2 += x2 ; 837check-equal set-append-empty : $(v2) : x2 ; 838v3 ?= x3 ; 839check-equal set-default-empty : $(v3) : x3 ; 840 841v1 = y1 ; 842check-equal set-set-non-empty : $(v1) : y1 ; 843v2 += y2 ; 844check-equal set-append-non-empty : $(v2) : x2 y2 ; 845v3 ?= y3 ; 846check-equal set-default-non-empty : $(v3) : x3 ; 847 848v1 = ; 849v2 = ; 850v3 = ; 851$(vars) = z ; 852check-equal set-set-empty-group : $(v1) - $(v2) - $(v3) : z - z - z ; 853 854v1 = ; 855v2 = ; 856v3 = ; 857$(vars) += z ; 858check-equal set-append-empty-group : $(v1) - $(v2) - $(v3) : z - z - z ; 859 860v1 = ; 861v2 = ; 862v3 = ; 863$(vars) ?= z ; 864check-equal set-default-empty-group : $(v1) - $(v2) - $(v3) : z - z - z ; 865 866v1 = x1 ; 867v2 = x2 ; 868v3 = x3 ; 869$(vars) = z ; 870check-equal set-set-non-empty-group : $(v1) - $(v2) - $(v3) : z - z - z ; 871 872v1 = x1 ; 873v2 = x2 ; 874v3 = x3 ; 875$(vars) += z ; 876check-equal set-append-non-empty-group : $(v1) - $(v2) - $(v3) : x1 z - x2 z - x3 z ; 877 878v1 = x1 ; 879v2 = x2 ; 880v3 = x3 ; 881$(vars) ?= z ; 882check-equal set-default-non-empty-group : $(v1) - $(v2) - $(v3) : x1 - x2 - x3 ; 883 884v1 = x1 ; 885v2 = ; 886v3 = x3 ; 887$(vars) = z ; 888check-equal set-set-mixed-group : $(v1) - $(v2) - $(v3) : z - z - z ; 889 890v1 = x1 ; 891v2 = ; 892v3 = x3 ; 893$(vars) += z ; 894check-equal set-append-mixed-group : $(v1) - $(v2) - $(v3) : x1 z - z - x3 z ; 895 896v1 = x1 ; 897v2 = ; 898v3 = x3 ; 899$(vars) ?= z ; 900check-equal set-default-mixed-group : $(v1) - $(v2) - $(v3) : x1 - z - x3 ; 901 902vars = v1 v1 ; 903 904v1 = ; 905$(vars) = z ; 906check-equal set-set-duplicate-empty : $(v1) : z ; 907v1 = ; 908$(vars) += z ; 909check-equal set-append-duplicate-empty : $(v1) : z z ; 910v1 = ; 911$(vars) ?= z ; 912check-equal set-default-duplicate-empty : $(v1) : z ; 913 914v1 = x1 ; 915$(vars) = z ; 916check-equal set-set-duplicate-non-empty : $(v1) : z ; 917v1 = x1 ; 918$(vars) += z ; 919check-equal set-append-duplicate-non-empty : $(v1) : x1 z z ; 920v1 = x1 ; 921$(vars) ?= z ; 922check-equal set-default-duplicate-non-empty : $(v1) : x1 ; 923 924rule test-rule { v1 = x1 ; } 925check-equal set-set-result : [ test-rule ] : x1 ; 926rule test-rule { v1 += x1 ; } 927check-equal set-append-result : [ test-rule ] : x1 ; 928rule test-rule { v1 ?= x1 ; } 929check-equal set-default-result : [ test-rule ] : x1 ; 930 931[ mark-order r1 ] = [ mark-order r2 ] ; 932check-order set-set-order : r1 r2 ; 933[ mark-order r1 ] += [ mark-order r2 ] ; 934check-order set-append-order : r1 r2 ; 935[ mark-order r1 ] ?= [ mark-order r2 ] ; 936check-order set-default-order : r1 r2 ; 937 938} 939 940# Check setcomp 941 942{ 943#FIXME 944# Expand arguments 945# Don't expand name 946} 947 948# Check setexec 949 950{ 951#FIXME: 952# Don't expand name 953# Evaluate bindlist 954} 955 956# Check settings ; 957 958{ 959 960local target1 = test-settings-target1 ; 961local target2 = test-settings-target2 ; 962local target3 = test-settings-target3 ; 963local targets = $(target2) $(target3) ; 964 965local vars = v1 v2 v3 ; 966 967v1 on $(target1) = x1 ; 968check-equal settings-set-empty : [ on $(target1) return $(v1) ] : x1 ; 969v2 on $(target1) += x2 ; 970check-equal settings-append-empty : [ on $(target1) return $(v2) ] : x2 ; 971v3 on $(target1) ?= x3 ; 972check-equal settings-default-empty : [ on $(target1) return $(v3) ] : x3 ; 973 974v1 on $(target1) = y1 ; 975check-equal settings-set-non-empty : [ on $(target1) return $(v1) ] : y1 ; 976v2 on $(target1) += y2 ; 977check-equal settings-append-non-empty : [ on $(target1) return $(v2) ] : x2 y2 ; 978v3 on $(target1) ?= y3 ; 979check-equal settings-default-non-empty : [ on $(target1) return $(v3) ] : x3 ; 980 981$(vars) on setting-target2 = z ; 982check-equal settings-set-empty-group : [ on setting-target2 return $(v1) ] - [ on setting-target2 return $(v2) ] - [ on setting-target2 return $(v3) ] : z - z - z ; 983 984$(vars) on setting-target3 += z ; 985check-equal settings-append-empty-group : [ on setting-target3 return $(v1) ] - [ on setting-target3 return $(v2) ] - [ on setting-target3 return $(v3) ] : z - z - z ; 986 987$(vars) on setting-target4 ?= z ; 988check-equal settings-default-empty-group : [ on setting-target4 return $(v1) ] - [ on setting-target4 return $(v2) ] - [ on setting-target4 return $(v3) ] : z - z - z ; 989 990v1 on $(target1) = x1 ; 991v2 on $(target1) = x2 ; 992v3 on $(target1) = x3 ; 993$(vars) on $(target1) = z ; 994check-equal settings-set-non-empty-group : [ on $(target1) return $(v1) ] - [ on $(target1) return $(v2) ] - [ on $(target1) return $(v3) ] : z - z - z ; 995 996v1 on $(target1) = x1 ; 997v2 on $(target1) = x2 ; 998v3 on $(target1) = x3 ; 999$(vars) on $(target1) += z ; 1000check-equal settings-append-non-empty-group : [ on $(target1) return $(v1) ] - [ on $(target1) return $(v2) ] - [ on $(target1) return $(v3) ] : x1 z - x2 z - x3 z ; 1001 1002v1 on $(target1) = x1 ; 1003v2 on $(target1) = x2 ; 1004v3 on $(target1) = x3 ; 1005$(vars) on $(target1) ?= z ; 1006check-equal settings-default-non-empty-group : [ on $(target1) return $(v1) ] - [ on $(target1) return $(v2) ] - [ on $(target1) return $(v3) ] : x1 - x2 - x3 ; 1007 1008v1 on setting-target5 = x1 ; 1009v3 on setting-target5 = x3 ; 1010$(vars) on setting-target5 = z ; 1011check-equal settings-set-mixed-group : [ on setting-target5 return $(v1) ] - [ on setting-target5 return $(v2) ] - [ on setting-target5 return $(v3) ] : z - z - z ; 1012 1013v1 on setting-target6 = x1 ; 1014v3 on setting-target6 = x3 ; 1015$(vars) on setting-target6 += z ; 1016check-equal settings-append-mixed-group : [ on setting-target6 return $(v1) ] - [ on setting-target6 return $(v2) ] - [ on setting-target6 return $(v3) ] : x1 z - z - x3 z ; 1017 1018v1 on setting-target7 = x1 ; 1019v3 on setting-target7 = x3 ; 1020$(vars) on setting-target7 ?= z ; 1021check-equal settings-default-mixed-group : [ on setting-target7 return $(v1) ] - [ on setting-target7 return $(v2) ] - [ on setting-target7 return $(v3) ] : x1 - z - x3 ; 1022 1023vars = v1 v1 ; 1024 1025$(vars) on setting-target8 = z ; 1026check-equal settings-set-duplicate-empty : [ on setting-target8 return $(v1) ] : z ; 1027$(vars) on setting-target9 += z ; 1028check-equal settings-append-duplicate-empty : [ on setting-target9 return $(v1) ] : z z ; 1029$(vars) on setting-target10 ?= z ; 1030check-equal settings-default-duplicate-empty : [ on setting-target10 return $(v1) ] : z ; 1031 1032v1 on $(target1) = x1 ; 1033$(vars) on $(target1) = z ; 1034check-equal settings-set-duplicate-non-empty : [ on $(target1) return $(v1) ] : z ; 1035v1 on $(target1) = x1 ; 1036$(vars) on $(target1) += z ; 1037check-equal settings-append-duplicate-non-empty : [ on $(target1) return $(v1) ] : x1 z z ; 1038v1 on $(target1) = x1 ; 1039$(vars) on $(target1) ?= z ; 1040check-equal settings-default-duplicate-non-empty : [ on $(target1) return $(v1) ] : x1 ; 1041 1042v1 on $(target1) = ; 1043v1 on $(target1) ?= z ; 1044check-equal settings-default-set-but-empty : [ on $(target1) return $(v1) ] : ; 1045 1046v1 on $(targets) = multi ; 1047check-equal settings-set-multi-empty : [ on $(target2) return $(v1) ] - [ on $(target3) return $(v1) ] : multi - multi ; 1048v2 on $(targets) += multi ; 1049check-equal settings-append-multi-empty : [ on $(target2) return $(v2) ] - [ on $(target3) return $(v2) ] : multi - multi ; 1050v3 on $(targets) ?= multi ; 1051check-equal settings-default-multi-empty : [ on $(target2) return $(v3) ] - [ on $(target3) return $(v3) ] : multi - multi ; 1052 1053v1 on $(targets) = multi2 ; 1054check-equal settings-set-multi-empty : [ on $(target2) return $(v1) ] - [ on $(target3) return $(v1) ] : multi2 - multi2 ; 1055v2 on $(targets) += multi2 ; 1056check-equal settings-append-multi-empty : [ on $(target2) return $(v2) ] - [ on $(target3) return $(v2) ] : multi multi2 - multi multi2 ; 1057v3 on $(targets) ?= multi2 ; 1058check-equal settings-default-multi-empty : [ on $(target2) return $(v3) ] - [ on $(target3) return $(v3) ] : multi - multi ; 1059 1060rule test-rule { v1 on $(target1) = x1 ; } 1061check-equal settings-set-result : [ test-rule ] : x1 ; 1062rule test-rule { v1 on $(target1) += x1 ; } 1063check-equal settings-append-result : [ test-rule ] : x1 ; 1064rule test-rule { v1 on $(target1) ?= x1 ; } 1065check-equal settings-default-result : [ test-rule ] : x1 ; 1066 1067[ mark-order r1 : var ] on [ mark-order r3 : $(target1) ] = [ mark-order r2 : value ] ; 1068check-order settings-set-order : r1 r2 r3 ; 1069[ mark-order r1 : var ] on [ mark-order r3 : $(target1) ] += [ mark-order r2 : value ] ; 1070check-order settings-append-order : r1 r2 r3 ; 1071[ mark-order r1 : var ] on [ mark-order r3 : $(target1) ] ?= [ mark-order r2 : value ] ; 1072check-order settings-default-order : r1 r2 r3 ; 1073 1074} 1075 1076# Check switch 1077 1078{ 1079 1080local pattern = * ; 1081 1082switch value 1083{ 1084 case * : mark-order r1 ; 1085} 1086 1087check-order switch-match-any : r1 ; 1088 1089switch value 1090{ 1091 case v2 : mark-order r1 ; 1092} 1093 1094check-order switch-no-match : ; 1095 1096switch value 1097{ 1098 case $(pattern) : mark-order r1 ; 1099} 1100 1101check-order switch-no-expand : ; 1102 1103switch value 1104{ 1105 case value : mark-order r1 ; 1106 case * : mark-order r2 ; 1107} 1108 1109check-order switch-match-several : r1 ; 1110 1111rule test-rule ( value ) 1112{ 1113 switch $(value) 1114 { 1115 case value : return 1 ; 1116 } 1117} 1118 1119check-equal switch-result-match : [ test-rule value ] : 1 ; 1120check-equal switch-result-match : [ test-rule v1 ] : ; 1121 1122switch $() 1123{ 1124 case "" : mark-order r1 ; 1125 case * : mark-order r2 ; 1126} 1127 1128check-order switch-empty : r1 ; 1129 1130local values = v1 v2 v3 ; 1131switch $(values) 1132{ 1133 case v1 : mark-order r1 ; 1134 case v2 : mark-order r2 ; 1135 case v3 : mark-order r3 ; 1136} 1137 1138check-order switch-multiple : r1 ; 1139 1140# Test glob matching 1141 1142switch value { case * : mark-order r1 ; } 1143check-order switch-glob-star : r1 ; 1144 1145switch value { case va*e : mark-order r1 ; } 1146check-order switch-glob-star-1 : r1 ; 1147 1148switch value { case *a* : mark-order r1 ; } 1149check-order switch-glob-star-2 : r1 ; 1150 1151switch value { case *a*ue* : mark-order r1 ; } 1152check-order switch-glob-star-3 : r1 ; 1153 1154switch value { case *[eaiou]*ue : mark-order r1 ; } 1155check-order switch-glob-group : r1 ; 1156 1157switch value { case *[eaiou]ue : mark-order r1 ; } 1158check-order switch-glob-group-fail : ; 1159 1160switch value { case ?a?ue : mark-order r1 ; } 1161check-order switch-glob-any : r1 ; 1162 1163switch value { case ?lue : mark-order r1 ; } 1164check-order switch-glob-any-fail : ; 1165 1166} 1167 1168# Test while 1169 1170{ 1171 1172local value = 1 2 3 ; 1173 1174while $(value) 1175{ 1176 mark-order r$(value[1]) ; 1177 value = $(value[2-]) ; 1178} 1179 1180check-order while-exec : r1 r2 r3 ; 1181 1182rule test-rule 1183{ 1184 local value = 1 2 3 ; 1185 while $(value) 1186 { 1187 value = $(value[2-]) ; 1188 return x ; 1189 } 1190} 1191 1192check-equal while-result : [ test-rule ] : x ; 1193 1194rule test-rule 1195{ 1196 local value = 1 2 ; 1197 while $(value) 1198 { 1199 value = $(value[2-]) ; 1200 local inner = $(value) ; 1201 while $(inner) 1202 { 1203 inner = $(inner[2-]) ; 1204 return x ; 1205 } 1206 } 1207} 1208 1209check-equal while-result-2 : [ test-rule ] : x ; 1210 1211} 1212 1213 1214# 1215# test break 1216# 1217 1218{ 1219 1220local z = original ; 1221local done ; 1222while ! $(done) 1223{ 1224 local z = inner ; 1225 mark-order r1 ; 1226 break ; 1227 mark-order r2 ; 1228 done = true ; 1229} 1230 1231check-order break-while-exec : r1 ; 1232check-equal break-while-cleanup : $(z) : original ; 1233 1234local values = v1 v2 ; 1235 1236for y in $(values) 1237{ 1238 local z = inner ; 1239 mark-order r1-$(y) ; 1240 break ; 1241 mark-order r2-$(y) ; 1242} 1243 1244check-order break-for-exec : r1-v1 ; 1245check-equal break-for-cleanup : $(z) : original ; 1246 1247for local y in $(values) 1248{ 1249 local z = inner ; 1250 mark-order r1-$(y) ; 1251 break ; 1252 mark-order r2-$(y) ; 1253} 1254 1255check-order break-for-local-exec : r1-v1 ; 1256check-equal break-for-local-cleanup : $(z) : original ; 1257 1258local z1 = z1val ; 1259local z2 = z2val ; 1260done = ; 1261while ! $(done) 1262{ 1263 local z1 = z1new ; 1264 mark-order r1 ; 1265 for local y in $(values) 1266 { 1267 local z2 = z2new ; 1268 mark-order r2 ; 1269 break ; 1270 mark-order r3 ; 1271 } 1272 mark-order r4 ; 1273 break ; 1274 mark-order r5 ; 1275 done = true ; 1276} 1277 1278check-order break-nested-exec : r1 r2 r4 ; 1279check-equal break-nested-cleanup1 : $(z1) : z1val ; 1280check-equal break-nested-cleanup2 : $(z2) : z2val ; 1281 1282} 1283 1284# 1285# test continue 1286# 1287 1288{ 1289 1290local z = original ; 1291local done ; 1292while ! [ mark-order r1 : $(done) ] 1293{ 1294 local z = inner ; 1295 done = true ; 1296 mark-order r2 ; 1297 continue ; 1298 mark-order r3 ; 1299} 1300 1301check-order continue-while-exec : r1 r2 r1 ; 1302check-equal continue-while-cleanup : $(z) : original ; 1303 1304local values = v1 v2 ; 1305for y in $(values) 1306{ 1307 local z = inner ; 1308 mark-order r1-$(y) ; 1309 continue ; 1310 mark-order r2-$(y) ; 1311} 1312 1313check-order continue-for-exec : r1-v1 r1-v2 ; 1314check-equal continue-for-cleanup : $(z) : original ; 1315 1316for local y in $(values) 1317{ 1318 local z = inner ; 1319 mark-order r1-$(y) ; 1320 continue ; 1321 mark-order r2-$(y) ; 1322} 1323 1324check-order continue-for-local-exec : r1-v1 r1-v2 ; 1325check-equal continue-for-local-cleanup : $(z) : original ; 1326 1327local z1 = z1val ; 1328local z2 = z2val ; 1329done = ; 1330while ! [ mark-order r1 : $(done) ] 1331{ 1332 local z1 = z1new ; 1333 done = true ; 1334 mark-order r2 ; 1335 for local y in $(values) 1336 { 1337 local z2 = z2new ; 1338 mark-order r3-$(y) ; 1339 continue ; 1340 mark-order r4-$(y) ; 1341 } 1342 mark-order r5 ; 1343 continue ; 1344 mark-order r6 ; 1345} 1346 1347check-order continue-nested-exec : r1 r2 r3-v1 r3-v2 r5 r1 ; 1348check-equal continue-nested-cleanup1 : $(z1) : z1val ; 1349check-equal continue-nested-cleanup2 : $(z2) : z2val ; 1350 1351} 1352 1353# 1354# test CALLER_MODULE and backtrace 1355# 1356 1357{ 1358 local base = [ BACKTRACE ] ; 1359 base = $(base[2]) ; 1360 rule backtrace ( ) 1361 { 1362 local bt = [ BACKTRACE ] ; 1363 check-equal backtrace-1-file : $(bt) : 1364 test.jam [ CALC $(base) + 4 ] "" backtrace 1365 test.jam [ CALC $(base) + 28 ] module2. module2.f 1366 test.jam [ CALC $(base) + 19 ] module1. module1.f 1367 test.jam [ CALC $(base) + 32 ] "" "module scope" 1368 ; 1369 } 1370 module module1 1371 { 1372 IMPORT_MODULE module2 : module1 ; 1373 rule f ( ) 1374 { 1375 local m = [ CALLER_MODULE ] ; 1376 check-equal caller-module-root : $(m) ; 1377 module2.f ; 1378 } 1379 } 1380 module module2 1381 { 1382 rule f ( ) 1383 { 1384 local m = [ CALLER_MODULE ] ; 1385 check-equal caller-module : module1 : $(m) ; 1386 backtrace ; 1387 } 1388 } 1389 IMPORT_MODULE module1 ; 1390 module1.f ; 1391} 1392 1393 1394# Test NORMALIZE_PATH 1395 1396{ 1397check-equal normalize-path : "." : [ NORMALIZE_PATH ] ; 1398check-equal normalize-path : "." : [ NORMALIZE_PATH "" ] ; 1399check-equal normalize-path : "." : [ NORMALIZE_PATH "." ] ; 1400check-equal normalize-path : ".." : [ NORMALIZE_PATH ".." ] ; 1401check-equal normalize-path : "/" : [ NORMALIZE_PATH "/" ] ; 1402check-equal normalize-path : "/" : [ NORMALIZE_PATH "\\" ] ; 1403check-equal normalize-path : "/" : [ NORMALIZE_PATH "//" ] ; 1404check-equal normalize-path : "/" : [ NORMALIZE_PATH "\\\\" ] ; 1405check-equal normalize-path : "/" : [ NORMALIZE_PATH "//\\\\//\\\\" ] ; 1406check-equal normalize-path : "/" : [ NORMALIZE_PATH "/." ] ; 1407check-equal normalize-path : "/" : [ NORMALIZE_PATH "/./" ] ; 1408check-equal normalize-path : "/" : [ NORMALIZE_PATH "\\\\///.///\\\\\\" ] ; 1409check-equal normalize-path : "." : [ NORMALIZE_PATH "./././././." ] ; 1410check-equal normalize-path : "/" : [ NORMALIZE_PATH "/./././././." ] ; 1411check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo" ] ; 1412check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo/" ] ; 1413check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo\\" ] ; 1414check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo\\\\/////" ] ; 1415check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo\\\\/////././." ] ; 1416check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo\\\\/////./././" ] ; 1417check-equal normalize-path : "." : [ NORMALIZE_PATH "foo/.." ] ; 1418check-equal normalize-path : "." : [ NORMALIZE_PATH "foo////.." ] ; 1419check-equal normalize-path : "/" : [ NORMALIZE_PATH "///foo/\\\\/.." ] ; 1420check-equal normalize-path : "/" : [ NORMALIZE_PATH "\\\\\\foo\\//\\.." ] ; 1421check-equal normalize-path : "." : [ NORMALIZE_PATH "foo/./.." ] ; 1422check-equal normalize-path : "." : [ NORMALIZE_PATH "foo/././././.." ] ; 1423check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo/./././bar/./././.././././baz/./././.." ] ; 1424check-equal normalize-path : "/foo" : [ NORMALIZE_PATH "/foo/./././bar/./././.././././baz/./././.." ] ; 1425check-equal normalize-path : "foo" : [ NORMALIZE_PATH "foo/./././bar/./././////.././././baz/./././.." ] ; 1426check-equal normalize-path : "/foo" : [ NORMALIZE_PATH "/foo/./././bar/./././////.././././baz/./././.." ] ; 1427check-equal normalize-path : ".." : [ NORMALIZE_PATH "./.." ] ; 1428check-equal normalize-path : ".." : [ NORMALIZE_PATH "././././.." ] ; 1429check-equal normalize-path : "../.." : [ NORMALIZE_PATH "../.." ] ; 1430check-equal normalize-path : "../.." : [ NORMALIZE_PATH "./../.." ] ; 1431check-equal normalize-path : "../.." : [ NORMALIZE_PATH "././././../.." ] ; 1432check-equal normalize-path : "../.." : [ NORMALIZE_PATH "./.././././.." ] ; 1433check-equal normalize-path : "../.." : [ NORMALIZE_PATH "././././.././././.." ] ; 1434check-equal normalize-path : "../.." : [ NORMALIZE_PATH "..//\\\\\\//.." ] ; 1435check-equal normalize-path : "../.." : [ NORMALIZE_PATH "../..\\\\/\\\\" ] ; 1436check-equal normalize-path : "." : [ NORMALIZE_PATH "foo/../bar/../baz/.." ] ; 1437check-equal normalize-path : "." : [ NORMALIZE_PATH "foo////..////bar////.//////.////../baz/.." ] ; 1438check-equal normalize-path : "/" : [ NORMALIZE_PATH "/foo/../bar/../baz/.." ] ; 1439check-equal normalize-path : "/" : [ NORMALIZE_PATH "/foo////..////bar////.//////.////../baz/.." ] ; 1440 1441# Invalid rooted paths with leading dotdots. 1442check-equal normalize-path-invalid : : [ NORMALIZE_PATH "/.." ] ; 1443check-equal normalize-path-invalid : : [ NORMALIZE_PATH "/../" ] ; 1444check-equal normalize-path-invalid : : [ NORMALIZE_PATH "//\\\\//\\\\/.." ] ; 1445check-equal normalize-path-invalid : : [ NORMALIZE_PATH "\\\\//\\\\//\\.." ] ; 1446check-equal normalize-path-invalid : : [ NORMALIZE_PATH "/../.." ] ; 1447check-equal normalize-path-invalid : : [ NORMALIZE_PATH "/../../.." ] ; 1448check-equal normalize-path-invalid : : [ NORMALIZE_PATH "/foo/bar/../baz/../../.." ] ; 1449check-equal normalize-path-invalid : : [ NORMALIZE_PATH "/../for/././../././bar/././../././.." ] ; 1450check-equal normalize-path-invalid : : [ NORMALIZE_PATH "/../foo/bar" ] ; 1451 1452check-equal normalize-path : "../d" : [ NORMALIZE_PATH "../d" ] ; 1453check-equal normalize-path : "../d" : [ NORMALIZE_PATH ".." "d" ] ; 1454check-equal normalize-path : "../../d" : [ NORMALIZE_PATH ".." ".." "d" ] ; 1455check-equal normalize-path : "../d" : [ NORMALIZE_PATH "" ".." "d" ] ; 1456 1457} 1458 1459# Test W32_GETREGNAMES 1460 1461{ 1462 1463if $(NT) 1464{ 1465 local sound = "Beep" "ExtendedSounds" ; 1466 local r1 = [ W32_GETREGNAMES "HKEY_CURRENT_USER\\Control Panel\\Sound" : 1467 values ] ; 1468 check-equal w32_getregnames : $(sound:L) : [ SORT $(r1:L) ] ; 1469 local r2 = [ W32_GETREGNAMES "HKCU\\Control Panel\\Sound" : values ] ; 1470 check-equal w32_getregnames : $(sound:L) : [ SORT $(r2:L) ] ; 1471 1472 # Some Windows platforms may have additional keys under 1473 # 'CurrentControlSet' which we then remove here so they would not be 1474 # reported as errors by our test. 1475 local rule remove-policies ( param * ) 1476 { 1477 local found ; 1478 local r ; 1479 for local x in $(param:L) 1480 { 1481 if ! x in $(found) && 1482 $(x) in "addservices" "policies" "deleted device ids" "software" 1483 { 1484 found += $(x) ; 1485 } 1486 else 1487 { 1488 r += $(x) ; 1489 } 1490 } 1491 return $(r) ; 1492 } 1493 local CurrentControlSet = "Control" "Enum" "Hardware Profiles" "Services" ; 1494 local r3 = [ W32_GETREGNAMES "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet" 1495 : subkeys ] ; 1496 check-equal w32_getregnames : $(CurrentControlSet:L) : [ remove-policies 1497 $(r3:L) ] ; 1498 local r4 = [ W32_GETREGNAMES "HKLM\\SYSTEM\\CurrentControlSet" : subkeys ] ; 1499 check-equal w32_getregnames : $(CurrentControlSet:L) : [ remove-policies 1500 $(r4:L) ] ; 1501} 1502 1503} 1504 1505# Test SHELL 1506 1507{ 1508 1509local c = "echo value" ; 1510if $(OS) = VMS { c = "PIPE WRITE SYS$OUTPUT \"value\"" ; } 1511 1512check-equal shell : "value\n" : [ SHELL $(c) ] ; 1513check-equal shell : "" : [ SHELL $(c) : no-output ] ; 1514check-equal shell : "value\n" 0 : [ SHELL $(c) : exit-status ] ; 1515check-equal shell : "" 0 : [ SHELL $(c) : no-output : exit-status ] ; 1516check-equal shell : "" 0 : [ SHELL $(c) : no-output : exit-status : strip-eol ] ; 1517check-equal command : "value\n" : [ COMMAND $(c) ] ; 1518check-equal command : "" : [ COMMAND $(c) : no-output ] ; 1519check-equal command : "value\n" 0 : [ COMMAND $(c) : exit-status ] ; 1520check-equal command : "" 0 : [ COMMAND $(c) : no-output : exit-status ] ; 1521 1522# buffered output 1523 1524local expected = "When the shell output buffer splits on whitespace, the whitespace shouldn't be trimmed. end." ; 1525local buffered = "echo \"$(expected)\"" ; 1526if $(OS) = VMS { buffered = "PIPE WRITE SYS$OUTPUT \"$(expected)\"" ; } 1527if $(OS) = NT { buffered = "echo $(expected)" ; } 1528 1529check-equal shell : "$(expected)\n" : [ SHELL $(buffered) ] ; 1530check-equal shell : "" : [ SHELL $(buffered) : no-output ] ; 1531check-equal shell : "$(expected)\n" 0 : [ SHELL $(buffered) : exit-status ] ; 1532check-equal shell : "$(expected)" 0 : [ SHELL $(buffered) : strip-eol : exit-status ] ; 1533check-equal shell : "" 0 : [ SHELL $(buffered) : no-output : exit-status ] ; 1534check-equal shell : "" 0 : [ SHELL $(buffered) : no-output : exit-status : strip-eol ] ; 1535check-equal shell : "$(expected)" 0 : [ SHELL $(buffered) : strip-eol : exit-status ] ; 1536 1537check-equal command : "$(expected)\n" : [ COMMAND $(buffered) ] ; 1538check-equal command : "" : [ COMMAND $(buffered) : no-output ] ; 1539check-equal command : "$(expected)\n" 0 : [ COMMAND $(buffered) : exit-status ] ; 1540check-equal command : "$(expected)" 0 : [ COMMAND $(buffered) : strip-eol : exit-status ] ; 1541check-equal command : "" 0 : [ COMMAND $(buffered) : no-output : exit-status ] ; 1542 1543} 1544 1545# Test SUBST 1546 1547{ 1548 1549# Check that unmatched subst returns an empty list 1550check-equal subst-nomatch : [ SUBST "abc" "d+" x ] : ; 1551 1552# Check that a matched subst works 1553check-equal subst-match : [ SUBST "ddd" "d+" x ] : x ; 1554 1555# Check that we can get multiple substitutions from a single invocation 1556check-equal subst-multiple : [ SUBST "x/y/z" "([^/]*)/([^/]*).*" "\\1" $2 "\\1-\\2" ] : x y x-y ; 1557 1558} 1559 1560# Test summary 1561 1562if $(failed) = 0 1563{ 1564 status = 0 ; 1565} 1566else 1567{ 1568 status = 1 ; 1569} 1570 1571EXIT $(passed) passed $(failed) failed : $(status) ; 1572