1256a93a4Safresh1use 5.008001; 2256a93a4Safresh1 3256a93a4Safresh1use strict; 4256a93a4Safresh1use warnings; 5*f2a19305Safresh1use Test::More; 6b39c5158Smillertuse Text::Balanced qw ( :ALL ); 7b39c5158Smillert 8*f2a19305Safresh1our $DEBUG; 9*f2a19305Safresh1sub debug { print "\t>>>",@_ if $DEBUG } 10b39c5158Smillert 11b39c5158Smillertsub expect 12b39c5158Smillert{ 13b39c5158Smillert my ($l1, $l2) = @_; 14*f2a19305Safresh1 is_deeply $l1, $l2 or do { 15*f2a19305Safresh1 diag 'got:', explain $l1; 16*f2a19305Safresh1 diag 'expected:', explain $l2; 17*f2a19305Safresh1 }; 18b39c5158Smillert} 19b39c5158Smillert 20b39c5158Smillertsub divide 21b39c5158Smillert{ 22b39c5158Smillert my ($text, @index) = @_; 23b39c5158Smillert my @bits = (); 24b39c5158Smillert unshift @index, 0; 25b39c5158Smillert push @index, length($text); 26b39c5158Smillert for ( my $i= 0; $i < $#index; $i++) 27b39c5158Smillert { 28b39c5158Smillert push @bits, substr($text, $index[$i], $index[$i+1]-$index[$i]); 29b39c5158Smillert } 30b39c5158Smillert pop @bits; 31b39c5158Smillert return @bits; 32b39c5158Smillert 33b39c5158Smillert} 34b39c5158Smillert 35256a93a4Safresh1my $stdtext1 = q{$var = do {"val" && $val;};}; 36b39c5158Smillert 37256a93a4Safresh1my $text = $stdtext1; 38b39c5158Smillertexpect [ extract_multiple($text,undef,1) ], 39b39c5158Smillert [ divide $stdtext1 => 4 ]; 40b39c5158Smillert 41b39c5158Smillertexpect [ pos $text], [ 4 ]; 42b39c5158Smillertexpect [ $text ], [ $stdtext1 ]; 43b39c5158Smillert 44b39c5158Smillert$text = $stdtext1; 45b39c5158Smillertexpect [ scalar extract_multiple($text,undef,1) ], 46b39c5158Smillert [ divide $stdtext1 => 4 ]; 47b39c5158Smillert 48b39c5158Smillertexpect [ pos $text], [ 0 ]; 49b39c5158Smillertexpect [ $text ], [ substr($stdtext1,4) ]; 50b39c5158Smillert 51b39c5158Smillert 52b39c5158Smillert$text = $stdtext1; 53b39c5158Smillertexpect [ extract_multiple($text,undef,2) ], 54b39c5158Smillert [ divide($stdtext1 => 4, 10) ]; 55b39c5158Smillert 56b39c5158Smillertexpect [ pos $text], [ 10 ]; 57b39c5158Smillertexpect [ $text ], [ $stdtext1 ]; 58b39c5158Smillert 59b39c5158Smillert$text = $stdtext1; 60b39c5158Smillertexpect [ eval{local$^W;scalar extract_multiple($text,undef,2)} ], 61b39c5158Smillert [ substr($stdtext1,0,4) ]; 62b39c5158Smillert 63b39c5158Smillertexpect [ pos $text], [ 0 ]; 64b39c5158Smillertexpect [ $text ], [ substr($stdtext1,4) ]; 65b39c5158Smillert 66b39c5158Smillert 67b39c5158Smillert$text = $stdtext1; 68b39c5158Smillertexpect [ extract_multiple($text,undef,3) ], 69b39c5158Smillert [ divide($stdtext1 => 4, 10, 26) ]; 70b39c5158Smillert 71b39c5158Smillertexpect [ pos $text], [ 26 ]; 72b39c5158Smillertexpect [ $text ], [ $stdtext1 ]; 73b39c5158Smillert 74b39c5158Smillert$text = $stdtext1; 75b39c5158Smillertexpect [ eval{local$^W;scalar extract_multiple($text,undef,3)} ], 76b39c5158Smillert [ substr($stdtext1,0,4) ]; 77b39c5158Smillert 78b39c5158Smillertexpect [ pos $text], [ 0 ]; 79b39c5158Smillertexpect [ $text ], [ substr($stdtext1,4) ]; 80b39c5158Smillert 81b39c5158Smillert 82b39c5158Smillert$text = $stdtext1; 83b39c5158Smillertexpect [ extract_multiple($text,undef,4) ], 84b39c5158Smillert [ divide($stdtext1 => 4, 10, 26, 27) ]; 85b39c5158Smillert 86b39c5158Smillertexpect [ pos $text], [ 27 ]; 87b39c5158Smillertexpect [ $text ], [ $stdtext1 ]; 88b39c5158Smillert 89b39c5158Smillert$text = $stdtext1; 90b39c5158Smillertexpect [ eval{local$^W;scalar extract_multiple($text,undef,4)} ], 91b39c5158Smillert [ substr($stdtext1,0,4) ]; 92b39c5158Smillert 93b39c5158Smillertexpect [ pos $text], [ 0 ]; 94b39c5158Smillertexpect [ $text ], [ substr($stdtext1,4) ]; 95b39c5158Smillert 96b39c5158Smillert 97b39c5158Smillert$text = $stdtext1; 98b39c5158Smillertexpect [ extract_multiple($text,undef,5) ], 99b39c5158Smillert [ divide($stdtext1 => 4, 10, 26, 27) ]; 100b39c5158Smillert 101b39c5158Smillertexpect [ pos $text], [ 27 ]; 102b39c5158Smillertexpect [ $text ], [ $stdtext1 ]; 103b39c5158Smillert 104b39c5158Smillert 105b39c5158Smillert$text = $stdtext1; 106b39c5158Smillertexpect [ eval{local$^W;scalar extract_multiple($text,undef,5)} ], 107b39c5158Smillert [ substr($stdtext1,0,4) ]; 108b39c5158Smillert 109b39c5158Smillertexpect [ pos $text], [ 0 ]; 110b39c5158Smillertexpect [ $text ], [ substr($stdtext1,4) ]; 111b39c5158Smillert 112b39c5158Smillert 113b39c5158Smillert 114256a93a4Safresh1my $stdtext2 = q{$var = "val" && (1,2,3);}; 115b39c5158Smillert 116b39c5158Smillert$text = $stdtext2; 117b39c5158Smillertexpect [ extract_multiple($text) ], 118b39c5158Smillert [ divide($stdtext2 => 4, 7, 12, 24) ]; 119b39c5158Smillert 120b39c5158Smillertexpect [ pos $text], [ 24 ]; 121b39c5158Smillertexpect [ $text ], [ $stdtext2 ]; 122b39c5158Smillert 123b39c5158Smillert$text = $stdtext2; 124b39c5158Smillertexpect [ scalar extract_multiple($text) ], 125b39c5158Smillert [ substr($stdtext2,0,4) ]; 126b39c5158Smillert 127b39c5158Smillertexpect [ pos $text], [ 0 ]; 128b39c5158Smillertexpect [ $text ], [ substr($stdtext2,4) ]; 129b39c5158Smillert 130b39c5158Smillert 131b39c5158Smillert$text = $stdtext2; 132b39c5158Smillertexpect [ extract_multiple($text,[\&extract_bracketed]) ], 133b39c5158Smillert [ substr($stdtext2,0,16), substr($stdtext2,16,7), substr($stdtext2,23) ]; 134b39c5158Smillert 135b39c5158Smillertexpect [ pos $text], [ 24 ]; 136b39c5158Smillertexpect [ $text ], [ $stdtext2 ]; 137b39c5158Smillert 138b39c5158Smillert$text = $stdtext2; 139b39c5158Smillertexpect [ scalar extract_multiple($text,[\&extract_bracketed]) ], 140b39c5158Smillert [ substr($stdtext2,0,16) ]; 141b39c5158Smillert 142b39c5158Smillertexpect [ pos $text], [ 0 ]; 143b39c5158Smillertexpect [ $text ], [ substr($stdtext2,15) ]; 144b39c5158Smillert 145b39c5158Smillert 146b39c5158Smillert$text = $stdtext2; 147b39c5158Smillertexpect [ extract_multiple($text,[\&extract_variable]) ], 148b39c5158Smillert [ substr($stdtext2,0,4), substr($stdtext2,4) ]; 149b39c5158Smillert 150b39c5158Smillertexpect [ pos $text], [ length($text) ]; 151b39c5158Smillertexpect [ $text ], [ $stdtext2 ]; 152b39c5158Smillert 153b39c5158Smillert$text = $stdtext2; 154b39c5158Smillertexpect [ scalar extract_multiple($text,[\&extract_variable]) ], 155b39c5158Smillert [ substr($stdtext2,0,4) ]; 156b39c5158Smillert 157b39c5158Smillertexpect [ pos $text], [ 0 ]; 158b39c5158Smillertexpect [ $text ], [ substr($stdtext2,4) ]; 159b39c5158Smillert 160b39c5158Smillert 161b39c5158Smillert$text = $stdtext2; 162b39c5158Smillertexpect [ extract_multiple($text,[\&extract_quotelike]) ], 163b39c5158Smillert [ substr($stdtext2,0,7), substr($stdtext2,7,5), substr($stdtext2,12) ]; 164b39c5158Smillert 165b39c5158Smillertexpect [ pos $text], [ length($text) ]; 166b39c5158Smillertexpect [ $text ], [ $stdtext2 ]; 167b39c5158Smillert 168b39c5158Smillert$text = $stdtext2; 169b39c5158Smillertexpect [ scalar extract_multiple($text,[\&extract_quotelike]) ], 170b39c5158Smillert [ substr($stdtext2,0,7) ]; 171b39c5158Smillert 172b39c5158Smillertexpect [ pos $text], [ 0 ]; 173b39c5158Smillertexpect [ $text ], [ substr($stdtext2,6) ]; 174b39c5158Smillert 175b39c5158Smillert 176b39c5158Smillert$text = $stdtext2; 177b39c5158Smillertexpect [ extract_multiple($text,[\&extract_quotelike],2,1) ], 178b39c5158Smillert [ substr($stdtext2,7,5) ]; 179b39c5158Smillert 180b39c5158Smillertexpect [ pos $text], [ 23 ]; 181b39c5158Smillertexpect [ $text ], [ $stdtext2 ]; 182b39c5158Smillert 183b39c5158Smillert$text = $stdtext2; 184b39c5158Smillertexpect [ eval{local$^W;scalar extract_multiple($text,[\&extract_quotelike],2,1)} ], 185b39c5158Smillert [ substr($stdtext2,7,5) ]; 186b39c5158Smillert 187b39c5158Smillertexpect [ pos $text], [ 6 ]; 188b39c5158Smillertexpect [ $text ], [ substr($stdtext2,0,6). substr($stdtext2,12) ]; 189b39c5158Smillert 190b39c5158Smillert 191b39c5158Smillert$text = $stdtext2; 192b39c5158Smillertexpect [ extract_multiple($text,[\&extract_quotelike],1,1) ], 193b39c5158Smillert [ substr($stdtext2,7,5) ]; 194b39c5158Smillert 195b39c5158Smillertexpect [ pos $text], [ 12 ]; 196b39c5158Smillertexpect [ $text ], [ $stdtext2 ]; 197b39c5158Smillert 198b39c5158Smillert$text = $stdtext2; 199b39c5158Smillertexpect [ scalar extract_multiple($text,[\&extract_quotelike],1,1) ], 200b39c5158Smillert [ substr($stdtext2,7,5) ]; 201b39c5158Smillert 202b39c5158Smillertexpect [ pos $text], [ 6 ]; 203b39c5158Smillertexpect [ $text ], [ substr($stdtext2,0,6). substr($stdtext2,12) ]; 204b39c5158Smillert 205b39c5158Smillertmy $stdtext3 = "a,b,c"; 206b39c5158Smillert 207b39c5158Smillert$_ = $stdtext3; 208b39c5158Smillertexpect [ extract_multiple(undef, [ sub { /\G[a-z]/gc && $& } ]) ], 209b39c5158Smillert [ divide($stdtext3 => 1,2,3,4,5) ]; 210b39c5158Smillert 211b39c5158Smillertexpect [ pos ], [ 5 ]; 212b39c5158Smillertexpect [ $_ ], [ $stdtext3 ]; 213b39c5158Smillert 214b39c5158Smillert$_ = $stdtext3; 215b39c5158Smillertexpect [ scalar extract_multiple(undef, [ sub { /\G[a-z]/gc && $& } ]) ], 216b39c5158Smillert [ divide($stdtext3 => 1) ]; 217b39c5158Smillert 218b39c5158Smillertexpect [ pos ], [ 0 ]; 219b39c5158Smillertexpect [ $_ ], [ substr($stdtext3,1) ]; 220b39c5158Smillert 221b39c5158Smillert$_ = $stdtext3; 222b39c5158Smillertexpect [ extract_multiple(undef, [ qr/\G[a-z]/ ]) ], 223b39c5158Smillert [ divide($stdtext3 => 1,2,3,4,5) ]; 224b39c5158Smillert 225b39c5158Smillertexpect [ pos ], [ 5 ]; 226b39c5158Smillertexpect [ $_ ], [ $stdtext3 ]; 227b39c5158Smillert 228b39c5158Smillert$_ = $stdtext3; 229b39c5158Smillertexpect [ scalar extract_multiple(undef, [ qr/\G[a-z]/ ]) ], 230b39c5158Smillert [ divide($stdtext3 => 1) ]; 231b39c5158Smillert 232b39c5158Smillertexpect [ pos ], [ 0 ]; 233b39c5158Smillertexpect [ $_ ], [ substr($stdtext3,1) ]; 234b39c5158Smillert 235b39c5158Smillert$_ = $stdtext3; 236b39c5158Smillertexpect [ extract_multiple(undef, [ q/([a-z]),?/ ]) ], 237b39c5158Smillert [ qw(a b c) ]; 238b39c5158Smillert 239b39c5158Smillertexpect [ pos ], [ 5 ]; 240b39c5158Smillertexpect [ $_ ], [ $stdtext3 ]; 241b39c5158Smillert 242b39c5158Smillert$_ = $stdtext3; 243b39c5158Smillertexpect [ scalar extract_multiple(undef, [ q/([a-z]),?/ ]) ], 244b39c5158Smillert [ divide($stdtext3 => 1) ]; 245b39c5158Smillert 246b39c5158Smillertexpect [ pos ], [ 0 ]; 247b39c5158Smillertexpect [ $_ ], [ substr($stdtext3,2) ]; 248b39c5158Smillert 249b39c5158Smillert# Fails in Text-Balanced-1.95 with result ['1 ', '""', '1234'] 250b39c5158Smillert$_ = q{ ""1234}; 251b39c5158Smillertexpect [ extract_multiple(undef, [\&extract_quotelike]) ], 252b39c5158Smillert [ ' ', '""', '1234' ]; 253*f2a19305Safresh1 254*f2a19305Safresh1my $not_here_doc = "sub f {\n my \$pa <<= 2;\n}\n\n"; # wrong in 2.04 255*f2a19305Safresh1expect [ extract_multiple($not_here_doc, [ 256*f2a19305Safresh1 { DONT_MATCH => \&extract_quotelike } 257*f2a19305Safresh1]) ], 258*f2a19305Safresh1 [ "sub f {\n my \$pa <<= 2;\n}\n\n" ]; 259*f2a19305Safresh1 260*f2a19305Safresh1my $y_falsematch = <<'EOF'; # wrong in 2.04 261*f2a19305Safresh1my $p = {y => 1}; 262*f2a19305Safresh1{ $pa=ones(3,3,3); my $f = do { my $i=1; my $v=$$p{y}-$i; $pb = $pa(,$i,) }; } 263*f2a19305Safresh1EOF 264*f2a19305Safresh1expect [ extract_multiple($y_falsematch, [ 265*f2a19305Safresh1 \&extract_variable, 266*f2a19305Safresh1 { DONT_MATCH => \&extract_quotelike } 267*f2a19305Safresh1]) ], 268*f2a19305Safresh1 [ 'my ', '$p', " = {y => 1};\n{ ", '$pa', '=ones(3,3,3); my ', '$f', 269*f2a19305Safresh1 ' = do { my ', '$i', '=1; my ', '$v', qw(= $$p{y} - $i), '; ', '$pb', 270*f2a19305Safresh1 ' = ', '$pa', '(,', '$i', ",) }; }\n", 271*f2a19305Safresh1 ]; 272*f2a19305Safresh1 273*f2a19305Safresh1my $slashmatch = <<'EOF'; # wrong in 2.04 274*f2a19305Safresh1my $var = 10 / 3; if ($var !~ /\./) { decimal() ;} 275*f2a19305Safresh1EOF 276*f2a19305Safresh1my @expect_slash = ('my ', '$var', ' = 10 / 3; if (', '$var', " !~ ", 277*f2a19305Safresh1 '/\\./', ") { decimal() ;}\n" 278*f2a19305Safresh1); 279*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 280*f2a19305Safresh1 \&extract_variable, 281*f2a19305Safresh1 \&extract_quotelike, 282*f2a19305Safresh1]) ], 283*f2a19305Safresh1 \@expect_slash; 284*f2a19305Safresh1 285*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.04 286*f2a19305Safresh1my $var = 10 / 3; if ($var =~ /\./) { decimal() ;} 287*f2a19305Safresh1EOF 288*f2a19305Safresh1$expect_slash[4] = " =~ "; 289*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 290*f2a19305Safresh1 \&extract_variable, 291*f2a19305Safresh1 \&extract_quotelike, 292*f2a19305Safresh1]) ], 293*f2a19305Safresh1 \@expect_slash; 294*f2a19305Safresh1 295*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.04 296*f2a19305Safresh1my $var = 10 / 3; if ($var =~ 297*f2a19305Safresh1 # a comment 298*f2a19305Safresh1 /\./) { decimal() ;} 299*f2a19305Safresh1EOF 300*f2a19305Safresh1my $comment = qr/(?<![\$\@%])#.*/; 301*f2a19305Safresh1my $id = qr/\b(?!([ysm]|q[rqxw]?|tr)\b)\w+/; 302*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 303*f2a19305Safresh1 $comment, 304*f2a19305Safresh1 \&extract_variable, 305*f2a19305Safresh1 $id, 306*f2a19305Safresh1 \&extract_quotelike, 307*f2a19305Safresh1]) ], 308*f2a19305Safresh1 [ 'my', ' ', '$var', ' = ', '10', ' / ', '3', '; ', 'if', ' (', '$var', 309*f2a19305Safresh1 " =~\n ", '# a comment', "\n ", '/\\./', ') { ', 'decimal', "() ;}\n" 310*f2a19305Safresh1 ]; 311*f2a19305Safresh1 312*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.04_01 313*f2a19305Safresh1my $r=(1-$PCi)/1+czip(1, -1)/czip(1, 1); 314*f2a19305Safresh1EOF 315*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 316*f2a19305Safresh1 \&extract_variable, $id, \&extract_quotelike, 317*f2a19305Safresh1]) ], 318*f2a19305Safresh1 [ 319*f2a19305Safresh1 'my', ' ', '$r', '=(', '1', '-', '$PCi', ')/', '1', '+', 320*f2a19305Safresh1 'czip', '(', '1', ', -', '1', ')/', 321*f2a19305Safresh1 'czip', '(', '1', ', ', '1', ");\n" 322*f2a19305Safresh1 ]; 323*f2a19305Safresh1 324*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.04_01 325*f2a19305Safresh1$ndim--; $min = $mdim <= $ndim ? 1 : 0; $min = $mdim < $ndim ? 1 : 0; 326*f2a19305Safresh1EOF 327*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 328*f2a19305Safresh1 \&extract_variable, $id, \&extract_quotelike, 329*f2a19305Safresh1]) ], 330*f2a19305Safresh1 [ 331*f2a19305Safresh1 '$ndim', '--; ', 332*f2a19305Safresh1 '$min', ' = ', '$mdim', ' <= ', '$ndim', ' ? ', '1', ' : ', '0', '; ', 333*f2a19305Safresh1 '$min', ' = ', '$mdim', ' < ', '$ndim', ' ? ', '1', ' : ', '0', ";\n" 334*f2a19305Safresh1 ]; 335*f2a19305Safresh1 336*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.04_01 337*f2a19305Safresh1$x->t->(($a))->sever; 338*f2a19305Safresh1wantarray ? 1 : 0; $min = $var ? 0; 339*f2a19305Safresh1EOF 340*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 341*f2a19305Safresh1 \&extract_variable, $id, \&extract_quotelike, 342*f2a19305Safresh1]) ], 343*f2a19305Safresh1 [ 344*f2a19305Safresh1 '$x->t->(($a))->sever', ";\n", 345*f2a19305Safresh1 'wantarray', ' ? ', '1', ' : ', '0', '; ', 346*f2a19305Safresh1 '$min', ' = ', '$var', ' ? ', '0', ";\n", 347*f2a19305Safresh1 ]; 348*f2a19305Safresh1 349*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.04_01 350*f2a19305Safresh1$var //= 'default'; $x = 1 / 2; 351*f2a19305Safresh1EOF 352*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 353*f2a19305Safresh1 \&extract_variable, \&extract_quotelike, 354*f2a19305Safresh1]) ], 355*f2a19305Safresh1 [ 356*f2a19305Safresh1 '$var', ' //= ', '\'default\'', '; ', '$x', " = 1 / 2;\n" 357*f2a19305Safresh1 ]; 358*f2a19305Safresh1 359*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.04_01 360*f2a19305Safresh1$m; return wantarray ? ($m, $i) : $var ? $m : 0; 361*f2a19305Safresh1EOF 362*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 363*f2a19305Safresh1 \&extract_variable, \&extract_quotelike, 364*f2a19305Safresh1]) ], 365*f2a19305Safresh1 [ 366*f2a19305Safresh1 '$m', 367*f2a19305Safresh1 '; return wantarray ? (', '$m', ', ', '$i', ') : ', '$var', ' ? ', '$m', 368*f2a19305Safresh1 " : 0;\n" 369*f2a19305Safresh1 ]; 370*f2a19305Safresh1 371*f2a19305Safresh1$slashmatch = <<'EOF'; # wrong in 2.05 372*f2a19305Safresh1$_ = 1 unless defined $_ and /\d\b/; 373*f2a19305Safresh1EOF 374*f2a19305Safresh1expect [ extract_multiple($slashmatch, [ 375*f2a19305Safresh1 \&extract_variable, \&extract_quotelike, 376*f2a19305Safresh1]) ], 377*f2a19305Safresh1 [ '$_', ' = 1 unless defined ', '$_', ' and ', '/\\d\\b/', ";\n" ]; 378*f2a19305Safresh1 379*f2a19305Safresh1done_testing; 380