This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: [NOT OK] 23353 OpenVMS 7.2 VAX
[perl5.git] / ext / Devel / PPPort / t / ppphtest.t
CommitLineData
adfe19db
MHM
1################################################################################
2#
3# !!!!! Do NOT edit this file directly! !!!!!
4#
5# Edit mktests.PL and/or parts/inc/ppphtest instead.
6#
7################################################################################
8
9BEGIN {
10 if ($ENV{'PERL_CORE'}) {
11 chdir 't' if -d 't';
12 @INC = ('../lib', '../ext/Devel/PPPort/t') if -d '../lib' && -d '../ext';
13 require Config; import Config;
14 use vars '%Config';
a745474a 15 if (" $Config{'extensions'} " !~ m[ Devel/PPPort ]) {
adfe19db
MHM
16 print "1..0 # Skip -- Perl configured without Devel::PPPort module\n";
17 exit 0;
18 }
19 }
20 else {
21 unshift @INC, 't';
22 }
23
24 eval "use Test";
25 if ($@) {
26 require 'testutil.pl';
96ad942f 27 print "1..134\n";
adfe19db
MHM
28 }
29 else {
96ad942f 30 plan(tests => 134);
adfe19db
MHM
31 }
32}
33
34use Devel::PPPort;
35use strict;
36$^W = 1;
37
38use File::Path qw/rmtree mkpath/;
96ad942f 39use Config;
adfe19db
MHM
40
41my $tmp = 'ppptmp';
96ad942f
MHM
42my $inc = '';
43my $perl = find_perl();
adfe19db
MHM
44
45rmtree($tmp) if -d $tmp;
46mkpath($tmp) or die "mkpath $tmp: $!\n";
47chdir($tmp) or die "chdir $tmp: $!\n";
48
adfe19db 49if ($ENV{'PERL_CORE'}) {
87499469 50 if (-d '../../lib') {
d8d9a455 51 $inc = $^O eq 'VMS' ? '-"I../../lib"' : '-I../../lib';
87499469
MHM
52 unshift @INC, '../../lib';
53 }
adfe19db 54}
96ad942f
MHM
55if ($perl =~ m!^\./!) {
56 $perl = ".$perl";
57}
adfe19db
MHM
58
59END {
cd266515
MHM
60 chdir('..') if !-d $tmp && -d "../$tmp";
61 rmtree($tmp) if -d $tmp;
adfe19db
MHM
62}
63
64ok(&Devel::PPPort::WriteFile("ppport.h"));
65
66sub ppport
67{
68 my @args = @_;
96ad942f
MHM
69 print "# *** running $perl $inc ppport.h @args ***\n";
70 my $out = join '', `$perl $inc ppport.h @args`;
adfe19db
MHM
71 my $copy = $out;
72 $copy =~ s/^/# | /mg;
73 print "$copy\n";
74 return $out;
75}
76
77sub matches
78{
79 my($str, $re, $mod) = @_;
80 my @n;
81 eval "\@n = \$str =~ /$re/g$mod;";
82 if ($@) {
83 my $err = $@;
84 $err =~ s/^/# *** /mg;
85 print "# *** ERROR ***\n$err\n";
86 }
87 return $@ ? -42 : scalar @n;
88}
89
90sub eq_files
91{
92 my($f1, $f2) = @_;
93 return 0 unless -e $f1 && -e $f2;
94 local *F;
95 for ($f1, $f2) {
96 print "# File: $_\n";
97 unless (open F, $_) {
98 print "# couldn't open $_: $!\n";
99 return 0;
100 }
101 $_ = do { local $/; <F> };
102 close F;
103 my $copy = $_;
104 $copy =~ s/^/# | /mg;
105 print "$copy\n";
106 }
107 return $f1 eq $f2;
108}
109
110my @tests;
111
112for (split /\s*={70,}\s*/, do { local $/; <DATA> }) {
113 s/^\s+//; s/\s+$//;
114 my($c, %f);
115 ($c, @f{m/-{20,}\s+(\S+)\s+-{20,}/g}) = split /\s*-{20,}\s+\S+\s+-{20,}\s*/;
116 push @tests, { code => $c, files => \%f };
117}
118
119my $t;
120for $t (@tests) {
121 my $f;
122 for $f (keys %{$t->{files}}) {
123 my @f = split /\//, $f;
124 if (@f > 1) {
125 pop @f;
126 my $path = join '/', @f;
127 mkpath($path) or die "mkpath('$path'): $!\n";
128 }
129 my $txt = $t->{files}{$f};
130 local *F;
131 open F, ">$f" or die "open $f: $!\n";
132 print F "$txt\n";
133 close F;
134 $txt =~ s/^/# | /mg;
135 print "# *** writing $f ***\n$txt\n";
136 }
137
138 eval $t->{code};
139 if ($@) {
140 my $err = $@;
141 $err =~ s/^/# *** /mg;
142 print "# *** ERROR ***\n$err\n";
143 }
144 ok($@, '');
145
146 for (keys %{$t->{files}}) {
147 unlink $_ or die "unlink('$_'): $!\n";
148 }
149}
150
96ad942f
MHM
151sub find_perl
152{
153 my $perl = $^X;
154
155 return $perl if $^O eq 'VMS';
156
157 my $exe = $Config{'_exe'} || '';
158
159 if ($perl =~ /^perl\Q$exe\E$/i) {
160 $perl = "perl$exe";
161 eval "require File::Spec";
162 if ($@) {
163 $perl = "./$perl";
164 } else {
165 $perl = File::Spec->catfile(File::Spec->curdir(), $perl);
166 }
167 }
168
169 if ($perl !~ /\Q$exe\E$/i) {
170 $perl .= $exe;
171 }
172
173 warn "find_perl: cannot find $perl from $^X" unless -f $perl;
174
175 return $perl;
176}
177
adfe19db
MHM
178__DATA__
179
180my $o = ppport(qw(--help));
181ok($o =~ /^Usage:.*ppport\.h/m);
182ok($o =~ /--help/m);
183
184$o = ppport(qw(--nochanges));
185ok($o =~ /^scanning.*test\.xs/mi);
186ok($o =~ /analyzing.*test\.xs/mi);
187ok(matches($o, '^scanning', 'mi'), 1);
188ok(matches($o, 'analyzing', 'mi'), 1);
189ok($o =~ /Uses Perl_newSViv instead of newSViv/);
190
191$o = ppport(qw(--quiet --nochanges));
192ok($o =~ /^\s*$/);
193
194---------------------------- test.xs ------------------------------------------
195
196Perl_newSViv();
197
198===============================================================================
199
200# check if C and C++ comments are filtered correctly
201
202my $o = ppport(qw(--copy=a));
203ok($o =~ /^scanning.*MyExt\.xs/mi);
204ok($o =~ /analyzing.*MyExt\.xs/mi);
205ok(matches($o, '^scanning', 'mi'), 1);
206ok($o =~ /^Needs to include.*ppport\.h/m);
207ok($o !~ /^Uses grok_bin/m);
208ok($o !~ /^Uses newSVpv/m);
209ok($o =~ /Uses 1 C\+\+ style comment/m);
210ok(eq_files('MyExt.xsa', 'MyExt.ra'));
211
212# check if C++ are left untouched with --cplusplus
213
214$o = ppport(qw(--copy=b --cplusplus));
215ok($o =~ /^scanning.*MyExt\.xs/mi);
216ok($o =~ /analyzing.*MyExt\.xs/mi);
217ok(matches($o, '^scanning', 'mi'), 1);
218ok($o =~ /^Needs to include.*ppport\.h/m);
219ok($o !~ /^Uses grok_bin/m);
220ok($o !~ /^Uses newSVpv/m);
221ok($o !~ /Uses \d+ C\+\+ style comment/m);
222ok(eq_files('MyExt.xsb', 'MyExt.rb'));
223
224unlink qw(MyExt.xsa MyExt.xsb);
225
226---------------------------- MyExt.xs -----------------------------------------
227
228newSVuv();
229 // newSVpv();
230 XPUSHs(foo);
231/* grok_bin(); */
232
233---------------------------- MyExt.ra -----------------------------------------
234
235#include "ppport.h"
236newSVuv();
237 /* newSVpv(); */
238 XPUSHs(foo);
239/* grok_bin(); */
240
241---------------------------- MyExt.rb -----------------------------------------
242
243#include "ppport.h"
244newSVuv();
245 // newSVpv();
246 XPUSHs(foo);
247/* grok_bin(); */
248
249===============================================================================
250
251my $o = ppport(qw(--nochanges file1.xs));
252ok($o =~ /^scanning.*file1\.xs/mi);
253ok($o =~ /analyzing.*file1\.xs/mi);
254ok($o !~ /^scanning.*file2\.xs/mi);
255ok($o =~ /^Uses newCONSTSUB/m);
256ok($o =~ /^Uses SvPV_nolen.*depends.*sv_2pv_nolen/m);
257ok($o =~ /hint for newCONSTSUB/m);
258ok($o !~ /hint for sv_2pv_nolen/m);
259ok($o =~ /^Looks good/m);
260
261$o = ppport(qw(--nochanges --nohints file1.xs));
262ok($o =~ /^scanning.*file1\.xs/mi);
263ok($o =~ /analyzing.*file1\.xs/mi);
264ok($o !~ /^scanning.*file2\.xs/mi);
265ok($o =~ /^Uses newCONSTSUB/m);
266ok($o =~ /^Uses SvPV_nolen.*depends.*sv_2pv_nolen/m);
267ok($o !~ /hint for newCONSTSUB/m);
268ok($o !~ /hint for sv_2pv_nolen/m);
269ok($o =~ /^Looks good/m);
270
271$o = ppport(qw(--nochanges --nohints --nodiag file1.xs));
272ok($o =~ /^scanning.*file1\.xs/mi);
273ok($o =~ /analyzing.*file1\.xs/mi);
274ok($o !~ /^scanning.*file2\.xs/mi);
275ok($o !~ /^Uses newCONSTSUB/m);
276ok($o !~ /^Uses SvPV_nolen/m);
277ok($o !~ /hint for newCONSTSUB/m);
278ok($o !~ /hint for sv_2pv_nolen/m);
279ok($o =~ /^Looks good/m);
280
281$o = ppport(qw(--nochanges --quiet file1.xs));
282ok($o =~ /^\s*$/);
283
284$o = ppport(qw(--nochanges file2.xs));
285ok($o =~ /^scanning.*file2\.xs/mi);
286ok($o =~ /analyzing.*file2\.xs/mi);
287ok($o !~ /^scanning.*file1\.xs/mi);
288ok($o =~ /^Uses mXPUSHp/m);
289ok($o =~ /^Needs to include.*ppport\.h/m);
290ok($o !~ /^Looks good/m);
291ok($o =~ /^1 potentially required change detected/m);
292
293$o = ppport(qw(--nochanges --nohints file2.xs));
294ok($o =~ /^scanning.*file2\.xs/mi);
295ok($o =~ /analyzing.*file2\.xs/mi);
296ok($o !~ /^scanning.*file1\.xs/mi);
297ok($o =~ /^Uses mXPUSHp/m);
298ok($o =~ /^Needs to include.*ppport\.h/m);
299ok($o !~ /^Looks good/m);
300ok($o =~ /^1 potentially required change detected/m);
301
302$o = ppport(qw(--nochanges --nohints --nodiag file2.xs));
303ok($o =~ /^scanning.*file2\.xs/mi);
304ok($o =~ /analyzing.*file2\.xs/mi);
305ok($o !~ /^scanning.*file1\.xs/mi);
306ok($o !~ /^Uses mXPUSHp/m);
307ok($o !~ /^Needs to include.*ppport\.h/m);
308ok($o !~ /^Looks good/m);
309ok($o =~ /^1 potentially required change detected/m);
310
311$o = ppport(qw(--nochanges --quiet file2.xs));
312ok($o =~ /^\s*$/);
313
314---------------------------- file1.xs -----------------------------------------
315
316#define NEED_newCONSTSUB
317#define NEED_sv_2pv_nolen
318#include "ppport.h"
319
320newCONSTSUB();
321SvPV_nolen();
322
323---------------------------- file2.xs -----------------------------------------
324
325mXPUSHp(foo);
326
327===============================================================================
328
329my $o = ppport(qw(--nochanges));
330ok($o =~ /^scanning.*FooBar\.xs/mi);
331ok($o =~ /analyzing.*FooBar\.xs/mi);
332ok(matches($o, '^scanning', 'mi'), 1);
333ok($o !~ /^Looks good/m);
334ok($o =~ /^Uses grok_bin/m);
335
336---------------------------- FooBar.xs ----------------------------------------
337
338newSViv();
339XPUSHs(foo);
340grok_bin();
341
342===============================================================================
343
344my $o = ppport(qw(--nochanges));
345ok($o =~ /^scanning.*First\.xs/mi);
346ok($o =~ /analyzing.*First\.xs/mi);
347ok($o =~ /^scanning.*second\.h/mi);
348ok($o =~ /analyzing.*second\.h/mi);
349ok($o =~ /^scanning.*sub.*third\.c/mi);
350ok($o =~ /analyzing.*sub.*third\.c/mi);
351ok($o !~ /^scanning.*foobar/mi);
352ok(matches($o, '^scanning', 'mi'), 3);
353
354---------------------------- First.xs -----------------------------------------
355
356one
357
358---------------------------- foobar.xyz ---------------------------------------
359
360two
361
362---------------------------- second.h -----------------------------------------
363
364three
365
366---------------------------- sub/third.c --------------------------------------
367
368four
369
370===============================================================================
371
372my $o = ppport(qw(--nochanges));
373ok($o =~ /Possibly wrong #define NEED_foobar in.*test.xs/i);
374
375---------------------------- test.xs ------------------------------------------
376
377#define NEED_foobar
378
379===============================================================================
380
381# And now some complex "real-world" example
382
383my $o = ppport(qw(--copy=f));
384for (qw(main.xs mod1.c mod2.c mod3.c mod4.c mod5.c)) {
385 ok($o =~ /^scanning.*\Q$_\E/mi);
386 ok($o =~ /analyzing.*\Q$_\E/i);
387}
388ok(matches($o, '^scanning', 'mi'), 6);
389
390ok(matches($o, '^Writing copy of', 'mi'), 5);
391ok(!-e "mod5.cf");
392
393for (qw(main.xs mod1.c mod2.c mod3.c mod4.c)) {
394 ok($o =~ /^Writing copy of.*\Q$_\E.*with changes/mi);
395 ok(-e "${_}f");
396 ok(eq_files("${_}f", "${_}r"));
397 unlink "${_}f";
398}
399
400---------------------------- main.xs ------------------------------------------
401
402#include "EXTERN.h"
403#include "perl.h"
404#include "XSUB.h"
405
406#define NEED_newCONSTSUB
407#define NEED_grok_hex_GLOBAL
408#include "ppport.h"
409
410newCONSTSUB();
411grok_hex();
412Perl_grok_bin(aTHX_ foo, bar);
413
414/* some comment */
415
416perl_eval_pv();
417grok_bin();
418Perl_grok_bin(bar, sv_no);
419
420---------------------------- mod1.c -------------------------------------------
421
422#include "EXTERN.h"
423#include "perl.h"
424#include "XSUB.h"
425
426#define NEED_grok_bin_GLOBAL
427#define NEED_newCONSTSUB
428#include "ppport.h"
429
430newCONSTSUB();
431grok_bin();
432{
433 Perl_croak ("foo");
434 Perl_sv_catpvf(); /* I know it's wrong ;-) */
435}
436
437---------------------------- mod2.c -------------------------------------------
438
439#include "EXTERN.h"
440#include "perl.h"
441#include "XSUB.h"
442
443#define NEED_eval_pv
444#include "ppport.h"
445
446newSViv();
447
448/*
449 eval_pv();
450*/
451
452---------------------------- mod3.c -------------------------------------------
453
454#include "EXTERN.h"
455#include "perl.h"
456#include "XSUB.h"
457
458grok_oct();
459eval_pv();
460
461---------------------------- mod4.c -------------------------------------------
462
463#include "EXTERN.h"
464#include "perl.h"
465#include "XSUB.h"
466
467START_MY_CXT;
468
469---------------------------- mod5.c -------------------------------------------
470
471#include "EXTERN.h"
472#include "perl.h"
473#include "XSUB.h"
474
475#include "ppport.h"
476call_pv();
477
478---------------------------- main.xsr -----------------------------------------
479
480#include "EXTERN.h"
481#include "perl.h"
482#include "XSUB.h"
483
484#define NEED_eval_pv_GLOBAL
485#define NEED_grok_hex
486#define NEED_newCONSTSUB_GLOBAL
487#include "ppport.h"
488
489newCONSTSUB();
490grok_hex();
491grok_bin(foo, bar);
492
493/* some comment */
494
495eval_pv();
496grok_bin();
497grok_bin(bar, PL_sv_no);
498
499---------------------------- mod1.cr ------------------------------------------
500
501#include "EXTERN.h"
502#include "perl.h"
503#include "XSUB.h"
504
505#define NEED_grok_bin_GLOBAL
506#include "ppport.h"
507
508newCONSTSUB();
509grok_bin();
510{
511 Perl_croak (aTHX_ "foo");
512 Perl_sv_catpvf(aTHX); /* I know it's wrong ;-) */
513}
514
515---------------------------- mod2.cr ------------------------------------------
516
517#include "EXTERN.h"
518#include "perl.h"
519#include "XSUB.h"
520
521
522newSViv();
523
524/*
525 eval_pv();
526*/
527
528---------------------------- mod3.cr ------------------------------------------
529
530#include "EXTERN.h"
531#include "perl.h"
532#include "XSUB.h"
533#define NEED_grok_oct
534#include "ppport.h"
535
536grok_oct();
537eval_pv();
538
539---------------------------- mod4.cr ------------------------------------------
540
541#include "EXTERN.h"
542#include "perl.h"
543#include "XSUB.h"
544#include "ppport.h"
545
546START_MY_CXT;
547
548===============================================================================
549
550my $o = ppport(qw(--nochanges));
551ok($o =~ /Uses grok_hex/m);
552ok($o !~ /Looks good/m);
553
554$o = ppport(qw(--nochanges --compat-version=5.8.0));
555ok($o !~ /Uses grok_hex/m);
556ok($o =~ /Looks good/m);
557
558---------------------------- FooBar.xs ----------------------------------------
559
560grok_hex();
561
562===============================================================================
563
564my $o = ppport(qw(--nochanges));
565ok($o =~ /Uses SvPVutf8_force, which may not be portable/m);
566
567$o = ppport(qw(--nochanges --compat-version=5.6.0));
568ok($o !~ /Uses SvPVutf8_force/m);
569
570---------------------------- FooBar.xs ----------------------------------------
571
572SvPVutf8_force();
573
96ad942f
MHM
574===============================================================================
575
576my $o = ppport(qw(--nochanges));
577ok($o !~ /potentially required change/);
578ok(matches($o, '^Looks good', 'mi'), 2);
579
580---------------------------- FooBar.xs ----------------------------------------
581
582#define NEED_grok_numeric_radix
583#define NEED_grok_number
584#include "ppport.h"
585
586GROK_NUMERIC_RADIX();
587grok_number();
588
589---------------------------- foo.c --------------------------------------------
590
591#include "ppport.h"
592
593call_pv();
594