6 @INC = ('.', '../lib', '../ext/B/t');
12 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
13 print "1..0 # Skip -- Perl configured without B module\n";
16 # require 'test.pl'; # now done by OptreeCheck
19 # import checkOptree(), and %gOpts (containing test state)
20 use OptreeCheck; # ALSO DOES @ARGV HANDLING !!!!!!
26 skip "no perlio in this build", $tests unless $Config::Config{useperlio};
28 $SIG{__WARN__} = sub {
30 $err =~ m/Subroutine re::(un)?install redefined/ and return;
32 #################################
33 pass("CANONICAL B::Concise EXAMPLE");
37 if (((caller 0)[10]||{})->{open}) {
38 @open_todo = (skip => "\$^OPEN is set");
43 checkOptree ( name => 'canonical example w -basic',
45 code => sub{$a=$b+42},
47 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
48 # 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
49 # - <@> lineseq KP ->7
50 # 1 <;> nextstate(foo bar) v:{ ->2
51 # 6 <2> sassign sKS/2 ->7
52 # 4 <2> add[t3] sK/2 ->5
53 # - <1> ex-rv2sv sK/1 ->3
54 # 2 <#> gvsv[*b] s ->3
55 # 3 <$> const[IV 42] s ->4
56 # - <1> ex-rv2sv sKRM*/1 ->6
57 # 5 <#> gvsv[*a] s ->6
59 # 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
60 # - <@> lineseq KP ->7
61 # 1 <;> nextstate(main 60 optree_concise.t:122) v:{ ->2
62 # 6 <2> sassign sKS/2 ->7
63 # 4 <2> add[t1] sK/2 ->5
64 # - <1> ex-rv2sv sK/1 ->3
65 # 2 <$> gvsv(*b) s ->3
66 # 3 <$> const(IV 42) s ->4
67 # - <1> ex-rv2sv sKRM*/1 ->6
68 # 5 <$> gvsv(*a) s ->6
71 checkOptree ( name => 'canonical example w -exec',
73 code => sub{$a=$b+42},
75 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
76 # 1 <;> nextstate(main 61 optree_concise.t:139) v:{
78 # 3 <$> const[IV 42] s
82 # 7 <1> leavesub[1 ref] K/REFC,1
84 # 1 <;> nextstate(main 61 optree_concise.t:139) v:{
86 # 3 <$> const(IV 42) s
90 # 7 <1> leavesub[1 ref] K/REFC,1
93 #################################
94 pass("B::Concise OPTION TESTS");
96 checkOptree ( name => '-base3 sticky-exec',
98 code => sub{$a=$b+42},
100 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
101 1 <;> dbstate(main 24 optree_concise.t:132) v:{
103 10 <$> const[IV 42] s
107 21 <1> leavesub[1 ref] K/REFC,1
109 # 1 <;> nextstate(main 62 optree_concise.t:161) v:{
111 # 10 <$> const(IV 42) s
112 # 11 <2> add[t1] sK/2
114 # 20 <2> sassign sKS/2
115 # 21 <1> leavesub[1 ref] K/REFC,1
118 checkOptree ( name => 'sticky-base3, -basic over sticky-exec',
120 code => sub{$a=$b+42},
122 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
123 21 <1> leavesub[1 ref] K/REFC,1 ->(end)
124 - <@> lineseq KP ->21
125 1 <;> nextstate(main 32 optree_concise.t:164) v:{ ->2
126 20 <2> sassign sKS/2 ->21
127 11 <2> add[t3] sK/2 ->12
128 - <1> ex-rv2sv sK/1 ->10
129 2 <#> gvsv[*b] s ->10
130 10 <$> const[IV 42] s ->11
131 - <1> ex-rv2sv sKRM*/1 ->20
132 12 <#> gvsv[*a] s ->20
134 # 21 <1> leavesub[1 ref] K/REFC,1 ->(end)
135 # - <@> lineseq KP ->21
136 # 1 <;> nextstate(main 63 optree_concise.t:186) v:{ ->2
137 # 20 <2> sassign sKS/2 ->21
138 # 11 <2> add[t1] sK/2 ->12
139 # - <1> ex-rv2sv sK/1 ->10
140 # 2 <$> gvsv(*b) s ->10
141 # 10 <$> const(IV 42) s ->11
142 # - <1> ex-rv2sv sKRM*/1 ->20
143 # 12 <$> gvsv(*a) s ->20
146 checkOptree ( name => '-base4',
147 bcopts => [qw/ -basic -base4 /],
148 code => sub{$a=$b+42},
150 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
151 13 <1> leavesub[1 ref] K/REFC,1 ->(end)
152 - <@> lineseq KP ->13
153 1 <;> nextstate(main 26 optree_concise.t:145) v:{ ->2
154 12 <2> sassign sKS/2 ->13
155 10 <2> add[t3] sK/2 ->11
156 - <1> ex-rv2sv sK/1 ->3
158 3 <$> const[IV 42] s ->10
159 - <1> ex-rv2sv sKRM*/1 ->12
160 11 <#> gvsv[*a] s ->12
162 # 13 <1> leavesub[1 ref] K/REFC,1 ->(end)
163 # - <@> lineseq KP ->13
164 # 1 <;> nextstate(main 64 optree_concise.t:193) v:{ ->2
165 # 12 <2> sassign sKS/2 ->13
166 # 10 <2> add[t1] sK/2 ->11
167 # - <1> ex-rv2sv sK/1 ->3
168 # 2 <$> gvsv(*b) s ->3
169 # 3 <$> const(IV 42) s ->10
170 # - <1> ex-rv2sv sKRM*/1 ->12
171 # 11 <$> gvsv(*a) s ->12
174 checkOptree ( name => "restore -base36 default",
175 bcopts => [qw/ -basic -base36 /],
179 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
180 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
182 1 <;> nextstate(main 27 optree_concise.t:161) v ->2
183 - <1> ex-rv2sv sK/1 ->-
186 # 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
187 # - <@> lineseq KP ->3
188 # 1 <;> nextstate(main 65 optree_concise.t:210) v ->2
189 # - <1> ex-rv2sv sK/1 ->-
190 # 2 <$> gvsv(*a) s ->3
193 checkOptree ( name => "terse basic",
194 bcopts => [qw/ -basic -terse /],
196 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
197 UNOP (0x82b0918) leavesub [1]
198 LISTOP (0x82b08d8) lineseq
199 COP (0x82b0880) nextstate
200 UNOP (0x82b0860) null [15]
201 PADOP (0x82b0840) gvsv GV (0x82a818c) *a
203 # UNOP (0x8282310) leavesub [1]
204 # LISTOP (0x82822f0) lineseq
205 # COP (0x82822b8) nextstate
206 # UNOP (0x812fc20) null [15]
207 # SVOP (0x812fc00) gvsv GV (0x814692c) *a
210 checkOptree ( name => "sticky-terse exec",
211 bcopts => [qw/ -exec /],
213 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
214 COP (0x82b0d70) nextstate
215 PADOP (0x82b0d30) gvsv GV (0x82a818c) *a
216 UNOP (0x82b0e08) leavesub [1]
218 # COP (0x82828e0) nextstate
219 # SVOP (0x82828a0) gvsv GV (0x814692c) *a
220 # UNOP (0x8282938) leavesub [1]
223 pass("OPTIONS IN CMDLINE MODE");
225 checkOptree ( name => 'cmdline invoke -basic works',
227 errs => [ 'Useless use of sort in void context at -e line 1.',
228 'Name "main::a" used only once: possible typo at -e line 1.',
230 #bcopts => '-basic', # default
232 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
233 # 7 <@> leave[1 ref] vKP/REFC ->(end)
235 # 2 <;> nextstate(main 1 -e:1) v:{ ->3
237 # 3 <0> pushmark s ->4
238 # 5 <1> rv2av[t2] lK/1 ->6
241 # 7 <@> leave[1 ref] vKP/REFC ->(end)
243 # 2 <;> nextstate(main 1 -e:1) v:{ ->3
245 # 3 <0> pushmark s ->4
246 # 5 <1> rv2av[t1] lK/1 ->6
250 checkOptree ( name => 'cmdline invoke -exec works',
252 errs => [ 'Useless use of sort in void context at -e line 1.',
253 'Name "main::a" used only once: possible typo at -e line 1.',
257 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
259 2 <;> nextstate(main 1 -e:1) v:{
264 7 <@> leave[1 ref] vKP/REFC
267 # 2 <;> nextstate(main 1 -e:1) v:{
270 # 5 <1> rv2av[t1] lK/1
272 # 7 <@> leave[1 ref] vKP/REFC
278 ( name => 'cmdline self-strict compile err using prog',
279 prog => 'use strict; sort @a',
280 bcopts => [qw/ -basic -concise -exec /],
281 errs => 'Global symbol "@a" requires explicit package name at -e line 1.',
282 expect => 'nextstate',
283 expect_nt => 'nextstate',
284 noanchors => 1, # allow simple expectations to work
288 ( name => 'cmdline self-strict compile err using code',
289 code => 'use strict; sort @a',
290 bcopts => [qw/ -basic -concise -exec /],
291 errs => 'Global symbol "@a" requires explicit package name at .*? line 1.',
292 note => 'this test relys on a kludge which copies $@ to rendering when empty',
293 expect => 'Global symbol',
294 expect_nt => 'Global symbol',
295 noanchors => 1, # allow simple expectations to work
299 ( name => 'cmdline -basic -concise -exec works',
300 prog => 'our @a; sort @a',
301 bcopts => [qw/ -basic -concise -exec /],
302 errs => ['Useless use of sort in void context at -e line 1.'],
304 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
306 # 2 <;> nextstate(main 1 -e:1) v:{
308 # 4 <1> rv2av[t3] vK/OURINTR,1
309 # 5 <;> nextstate(main 2 -e:1) v:{
312 # 8 <1> rv2av[t5] lK/1
314 # a <@> leave[1 ref] vKP/REFC
317 # 2 <;> nextstate(main 1 -e:1) v:{
319 # 4 <1> rv2av[t2] vK/OURINTR,1
320 # 5 <;> nextstate(main 2 -e:1) v:{
323 # 8 <1> rv2av[t3] lK/1
325 # a <@> leave[1 ref] vKP/REFC
329 #################################
330 pass("B::Concise STYLE/CALLBACK TESTS");
332 use B::Concise qw( walk_output add_style set_style_standard add_callback );
334 # new relative style, added by set_up_relative_test()
336 ( "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
337 . "#exname#arg(?([#targarglife])?)~#flags(?(/#privateb)?)(x(;~->#next)x) "
338 . "(x(;~=> #extra)x)\n" # new 'variable' used here
340 , " (*( )*) goto #seq\n"
341 , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
342 #. "(x(;~=> #extra)x)\n" # new 'variable' used here
345 sub set_up_relative_test {
346 # add a new style, and a callback which adds an 'extra' property
348 add_style ( "relative" => @stylespec );
349 #set_style_standard ( "relative" );
353 my ($h, $op, $format, $level, $style) = @_;
355 # callback marks up const ops
356 $h->{arg} .= ' CALLBACK' if $h->{name} eq 'const';
359 if ($lastnext and $$lastnext != $$op) {
360 $h->{goto} = ($h->{seq} eq '-')
361 ? 'unresolved' : $h->{seq};
364 # 2 style specific behaviors
365 if ($style eq 'relative') {
366 $h->{extra} = 'RELATIVE';
367 $h->{arg} .= ' RELATIVE' if $h->{name} eq 'leavesub';
369 elsif ($style eq 'scope') {
370 # supress printout entirely
371 $$format="" unless grep { $h->{name} eq $_ } @scopeops;
376 #################################
377 set_up_relative_test();
378 pass("set_up_relative_test, new callback installed");
380 checkOptree ( name => 'callback used, independent of style',
381 bcopts => [qw/ -concise -exec /],
382 code => sub{$a=$b+42},
384 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
385 1 <;> nextstate(main 76 optree_concise.t:337) v:{
387 3 <$> const[IV 42] CALLBACK s
391 7 <1> leavesub[1 ref] K/REFC,1
393 # 1 <;> nextstate(main 455 optree_concise.t:328) v:{
395 # 3 <$> const(IV 42) CALLBACK s
398 # 6 <2> sassign sKS/2
399 # 7 <1> leavesub[1 ref] K/REFC,1
402 checkOptree ( name => "new 'relative' style, -exec mode",
403 bcopts => [qw/ -basic -relative /],
404 code => sub{$a=$b+42},
407 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
408 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
409 - <@> lineseq KP ->7 => RELATIVE
410 1 <;> nextstate(main 49 optree_concise.t:309) v ->2 => RELATIVE
411 6 <2> sassign sKS ->7 => RELATIVE
412 4 <2> add[t3] sK ->5 => RELATIVE
413 - <1> ex-rv2sv sK ->3 => RELATIVE
414 2 <#> gvsv[*b] s ->3 => RELATIVE
415 3 <$> const[IV 42] CALLBACK s ->4 => RELATIVE
416 - <1> ex-rv2sv sKRM* ->6 => RELATIVE
417 5 <#> gvsv[*a] s ->6 => RELATIVE
419 # 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
420 # - <@> lineseq KP ->7 => RELATIVE
421 # 1 <;> nextstate(main 77 optree_concise.t:353) v ->2 => RELATIVE
422 # 6 <2> sassign sKS ->7 => RELATIVE
423 # 4 <2> add[t1] sK ->5 => RELATIVE
424 # - <1> ex-rv2sv sK ->3 => RELATIVE
425 # 2 <$> gvsv(*b) s ->3 => RELATIVE
426 # 3 <$> const(IV 42) CALLBACK s ->4 => RELATIVE
427 # - <1> ex-rv2sv sKRM* ->6 => RELATIVE
428 # 5 <$> gvsv(*a) s ->6 => RELATIVE
431 checkOptree ( name => "both -exec -relative",
432 bcopts => [qw/ -exec -relative /],
433 code => sub{$a=$b+42},
435 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
436 1 <;> nextstate(main 50 optree_concise.t:326) v
438 3 <$> const[IV 42] CALLBACK s
442 7 <1> leavesub RELATIVE[1 ref] K
444 # 1 <;> nextstate(main 78 optree_concise.t:371) v
446 # 3 <$> const(IV 42) CALLBACK s
450 # 7 <1> leavesub RELATIVE[1 ref] K
453 #################################
455 @scopeops = qw( leavesub enter leave nextstate );
457 ( 'scope' # concise copy
458 , "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
459 . "#exname#arg(?([#targarglife])?)~#flags(?(/#private)?)(x(;~->#next)x) "
460 , " (*( )*) goto #seq\n"
461 , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
464 checkOptree ( name => "both -exec -scope",
465 bcopts => [qw/ -exec -scope /],
466 code => sub{$a=$b+42},
467 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
468 1 <;> nextstate(main 50 optree_concise.t:337) v
469 7 <1> leavesub[1 ref] K/REFC,1
471 1 <;> nextstate(main 75 optree_concise.t:396) v
472 7 <1> leavesub[1 ref] K/REFC,1
476 checkOptree ( name => "both -basic -scope",
477 bcopts => [qw/ -basic -scope /],
478 code => sub{$a=$b+42},
479 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
480 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
481 1 <;> nextstate(main 51 optree_concise.t:347) v ->2
483 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
484 1 <;> nextstate(main 76 optree_concise.t:407) v ->2