1################################################################################ 2## 3## Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz. 4## Version 2.x, Copyright (C) 2001, Paul Marquess. 5## Version 1.x, Copyright (C) 1999, Kenneth Albanowski. 6## 7## This program is free software; you can redistribute it and/or 8## modify it under the same terms as Perl itself. 9## 10################################################################################ 11 12=tests plan => 238 13 14BEGIN { 15 if ($ENV{'SKIP_SLOW_TESTS'}) { 16 for (1 .. 238) { 17 skip("skip: SKIP_SLOW_TESTS", 0); 18 } 19 exit 0; 20 } 21} 22 23use File::Path qw/rmtree mkpath/; 24use Config; 25 26my $tmp = 'ppptmp'; 27my $inc = ''; 28my $isVMS = $^O eq 'VMS'; 29my $isMAC = $^O eq 'MacOS'; 30my $perl = find_perl(); 31 32rmtree($tmp) if -d $tmp; 33mkpath($tmp) or die "mkpath $tmp: $!\n"; 34chdir($tmp) or die "chdir $tmp: $!\n"; 35 36if ($ENV{'PERL_CORE'}) { 37 if (-d '../../lib') { 38 if ($isVMS) { 39 $inc = '"-I../../lib"'; 40 } 41 elsif ($isMAC) { 42 $inc = '-I:::lib'; 43 } 44 else { 45 $inc = '-I../../lib'; 46 } 47 unshift @INC, '../../lib'; 48 } 49} 50if ($perl =~ m!^\./!) { 51 $perl = ".$perl"; 52} 53 54END { 55 chdir('..') if !-d $tmp && -d "../$tmp"; 56 rmtree($tmp) if -d $tmp; 57} 58 59ok(&Devel::PPPort::WriteFile("ppport.h")); 60 61# Check GetFileContents() 62ok(-e "ppport.h", 1); 63 64my $data; 65 66open(F, "<ppport.h") or die "Failed to open ppport.h: $!"; 67while(<F>) { 68 $data .= $_; 69} 70close(F); 71 72ok(Devel::PPPort::GetFileContents("ppport.h"), $data); 73ok(Devel::PPPort::GetFileContents(), $data); 74 75sub comment 76{ 77 my $c = shift; 78 my $x = 0; 79 $c =~ s/^/sprintf("# %2d| ", ++$x)/meg; 80 $c .= "\n" unless $c =~ /[\r\n]$/; 81 print $c; 82} 83 84sub ppport 85{ 86 my @args = ('ppport.h', @_); 87 unshift @args, $inc if $inc; 88 my $run = $perl =~ m/\s/ ? qq("$perl") : $perl; 89 $run .= ' -MMac::err=unix' if $isMAC; 90 for (@args) { 91 $_ = qq("$_") if $isVMS && /^[^"]/; 92 $run .= " $_"; 93 } 94 print "# *** running $run ***\n"; 95 $run .= ' 2>&1' unless $isMAC; 96 my @out = `$run`; 97 my $out = join '', @out; 98 comment($out); 99 return wantarray ? @out : $out; 100} 101 102sub matches 103{ 104 my($str, $re, $mod) = @_; 105 my @n; 106 eval "\@n = \$str =~ /$re/g$mod;"; 107 if ($@) { 108 my $err = $@; 109 $err =~ s/^/# *** /mg; 110 print "# *** ERROR ***\n$err\n"; 111 } 112 return $@ ? -42 : scalar @n; 113} 114 115sub eq_files 116{ 117 my($f1, $f2) = @_; 118 return 0 unless -e $f1 && -e $f2; 119 local *F; 120 for ($f1, $f2) { 121 print "# File: $_\n"; 122 unless (open F, $_) { 123 print "# couldn't open $_: $!\n"; 124 return 0; 125 } 126 $_ = do { local $/; <F> }; 127 close F; 128 comment($_); 129 } 130 return $f1 eq $f2; 131} 132 133my @tests; 134 135for (split /\s*={70,}\s*/, do { local $/; <DATA> }) { 136 s/^\s+//; s/\s+$//; 137 my($c, %f); 138 ($c, @f{m/-{20,}\s+(\S+)\s+-{20,}/g}) = split /\s*-{20,}\s+\S+\s+-{20,}\s*/; 139 push @tests, { code => $c, files => \%f }; 140} 141 142my $t; 143for $t (@tests) { 144 print "#\n", ('# ', '-'x70, "\n")x3, "#\n"; 145 my $f; 146 for $f (keys %{$t->{files}}) { 147 my @f = split /\//, $f; 148 if (@f > 1) { 149 pop @f; 150 my $path = join '/', @f; 151 mkpath($path) or die "mkpath('$path'): $!\n"; 152 } 153 my $txt = $t->{files}{$f}; 154 local *F; 155 open F, ">$f" or die "open $f: $!\n"; 156 print F "$txt\n"; 157 close F; 158 print "# *** writing $f ***\n"; 159 comment($txt); 160 } 161 162 print "# *** evaluating test code ***\n"; 163 comment($t->{code}); 164 165 eval $t->{code}; 166 if ($@) { 167 my $err = $@; 168 $err =~ s/^/# *** /mg; 169 print "# *** ERROR ***\n$err\n"; 170 } 171 ok($@, ''); 172 173 for (keys %{$t->{files}}) { 174 unlink $_ or die "unlink('$_'): $!\n"; 175 } 176} 177 178sub find_perl 179{ 180 my $perl = $^X; 181 182 return $perl if $isVMS; 183 184 my $exe = $Config{'_exe'} || ''; 185 186 if ($perl =~ /^perl\Q$exe\E$/i) { 187 $perl = "perl$exe"; 188 eval "require File::Spec"; 189 if ($@) { 190 $perl = "./$perl"; 191 } else { 192 $perl = File::Spec->catfile(File::Spec->curdir(), $perl); 193 } 194 } 195 196 if ($perl !~ /\Q$exe\E$/i) { 197 $perl .= $exe; 198 } 199 200 warn "find_perl: cannot find $perl from $^X" unless -f $perl; 201 202 return $perl; 203} 204 205__DATA__ 206 207my $o = ppport(qw(--help)); 208ok($o =~ /^Usage:.*ppport\.h/m); 209ok($o =~ /--help/m); 210 211$o = ppport(qw(--version)); 212ok($o =~ /^This is.*ppport.*\d+\.\d+(?:_?\d+)?\.$/); 213 214$o = ppport(qw(--nochanges)); 215ok($o =~ /^Scanning.*test\.xs/mi); 216ok($o =~ /Analyzing.*test\.xs/mi); 217ok(matches($o, '^Scanning', 'm'), 1); 218ok(matches($o, 'Analyzing', 'm'), 1); 219ok($o =~ /Uses Perl_newSViv instead of newSViv/); 220 221$o = ppport(qw(--quiet --nochanges)); 222ok($o =~ /^\s*$/); 223 224---------------------------- test.xs ------------------------------------------ 225 226Perl_newSViv(); 227 228=============================================================================== 229 230# check if C and C++ comments are filtered correctly 231 232my $o = ppport(qw(--copy=a)); 233ok($o =~ /^Scanning.*MyExt\.xs/mi); 234ok($o =~ /Analyzing.*MyExt\.xs/mi); 235ok(matches($o, '^Scanning', 'm'), 1); 236ok($o =~ /^Needs to include.*ppport\.h/m); 237ok($o !~ /^Uses grok_bin/m); 238ok($o !~ /^Uses newSVpv/m); 239ok($o =~ /Uses 1 C\+\+ style comment/m); 240ok(eq_files('MyExt.xsa', 'MyExt.ra')); 241 242# check if C++ are left untouched with --cplusplus 243 244$o = ppport(qw(--copy=b --cplusplus)); 245ok($o =~ /^Scanning.*MyExt\.xs/mi); 246ok($o =~ /Analyzing.*MyExt\.xs/mi); 247ok(matches($o, '^Scanning', 'm'), 1); 248ok($o =~ /^Needs to include.*ppport\.h/m); 249ok($o !~ /^Uses grok_bin/m); 250ok($o !~ /^Uses newSVpv/m); 251ok($o !~ /Uses \d+ C\+\+ style comment/m); 252ok(eq_files('MyExt.xsb', 'MyExt.rb')); 253 254unlink qw(MyExt.xsa MyExt.xsb); 255 256---------------------------- MyExt.xs ----------------------------------------- 257 258newSVuv(); 259 // newSVpv(); 260 XPUSHs(foo); 261/* grok_bin(); */ 262 263---------------------------- MyExt.ra ----------------------------------------- 264 265#include "ppport.h" 266newSVuv(); 267 /* newSVpv(); */ 268 XPUSHs(foo); 269/* grok_bin(); */ 270 271---------------------------- MyExt.rb ----------------------------------------- 272 273#include "ppport.h" 274newSVuv(); 275 // newSVpv(); 276 XPUSHs(foo); 277/* grok_bin(); */ 278 279=============================================================================== 280 281my $o = ppport(qw(--nochanges file1.xs)); 282ok($o =~ /^Scanning.*file1\.xs/mi); 283ok($o =~ /Analyzing.*file1\.xs/mi); 284ok($o !~ /^Scanning.*file2\.xs/mi); 285ok($o =~ /^Uses newCONSTSUB/m); 286ok($o =~ /^Uses PL_expect/m); 287ok($o =~ /^Uses SvPV_nolen.*depends.*sv_2pv_flags/m); 288ok($o =~ /WARNING: PL_expect/m); 289ok($o =~ /hint for newCONSTSUB/m); 290ok($o =~ /^Analysis completed \(1 warning\)/m); 291ok($o =~ /^Looks good/m); 292 293$o = ppport(qw(--nochanges --nohints file1.xs)); 294ok($o =~ /^Scanning.*file1\.xs/mi); 295ok($o =~ /Analyzing.*file1\.xs/mi); 296ok($o !~ /^Scanning.*file2\.xs/mi); 297ok($o =~ /^Uses newCONSTSUB/m); 298ok($o =~ /^Uses PL_expect/m); 299ok($o =~ /^Uses SvPV_nolen.*depends.*sv_2pv_flags/m); 300ok($o =~ /WARNING: PL_expect/m); 301ok($o !~ /hint for newCONSTSUB/m); 302ok($o =~ /^Analysis completed \(1 warning\)/m); 303ok($o =~ /^Looks good/m); 304 305$o = ppport(qw(--nochanges --nohints --nodiag file1.xs)); 306ok($o =~ /^Scanning.*file1\.xs/mi); 307ok($o =~ /Analyzing.*file1\.xs/mi); 308ok($o !~ /^Scanning.*file2\.xs/mi); 309ok($o !~ /^Uses newCONSTSUB/m); 310ok($o !~ /^Uses PL_expect/m); 311ok($o !~ /^Uses SvPV_nolen/m); 312ok($o =~ /WARNING: PL_expect/m); 313ok($o !~ /hint for newCONSTSUB/m); 314ok($o =~ /^Analysis completed \(1 warning\)/m); 315ok($o =~ /^Looks good/m); 316 317$o = ppport(qw(--nochanges --quiet file1.xs)); 318ok($o =~ /^\s*$/); 319 320$o = ppport(qw(--nochanges file2.xs)); 321ok($o =~ /^Scanning.*file2\.xs/mi); 322ok($o =~ /Analyzing.*file2\.xs/mi); 323ok($o !~ /^Scanning.*file1\.xs/mi); 324ok($o =~ /^Uses mXPUSHp/m); 325ok($o =~ /^Needs to include.*ppport\.h/m); 326ok($o !~ /^Looks good/m); 327ok($o =~ /^1 potentially required change detected/m); 328 329$o = ppport(qw(--nochanges --nohints file2.xs)); 330ok($o =~ /^Scanning.*file2\.xs/mi); 331ok($o =~ /Analyzing.*file2\.xs/mi); 332ok($o !~ /^Scanning.*file1\.xs/mi); 333ok($o =~ /^Uses mXPUSHp/m); 334ok($o =~ /^Needs to include.*ppport\.h/m); 335ok($o !~ /^Looks good/m); 336ok($o =~ /^1 potentially required change detected/m); 337 338$o = ppport(qw(--nochanges --nohints --nodiag file2.xs)); 339ok($o =~ /^Scanning.*file2\.xs/mi); 340ok($o =~ /Analyzing.*file2\.xs/mi); 341ok($o !~ /^Scanning.*file1\.xs/mi); 342ok($o !~ /^Uses mXPUSHp/m); 343ok($o !~ /^Needs to include.*ppport\.h/m); 344ok($o !~ /^Looks good/m); 345ok($o =~ /^1 potentially required change detected/m); 346 347$o = ppport(qw(--nochanges --quiet file2.xs)); 348ok($o =~ /^\s*$/); 349 350---------------------------- file1.xs ----------------------------------------- 351 352#define NEED_newCONSTSUB 353#define NEED_sv_2pv_flags 354#define NEED_PL_parser 355#include "ppport.h" 356 357newCONSTSUB(); 358SvPV_nolen(); 359PL_expect = 0; 360 361---------------------------- file2.xs ----------------------------------------- 362 363mXPUSHp(foo); 364 365=============================================================================== 366 367my $o = ppport(qw(--nochanges)); 368ok($o =~ /^Scanning.*FooBar\.xs/mi); 369ok($o =~ /Analyzing.*FooBar\.xs/mi); 370ok(matches($o, '^Scanning', 'm'), 1); 371ok($o !~ /^Looks good/m); 372ok($o =~ /^Uses grok_bin/m); 373 374---------------------------- FooBar.xs ---------------------------------------- 375 376newSViv(); 377XPUSHs(foo); 378grok_bin(); 379 380=============================================================================== 381 382my $o = ppport(qw(--nochanges)); 383ok($o =~ /^Scanning.*First\.xs/mi); 384ok($o =~ /Analyzing.*First\.xs/mi); 385ok($o =~ /^Scanning.*second\.h/mi); 386ok($o =~ /Analyzing.*second\.h/mi); 387ok($o =~ /^Scanning.*sub.*third\.c/mi); 388ok($o =~ /Analyzing.*sub.*third\.c/mi); 389ok($o !~ /^Scanning.*foobar/mi); 390ok(matches($o, '^Scanning', 'm'), 3); 391 392---------------------------- First.xs ----------------------------------------- 393 394one 395 396---------------------------- foobar.xyz --------------------------------------- 397 398two 399 400---------------------------- second.h ----------------------------------------- 401 402three 403 404---------------------------- sub/third.c -------------------------------------- 405 406four 407 408=============================================================================== 409 410my $o = ppport(qw(--nochanges)); 411ok($o =~ /Possibly wrong #define NEED_foobar in.*test.xs/i); 412 413---------------------------- test.xs ------------------------------------------ 414 415#define NEED_foobar 416 417=============================================================================== 418 419# And now some complex "real-world" example 420 421my $o = ppport(qw(--copy=f)); 422for (qw(main.xs mod1.c mod2.c mod3.c mod4.c mod5.c)) { 423 ok($o =~ /^Scanning.*\Q$_\E/mi); 424 ok($o =~ /Analyzing.*\Q$_\E/i); 425} 426ok(matches($o, '^Scanning', 'm'), 6); 427 428ok(matches($o, '^Writing copy of', 'm'), 5); 429ok(!-e "mod5.cf"); 430 431for (qw(main.xs mod1.c mod2.c mod3.c mod4.c)) { 432 ok($o =~ /^Writing copy of.*\Q$_\E.*with changes/mi); 433 ok(-e "${_}f"); 434 ok(eq_files("${_}f", "${_}r")); 435 unlink "${_}f"; 436} 437 438---------------------------- main.xs ------------------------------------------ 439 440#include "EXTERN.h" 441#include "perl.h" 442#include "XSUB.h" 443 444#define NEED_newCONSTSUB 445#define NEED_grok_hex_GLOBAL 446#include "ppport.h" 447 448newCONSTSUB(); 449grok_hex(); 450Perl_grok_bin(aTHX_ foo, bar); 451 452/* some comment */ 453 454perl_eval_pv(); 455grok_bin(); 456Perl_grok_bin(bar, sv_no); 457 458---------------------------- mod1.c ------------------------------------------- 459 460#include "EXTERN.h" 461#include "perl.h" 462#include "XSUB.h" 463 464#define NEED_grok_bin_GLOBAL 465#define NEED_newCONSTSUB 466#include "ppport.h" 467 468newCONSTSUB(); 469grok_bin(); 470{ 471 Perl_croak ("foo"); 472 Perl_sv_catpvf(); /* I know it's wrong ;-) */ 473} 474 475---------------------------- mod2.c ------------------------------------------- 476 477#include "EXTERN.h" 478#include "perl.h" 479#include "XSUB.h" 480 481#define NEED_eval_pv 482#include "ppport.h" 483 484newSViv(); 485 486/* 487 eval_pv(); 488*/ 489 490---------------------------- mod3.c ------------------------------------------- 491 492#include "EXTERN.h" 493#include "perl.h" 494#include "XSUB.h" 495 496grok_oct(); 497eval_pv(); 498 499---------------------------- mod4.c ------------------------------------------- 500 501#include "EXTERN.h" 502#include "perl.h" 503#include "XSUB.h" 504 505START_MY_CXT; 506 507---------------------------- mod5.c ------------------------------------------- 508 509#include "EXTERN.h" 510#include "perl.h" 511#include "XSUB.h" 512 513#include "ppport.h" 514call_pv(); 515 516---------------------------- main.xsr ----------------------------------------- 517 518#include "EXTERN.h" 519#include "perl.h" 520#include "XSUB.h" 521 522#define NEED_eval_pv_GLOBAL 523#define NEED_grok_hex 524#define NEED_newCONSTSUB_GLOBAL 525#define NEED_sv_2pv_flags_GLOBAL 526#include "ppport.h" 527 528newCONSTSUB(); 529grok_hex(); 530grok_bin(foo, bar); 531 532/* some comment */ 533 534eval_pv(); 535grok_bin(); 536grok_bin(bar, PL_sv_no); 537 538---------------------------- mod1.cr ------------------------------------------ 539 540#include "EXTERN.h" 541#include "perl.h" 542#include "XSUB.h" 543 544#define NEED_grok_bin_GLOBAL 545#include "ppport.h" 546 547newCONSTSUB(); 548grok_bin(); 549{ 550 Perl_croak (aTHX_ "foo"); 551 Perl_sv_catpvf(aTHX); /* I know it's wrong ;-) */ 552} 553 554---------------------------- mod2.cr ------------------------------------------ 555 556#include "EXTERN.h" 557#include "perl.h" 558#include "XSUB.h" 559 560 561newSViv(); 562 563/* 564 eval_pv(); 565*/ 566 567---------------------------- mod3.cr ------------------------------------------ 568 569#include "EXTERN.h" 570#include "perl.h" 571#include "XSUB.h" 572#define NEED_grok_oct 573#include "ppport.h" 574 575grok_oct(); 576eval_pv(); 577 578---------------------------- mod4.cr ------------------------------------------ 579 580#include "EXTERN.h" 581#include "perl.h" 582#include "XSUB.h" 583#include "ppport.h" 584 585START_MY_CXT; 586 587=============================================================================== 588 589my $o = ppport(qw(--nochanges)); 590ok($o =~ /Uses grok_hex/m); 591ok($o !~ /Looks good/m); 592 593$o = ppport(qw(--nochanges --compat-version=5.8.0)); 594ok($o !~ /Uses grok_hex/m); 595ok($o =~ /Looks good/m); 596 597---------------------------- FooBar.xs ---------------------------------------- 598 599grok_hex(); 600 601=============================================================================== 602 603my $o = ppport(qw(--nochanges)); 604ok($o =~ /Uses SvPVutf8_force, which may not be portable/m); 605 606$o = ppport(qw(--nochanges --compat-version=5.5.3)); 607ok($o =~ /Uses SvPVutf8_force, which may not be portable/m); 608 609$o = ppport(qw(--nochanges --compat-version=5.005_03)); 610ok($o =~ /Uses SvPVutf8_force, which may not be portable/m); 611 612$o = ppport(qw(--nochanges --compat-version=5.6.0)); 613ok($o !~ /Uses SvPVutf8_force/m); 614 615$o = ppport(qw(--nochanges --compat-version=5.006)); 616ok($o !~ /Uses SvPVutf8_force/m); 617 618$o = ppport(qw(--nochanges --compat-version=5.999.999)); 619ok($o !~ /Uses SvPVutf8_force/m); 620 621$o = ppport(qw(--nochanges --compat-version=6.0.0)); 622ok($o =~ /Only Perl 5 is supported/m); 623 624$o = ppport(qw(--nochanges --compat-version=5.1000.999)); 625ok($o =~ /Invalid version number: 5.1000.999/m); 626 627$o = ppport(qw(--nochanges --compat-version=5.999.1000)); 628ok($o =~ /Invalid version number: 5.999.1000/m); 629 630---------------------------- FooBar.xs ---------------------------------------- 631 632SvPVutf8_force(); 633 634=============================================================================== 635 636my $o = ppport(qw(--nochanges)); 637ok($o !~ /potentially required change/); 638ok(matches($o, '^Looks good', 'm'), 2); 639 640---------------------------- FooBar.xs ---------------------------------------- 641 642#define NEED_grok_numeric_radix 643#define NEED_grok_number 644#include "ppport.h" 645 646GROK_NUMERIC_RADIX(); 647grok_number(); 648 649---------------------------- foo.c -------------------------------------------- 650 651#include "ppport.h" 652 653call_pv(); 654 655=============================================================================== 656 657# check --api-info option 658 659my $o = ppport(qw(--api-info=INT2PTR)); 660my %found = map {($_ => 1)} $o =~ /^===\s+(\w+)\s+===/mg; 661ok(scalar keys %found, 1); 662ok(exists $found{INT2PTR}); 663ok(matches($o, '^Supported at least starting from perl-5\.6\.0\.', 'm'), 1); 664ok(matches($o, '^Support by .*ppport.* provided back to perl-5\.003\.', 'm'), 1); 665 666$o = ppport(qw(--api-info=Zero)); 667%found = map {($_ => 1)} $o =~ /^===\s+(\w+)\s+===/mg; 668ok(scalar keys %found, 1); 669ok(exists $found{Zero}); 670ok(matches($o, '^No portability information available\.', 'm'), 1); 671 672$o = ppport(qw(--api-info=/Zero/)); 673%found = map {($_ => 1)} $o =~ /^===\s+(\w+)\s+===/mg; 674ok(scalar keys %found, 2); 675ok(exists $found{Zero}); 676ok(exists $found{ZeroD}); 677 678=============================================================================== 679 680# check --list-provided option 681 682my @o = ppport(qw(--list-provided)); 683my %p; 684my $fail = 0; 685for (@o) { 686 my($name, $flags) = /^(\w+)(?:\s+\[(\w+(?:,\s+\w+)*)\])?$/ or $fail++; 687 exists $p{$name} and $fail++; 688 $p{$name} = defined $flags ? { map { ($_ => 1) } $flags =~ /(\w+)/g } : ''; 689} 690ok(@o > 100); 691ok($fail, 0); 692 693ok(exists $p{call_pv}); 694ok(not ref $p{call_pv}); 695 696ok(exists $p{grok_bin}); 697ok(ref $p{grok_bin}, 'HASH'); 698ok(scalar keys %{$p{grok_bin}}, 2); 699ok($p{grok_bin}{explicit}); 700ok($p{grok_bin}{depend}); 701 702ok(exists $p{gv_stashpvn}); 703ok(ref $p{gv_stashpvn}, 'HASH'); 704ok(scalar keys %{$p{gv_stashpvn}}, 2); 705ok($p{gv_stashpvn}{depend}); 706ok($p{gv_stashpvn}{hint}); 707 708ok(exists $p{sv_catpvf_mg}); 709ok(ref $p{sv_catpvf_mg}, 'HASH'); 710ok(scalar keys %{$p{sv_catpvf_mg}}, 2); 711ok($p{sv_catpvf_mg}{explicit}); 712ok($p{sv_catpvf_mg}{depend}); 713 714ok(exists $p{PL_signals}); 715ok(ref $p{PL_signals}, 'HASH'); 716ok(scalar keys %{$p{PL_signals}}, 1); 717ok($p{PL_signals}{explicit}); 718 719=============================================================================== 720 721# check --list-unsupported option 722 723my @o = ppport(qw(--list-unsupported)); 724my %p; 725my $fail = 0; 726for (@o) { 727 my($name, $ver) = /^(\w+)\s*\.+\s*([\d._]+)$/ or $fail++; 728 exists $p{$name} and $fail++; 729 $p{$name} = $ver; 730} 731ok(@o > 100); 732ok($fail, 0); 733 734ok(exists $p{utf8_distance}); 735ok($p{utf8_distance}, '5.6.0'); 736 737ok(exists $p{save_generic_svref}); 738ok($p{save_generic_svref}, '5.005_03'); 739 740=============================================================================== 741 742# check --nofilter option 743 744my $o = ppport(qw(--nochanges)); 745ok($o =~ /^Scanning.*foo\.cpp/mi); 746ok($o =~ /Analyzing.*foo\.cpp/mi); 747ok(matches($o, '^Scanning', 'm'), 1); 748ok(matches($o, 'Analyzing', 'm'), 1); 749 750$o = ppport(qw(--nochanges foo.cpp foo.o Makefile.PL)); 751ok($o =~ /Skipping the following files \(use --nofilter to avoid this\):/m); 752ok(matches($o, '^\|\s+foo\.o', 'mi'), 1); 753ok(matches($o, '^\|\s+Makefile\.PL', 'mi'), 1); 754ok($o =~ /^Scanning.*foo\.cpp/mi); 755ok($o =~ /Analyzing.*foo\.cpp/mi); 756ok(matches($o, '^Scanning', 'm'), 1); 757ok(matches($o, 'Analyzing', 'm'), 1); 758 759$o = ppport(qw(--nochanges --nofilter foo.cpp foo.o Makefile.PL)); 760ok($o =~ /^Scanning.*foo\.cpp/mi); 761ok($o =~ /Analyzing.*foo\.cpp/mi); 762ok($o =~ /^Scanning.*foo\.o/mi); 763ok($o =~ /Analyzing.*foo\.o/mi); 764ok($o =~ /^Scanning.*Makefile/mi); 765ok($o =~ /Analyzing.*Makefile/mi); 766ok(matches($o, '^Scanning', 'm'), 3); 767ok(matches($o, 'Analyzing', 'm'), 3); 768 769---------------------------- foo.cpp ------------------------------------------ 770 771newSViv(); 772 773---------------------------- foo.o -------------------------------------------- 774 775newSViv(); 776 777---------------------------- Makefile.PL -------------------------------------- 778 779newSViv(); 780 781=============================================================================== 782 783# check if explicit variables are handled propery 784 785my $o = ppport(qw(--copy=a)); 786ok($o =~ /^Needs to include.*ppport\.h/m); 787ok($o =~ /^Uses PL_signals/m); 788ok($o =~ /^File needs PL_signals, adding static request/m); 789ok(eq_files('MyExt.xsa', 'MyExt.ra')); 790 791unlink qw(MyExt.xsa); 792 793---------------------------- MyExt.xs ----------------------------------------- 794 795PL_signals = 123; 796if (PL_signals == 42) 797 foo(); 798 799---------------------------- MyExt.ra ----------------------------------------- 800 801#define NEED_PL_signals 802#include "ppport.h" 803PL_signals = 123; 804if (PL_signals == 42) 805 foo(); 806 807=============================================================================== 808 809my $o = ppport(qw(--nochanges file.xs)); 810ok($o =~ /^Uses PL_copline/m); 811ok($o =~ /WARNING: PL_copline/m); 812ok($o =~ /^Uses SvUOK/m); 813ok($o =~ /WARNING: Uses SvUOK, which may not be portable/m); 814ok($o =~ /^Analysis completed \(2 warnings\)/m); 815ok($o =~ /^Looks good/m); 816 817$o = ppport(qw(--nochanges --compat-version=5.8.0 file.xs)); 818ok($o =~ /^Uses PL_copline/m); 819ok($o =~ /WARNING: PL_copline/m); 820ok($o !~ /WARNING: Uses SvUOK, which may not be portable/m); 821ok($o =~ /^Analysis completed \(1 warning\)/m); 822ok($o =~ /^Looks good/m); 823 824---------------------------- file.xs ----------------------------------------- 825 826#define NEED_PL_parser 827#include "ppport.h" 828SvUOK 829PL_copline 830 831=============================================================================== 832 833my $o = ppport(qw(--copy=f)); 834 835for (qw(file.xs)) { 836 ok($o =~ /^Writing copy of.*\Q$_\E.*with changes/mi); 837 ok(-e "${_}f"); 838 ok(eq_files("${_}f", "${_}r")); 839 unlink "${_}f"; 840} 841 842---------------------------- file.xs ----------------------------------------- 843 844a_string = "sv_undef" 845a_char = 'sv_yes' 846#define SOMETHING defgv 847/* C-comment: sv_tainted */ 848# 849# This is just a big XS comment using sv_no 850# 851/* The following, is NOT an XS comment! */ 852# define SOMETHING_ELSE defgv + \ 853 sv_undef 854 855---------------------------- file.xsr ----------------------------------------- 856 857#include "ppport.h" 858a_string = "sv_undef" 859a_char = 'sv_yes' 860#define SOMETHING PL_defgv 861/* C-comment: sv_tainted */ 862# 863# This is just a big XS comment using sv_no 864# 865/* The following, is NOT an XS comment! */ 866# define SOMETHING_ELSE PL_defgv + \ 867 PL_sv_undef 868 869=============================================================================== 870 871my $o = ppport(qw(--copy=f)); 872 873for (qw(file.xs)) { 874 ok($o =~ /^Writing copy of.*\Q$_\E.*with changes/mi); 875 ok(-e "${_}f"); 876 ok(eq_files("${_}f", "${_}r")); 877 unlink "${_}f"; 878} 879 880---------------------------- file.xs ----------------------------------------- 881 882#define NEED_sv_2pv_flags 883#define NEED_vnewSVpvf 884#define NEED_warner 885#include "ppport.h" 886Perl_croak_nocontext("foo"); 887Perl_croak("bar"); 888croak("foo"); 889croak_nocontext("foo"); 890Perl_warner_nocontext("foo"); 891Perl_warner("foo"); 892warner_nocontext("foo"); 893warner("foo"); 894 895---------------------------- file.xsr ----------------------------------------- 896 897#define NEED_sv_2pv_flags 898#define NEED_vnewSVpvf 899#define NEED_warner 900#include "ppport.h" 901Perl_croak_nocontext("foo"); 902Perl_croak(aTHX_ "bar"); 903croak("foo"); 904croak_nocontext("foo"); 905Perl_warner_nocontext("foo"); 906Perl_warner(aTHX_ "foo"); 907warner_nocontext("foo"); 908warner("foo"); 909