6 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
7 print "1..0 # Skip -- Perl configured without B module\n";
10 if (!$Config::Config{useperlio}) {
11 print "1..0 # Skip -- need perlio to walk the optree\n";
16 # import checkOptree(), and %gOpts (containing test state)
17 use OptreeCheck; # ALSO DOES @ARGV HANDLING !!!!!!
22 $SIG{__WARN__} = sub {
24 $err =~ m/Subroutine re::(un)?install redefined/ and return;
26 #################################
27 pass("CANONICAL B::Concise EXAMPLE");
29 checkOptree ( name => 'canonical example w -basic',
31 code => sub{$a=$b+42},
32 strip_open_hints => 1,
33 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
34 # 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
35 # - <@> lineseq KP ->7
36 # 1 <;> nextstate(foo bar) v:>,<,%,{ ->2
37 # 6 <2> sassign sKS/2 ->7
38 # 4 <2> add[t3] sK/2 ->5
39 # - <1> ex-rv2sv sK/1 ->3
40 # 2 <#> gvsv[*b] s ->3
41 # 3 <$> const[IV 42] s ->4
42 # - <1> ex-rv2sv sKRM*/1 ->6
43 # 5 <#> gvsv[*a] s ->6
45 # 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
46 # - <@> lineseq KP ->7
47 # 1 <;> nextstate(main 60 optree_concise.t:122) v:>,<,%,{ ->2
48 # 6 <2> sassign sKS/2 ->7
49 # 4 <2> add[t1] sK/2 ->5
50 # - <1> ex-rv2sv sK/1 ->3
51 # 2 <$> gvsv(*b) s ->3
52 # 3 <$> const(IV 42) s ->4
53 # - <1> ex-rv2sv sKRM*/1 ->6
54 # 5 <$> gvsv(*a) s ->6
57 checkOptree ( name => 'canonical example w -exec',
59 code => sub{$a=$b+42},
60 strip_open_hints => 1,
61 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
62 # 1 <;> nextstate(main 61 optree_concise.t:139) v:>,<,%,{
64 # 3 <$> const[IV 42] s
68 # 7 <1> leavesub[1 ref] K/REFC,1
70 # 1 <;> nextstate(main 61 optree_concise.t:139) v:>,<,%,{
72 # 3 <$> const(IV 42) s
76 # 7 <1> leavesub[1 ref] K/REFC,1
79 #################################
80 pass("B::Concise OPTION TESTS");
82 checkOptree ( name => '-base3 sticky-exec',
84 code => sub{$a=$b+42},
85 strip_open_hints => 1,
86 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
87 1 <;> dbstate(main 24 optree_concise.t:132) v:>,<,%,{
93 21 <1> leavesub[1 ref] K/REFC,1
95 # 1 <;> nextstate(main 62 optree_concise.t:161) v:>,<,%,{
97 # 10 <$> const(IV 42) s
100 # 20 <2> sassign sKS/2
101 # 21 <1> leavesub[1 ref] K/REFC,1
104 checkOptree ( name => 'sticky-base3, -basic over sticky-exec',
106 code => sub{$a=$b+42},
107 strip_open_hints => 1,
108 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
109 21 <1> leavesub[1 ref] K/REFC,1 ->(end)
110 - <@> lineseq KP ->21
111 1 <;> nextstate(main 32 optree_concise.t:164) v:>,<,%,{ ->2
112 20 <2> sassign sKS/2 ->21
113 11 <2> add[t3] sK/2 ->12
114 - <1> ex-rv2sv sK/1 ->10
115 2 <#> gvsv[*b] s ->10
116 10 <$> const[IV 42] s ->11
117 - <1> ex-rv2sv sKRM*/1 ->20
118 12 <#> gvsv[*a] s ->20
120 # 21 <1> leavesub[1 ref] K/REFC,1 ->(end)
121 # - <@> lineseq KP ->21
122 # 1 <;> nextstate(main 63 optree_concise.t:186) v:>,<,%,{ ->2
123 # 20 <2> sassign sKS/2 ->21
124 # 11 <2> add[t1] sK/2 ->12
125 # - <1> ex-rv2sv sK/1 ->10
126 # 2 <$> gvsv(*b) s ->10
127 # 10 <$> const(IV 42) s ->11
128 # - <1> ex-rv2sv sKRM*/1 ->20
129 # 12 <$> gvsv(*a) s ->20
132 checkOptree ( name => '-base4',
133 bcopts => [qw/ -basic -base4 /],
134 code => sub{$a=$b+42},
135 strip_open_hints => 1,
136 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
137 13 <1> leavesub[1 ref] K/REFC,1 ->(end)
138 - <@> lineseq KP ->13
139 1 <;> nextstate(main 26 optree_concise.t:145) v:>,<,%,{ ->2
140 12 <2> sassign sKS/2 ->13
141 10 <2> add[t3] sK/2 ->11
142 - <1> ex-rv2sv sK/1 ->3
144 3 <$> const[IV 42] s ->10
145 - <1> ex-rv2sv sKRM*/1 ->12
146 11 <#> gvsv[*a] s ->12
148 # 13 <1> leavesub[1 ref] K/REFC,1 ->(end)
149 # - <@> lineseq KP ->13
150 # 1 <;> nextstate(main 64 optree_concise.t:193) v:>,<,%,{ ->2
151 # 12 <2> sassign sKS/2 ->13
152 # 10 <2> add[t1] sK/2 ->11
153 # - <1> ex-rv2sv sK/1 ->3
154 # 2 <$> gvsv(*b) s ->3
155 # 3 <$> const(IV 42) s ->10
156 # - <1> ex-rv2sv sKRM*/1 ->12
157 # 11 <$> gvsv(*a) s ->12
160 checkOptree ( name => "restore -base36 default",
161 bcopts => [qw/ -basic -base36 /],
164 strip_open_hints => 1,
165 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
166 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
168 1 <;> nextstate(main 27 optree_concise.t:161) v:>,<,% ->2
169 - <1> ex-rv2sv sK/1 ->-
172 # 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
173 # - <@> lineseq KP ->3
174 # 1 <;> nextstate(main 65 optree_concise.t:210) v:>,<,% ->2
175 # - <1> ex-rv2sv sK/1 ->-
176 # 2 <$> gvsv(*a) s ->3
179 checkOptree ( name => "terse basic",
180 bcopts => [qw/ -basic -terse /],
182 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
183 UNOP (0x82b0918) leavesub [1]
184 LISTOP (0x82b08d8) lineseq
185 COP (0x82b0880) nextstate
186 UNOP (0x82b0860) null [15]
187 PADOP (0x82b0840) gvsv GV (0x82a818c) *a
189 # UNOP (0x8282310) leavesub [1]
190 # LISTOP (0x82822f0) lineseq
191 # COP (0x82822b8) nextstate
192 # UNOP (0x812fc20) null [15]
193 # SVOP (0x812fc00) gvsv GV (0x814692c) *a
196 checkOptree ( name => "sticky-terse exec",
197 bcopts => [qw/ -exec /],
199 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
200 COP (0x82b0d70) nextstate
201 PADOP (0x82b0d30) gvsv GV (0x82a818c) *a
202 UNOP (0x82b0e08) leavesub [1]
204 # COP (0x82828e0) nextstate
205 # SVOP (0x82828a0) gvsv GV (0x814692c) *a
206 # UNOP (0x8282938) leavesub [1]
209 pass("OPTIONS IN CMDLINE MODE");
211 checkOptree ( name => 'cmdline invoke -basic works',
213 errs => [ 'Useless use of sort in void context at -e line 1.',
214 'Name "main::a" used only once: possible typo at -e line 1.',
216 #bcopts => '-basic', # default
217 strip_open_hints => 1,
218 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
219 # 7 <@> leave[1 ref] vKP/REFC ->(end)
221 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3
223 # 3 <0> pushmark s ->4
224 # 5 <1> rv2av[t2] lK/1 ->6
227 # 7 <@> leave[1 ref] vKP/REFC ->(end)
229 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3
231 # 3 <0> pushmark s ->4
232 # 5 <1> rv2av[t1] lK/1 ->6
236 checkOptree ( name => 'cmdline invoke -exec works',
238 errs => [ 'Useless use of sort in void context at -e line 1.',
239 'Name "main::a" used only once: possible typo at -e line 1.',
242 strip_open_hints => 1,
243 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
245 2 <;> nextstate(main 1 -e:1) v:>,<,%,{
250 7 <@> leave[1 ref] vKP/REFC
253 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{
256 # 5 <1> rv2av[t1] lK/1
258 # 7 <@> leave[1 ref] vKP/REFC
264 ( name => 'cmdline self-strict compile err using prog',
265 prog => 'use strict; sort @a',
266 bcopts => [qw/ -basic -concise -exec /],
267 errs => 'Global symbol "@a" requires explicit package name at -e line 1.',
268 expect => 'nextstate',
269 expect_nt => 'nextstate',
270 noanchors => 1, # allow simple expectations to work
274 ( name => 'cmdline self-strict compile err using code',
275 code => 'use strict; sort @a',
276 bcopts => [qw/ -basic -concise -exec /],
277 errs => qr/Global symbol "\@a" requires explicit package name at .*? line 1\./,
278 note => 'this test relys on a kludge which copies $@ to rendering when empty',
279 expect => 'Global symbol',
280 expect_nt => 'Global symbol',
281 noanchors => 1, # allow simple expectations to work
285 ( name => 'cmdline -basic -concise -exec works',
286 prog => 'our @a; sort @a',
287 bcopts => [qw/ -basic -concise -exec /],
288 errs => ['Useless use of sort in void context at -e line 1.'],
289 strip_open_hints => 1,
290 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
292 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{
294 # 4 <1> rv2av[t3] vK/OURINTR,1
295 # 5 <;> nextstate(main 2 -e:1) v:>,<,%,{
298 # 8 <1> rv2av[t5] lK/1
300 # a <@> leave[1 ref] vKP/REFC
303 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{
305 # 4 <1> rv2av[t2] vK/OURINTR,1
306 # 5 <;> nextstate(main 2 -e:1) v:>,<,%,{
309 # 8 <1> rv2av[t3] lK/1
311 # a <@> leave[1 ref] vKP/REFC
315 #################################
316 pass("B::Concise STYLE/CALLBACK TESTS");
318 use B::Concise qw( walk_output add_style set_style_standard add_callback );
320 # new relative style, added by set_up_relative_test()
322 ( "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
323 . "#exname#arg(?([#targarglife])?)~#flags(?(/#privateb)?)(x(;~->#next)x) "
324 . "(x(;~=> #extra)x)\n" # new 'variable' used here
326 , " (*( )*) goto #seq\n"
327 , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
328 #. "(x(;~=> #extra)x)\n" # new 'variable' used here
331 sub set_up_relative_test {
332 # add a new style, and a callback which adds an 'extra' property
334 add_style ( "relative" => @stylespec );
335 #set_style_standard ( "relative" );
339 my ($h, $op, $format, $level, $style) = @_;
341 # callback marks up const ops
342 $h->{arg} .= ' CALLBACK' if $h->{name} eq 'const';
345 if ($lastnext and $$lastnext != $$op) {
346 $h->{goto} = ($h->{seq} eq '-')
347 ? 'unresolved' : $h->{seq};
350 # 2 style specific behaviors
351 if ($style eq 'relative') {
352 $h->{extra} = 'RELATIVE';
353 $h->{arg} .= ' RELATIVE' if $h->{name} eq 'leavesub';
355 elsif ($style eq 'scope') {
356 # suppress printout entirely
357 $$format="" unless grep { $h->{name} eq $_ } @scopeops;
362 #################################
363 set_up_relative_test();
364 pass("set_up_relative_test, new callback installed");
366 checkOptree ( name => 'callback used, independent of style',
367 bcopts => [qw/ -concise -exec /],
368 code => sub{$a=$b+42},
369 strip_open_hints => 1,
370 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
371 1 <;> nextstate(main 76 optree_concise.t:337) v:>,<,%,{
373 3 <$> const[IV 42] CALLBACK s
377 7 <1> leavesub[1 ref] K/REFC,1
379 # 1 <;> nextstate(main 455 optree_concise.t:328) v:>,<,%,{
381 # 3 <$> const(IV 42) CALLBACK s
384 # 6 <2> sassign sKS/2
385 # 7 <1> leavesub[1 ref] K/REFC,1
388 checkOptree ( name => "new 'relative' style, -exec mode",
389 bcopts => [qw/ -basic -relative /],
390 code => sub{$a=$b+42},
393 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
394 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
395 - <@> lineseq KP ->7 => RELATIVE
396 1 <;> nextstate(main 49 optree_concise.t:309) v ->2 => RELATIVE
397 6 <2> sassign sKS ->7 => RELATIVE
398 4 <2> add[t3] sK ->5 => RELATIVE
399 - <1> ex-rv2sv sK ->3 => RELATIVE
400 2 <#> gvsv[*b] s ->3 => RELATIVE
401 3 <$> const[IV 42] CALLBACK s ->4 => RELATIVE
402 - <1> ex-rv2sv sKRM* ->6 => RELATIVE
403 5 <#> gvsv[*a] s ->6 => RELATIVE
405 # 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
406 # - <@> lineseq KP ->7 => RELATIVE
407 # 1 <;> nextstate(main 77 optree_concise.t:353) v ->2 => RELATIVE
408 # 6 <2> sassign sKS ->7 => RELATIVE
409 # 4 <2> add[t1] sK ->5 => RELATIVE
410 # - <1> ex-rv2sv sK ->3 => RELATIVE
411 # 2 <$> gvsv(*b) s ->3 => RELATIVE
412 # 3 <$> const(IV 42) CALLBACK s ->4 => RELATIVE
413 # - <1> ex-rv2sv sKRM* ->6 => RELATIVE
414 # 5 <$> gvsv(*a) s ->6 => RELATIVE
417 checkOptree ( name => "both -exec -relative",
418 bcopts => [qw/ -exec -relative /],
419 code => sub{$a=$b+42},
421 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
422 1 <;> nextstate(main 50 optree_concise.t:326) v
424 3 <$> const[IV 42] CALLBACK s
428 7 <1> leavesub RELATIVE[1 ref] K
430 # 1 <;> nextstate(main 78 optree_concise.t:371) v
432 # 3 <$> const(IV 42) CALLBACK s
436 # 7 <1> leavesub RELATIVE[1 ref] K
439 #################################
441 @scopeops = qw( leavesub enter leave nextstate );
443 ( 'scope' # concise copy
444 , "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
445 . "#exname#arg(?([#targarglife])?)~#flags(?(/#private)?)(x(;~->#next)x) "
446 , " (*( )*) goto #seq\n"
447 , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
450 checkOptree ( name => "both -exec -scope",
451 bcopts => [qw/ -exec -scope /],
452 code => sub{$a=$b+42},
453 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
454 1 <;> nextstate(main 50 optree_concise.t:337) v
455 7 <1> leavesub[1 ref] K/REFC,1
457 1 <;> nextstate(main 75 optree_concise.t:396) v
458 7 <1> leavesub[1 ref] K/REFC,1
462 checkOptree ( name => "both -basic -scope",
463 bcopts => [qw/ -basic -scope /],
464 code => sub{$a=$b+42},
465 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
466 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
467 1 <;> nextstate(main 51 optree_concise.t:347) v ->2
469 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
470 1 <;> nextstate(main 76 optree_concise.t:407) v ->2