prasb commited on
Commit
55bff2c
·
verified ·
1 Parent(s): 7074695

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. my_container_sandbox/usr/share/perl/5.30.0/Archive/Tar/File.pm +716 -0
  2. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Base.pm +405 -0
  3. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/Unix.pm +40 -0
  4. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/VMS.pm +290 -0
  5. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/android.pm +39 -0
  6. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/cygwin.pm +33 -0
  7. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/darwin.pm +22 -0
  8. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Command/MM.pm +323 -0
  9. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Constant/Base.pm +1019 -0
  10. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Constant/ProxySubs.pm +682 -0
  11. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Constant/XS.pm +259 -0
  12. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/MakeMaker/FAQ.pod +666 -0
  13. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/Constants.pm +44 -0
  14. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/CountLines.pm +54 -0
  15. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/Eval.pm +97 -0
  16. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/Utilities.pm +821 -0
  17. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/Cmd.pm +168 -0
  18. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/InputMap.pm +116 -0
  19. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/OutputMap.pm +209 -0
  20. my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/Type.pm +121 -0
  21. my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Breakage.pm +178 -0
  22. my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Context.pm +1013 -0
  23. my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Instance.pm +822 -0
  24. my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Stack.pm +220 -0
  25. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Diag.pm +99 -0
  26. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Encoding.pm +97 -0
  27. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Fail.pm +118 -0
  28. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Generic.pm +280 -0
  29. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Note.pm +97 -0
  30. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Pass.pm +114 -0
  31. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Plan.pm +169 -0
  32. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Skip.pm +127 -0
  33. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Subtest.pm +160 -0
  34. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/V2.pm +238 -0
  35. my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Waiting.pm +76 -0
  36. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/About.pm +92 -0
  37. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Amnesty.pm +91 -0
  38. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Assert.pm +93 -0
  39. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Control.pm +100 -0
  40. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Error.pm +93 -0
  41. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Hub.pm +109 -0
  42. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Info.pm +132 -0
  43. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Meta.pm +104 -0
  44. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Parent.pm +98 -0
  45. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Plan.pm +94 -0
  46. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Render.pm +106 -0
  47. my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Trace.pm +279 -0
  48. my_container_sandbox/usr/share/perl/5.30.0/Test2/Formatter/TAP.pm +524 -0
  49. my_container_sandbox/usr/share/perl/5.30.0/Test2/Tools/Tiny.pm +435 -0
  50. my_container_sandbox/usr/share/perl/5.30.0/Test2/Util/HashBase.pm +435 -0
my_container_sandbox/usr/share/perl/5.30.0/Archive/Tar/File.pm ADDED
@@ -0,0 +1,716 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Archive::Tar::File;
2
+ use strict;
3
+
4
+ use Carp ();
5
+ use IO::File;
6
+ use File::Spec::Unix ();
7
+ use File::Spec ();
8
+ use File::Basename ();
9
+
10
+ ### avoid circular use, so only require;
11
+ require Archive::Tar;
12
+ use Archive::Tar::Constant;
13
+
14
+ use vars qw[@ISA $VERSION];
15
+ #@ISA = qw[Archive::Tar];
16
+ $VERSION = '2.32';
17
+
18
+ ### set value to 1 to oct() it during the unpack ###
19
+
20
+ my $tmpl = [
21
+ name => 0, # string A100
22
+ mode => 1, # octal A8
23
+ uid => 1, # octal A8
24
+ gid => 1, # octal A8
25
+ size => 0, # octal # cdrake - not *always* octal.. A12
26
+ mtime => 1, # octal A12
27
+ chksum => 1, # octal A8
28
+ type => 0, # character A1
29
+ linkname => 0, # string A100
30
+ magic => 0, # string A6
31
+ version => 0, # 2 bytes A2
32
+ uname => 0, # string A32
33
+ gname => 0, # string A32
34
+ devmajor => 1, # octal A8
35
+ devminor => 1, # octal A8
36
+ prefix => 0, # A155 x 12
37
+
38
+ ### end UNPACK items ###
39
+ raw => 0, # the raw data chunk
40
+ data => 0, # the data associated with the file --
41
+ # This might be very memory intensive
42
+ ];
43
+
44
+ ### install get/set accessors for this object.
45
+ for ( my $i=0; $i<scalar @$tmpl ; $i+=2 ) {
46
+ my $key = $tmpl->[$i];
47
+ no strict 'refs';
48
+ *{__PACKAGE__."::$key"} = sub {
49
+ my $self = shift;
50
+ $self->{$key} = $_[0] if @_;
51
+
52
+ ### just in case the key is not there or undef or something ###
53
+ { local $^W = 0;
54
+ return $self->{$key};
55
+ }
56
+ }
57
+ }
58
+
59
+ =head1 NAME
60
+
61
+ Archive::Tar::File - a subclass for in-memory extracted file from Archive::Tar
62
+
63
+ =head1 SYNOPSIS
64
+
65
+ my @items = $tar->get_files;
66
+
67
+ print $_->name, ' ', $_->size, "\n" for @items;
68
+
69
+ print $object->get_content;
70
+ $object->replace_content('new content');
71
+
72
+ $object->rename( 'new/full/path/to/file.c' );
73
+
74
+ =head1 DESCRIPTION
75
+
76
+ Archive::Tar::Files provides a neat little object layer for in-memory
77
+ extracted files. It's mostly used internally in Archive::Tar to tidy
78
+ up the code, but there's no reason users shouldn't use this API as
79
+ well.
80
+
81
+ =head2 Accessors
82
+
83
+ A lot of the methods in this package are accessors to the various
84
+ fields in the tar header:
85
+
86
+ =over 4
87
+
88
+ =item name
89
+
90
+ The file's name
91
+
92
+ =item mode
93
+
94
+ The file's mode
95
+
96
+ =item uid
97
+
98
+ The user id owning the file
99
+
100
+ =item gid
101
+
102
+ The group id owning the file
103
+
104
+ =item size
105
+
106
+ File size in bytes
107
+
108
+ =item mtime
109
+
110
+ Modification time. Adjusted to mac-time on MacOS if required
111
+
112
+ =item chksum
113
+
114
+ Checksum field for the tar header
115
+
116
+ =item type
117
+
118
+ File type -- numeric, but comparable to exported constants -- see
119
+ Archive::Tar's documentation
120
+
121
+ =item linkname
122
+
123
+ If the file is a symlink, the file it's pointing to
124
+
125
+ =item magic
126
+
127
+ Tar magic string -- not useful for most users
128
+
129
+ =item version
130
+
131
+ Tar version string -- not useful for most users
132
+
133
+ =item uname
134
+
135
+ The user name that owns the file
136
+
137
+ =item gname
138
+
139
+ The group name that owns the file
140
+
141
+ =item devmajor
142
+
143
+ Device major number in case of a special file
144
+
145
+ =item devminor
146
+
147
+ Device minor number in case of a special file
148
+
149
+ =item prefix
150
+
151
+ Any directory to prefix to the extraction path, if any
152
+
153
+ =item raw
154
+
155
+ Raw tar header -- not useful for most users
156
+
157
+ =back
158
+
159
+ =head1 Methods
160
+
161
+ =head2 Archive::Tar::File->new( file => $path )
162
+
163
+ Returns a new Archive::Tar::File object from an existing file.
164
+
165
+ Returns undef on failure.
166
+
167
+ =head2 Archive::Tar::File->new( data => $path, $data, $opt )
168
+
169
+ Returns a new Archive::Tar::File object from data.
170
+
171
+ C<$path> defines the file name (which need not exist), C<$data> the
172
+ file contents, and C<$opt> is a reference to a hash of attributes
173
+ which may be used to override the default attributes (fields in the
174
+ tar header), which are described above in the Accessors section.
175
+
176
+ Returns undef on failure.
177
+
178
+ =head2 Archive::Tar::File->new( chunk => $chunk )
179
+
180
+ Returns a new Archive::Tar::File object from a raw 512-byte tar
181
+ archive chunk.
182
+
183
+ Returns undef on failure.
184
+
185
+ =cut
186
+
187
+ sub new {
188
+ my $class = shift;
189
+ my $what = shift;
190
+
191
+ my $obj = ($what eq 'chunk') ? __PACKAGE__->_new_from_chunk( @_ ) :
192
+ ($what eq 'file' ) ? __PACKAGE__->_new_from_file( @_ ) :
193
+ ($what eq 'data' ) ? __PACKAGE__->_new_from_data( @_ ) :
194
+ undef;
195
+
196
+ return $obj;
197
+ }
198
+
199
+ ### copies the data, creates a clone ###
200
+ sub clone {
201
+ my $self = shift;
202
+ return bless { %$self }, ref $self;
203
+ }
204
+
205
+ sub _new_from_chunk {
206
+ my $class = shift;
207
+ my $chunk = shift or return; # 512 bytes of tar header
208
+ my %hash = @_;
209
+
210
+ ### filter any arguments on defined-ness of values.
211
+ ### this allows overriding from what the tar-header is saying
212
+ ### about this tar-entry. Particularly useful for @LongLink files
213
+ my %args = map { $_ => $hash{$_} } grep { defined $hash{$_} } keys %hash;
214
+
215
+ ### makes it start at 0 actually... :) ###
216
+ my $i = -1;
217
+ my %entry = map {
218
+ my ($s,$v)=($tmpl->[++$i],$tmpl->[++$i]); # cdrake
219
+ ($_)=($_=~/^([^\0]*)/) unless($s eq 'size'); # cdrake
220
+ $s=> $v ? oct $_ : $_ # cdrake
221
+ # $tmpl->[++$i] => $tmpl->[++$i] ? oct $_ : $_ # removed by cdrake - mucks up binary sizes >8gb
222
+ } unpack( UNPACK, $chunk ); # cdrake
223
+ # } map { /^([^\0]*)/ } unpack( UNPACK, $chunk ); # old - replaced now by cdrake
224
+
225
+
226
+ if(substr($entry{'size'}, 0, 1) eq "\x80") { # binary size extension for files >8gigs (> octal 77777777777777) # cdrake
227
+ my @sz=unpack("aCSNN",$entry{'size'}); $entry{'size'}=$sz[4]+(2**32)*$sz[3]+$sz[2]*(2**64); # Use the low 80 bits (should use the upper 15 as well, but as at year 2011, that seems unlikely to ever be needed - the numbers are just too big...) # cdrake
228
+ } else { # cdrake
229
+ ($entry{'size'})=($entry{'size'}=~/^([^\0]*)/); $entry{'size'}=oct $entry{'size'}; # cdrake
230
+ } # cdrake
231
+
232
+
233
+ my $obj = bless { %entry, %args }, $class;
234
+
235
+ ### magic is a filetype string.. it should have something like 'ustar' or
236
+ ### something similar... if the chunk is garbage, skip it
237
+ return unless $obj->magic !~ /\W/;
238
+
239
+ ### store the original chunk ###
240
+ $obj->raw( $chunk );
241
+
242
+ $obj->type(FILE) if ( (!length $obj->type) or ($obj->type =~ /\W/) );
243
+ $obj->type(DIR) if ( ($obj->is_file) && ($obj->name =~ m|/$|) );
244
+
245
+
246
+ return $obj;
247
+
248
+ }
249
+
250
+ sub _new_from_file {
251
+ my $class = shift;
252
+ my $path = shift;
253
+
254
+ ### path has to at least exist
255
+ return unless defined $path;
256
+
257
+ my $type = __PACKAGE__->_filetype($path);
258
+ my $data = '';
259
+
260
+ READ: {
261
+ unless ($type == DIR ) {
262
+ my $fh = IO::File->new;
263
+
264
+ unless( $fh->open($path) ) {
265
+ ### dangling symlinks are fine, stop reading but continue
266
+ ### creating the object
267
+ last READ if $type == SYMLINK;
268
+
269
+ ### otherwise, return from this function --
270
+ ### anything that's *not* a symlink should be
271
+ ### resolvable
272
+ return;
273
+ }
274
+
275
+ ### binmode needed to read files properly on win32 ###
276
+ binmode $fh;
277
+ $data = do { local $/; <$fh> };
278
+ close $fh;
279
+ }
280
+ }
281
+
282
+ my @items = qw[mode uid gid size mtime];
283
+ my %hash = map { shift(@items), $_ } (lstat $path)[2,4,5,7,9];
284
+
285
+ if (ON_VMS) {
286
+ ### VMS has two UID modes, traditional and POSIX. Normally POSIX is
287
+ ### not used. We currently do not have an easy way to see if we are in
288
+ ### POSIX mode. In traditional mode, the UID is actually the VMS UIC.
289
+ ### The VMS UIC has the upper 16 bits is the GID, which in many cases
290
+ ### the VMS UIC will be larger than 209715, the largest that TAR can
291
+ ### handle. So for now, assume it is traditional if the UID is larger
292
+ ### than 0x10000.
293
+
294
+ if ($hash{uid} > 0x10000) {
295
+ $hash{uid} = $hash{uid} & 0xFFFF;
296
+ }
297
+
298
+ ### The file length from stat() is the physical length of the file
299
+ ### However the amount of data read in may be more for some file types.
300
+ ### Fixed length files are read past the logical EOF to end of the block
301
+ ### containing. Other file types get expanded on read because record
302
+ ### delimiters are added.
303
+
304
+ my $data_len = length $data;
305
+ $hash{size} = $data_len if $hash{size} < $data_len;
306
+
307
+ }
308
+ ### you *must* set size == 0 on symlinks, or the next entry will be
309
+ ### though of as the contents of the symlink, which is wrong.
310
+ ### this fixes bug #7937
311
+ $hash{size} = 0 if ($type == DIR or $type == SYMLINK);
312
+ $hash{mtime} -= TIME_OFFSET;
313
+
314
+ ### strip the high bits off the mode, which we don't need to store
315
+ $hash{mode} = STRIP_MODE->( $hash{mode} );
316
+
317
+
318
+ ### probably requires some file path munging here ... ###
319
+ ### name and prefix are set later
320
+ my $obj = {
321
+ %hash,
322
+ name => '',
323
+ chksum => CHECK_SUM,
324
+ type => $type,
325
+ linkname => ($type == SYMLINK and CAN_READLINK)
326
+ ? readlink $path
327
+ : '',
328
+ magic => MAGIC,
329
+ version => TAR_VERSION,
330
+ uname => UNAME->( $hash{uid} ),
331
+ gname => GNAME->( $hash{gid} ),
332
+ devmajor => 0, # not handled
333
+ devminor => 0, # not handled
334
+ prefix => '',
335
+ data => $data,
336
+ };
337
+
338
+ bless $obj, $class;
339
+
340
+ ### fix up the prefix and file from the path
341
+ my($prefix,$file) = $obj->_prefix_and_file( $path );
342
+ $obj->prefix( $prefix );
343
+ $obj->name( $file );
344
+
345
+ return $obj;
346
+ }
347
+
348
+ sub _new_from_data {
349
+ my $class = shift;
350
+ my $path = shift; return unless defined $path;
351
+ my $data = shift; return unless defined $data;
352
+ my $opt = shift;
353
+
354
+ my $obj = {
355
+ data => $data,
356
+ name => '',
357
+ mode => MODE,
358
+ uid => UID,
359
+ gid => GID,
360
+ size => length $data,
361
+ mtime => time - TIME_OFFSET,
362
+ chksum => CHECK_SUM,
363
+ type => FILE,
364
+ linkname => '',
365
+ magic => MAGIC,
366
+ version => TAR_VERSION,
367
+ uname => UNAME->( UID ),
368
+ gname => GNAME->( GID ),
369
+ devminor => 0,
370
+ devmajor => 0,
371
+ prefix => '',
372
+ };
373
+
374
+ ### overwrite with user options, if provided ###
375
+ if( $opt and ref $opt eq 'HASH' ) {
376
+ for my $key ( keys %$opt ) {
377
+
378
+ ### don't write bogus options ###
379
+ next unless exists $obj->{$key};
380
+ $obj->{$key} = $opt->{$key};
381
+ }
382
+ }
383
+
384
+ bless $obj, $class;
385
+
386
+ ### fix up the prefix and file from the path
387
+ my($prefix,$file) = $obj->_prefix_and_file( $path );
388
+ $obj->prefix( $prefix );
389
+ $obj->name( $file );
390
+
391
+ return $obj;
392
+ }
393
+
394
+ sub _prefix_and_file {
395
+ my $self = shift;
396
+ my $path = shift;
397
+
398
+ my ($vol, $dirs, $file) = File::Spec->splitpath( $path, $self->is_dir );
399
+ my @dirs = File::Spec->splitdir( File::Spec->canonpath($dirs) );
400
+
401
+ ### if it's a directory, then $file might be empty
402
+ $file = pop @dirs if $self->is_dir and not length $file;
403
+
404
+ ### splitting ../ gives you the relative path in native syntax
405
+ ### Remove the root (000000) directory
406
+ ### The volume from splitpath will also be in native syntax
407
+ if (ON_VMS) {
408
+ map { $_ = '..' if $_ eq '-'; $_ = '' if $_ eq '000000' } @dirs;
409
+ if (length($vol)) {
410
+ $vol = VMS::Filespec::unixify($vol);
411
+ unshift @dirs, $vol;
412
+ }
413
+ }
414
+
415
+ my $prefix = File::Spec::Unix->catdir(@dirs);
416
+ return( $prefix, $file );
417
+ }
418
+
419
+ sub _filetype {
420
+ my $self = shift;
421
+ my $file = shift;
422
+
423
+ return unless defined $file;
424
+
425
+ return SYMLINK if (-l $file); # Symlink
426
+
427
+ return FILE if (-f _); # Plain file
428
+
429
+ return DIR if (-d _); # Directory
430
+
431
+ return FIFO if (-p _); # Named pipe
432
+
433
+ return SOCKET if (-S _); # Socket
434
+
435
+ return BLOCKDEV if (-b _); # Block special
436
+
437
+ return CHARDEV if (-c _); # Character special
438
+
439
+ ### shouldn't happen, this is when making archives, not reading ###
440
+ return LONGLINK if ( $file eq LONGLINK_NAME );
441
+
442
+ return UNKNOWN; # Something else (like what?)
443
+
444
+ }
445
+
446
+ ### this method 'downgrades' a file to plain file -- this is used for
447
+ ### symlinks when FOLLOW_SYMLINKS is true.
448
+ sub _downgrade_to_plainfile {
449
+ my $entry = shift;
450
+ $entry->type( FILE );
451
+ $entry->mode( MODE );
452
+ $entry->linkname('');
453
+
454
+ return 1;
455
+ }
456
+
457
+ =head2 $bool = $file->extract( [ $alternative_name ] )
458
+
459
+ Extract this object, optionally to an alternative name.
460
+
461
+ See C<< Archive::Tar->extract_file >> for details.
462
+
463
+ Returns true on success and false on failure.
464
+
465
+ =cut
466
+
467
+ sub extract {
468
+ my $self = shift;
469
+
470
+ local $Carp::CarpLevel += 1;
471
+
472
+ return Archive::Tar->_extract_file( $self, @_ );
473
+ }
474
+
475
+ =head2 $path = $file->full_path
476
+
477
+ Returns the full path from the tar header; this is basically a
478
+ concatenation of the C<prefix> and C<name> fields.
479
+
480
+ =cut
481
+
482
+ sub full_path {
483
+ my $self = shift;
484
+
485
+ ### if prefix field is empty
486
+ return $self->name unless defined $self->prefix and length $self->prefix;
487
+
488
+ ### or otherwise, catfile'd
489
+ return File::Spec::Unix->catfile( $self->prefix, $self->name );
490
+ }
491
+
492
+
493
+ =head2 $bool = $file->validate
494
+
495
+ Done by Archive::Tar internally when reading the tar file:
496
+ validate the header against the checksum to ensure integer tar file.
497
+
498
+ Returns true on success, false on failure
499
+
500
+ =cut
501
+
502
+ sub validate {
503
+ my $self = shift;
504
+
505
+ my $raw = $self->raw;
506
+
507
+ ### don't know why this one is different from the one we /write/ ###
508
+ substr ($raw, 148, 8) = " ";
509
+
510
+ ### bug #43513: [PATCH] Accept wrong checksums from SunOS and HP-UX tar
511
+ ### like GNU tar does. See here for details:
512
+ ### http://www.gnu.org/software/tar/manual/tar.html#SEC139
513
+ ### so we do both a signed AND unsigned validate. if one succeeds, that's
514
+ ### good enough
515
+ return ( (unpack ("%16C*", $raw) == $self->chksum)
516
+ or (unpack ("%16c*", $raw) == $self->chksum)) ? 1 : 0;
517
+ }
518
+
519
+ =head2 $bool = $file->has_content
520
+
521
+ Returns a boolean to indicate whether the current object has content.
522
+ Some special files like directories and so on never will have any
523
+ content. This method is mainly to make sure you don't get warnings
524
+ for using uninitialized values when looking at an object's content.
525
+
526
+ =cut
527
+
528
+ sub has_content {
529
+ my $self = shift;
530
+ return defined $self->data() && length $self->data() ? 1 : 0;
531
+ }
532
+
533
+ =head2 $content = $file->get_content
534
+
535
+ Returns the current content for the in-memory file
536
+
537
+ =cut
538
+
539
+ sub get_content {
540
+ my $self = shift;
541
+ $self->data( );
542
+ }
543
+
544
+ =head2 $cref = $file->get_content_by_ref
545
+
546
+ Returns the current content for the in-memory file as a scalar
547
+ reference. Normal users won't need this, but it will save memory if
548
+ you are dealing with very large data files in your tar archive, since
549
+ it will pass the contents by reference, rather than make a copy of it
550
+ first.
551
+
552
+ =cut
553
+
554
+ sub get_content_by_ref {
555
+ my $self = shift;
556
+
557
+ return \$self->{data};
558
+ }
559
+
560
+ =head2 $bool = $file->replace_content( $content )
561
+
562
+ Replace the current content of the file with the new content. This
563
+ only affects the in-memory archive, not the on-disk version until
564
+ you write it.
565
+
566
+ Returns true on success, false on failure.
567
+
568
+ =cut
569
+
570
+ sub replace_content {
571
+ my $self = shift;
572
+ my $data = shift || '';
573
+
574
+ $self->data( $data );
575
+ $self->size( length $data );
576
+ return 1;
577
+ }
578
+
579
+ =head2 $bool = $file->rename( $new_name )
580
+
581
+ Rename the current file to $new_name.
582
+
583
+ Note that you must specify a Unix path for $new_name, since per tar
584
+ standard, all files in the archive must be Unix paths.
585
+
586
+ Returns true on success and false on failure.
587
+
588
+ =cut
589
+
590
+ sub rename {
591
+ my $self = shift;
592
+ my $path = shift;
593
+
594
+ return unless defined $path;
595
+
596
+ my ($prefix,$file) = $self->_prefix_and_file( $path );
597
+
598
+ $self->name( $file );
599
+ $self->prefix( $prefix );
600
+
601
+ return 1;
602
+ }
603
+
604
+ =head2 $bool = $file->chmod $mode)
605
+
606
+ Change mode of $file to $mode. The mode can be a string or a number
607
+ which is interpreted as octal whether or not a leading 0 is given.
608
+
609
+ Returns true on success and false on failure.
610
+
611
+ =cut
612
+
613
+ sub chmod {
614
+ my $self = shift;
615
+ my $mode = shift; return unless defined $mode && $mode =~ /^[0-7]{1,4}$/;
616
+ $self->{mode} = oct($mode);
617
+ return 1;
618
+ }
619
+
620
+ =head2 $bool = $file->chown( $user [, $group])
621
+
622
+ Change owner of $file to $user. If a $group is given that is changed
623
+ as well. You can also pass a single parameter with a colon separating the
624
+ use and group as in 'root:wheel'.
625
+
626
+ Returns true on success and false on failure.
627
+
628
+ =cut
629
+
630
+ sub chown {
631
+ my $self = shift;
632
+ my $uname = shift;
633
+ return unless defined $uname;
634
+ my $gname;
635
+ if (-1 != index($uname, ':')) {
636
+ ($uname, $gname) = split(/:/, $uname);
637
+ } else {
638
+ $gname = shift if @_ > 0;
639
+ }
640
+
641
+ $self->uname( $uname );
642
+ $self->gname( $gname ) if $gname;
643
+ return 1;
644
+ }
645
+
646
+ =head1 Convenience methods
647
+
648
+ To quickly check the type of a C<Archive::Tar::File> object, you can
649
+ use the following methods:
650
+
651
+ =over 4
652
+
653
+ =item $file->is_file
654
+
655
+ Returns true if the file is of type C<file>
656
+
657
+ =item $file->is_dir
658
+
659
+ Returns true if the file is of type C<dir>
660
+
661
+ =item $file->is_hardlink
662
+
663
+ Returns true if the file is of type C<hardlink>
664
+
665
+ =item $file->is_symlink
666
+
667
+ Returns true if the file is of type C<symlink>
668
+
669
+ =item $file->is_chardev
670
+
671
+ Returns true if the file is of type C<chardev>
672
+
673
+ =item $file->is_blockdev
674
+
675
+ Returns true if the file is of type C<blockdev>
676
+
677
+ =item $file->is_fifo
678
+
679
+ Returns true if the file is of type C<fifo>
680
+
681
+ =item $file->is_socket
682
+
683
+ Returns true if the file is of type C<socket>
684
+
685
+ =item $file->is_longlink
686
+
687
+ Returns true if the file is of type C<LongLink>.
688
+ Should not happen after a successful C<read>.
689
+
690
+ =item $file->is_label
691
+
692
+ Returns true if the file is of type C<Label>.
693
+ Should not happen after a successful C<read>.
694
+
695
+ =item $file->is_unknown
696
+
697
+ Returns true if the file type is C<unknown>
698
+
699
+ =back
700
+
701
+ =cut
702
+
703
+ #stupid perl5.5.3 needs to warn if it's not numeric
704
+ sub is_file { local $^W; FILE == $_[0]->type }
705
+ sub is_dir { local $^W; DIR == $_[0]->type }
706
+ sub is_hardlink { local $^W; HARDLINK == $_[0]->type }
707
+ sub is_symlink { local $^W; SYMLINK == $_[0]->type }
708
+ sub is_chardev { local $^W; CHARDEV == $_[0]->type }
709
+ sub is_blockdev { local $^W; BLOCKDEV == $_[0]->type }
710
+ sub is_fifo { local $^W; FIFO == $_[0]->type }
711
+ sub is_socket { local $^W; SOCKET == $_[0]->type }
712
+ sub is_unknown { local $^W; UNKNOWN == $_[0]->type }
713
+ sub is_longlink { local $^W; LONGLINK eq $_[0]->type }
714
+ sub is_label { local $^W; LABEL eq $_[0]->type }
715
+
716
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Base.pm ADDED
@@ -0,0 +1,405 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::CBuilder::Base;
2
+ use strict;
3
+ use warnings;
4
+ use File::Spec;
5
+ use File::Basename;
6
+ use Cwd ();
7
+ use Config;
8
+ use Text::ParseWords;
9
+ use IPC::Cmd qw(can_run);
10
+ use File::Temp qw(tempfile);
11
+
12
+ our $VERSION = '0.280231'; # VERSION
13
+
14
+ # More details about C/C++ compilers:
15
+ # http://developers.sun.com/sunstudio/documentation/product/compiler.jsp
16
+ # http://gcc.gnu.org/
17
+ # http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp
18
+ # http://msdn.microsoft.com/en-us/vstudio/default.aspx
19
+
20
+ my %cc2cxx = (
21
+ # first line order is important to support wrappers like in pkgsrc
22
+ cc => [ 'c++', 'CC', 'aCC', 'cxx', ], # Sun Studio, HP ANSI C/C++ Compilers
23
+ gcc => [ 'g++' ], # GNU Compiler Collection
24
+ xlc => [ 'xlC' ], # IBM C/C++ Set, xlc without thread-safety
25
+ xlc_r => [ 'xlC_r' ], # IBM C/C++ Set, xlc with thread-safety
26
+ cl => [ 'cl' ], # Microsoft Visual Studio
27
+ );
28
+
29
+ sub new {
30
+ my $class = shift;
31
+ my $self = bless {@_}, $class;
32
+
33
+ $self->{properties}{perl} = $class->find_perl_interpreter
34
+ or warn "Warning: Can't locate your perl binary";
35
+
36
+ while (my ($k,$v) = each %Config) {
37
+ $self->{config}{$k} = $v unless exists $self->{config}{$k};
38
+ }
39
+ $self->{config}{cc} = $ENV{CC} if defined $ENV{CC};
40
+ $self->{config}{ccflags} = join(" ", $self->{config}{ccflags}, $ENV{CFLAGS})
41
+ if defined $ENV{CFLAGS};
42
+ $self->{config}{cxx} = $ENV{CXX} if defined $ENV{CXX};
43
+ $self->{config}{cxxflags} = $ENV{CXXFLAGS} if defined $ENV{CXXFLAGS};
44
+ $self->{config}{ld} = $ENV{LD} if defined $ENV{LD};
45
+ $self->{config}{ldflags} = join(" ", $self->{config}{ldflags}, $ENV{LDFLAGS})
46
+ if defined $ENV{LDFLAGS};
47
+
48
+ unless ( exists $self->{config}{cxx} ) {
49
+
50
+ my ($ccbase, $ccpath, $ccsfx ) = fileparse($self->{config}{cc}, qr/\.[^.]*/);
51
+
52
+ ## If the path is just "cc", fileparse returns $ccpath as "./"
53
+ $ccpath = "" if $self->{config}{cc} =~ /^\Q$ccbase$ccsfx\E$/;
54
+
55
+ foreach my $cxx (@{$cc2cxx{$ccbase}}) {
56
+ my $cxx1 = File::Spec->catfile( $ccpath, $cxx . $ccsfx);
57
+
58
+ if( can_run( $cxx1 ) ) {
59
+ $self->{config}{cxx} = $cxx1;
60
+ last;
61
+ }
62
+ my $cxx2 = $cxx . $ccsfx;
63
+
64
+ if( can_run( $cxx2 ) ) {
65
+ $self->{config}{cxx} = $cxx2;
66
+ last;
67
+ }
68
+
69
+ if( can_run( $cxx ) ) {
70
+ $self->{config}{cxx} = $cxx;
71
+ last;
72
+ }
73
+ }
74
+ unless ( exists $self->{config}{cxx} ) {
75
+ $self->{config}{cxx} = $self->{config}{cc};
76
+ my $cflags = $self->{config}{ccflags};
77
+ $self->{config}{cxxflags} = '-x c++';
78
+ $self->{config}{cxxflags} .= " $cflags" if defined $cflags;
79
+ }
80
+ }
81
+
82
+ return $self;
83
+ }
84
+
85
+ sub find_perl_interpreter {
86
+ my $perl;
87
+ File::Spec->file_name_is_absolute($perl = $^X)
88
+ or -f ($perl = $Config::Config{perlpath})
89
+ or ($perl = $^X); # XXX how about using IPC::Cmd::can_run here?
90
+ return $perl;
91
+ }
92
+
93
+ sub add_to_cleanup {
94
+ my $self = shift;
95
+ foreach (@_) {
96
+ $self->{files_to_clean}{$_} = 1;
97
+ }
98
+ }
99
+
100
+ sub cleanup {
101
+ my $self = shift;
102
+ foreach my $file (keys %{$self->{files_to_clean}}) {
103
+ unlink $file;
104
+ }
105
+ }
106
+
107
+ sub get_config {
108
+ return %{ $_[0]->{config} };
109
+ }
110
+
111
+ sub object_file {
112
+ my ($self, $filename) = @_;
113
+
114
+ # File name, minus the suffix
115
+ (my $file_base = $filename) =~ s/\.[^.]+$//;
116
+ return "$file_base$self->{config}{obj_ext}";
117
+ }
118
+
119
+ sub arg_include_dirs {
120
+ my $self = shift;
121
+ return map {"-I$_"} @_;
122
+ }
123
+
124
+ sub arg_nolink { '-c' }
125
+
126
+ sub arg_object_file {
127
+ my ($self, $file) = @_;
128
+ return ('-o', $file);
129
+ }
130
+
131
+ sub arg_share_object_file {
132
+ my ($self, $file) = @_;
133
+ return ($self->split_like_shell($self->{config}{lddlflags}), '-o', $file);
134
+ }
135
+
136
+ sub arg_exec_file {
137
+ my ($self, $file) = @_;
138
+ return ('-o', $file);
139
+ }
140
+
141
+ sub arg_defines {
142
+ my ($self, %args) = @_;
143
+ return map "-D$_=$args{$_}", sort keys %args;
144
+ }
145
+
146
+ sub compile {
147
+ my ($self, %args) = @_;
148
+ die "Missing 'source' argument to compile()" unless defined $args{source};
149
+
150
+ my $cf = $self->{config}; # For convenience
151
+
152
+ my $object_file = $args{object_file}
153
+ ? $args{object_file}
154
+ : $self->object_file($args{source});
155
+
156
+ my $include_dirs_ref =
157
+ (exists($args{include_dirs}) && ref($args{include_dirs}) ne "ARRAY")
158
+ ? [ $args{include_dirs} ]
159
+ : $args{include_dirs};
160
+ my @include_dirs = $self->arg_include_dirs(
161
+ @{ $include_dirs_ref || [] },
162
+ $self->perl_inc(),
163
+ );
164
+
165
+ my @defines = $self->arg_defines( %{$args{defines} || {}} );
166
+
167
+ my @extra_compiler_flags =
168
+ $self->split_like_shell($args{extra_compiler_flags});
169
+ my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
170
+ my @ccflags = $self->split_like_shell($args{'C++'} ? $cf->{cxxflags} : $cf->{ccflags});
171
+ my @optimize = $self->split_like_shell($cf->{optimize});
172
+ my @flags = (
173
+ @include_dirs,
174
+ @defines,
175
+ @cccdlflags,
176
+ @extra_compiler_flags,
177
+ $self->arg_nolink,
178
+ @ccflags,
179
+ @optimize,
180
+ $self->arg_object_file($object_file),
181
+ );
182
+ my @cc = $self->split_like_shell($args{'C++'} ? $cf->{cxx} : $cf->{cc});
183
+
184
+ $self->do_system(@cc, @flags, $args{source})
185
+ or die "error building $object_file from '$args{source}'";
186
+
187
+ return $object_file;
188
+ }
189
+
190
+ sub have_compiler {
191
+ my ($self, $is_cplusplus) = @_;
192
+ my $have_compiler_flag = $is_cplusplus ? "have_cxx" : "have_cc";
193
+ my $suffix = $is_cplusplus ? ".cc" : ".c";
194
+ return $self->{$have_compiler_flag} if defined $self->{$have_compiler_flag};
195
+
196
+ my $result;
197
+ my $attempts = 3;
198
+ # tmpdir has issues for some people so fall back to current dir
199
+
200
+ # don't clobber existing files (rare, but possible)
201
+ my ( $FH, $tmpfile ) = tempfile( "compilet-XXXXX", SUFFIX => $suffix );
202
+ binmode $FH;
203
+
204
+ if ( $is_cplusplus ) {
205
+ print $FH "class Bogus { public: int boot_compilet() { return 1; } };\n";
206
+ }
207
+ else {
208
+ print $FH "int boot_compilet() { return 1; }\n";
209
+ }
210
+ close $FH;
211
+
212
+ my ($obj_file, @lib_files);
213
+ eval {
214
+ local $^W = 0;
215
+ local $self->{quiet} = 1;
216
+ $obj_file = $self->compile('C++' => $is_cplusplus, source => $tmpfile);
217
+ @lib_files = $self->link(objects => $obj_file, module_name => 'compilet');
218
+ };
219
+ $result = $@ ? 0 : 1;
220
+
221
+ foreach (grep defined, $tmpfile, $obj_file, @lib_files) {
222
+ 1 while unlink;
223
+ }
224
+
225
+ return $self->{$have_compiler_flag} = $result;
226
+ }
227
+
228
+ sub have_cplusplus {
229
+ push @_, 1;
230
+ goto &have_compiler;
231
+ }
232
+
233
+ sub lib_file {
234
+ my ($self, $dl_file, %args) = @_;
235
+ $dl_file =~ s/\.[^.]+$//;
236
+ $dl_file =~ tr/"//d;
237
+
238
+ if (defined $args{module_name} and length $args{module_name}) {
239
+ # Need to create with the same name as DynaLoader will load with.
240
+ require DynaLoader;
241
+ if (defined &DynaLoader::mod2fname) {
242
+ my $lib = DynaLoader::mod2fname([split /::/, $args{module_name}]);
243
+ my ($dev, $lib_dir, undef) = File::Spec->splitpath($dl_file);
244
+ $dl_file = File::Spec->catpath($dev, $lib_dir, $lib);
245
+ }
246
+ }
247
+
248
+ $dl_file .= ".$self->{config}{dlext}";
249
+
250
+ return $dl_file;
251
+ }
252
+
253
+
254
+ sub exe_file {
255
+ my ($self, $dl_file) = @_;
256
+ $dl_file =~ s/\.[^.]+$//;
257
+ $dl_file =~ tr/"//d;
258
+ return "$dl_file$self->{config}{_exe}";
259
+ }
260
+
261
+ sub need_prelink { 0 }
262
+
263
+ sub extra_link_args_after_prelink { return }
264
+
265
+ sub prelink {
266
+ my ($self, %args) = @_;
267
+
268
+ my ($dl_file_out, $mksymlists_args) = _prepare_mksymlists_args(\%args);
269
+
270
+ require ExtUtils::Mksymlists;
271
+ # dl. abbrev for dynamic library
272
+ ExtUtils::Mksymlists::Mksymlists( %{ $mksymlists_args } );
273
+
274
+ # Mksymlists will create one of these files
275
+ return grep -e, map "$dl_file_out.$_", qw(ext def opt);
276
+ }
277
+
278
+ sub _prepare_mksymlists_args {
279
+ my $args = shift;
280
+ ($args->{dl_file} = $args->{dl_name}) =~ s/.*::// unless $args->{dl_file};
281
+
282
+ my %mksymlists_args = (
283
+ DL_VARS => $args->{dl_vars} || [],
284
+ DL_FUNCS => $args->{dl_funcs} || {},
285
+ FUNCLIST => $args->{dl_func_list} || [],
286
+ IMPORTS => $args->{dl_imports} || {},
287
+ NAME => $args->{dl_name}, # Name of the Perl module
288
+ DLBASE => $args->{dl_base}, # Basename of DLL file
289
+ FILE => $args->{dl_file}, # Dir + Basename of symlist file
290
+ VERSION => (defined $args->{dl_version} ? $args->{dl_version} : '0.0'),
291
+ );
292
+ return ($args->{dl_file}, \%mksymlists_args);
293
+ }
294
+
295
+ sub link {
296
+ my ($self, %args) = @_;
297
+ return $self->_do_link('lib_file', lddl => 1, %args);
298
+ }
299
+
300
+ sub link_executable {
301
+ my ($self, %args) = @_;
302
+ return $self->_do_link('exe_file', lddl => 0, %args);
303
+ }
304
+
305
+ sub _do_link {
306
+ my ($self, $type, %args) = @_;
307
+
308
+ my $cf = $self->{config}; # For convenience
309
+
310
+ my $objects = delete $args{objects};
311
+ $objects = [$objects] unless ref $objects;
312
+ my $out = $args{$type} || $self->$type($objects->[0], %args);
313
+
314
+ my @temp_files;
315
+ @temp_files =
316
+ $self->prelink(%args, dl_name => $args{module_name})
317
+ if $args{lddl} && $self->need_prelink;
318
+
319
+ my @linker_flags = (
320
+ $self->split_like_shell($args{extra_linker_flags}),
321
+ $self->extra_link_args_after_prelink(
322
+ %args, dl_name => $args{module_name}, prelink_res => \@temp_files
323
+ )
324
+ );
325
+
326
+ my @output = $args{lddl}
327
+ ? $self->arg_share_object_file($out)
328
+ : $self->arg_exec_file($out);
329
+ my @shrp = $self->split_like_shell($cf->{shrpenv});
330
+ my @ld = $self->split_like_shell($cf->{ld});
331
+
332
+ $self->do_system(@shrp, @ld, @output, @$objects, @linker_flags)
333
+ or die "error building $out from @$objects";
334
+
335
+ return wantarray ? ($out, @temp_files) : $out;
336
+ }
337
+
338
+
339
+ sub do_system {
340
+ my ($self, @cmd) = @_;
341
+ print "@cmd\n" if !$self->{quiet};
342
+ return !system(@cmd);
343
+ }
344
+
345
+ sub split_like_shell {
346
+ my ($self, $string) = @_;
347
+
348
+ return () unless defined($string);
349
+ return @$string if UNIVERSAL::isa($string, 'ARRAY');
350
+ $string =~ s/^\s+|\s+$//g;
351
+ return () unless length($string);
352
+
353
+ # Text::ParseWords replaces all 'escaped' characters with themselves, which completely
354
+ # breaks paths under windows. As such, we forcibly replace backwards slashes with forward
355
+ # slashes on windows.
356
+ $string =~ s@\\@/@g if $^O eq 'MSWin32';
357
+
358
+ return Text::ParseWords::shellwords($string);
359
+ }
360
+
361
+ # if building perl, perl's main source directory
362
+ sub perl_src {
363
+ # N.B. makemaker actually searches regardless of PERL_CORE, but
364
+ # only squawks at not finding it if PERL_CORE is set
365
+
366
+ return unless $ENV{PERL_CORE};
367
+
368
+ my $Updir = File::Spec->updir;
369
+ my $dir = File::Spec->curdir;
370
+
371
+ # Try up to 5 levels upwards
372
+ for (0..10) {
373
+ if (
374
+ -f File::Spec->catfile($dir,"config_h.SH")
375
+ &&
376
+ -f File::Spec->catfile($dir,"perl.h")
377
+ &&
378
+ -f File::Spec->catfile($dir,"lib","Exporter.pm")
379
+ ) {
380
+ return Cwd::realpath( $dir );
381
+ }
382
+
383
+ $dir = File::Spec->catdir($dir, $Updir);
384
+ }
385
+
386
+ warn "PERL_CORE is set but I can't find your perl source!\n";
387
+ return ''; # return empty string if $ENV{PERL_CORE} but can't find dir ???
388
+ }
389
+
390
+ # directory of perl's include files
391
+ sub perl_inc {
392
+ my $self = shift;
393
+
394
+ $self->perl_src() || File::Spec->catdir($self->{config}{archlibexp},"CORE");
395
+ }
396
+
397
+ sub DESTROY {
398
+ my $self = shift;
399
+ local($., $@, $!, $^E, $?);
400
+ $self->cleanup();
401
+ }
402
+
403
+ 1;
404
+
405
+ # vim: ts=2 sw=2 et:
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/Unix.pm ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::CBuilder::Platform::Unix;
2
+
3
+ use warnings;
4
+ use strict;
5
+ use ExtUtils::CBuilder::Base;
6
+
7
+ our $VERSION = '0.280231'; # VERSION
8
+ our @ISA = qw(ExtUtils::CBuilder::Base);
9
+
10
+ sub link_executable {
11
+ my $self = shift;
12
+
13
+ # On some platforms (which ones??) $Config{cc} seems to be a better
14
+ # bet for linking executables than $Config{ld}. Cygwin is a notable
15
+ # exception.
16
+ local $self->{config}{ld} =
17
+ $self->{config}{cc} . " " . $self->{config}{ldflags};
18
+ return $self->SUPER::link_executable(@_);
19
+ }
20
+
21
+ sub link {
22
+ my $self = shift;
23
+ my $cf = $self->{config};
24
+
25
+ # Some platforms (notably Mac OS X 10.3, but some others too) expect
26
+ # the syntax "FOO=BAR /bin/command arg arg" to work in %Config
27
+ # (notably $Config{ld}). It usually works in system(SCALAR), but we
28
+ # use system(LIST). We fix it up here with 'env'.
29
+
30
+ local $cf->{ld} = $cf->{ld};
31
+ if (ref $cf->{ld}) {
32
+ unshift @{$cf->{ld}}, 'env' if $cf->{ld}[0] =~ /^\s*\w+=/;
33
+ } else {
34
+ $cf->{ld} =~ s/^(\s*\w+=)/env $1/;
35
+ }
36
+
37
+ return $self->SUPER::link(@_);
38
+ }
39
+
40
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/VMS.pm ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::CBuilder::Platform::VMS;
2
+
3
+ use warnings;
4
+ use strict;
5
+ use ExtUtils::CBuilder::Base;
6
+
7
+ our $VERSION = '0.280231'; # VERSION
8
+ our @ISA = qw(ExtUtils::CBuilder::Base);
9
+
10
+ use File::Spec::Functions qw(catfile catdir);
11
+ use Config;
12
+
13
+ # We do prelink, but don't want the parent to redo it.
14
+
15
+ sub need_prelink { 0 }
16
+
17
+ sub arg_defines {
18
+ my ($self, %args) = @_;
19
+
20
+ s/"/""/g foreach values %args;
21
+
22
+ my @config_defines;
23
+
24
+ # VMS can only have one define qualifier; add the one from config, if any.
25
+ if ($self->{config}{ccflags} =~ s{/ def[^=]+ =+ \(? ([^\/\)]*) } {}ix) {
26
+ push @config_defines, $1;
27
+ }
28
+
29
+ return '' unless keys(%args) || @config_defines;
30
+
31
+ return ('/define=('
32
+ . join(',',
33
+ @config_defines,
34
+ map "\"$_" . ( length($args{$_}) ? "=$args{$_}" : '') . "\"",
35
+ sort keys %args)
36
+ . ')');
37
+ }
38
+
39
+ sub arg_include_dirs {
40
+ my ($self, @dirs) = @_;
41
+
42
+ # VMS can only have one include list, add the one from config.
43
+ if ($self->{config}{ccflags} =~ s{/inc[^=]+(?:=)+(?:\()?([^\/\)]*)} {}i) {
44
+ unshift @dirs, $1;
45
+ }
46
+ return unless @dirs;
47
+
48
+ return ('/include=(' . join(',', @dirs) . ')');
49
+ }
50
+
51
+ # We override the compile method because we consume the includes and defines
52
+ # parts of ccflags in the process of compiling but don't save those parts
53
+ # anywhere, so $self->{config}{ccflags} needs to be reset for each compile
54
+ # operation.
55
+
56
+ sub compile {
57
+ my ($self, %args) = @_;
58
+
59
+ $self->{config}{ccflags} = $Config{ccflags};
60
+ $self->{config}{ccflags} = $ENV{CFLAGS} if defined $ENV{CFLAGS};
61
+
62
+ return $self->SUPER::compile(%args);
63
+ }
64
+
65
+ sub _do_link {
66
+ my ($self, $type, %args) = @_;
67
+
68
+ my $objects = delete $args{objects};
69
+ $objects = [$objects] unless ref $objects;
70
+
71
+ if ($args{lddl}) {
72
+
73
+ # prelink will call Mksymlists, which creates the extension-specific
74
+ # linker options file and populates it with the boot symbol.
75
+
76
+ my @temp_files = $self->prelink(%args, dl_name => $args{module_name});
77
+
78
+ # We now add the rest of what we need to the linker options file. We
79
+ # should replicate the functionality of C<ExtUtils::MM_VMS::dlsyms>,
80
+ # but there is as yet no infrastructure for handling object libraries,
81
+ # so for now we depend on object files being listed individually on the
82
+ # command line, which should work for simple cases. We do bring in our
83
+ # own version of C<ExtUtils::Liblist::Kid::ext> so that any additional
84
+ # libraries (including PERLSHR) can be added to the options file.
85
+
86
+ my @optlibs = $self->_liblist_ext( $args{'libs'} );
87
+
88
+ my $optfile = 'sys$disk:[]' . $temp_files[0];
89
+ open my $opt_fh, '>>', $optfile
90
+ or die "_do_link: Unable to open $optfile: $!";
91
+ for my $lib (@optlibs) {print $opt_fh "$lib\n" if length $lib }
92
+ close $opt_fh;
93
+
94
+ $objects->[-1] .= ',';
95
+ push @$objects, $optfile . '/OPTIONS,';
96
+
97
+ # This one not needed for DEC C, but leave for completeness.
98
+ push @$objects, $self->perl_inc() . 'perlshr_attr.opt/OPTIONS';
99
+ }
100
+
101
+ return $self->SUPER::_do_link($type, %args, objects => $objects);
102
+ }
103
+
104
+ sub arg_nolink { return; }
105
+
106
+ sub arg_object_file {
107
+ my ($self, $file) = @_;
108
+ return "/obj=$file";
109
+ }
110
+
111
+ sub arg_exec_file {
112
+ my ($self, $file) = @_;
113
+ return ("/exe=$file");
114
+ }
115
+
116
+ sub arg_share_object_file {
117
+ my ($self, $file) = @_;
118
+ return ("$self->{config}{lddlflags}=$file");
119
+ }
120
+
121
+ # The following is reproduced almost verbatim from ExtUtils::Liblist::Kid::_vms_ext.
122
+ # We can't just call that because it's tied up with the MakeMaker object hierarchy.
123
+
124
+ sub _liblist_ext {
125
+ my($self, $potential_libs,$verbose,$give_libs) = @_;
126
+ $verbose ||= 0;
127
+
128
+ my(@crtls,$crtlstr);
129
+ @crtls = ( ($self->{'config'}{'ldflags'} =~ m-/Debug-i ? $self->{'config'}{'dbgprefix'} : '')
130
+ . 'PerlShr/Share' );
131
+ push(@crtls, grep { not /\(/ } split /\s+/, $self->{'config'}{'perllibs'});
132
+ push(@crtls, grep { not /\(/ } split /\s+/, $self->{'config'}{'libc'});
133
+ # In general, we pass through the basic libraries from %Config unchanged.
134
+ # The one exception is that if we're building in the Perl source tree, and
135
+ # a library spec could be resolved via a logical name, we go to some trouble
136
+ # to ensure that the copy in the local tree is used, rather than one to
137
+ # which a system-wide logical may point.
138
+ if ($self->perl_src) {
139
+ my($lib,$locspec,$type);
140
+ foreach $lib (@crtls) {
141
+ if (($locspec,$type) = $lib =~ m{^([\w\$-]+)(/\w+)?} and $locspec =~ /perl/i) {
142
+ if (lc $type eq '/share') { $locspec .= $self->{'config'}{'exe_ext'}; }
143
+ elsif (lc $type eq '/library') { $locspec .= $self->{'config'}{'lib_ext'}; }
144
+ else { $locspec .= $self->{'config'}{'obj_ext'}; }
145
+ $locspec = catfile($self->perl_src, $locspec);
146
+ $lib = "$locspec$type" if -e $locspec;
147
+ }
148
+ }
149
+ }
150
+ $crtlstr = @crtls ? join(' ',@crtls) : '';
151
+
152
+ unless ($potential_libs) {
153
+ warn "Result:\n\tEXTRALIBS: \n\tLDLOADLIBS: $crtlstr\n" if $verbose;
154
+ return ('', '', $crtlstr, '', ($give_libs ? [] : ()));
155
+ }
156
+
157
+ my(@dirs,@libs,$dir,$lib,%found,@fndlibs,$ldlib);
158
+ my $cwd = cwd();
159
+ my($so,$lib_ext,$obj_ext) = @{$self->{'config'}}{'so','lib_ext','obj_ext'};
160
+ # List of common Unix library names and their VMS equivalents
161
+ # (VMS equivalent of '' indicates that the library is automatically
162
+ # searched by the linker, and should be skipped here.)
163
+ my(@flibs, %libs_seen);
164
+ my %libmap = ( 'm' => '', 'f77' => '', 'F77' => '', 'V77' => '', 'c' => '',
165
+ 'malloc' => '', 'crypt' => '', 'resolv' => '', 'c_s' => '',
166
+ 'socket' => '', 'X11' => 'DECW$XLIBSHR',
167
+ 'Xt' => 'DECW$XTSHR', 'Xm' => 'DECW$XMLIBSHR',
168
+ 'Xmu' => 'DECW$XMULIBSHR');
169
+
170
+ warn "Potential libraries are '$potential_libs'\n" if $verbose;
171
+
172
+ # First, sort out directories and library names in the input
173
+ foreach $lib (split ' ',$potential_libs) {
174
+ push(@dirs,$1), next if $lib =~ /^-L(.*)/;
175
+ push(@dirs,$lib), next if $lib =~ /[:>\]]$/;
176
+ push(@dirs,$lib), next if -d $lib;
177
+ push(@libs,$1), next if $lib =~ /^-l(.*)/;
178
+ push(@libs,$lib);
179
+ }
180
+ push(@dirs,split(' ',$self->{'config'}{'libpth'}));
181
+
182
+ # Now make sure we've got VMS-syntax absolute directory specs
183
+ # (We don't, however, check whether someone's hidden a relative
184
+ # path in a logical name.)
185
+ foreach $dir (@dirs) {
186
+ unless (-d $dir) {
187
+ warn "Skipping nonexistent Directory $dir\n" if $verbose > 1;
188
+ $dir = '';
189
+ next;
190
+ }
191
+ warn "Resolving directory $dir\n" if $verbose;
192
+ if (!File::Spec->file_name_is_absolute($dir)) {
193
+ $dir = catdir($cwd,$dir);
194
+ }
195
+ }
196
+ @dirs = grep { length($_) } @dirs;
197
+ unshift(@dirs,''); # Check each $lib without additions first
198
+
199
+ LIB: foreach $lib (@libs) {
200
+ if (exists $libmap{$lib}) {
201
+ next unless length $libmap{$lib};
202
+ $lib = $libmap{$lib};
203
+ }
204
+
205
+ my(@variants,$variant,$cand);
206
+ my($ctype) = '';
207
+
208
+ # If we don't have a file type, consider it a possibly abbreviated name and
209
+ # check for common variants. We try these first to grab libraries before
210
+ # a like-named executable image (e.g. -lperl resolves to perlshr.exe
211
+ # before perl.exe).
212
+ if ($lib !~ /\.[^:>\]]*$/) {
213
+ push(@variants,"${lib}shr","${lib}rtl","${lib}lib");
214
+ push(@variants,"lib$lib") if $lib !~ /[:>\]]/;
215
+ }
216
+ push(@variants,$lib);
217
+ warn "Looking for $lib\n" if $verbose;
218
+ foreach $variant (@variants) {
219
+ my($fullname, $name);
220
+
221
+ foreach $dir (@dirs) {
222
+ my($type);
223
+
224
+ $name = "$dir$variant";
225
+ warn "\tChecking $name\n" if $verbose > 2;
226
+ $fullname = VMS::Filespec::rmsexpand($name);
227
+ if (defined $fullname and -f $fullname) {
228
+ # It's got its own suffix, so we'll have to figure out the type
229
+ if ($fullname =~ /(?:$so|exe)$/i) { $type = 'SHR'; }
230
+ elsif ($fullname =~ /(?:$lib_ext|olb)$/i) { $type = 'OLB'; }
231
+ elsif ($fullname =~ /(?:$obj_ext|obj)$/i) {
232
+ warn "Note (probably harmless): "
233
+ ."Plain object file $fullname found in library list\n";
234
+ $type = 'OBJ';
235
+ }
236
+ else {
237
+ warn "Note (probably harmless): "
238
+ ."Unknown library type for $fullname; assuming shared\n";
239
+ $type = 'SHR';
240
+ }
241
+ }
242
+ elsif (-f ($fullname = VMS::Filespec::rmsexpand($name,$so)) or
243
+ -f ($fullname = VMS::Filespec::rmsexpand($name,'.exe'))) {
244
+ $type = 'SHR';
245
+ $name = $fullname unless $fullname =~ /exe;?\d*$/i;
246
+ }
247
+ elsif (not length($ctype) and # If we've got a lib already,
248
+ # don't bother
249
+ ( -f ($fullname = VMS::Filespec::rmsexpand($name,$lib_ext)) or
250
+ -f ($fullname = VMS::Filespec::rmsexpand($name,'.olb')))) {
251
+ $type = 'OLB';
252
+ $name = $fullname unless $fullname =~ /olb;?\d*$/i;
253
+ }
254
+ elsif (not length($ctype) and # If we've got a lib already,
255
+ # don't bother
256
+ ( -f ($fullname = VMS::Filespec::rmsexpand($name,$obj_ext)) or
257
+ -f ($fullname = VMS::Filespec::rmsexpand($name,'.obj')))) {
258
+ warn "Note (probably harmless): "
259
+ ."Plain object file $fullname found in library list\n";
260
+ $type = 'OBJ';
261
+ $name = $fullname unless $fullname =~ /obj;?\d*$/i;
262
+ }
263
+ if (defined $type) {
264
+ $ctype = $type; $cand = $name;
265
+ last if $ctype eq 'SHR';
266
+ }
267
+ }
268
+ if ($ctype) {
269
+ push @{$found{$ctype}}, $cand;
270
+ warn "\tFound as $cand (really $fullname), type $ctype\n"
271
+ if $verbose > 1;
272
+ push @flibs, $name unless $libs_seen{$fullname}++;
273
+ next LIB;
274
+ }
275
+ }
276
+ warn "Note (probably harmless): "
277
+ ."No library found for $lib\n";
278
+ }
279
+
280
+ push @fndlibs, @{$found{OBJ}} if exists $found{OBJ};
281
+ push @fndlibs, map { "$_/Library" } @{$found{OLB}} if exists $found{OLB};
282
+ push @fndlibs, map { "$_/Share" } @{$found{SHR}} if exists $found{SHR};
283
+ $lib = join(' ',@fndlibs);
284
+
285
+ $ldlib = $crtlstr ? "$lib $crtlstr" : $lib;
286
+ warn "Result:\n\tEXTRALIBS: $lib\n\tLDLOADLIBS: $ldlib\n" if $verbose;
287
+ wantarray ? ($lib, '', $ldlib, '', ($give_libs ? \@flibs : ())) : $lib;
288
+ }
289
+
290
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/android.pm ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::CBuilder::Platform::android;
2
+
3
+ use warnings;
4
+ use strict;
5
+ use File::Spec;
6
+ use ExtUtils::CBuilder::Platform::Unix;
7
+ use Config;
8
+
9
+ our $VERSION = '0.280231'; # VERSION
10
+ our @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
11
+
12
+ # The Android linker will not recognize symbols from
13
+ # libperl unless the module explicitly depends on it.
14
+ sub link {
15
+ my ($self, %args) = @_;
16
+
17
+ if ($self->{config}{useshrplib} eq 'true') {
18
+ $args{extra_linker_flags} = [
19
+ $self->split_like_shell($args{extra_linker_flags}),
20
+ '-L' . $self->perl_inc(),
21
+ '-lperl',
22
+ $self->split_like_shell($Config{perllibs}),
23
+ ];
24
+ }
25
+
26
+ # Several modules on CPAN rather rightfully expect being
27
+ # able to pass $so_file to DynaLoader::dl_load_file and
28
+ # have it Just Work. However, $so_file will more likely
29
+ # than not be a relative path, and unless the module
30
+ # author subclasses MakeMaker/Module::Build to modify
31
+ # LD_LIBRARY_PATH, which would be insane, Android's linker
32
+ # won't find the .so
33
+ # So we make this all work by returning an absolute path.
34
+ my($so_file, @so_tmps) = $self->SUPER::link(%args);
35
+ $so_file = File::Spec->rel2abs($so_file);
36
+ return wantarray ? ($so_file, @so_tmps) : $so_file;
37
+ }
38
+
39
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/cygwin.pm ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::CBuilder::Platform::cygwin;
2
+
3
+ use warnings;
4
+ use strict;
5
+ use File::Spec;
6
+ use ExtUtils::CBuilder::Platform::Unix;
7
+
8
+ our $VERSION = '0.280231'; # VERSION
9
+ our @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
10
+
11
+ # TODO: If a specific exe_file name is requested, if the exe created
12
+ # doesn't have that name, we might want to rename it. Apparently asking
13
+ # for an exe of "foo" might result in "foo.exe". Alternatively, we should
14
+ # make sure the return value is correctly "foo.exe".
15
+ # C.f http://rt.cpan.org/Public/Bug/Display.html?id=41003
16
+ sub link_executable {
17
+ my $self = shift;
18
+ return $self->SUPER::link_executable(@_);
19
+ }
20
+
21
+ sub link {
22
+ my ($self, %args) = @_;
23
+
24
+ my $lib = $self->{config}{useshrplib} ? 'libperl.dll.a' : 'libperl.a';
25
+ $args{extra_linker_flags} = [
26
+ File::Spec->catfile($self->perl_inc(), $lib),
27
+ $self->split_like_shell($args{extra_linker_flags})
28
+ ];
29
+
30
+ return $self->SUPER::link(%args);
31
+ }
32
+
33
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/CBuilder/Platform/darwin.pm ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::CBuilder::Platform::darwin;
2
+
3
+ use warnings;
4
+ use strict;
5
+ use ExtUtils::CBuilder::Platform::Unix;
6
+
7
+ our $VERSION = '0.280231'; # VERSION
8
+ our @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
9
+
10
+ sub compile {
11
+ my $self = shift;
12
+ my $cf = $self->{config};
13
+
14
+ # -flat_namespace isn't a compile flag, it's a linker flag. But
15
+ # it's mistakenly in Config.pm as both. Make the correction here.
16
+ local $cf->{ccflags} = $cf->{ccflags};
17
+ $cf->{ccflags} =~ s/-flat_namespace//;
18
+ $self->SUPER::compile(@_);
19
+ }
20
+
21
+
22
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Command/MM.pm ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Command::MM;
2
+
3
+ require 5.006;
4
+
5
+ use strict;
6
+ use warnings;
7
+
8
+ require Exporter;
9
+ our @ISA = qw(Exporter);
10
+
11
+ our @EXPORT = qw(test_harness pod2man perllocal_install uninstall
12
+ warn_if_old_packlist test_s cp_nonempty);
13
+ our $VERSION = '7.34';
14
+ $VERSION = eval $VERSION;
15
+
16
+ my $Is_VMS = $^O eq 'VMS';
17
+
18
+ sub mtime {
19
+ no warnings 'redefine';
20
+ local $@;
21
+ *mtime = (eval { require Time::HiRes } && defined &Time::HiRes::stat)
22
+ ? sub { (Time::HiRes::stat($_[0]))[9] }
23
+ : sub { ( stat($_[0]))[9] }
24
+ ;
25
+ goto &mtime;
26
+ }
27
+
28
+ =head1 NAME
29
+
30
+ ExtUtils::Command::MM - Commands for the MM's to use in Makefiles
31
+
32
+ =head1 SYNOPSIS
33
+
34
+ perl "-MExtUtils::Command::MM" -e "function" "--" arguments...
35
+
36
+
37
+ =head1 DESCRIPTION
38
+
39
+ B<FOR INTERNAL USE ONLY!> The interface is not stable.
40
+
41
+ ExtUtils::Command::MM encapsulates code which would otherwise have to
42
+ be done with large "one" liners.
43
+
44
+ Any $(FOO) used in the examples are make variables, not Perl.
45
+
46
+ =over 4
47
+
48
+ =item B<test_harness>
49
+
50
+ test_harness($verbose, @test_libs);
51
+
52
+ Runs the tests on @ARGV via Test::Harness passing through the $verbose
53
+ flag. Any @test_libs will be unshifted onto the test's @INC.
54
+
55
+ @test_libs are run in alphabetical order.
56
+
57
+ =cut
58
+
59
+ sub test_harness {
60
+ require Test::Harness;
61
+ require File::Spec;
62
+
63
+ $Test::Harness::verbose = shift;
64
+
65
+ # Because Windows doesn't do this for us and listing all the *.t files
66
+ # out on the command line can blow over its exec limit.
67
+ require ExtUtils::Command;
68
+ my @argv = ExtUtils::Command::expand_wildcards(@ARGV);
69
+
70
+ local @INC = @INC;
71
+ unshift @INC, map { File::Spec->rel2abs($_) } @_;
72
+ Test::Harness::runtests(sort { lc $a cmp lc $b } @argv);
73
+ }
74
+
75
+
76
+
77
+ =item B<pod2man>
78
+
79
+ pod2man( '--option=value',
80
+ $podfile1 => $manpage1,
81
+ $podfile2 => $manpage2,
82
+ ...
83
+ );
84
+
85
+ # or args on @ARGV
86
+
87
+ pod2man() is a function performing most of the duties of the pod2man
88
+ program. Its arguments are exactly the same as pod2man as of 5.8.0
89
+ with the addition of:
90
+
91
+ --perm_rw octal permission to set the resulting manpage to
92
+
93
+ And the removal of:
94
+
95
+ --verbose/-v
96
+ --help/-h
97
+
98
+ If no arguments are given to pod2man it will read from @ARGV.
99
+
100
+ If Pod::Man is unavailable, this function will warn and return undef.
101
+
102
+ =cut
103
+
104
+ sub pod2man {
105
+ local @ARGV = @_ ? @_ : @ARGV;
106
+
107
+ {
108
+ local $@;
109
+ if( !eval { require Pod::Man } ) {
110
+ warn "Pod::Man is not available: $@".
111
+ "Man pages will not be generated during this install.\n";
112
+ return 0;
113
+ }
114
+ }
115
+ require Getopt::Long;
116
+
117
+ # We will cheat and just use Getopt::Long. We fool it by putting
118
+ # our arguments into @ARGV. Should be safe.
119
+ my %options = ();
120
+ Getopt::Long::config ('bundling_override');
121
+ Getopt::Long::GetOptions (\%options,
122
+ 'section|s=s', 'release|r=s', 'center|c=s',
123
+ 'date|d=s', 'fixed=s', 'fixedbold=s', 'fixeditalic=s',
124
+ 'fixedbolditalic=s', 'official|o', 'quotes|q=s', 'lax|l',
125
+ 'name|n=s', 'perm_rw=i', 'utf8|u'
126
+ );
127
+ delete $options{utf8} unless $Pod::Man::VERSION >= 2.17;
128
+
129
+ # If there's no files, don't bother going further.
130
+ return 0 unless @ARGV;
131
+
132
+ # Official sets --center, but don't override things explicitly set.
133
+ if ($options{official} && !defined $options{center}) {
134
+ $options{center} = q[Perl Programmer's Reference Guide];
135
+ }
136
+
137
+ # This isn't a valid Pod::Man option and is only accepted for backwards
138
+ # compatibility.
139
+ delete $options{lax};
140
+ my $count = scalar @ARGV / 2;
141
+ my $plural = $count == 1 ? 'document' : 'documents';
142
+ print "Manifying $count pod $plural\n";
143
+
144
+ do {{ # so 'next' works
145
+ my ($pod, $man) = splice(@ARGV, 0, 2);
146
+
147
+ next if ((-e $man) &&
148
+ (mtime($man) > mtime($pod)) &&
149
+ (mtime($man) > mtime("Makefile")));
150
+
151
+ my $parser = Pod::Man->new(%options);
152
+ $parser->parse_from_file($pod, $man)
153
+ or do { warn("Could not install $man\n"); next };
154
+
155
+ if (exists $options{perm_rw}) {
156
+ chmod(oct($options{perm_rw}), $man)
157
+ or do { warn("chmod $options{perm_rw} $man: $!\n"); next };
158
+ }
159
+ }} while @ARGV;
160
+
161
+ return 1;
162
+ }
163
+
164
+
165
+ =item B<warn_if_old_packlist>
166
+
167
+ perl "-MExtUtils::Command::MM" -e warn_if_old_packlist <somefile>
168
+
169
+ Displays a warning that an old packlist file was found. Reads the
170
+ filename from @ARGV.
171
+
172
+ =cut
173
+
174
+ sub warn_if_old_packlist {
175
+ my $packlist = $ARGV[0];
176
+
177
+ return unless -f $packlist;
178
+ print <<"PACKLIST_WARNING";
179
+ WARNING: I have found an old package in
180
+ $packlist.
181
+ Please make sure the two installations are not conflicting
182
+ PACKLIST_WARNING
183
+
184
+ }
185
+
186
+
187
+ =item B<perllocal_install>
188
+
189
+ perl "-MExtUtils::Command::MM" -e perllocal_install
190
+ <type> <module name> <key> <value> ...
191
+
192
+ # VMS only, key|value pairs come on STDIN
193
+ perl "-MExtUtils::Command::MM" -e perllocal_install
194
+ <type> <module name> < <key>|<value> ...
195
+
196
+ Prints a fragment of POD suitable for appending to perllocal.pod.
197
+ Arguments are read from @ARGV.
198
+
199
+ 'type' is the type of what you're installing. Usually 'Module'.
200
+
201
+ 'module name' is simply the name of your module. (Foo::Bar)
202
+
203
+ Key/value pairs are extra information about the module. Fields include:
204
+
205
+ installed into which directory your module was out into
206
+ LINKTYPE dynamic or static linking
207
+ VERSION module version number
208
+ EXE_FILES any executables installed in a space separated
209
+ list
210
+
211
+ =cut
212
+
213
+ sub perllocal_install {
214
+ my($type, $name) = splice(@ARGV, 0, 2);
215
+
216
+ # VMS feeds args as a piped file on STDIN since it usually can't
217
+ # fit all the args on a single command line.
218
+ my @mod_info = $Is_VMS ? split /\|/, <STDIN>
219
+ : @ARGV;
220
+
221
+ my $pod;
222
+ my $time = gmtime($ENV{SOURCE_DATE_EPOCH} || time);
223
+ $pod = sprintf <<'POD', scalar($time), $type, $name, $name;
224
+ =head2 %s: C<%s> L<%s|%s>
225
+
226
+ =over 4
227
+
228
+ POD
229
+
230
+ do {
231
+ my($key, $val) = splice(@mod_info, 0, 2);
232
+
233
+ $pod .= <<POD
234
+ =item *
235
+
236
+ C<$key: $val>
237
+
238
+ POD
239
+
240
+ } while(@mod_info);
241
+
242
+ $pod .= "=back\n\n";
243
+ $pod =~ s/^ //mg;
244
+ print $pod;
245
+
246
+ return 1;
247
+ }
248
+
249
+ =item B<uninstall>
250
+
251
+ perl "-MExtUtils::Command::MM" -e uninstall <packlist>
252
+
253
+ A wrapper around ExtUtils::Install::uninstall(). Warns that
254
+ uninstallation is deprecated and doesn't actually perform the
255
+ uninstallation.
256
+
257
+ =cut
258
+
259
+ sub uninstall {
260
+ my($packlist) = shift @ARGV;
261
+
262
+ require ExtUtils::Install;
263
+
264
+ print <<'WARNING';
265
+
266
+ Uninstall is unsafe and deprecated, the uninstallation was not performed.
267
+ We will show what would have been done.
268
+
269
+ WARNING
270
+
271
+ ExtUtils::Install::uninstall($packlist, 1, 1);
272
+
273
+ print <<'WARNING';
274
+
275
+ Uninstall is unsafe and deprecated, the uninstallation was not performed.
276
+ Please check the list above carefully, there may be errors.
277
+ Remove the appropriate files manually.
278
+ Sorry for the inconvenience.
279
+
280
+ WARNING
281
+
282
+ }
283
+
284
+ =item B<test_s>
285
+
286
+ perl "-MExtUtils::Command::MM" -e test_s <file>
287
+
288
+ Tests if a file exists and is not empty (size > 0).
289
+ I<Exits> with 0 if it does, 1 if it does not.
290
+
291
+ =cut
292
+
293
+ sub test_s {
294
+ exit(-s $ARGV[0] ? 0 : 1);
295
+ }
296
+
297
+ =item B<cp_nonempty>
298
+
299
+ perl "-MExtUtils::Command::MM" -e cp_nonempty <srcfile> <dstfile> <perm>
300
+
301
+ Tests if the source file exists and is not empty (size > 0). If it is not empty
302
+ it copies it to the given destination with the given permissions.
303
+
304
+ =back
305
+
306
+ =cut
307
+
308
+ sub cp_nonempty {
309
+ my @args = @ARGV;
310
+ return 0 unless -s $args[0];
311
+ require ExtUtils::Command;
312
+ {
313
+ local @ARGV = @args[0,1];
314
+ ExtUtils::Command::cp(@ARGV);
315
+ }
316
+ {
317
+ local @ARGV = @args[2,1];
318
+ ExtUtils::Command::chmod(@ARGV);
319
+ }
320
+ }
321
+
322
+
323
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Constant/Base.pm ADDED
@@ -0,0 +1,1019 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Constant::Base;
2
+
3
+ use strict;
4
+ use vars qw($VERSION);
5
+ use Carp;
6
+ use Text::Wrap;
7
+ use ExtUtils::Constant::Utils qw(C_stringify perl_stringify);
8
+ $VERSION = '0.06';
9
+
10
+ use constant is_perl56 => ($] < 5.007 && $] > 5.005_50);
11
+
12
+
13
+ =head1 NAME
14
+
15
+ ExtUtils::Constant::Base - base class for ExtUtils::Constant objects
16
+
17
+ =head1 SYNOPSIS
18
+
19
+ require ExtUtils::Constant::Base;
20
+ @ISA = 'ExtUtils::Constant::Base';
21
+
22
+ =head1 DESCRIPTION
23
+
24
+ ExtUtils::Constant::Base provides a base implementation of methods to
25
+ generate C code to give fast constant value lookup by named string. Currently
26
+ it's mostly used ExtUtils::Constant::XS, which generates the lookup code
27
+ for the constant() subroutine found in many XS modules.
28
+
29
+ =head1 USAGE
30
+
31
+ ExtUtils::Constant::Base exports no subroutines. The following methods are
32
+ available
33
+
34
+ =over 4
35
+
36
+ =cut
37
+
38
+ sub valid_type {
39
+ # Default to assuming that you don't need different types of return data.
40
+ 1;
41
+ }
42
+ sub default_type {
43
+ '';
44
+ }
45
+
46
+ =item header
47
+
48
+ A method returning a scalar containing definitions needed, typically for a
49
+ C header file.
50
+
51
+ =cut
52
+
53
+ sub header {
54
+ ''
55
+ }
56
+
57
+ # This might actually be a return statement. Note that you are responsible
58
+ # for any space you might need before your value, as it lets to perform
59
+ # "tricks" such as "return KEY_" and have strings appended.
60
+ sub assignment_clause_for_type;
61
+ # In which case this might be an empty string
62
+ sub return_statement_for_type {undef};
63
+ sub return_statement_for_notdef;
64
+ sub return_statement_for_notfound;
65
+
66
+ # "#if 1" is true to a C pre-processor
67
+ sub macro_from_name {
68
+ 1;
69
+ }
70
+
71
+ sub macro_from_item {
72
+ 1;
73
+ }
74
+
75
+ sub macro_to_ifdef {
76
+ my ($self, $macro) = @_;
77
+ if (ref $macro) {
78
+ return $macro->[0];
79
+ }
80
+ if (defined $macro && $macro ne "" && $macro ne "1") {
81
+ return $macro ? "#ifdef $macro\n" : "#if 0\n";
82
+ }
83
+ return "";
84
+ }
85
+
86
+ sub macro_to_ifndef {
87
+ my ($self, $macro) = @_;
88
+ if (ref $macro) {
89
+ # Can't invert these stylishly, so "bodge it"
90
+ return "$macro->[0]#else\n";
91
+ }
92
+ if (defined $macro && $macro ne "" && $macro ne "1") {
93
+ return $macro ? "#ifndef $macro\n" : "#if 1\n";
94
+ }
95
+ croak "Can't generate an ifndef for unconditional code";
96
+ }
97
+
98
+ sub macro_to_endif {
99
+ my ($self, $macro) = @_;
100
+
101
+ if (ref $macro) {
102
+ return $macro->[1];
103
+ }
104
+ if (defined $macro && $macro ne "" && $macro ne "1") {
105
+ return "#endif\n";
106
+ }
107
+ return "";
108
+ }
109
+
110
+ sub name_param {
111
+ 'name';
112
+ }
113
+
114
+ # This is possibly buggy, in that it's not mandatory (below, in the main
115
+ # C_constant parameters, but is expected to exist here, if it's needed)
116
+ # Buggy because if you're definitely pure 8 bit only, and will never be
117
+ # presented with your constants in utf8, the default form of C_constant can't
118
+ # be told not to do the utf8 version.
119
+
120
+ sub is_utf8_param {
121
+ 'utf8';
122
+ }
123
+
124
+ sub memEQ {
125
+ "!memcmp";
126
+ }
127
+
128
+ =item memEQ_clause args_hashref
129
+
130
+ A method to return a suitable C C<if> statement to check whether I<name>
131
+ is equal to the C variable C<name>. If I<checked_at> is defined, then it
132
+ is used to avoid C<memEQ> for short names, or to generate a comment to
133
+ highlight the position of the character in the C<switch> statement.
134
+
135
+ If i<checked_at> is a reference to a scalar, then instead it gives
136
+ the characters pre-checked at the beginning, (and the number of chars by
137
+ which the C variable name has been advanced. These need to be chopped from
138
+ the front of I<name>).
139
+
140
+ =cut
141
+
142
+ sub memEQ_clause {
143
+ # if (memEQ(name, "thingy", 6)) {
144
+ # Which could actually be a character comparison or even ""
145
+ my ($self, $args) = @_;
146
+ my ($name, $checked_at, $indent) = @{$args}{qw(name checked_at indent)};
147
+ $indent = ' ' x ($indent || 4);
148
+ my $front_chop;
149
+ if (ref $checked_at) {
150
+ # regexp won't work on 5.6.1 without use utf8; in turn that won't work
151
+ # on 5.005_03.
152
+ substr ($name, 0, length $$checked_at,) = '';
153
+ $front_chop = C_stringify ($$checked_at);
154
+ undef $checked_at;
155
+ }
156
+ my $len = length $name;
157
+
158
+ if ($len < 2) {
159
+ return $indent . "{\n"
160
+ if (defined $checked_at and $checked_at == 0) or $len == 0;
161
+ # We didn't switch, drop through to the code for the 2 character string
162
+ $checked_at = 1;
163
+ }
164
+
165
+ my $name_param = $self->name_param;
166
+
167
+ if ($len < 3 and defined $checked_at) {
168
+ my $check;
169
+ if ($checked_at == 1) {
170
+ $check = 0;
171
+ } elsif ($checked_at == 0) {
172
+ $check = 1;
173
+ }
174
+ if (defined $check) {
175
+ my $char = C_stringify (substr $name, $check, 1);
176
+ # Placate 5.005 with a break in the string. I can't see a good way of
177
+ # getting it to not take [ as introducing an array lookup, even with
178
+ # ${name_param}[$check]
179
+ return $indent . "if ($name_param" . "[$check] == '$char') {\n";
180
+ }
181
+ }
182
+ if (($len == 2 and !defined $checked_at)
183
+ or ($len == 3 and defined ($checked_at) and $checked_at == 2)) {
184
+ my $char1 = C_stringify (substr $name, 0, 1);
185
+ my $char2 = C_stringify (substr $name, 1, 1);
186
+ return $indent .
187
+ "if ($name_param" . "[0] == '$char1' && $name_param" . "[1] == '$char2') {\n";
188
+ }
189
+ if (($len == 3 and defined ($checked_at) and $checked_at == 1)) {
190
+ my $char1 = C_stringify (substr $name, 0, 1);
191
+ my $char2 = C_stringify (substr $name, 2, 1);
192
+ return $indent .
193
+ "if ($name_param" . "[0] == '$char1' && $name_param" . "[2] == '$char2') {\n";
194
+ }
195
+
196
+ my $pointer = '^';
197
+ my $have_checked_last = defined ($checked_at) && $len == $checked_at + 1;
198
+ if ($have_checked_last) {
199
+ # Checked at the last character, so no need to memEQ it.
200
+ $pointer = C_stringify (chop $name);
201
+ $len--;
202
+ }
203
+
204
+ $name = C_stringify ($name);
205
+ my $memEQ = $self->memEQ();
206
+ my $body = $indent . "if ($memEQ($name_param, \"$name\", $len)) {\n";
207
+ # Put a little ^ under the letter we checked at
208
+ # Screws up for non printable and non-7 bit stuff, but that's too hard to
209
+ # get right.
210
+ if (defined $checked_at) {
211
+ $body .= $indent . "/* " . (' ' x length $memEQ)
212
+ . (' ' x length $name_param)
213
+ . (' ' x $checked_at) . $pointer
214
+ . (' ' x ($len - $checked_at + length $len)) . " */\n";
215
+ } elsif (defined $front_chop) {
216
+ $body .= $indent . "/* $front_chop"
217
+ . (' ' x ($len + 1 + length $len)) . " */\n";
218
+ }
219
+ return $body;
220
+ }
221
+
222
+ =item dump_names arg_hashref, ITEM...
223
+
224
+ An internal function to generate the embedded perl code that will regenerate
225
+ the constant subroutines. I<default_type>, I<types> and I<ITEM>s are the
226
+ same as for C_constant. I<indent> is treated as number of spaces to indent
227
+ by. If C<declare_types> is true a C<$types> is always declared in the perl
228
+ code generated, if defined and false never declared, and if undefined C<$types>
229
+ is only declared if the values in I<types> as passed in cannot be inferred from
230
+ I<default_types> and the I<ITEM>s.
231
+
232
+ =cut
233
+
234
+ sub dump_names {
235
+ my ($self, $args, @items) = @_;
236
+ my ($default_type, $what, $indent, $declare_types)
237
+ = @{$args}{qw(default_type what indent declare_types)};
238
+ $indent = ' ' x ($indent || 0);
239
+
240
+ my $result;
241
+ my (@simple, @complex, %used_types);
242
+ foreach (@items) {
243
+ my $type;
244
+ if (ref $_) {
245
+ $type = $_->{type} || $default_type;
246
+ if ($_->{utf8}) {
247
+ # For simplicity always skip the bytes case, and reconstitute this entry
248
+ # from its utf8 twin.
249
+ next if $_->{utf8} eq 'no';
250
+ # Copy the hashref, as we don't want to mess with the caller's hashref.
251
+ $_ = {%$_};
252
+ unless (is_perl56) {
253
+ utf8::decode ($_->{name});
254
+ } else {
255
+ $_->{name} = pack 'U*', unpack 'U0U*', $_->{name};
256
+ }
257
+ delete $_->{utf8};
258
+ }
259
+ } else {
260
+ $_ = {name=>$_};
261
+ $type = $default_type;
262
+ }
263
+ $used_types{$type}++;
264
+ if ($type eq $default_type
265
+ # grr 5.6.1
266
+ and length $_->{name}
267
+ and length $_->{name} == ($_->{name} =~ tr/A-Za-z0-9_//)
268
+ and !defined ($_->{macro}) and !defined ($_->{value})
269
+ and !defined ($_->{default}) and !defined ($_->{pre})
270
+ and !defined ($_->{post}) and !defined ($_->{def_pre})
271
+ and !defined ($_->{def_post}) and !defined ($_->{weight})) {
272
+ # It's the default type, and the name consists only of A-Za-z0-9_
273
+ push @simple, $_->{name};
274
+ } else {
275
+ push @complex, $_;
276
+ }
277
+ }
278
+
279
+ if (!defined $declare_types) {
280
+ # Do they pass in any types we weren't already using?
281
+ foreach (keys %$what) {
282
+ next if $used_types{$_};
283
+ $declare_types++; # Found one in $what that wasn't used.
284
+ last; # And one is enough to terminate this loop
285
+ }
286
+ }
287
+ if ($declare_types) {
288
+ $result = $indent . 'my $types = {map {($_, 1)} qw('
289
+ . join (" ", sort keys %$what) . ")};\n";
290
+ }
291
+ local $Text::Wrap::huge = 'overflow';
292
+ local $Text::Wrap::columns = 80;
293
+ $result .= wrap ($indent . "my \@names = (qw(",
294
+ $indent . " ", join (" ", sort @simple) . ")");
295
+ if (@complex) {
296
+ foreach my $item (sort {$a->{name} cmp $b->{name}} @complex) {
297
+ my $name = perl_stringify $item->{name};
298
+ my $line = ",\n$indent {name=>\"$name\"";
299
+ $line .= ", type=>\"$item->{type}\"" if defined $item->{type};
300
+ foreach my $thing (qw (macro value default pre post def_pre def_post)) {
301
+ my $value = $item->{$thing};
302
+ if (defined $value) {
303
+ if (ref $value) {
304
+ $line .= ", $thing=>[\""
305
+ . join ('", "', map {perl_stringify $_} @$value) . '"]';
306
+ } else {
307
+ $line .= ", $thing=>\"" . perl_stringify($value) . "\"";
308
+ }
309
+ }
310
+ }
311
+ $line .= "}";
312
+ # Ensure that the enclosing C comment doesn't end
313
+ # by turning */ into *" . "/
314
+ $line =~ s!\*\/!\*" . "/!gs;
315
+ # gcc -Wall doesn't like finding /* inside a comment
316
+ $line =~ s!\/\*!/" . "\*!gs;
317
+ $result .= $line;
318
+ }
319
+ }
320
+ $result .= ");\n";
321
+
322
+ $result;
323
+ }
324
+
325
+ =item assign arg_hashref, VALUE...
326
+
327
+ A method to return a suitable assignment clause. If I<type> is aggregate
328
+ (eg I<PVN> expects both pointer and length) then there should be multiple
329
+ I<VALUE>s for the components. I<pre> and I<post> if defined give snippets
330
+ of C code to proceed and follow the assignment. I<pre> will be at the start
331
+ of a block, so variables may be defined in it.
332
+
333
+ =cut
334
+ # Hmm. value undef to do NOTDEF? value () to do NOTFOUND?
335
+
336
+ sub assign {
337
+ my $self = shift;
338
+ my $args = shift;
339
+ my ($indent, $type, $pre, $post, $item)
340
+ = @{$args}{qw(indent type pre post item)};
341
+ $post ||= '';
342
+ my $clause;
343
+ my $close;
344
+ if ($pre) {
345
+ chomp $pre;
346
+ $close = "$indent}\n";
347
+ $clause = $indent . "{\n";
348
+ $indent .= " ";
349
+ $clause .= "$indent$pre";
350
+ $clause .= ";" unless $pre =~ /;$/;
351
+ $clause .= "\n";
352
+ }
353
+ confess "undef \$type" unless defined $type;
354
+ confess "Can't generate code for type $type"
355
+ unless $self->valid_type($type);
356
+
357
+ $clause .= join '', map {"$indent$_\n"}
358
+ $self->assignment_clause_for_type({type=>$type,item=>$item}, @_);
359
+ chomp $post;
360
+ if (length $post) {
361
+ $clause .= "$post";
362
+ $clause .= ";" unless $post =~ /;$/;
363
+ $clause .= "\n";
364
+ }
365
+ my $return = $self->return_statement_for_type($type);
366
+ $clause .= "$indent$return\n" if defined $return;
367
+ $clause .= $close if $close;
368
+ return $clause;
369
+ }
370
+
371
+ =item return_clause arg_hashref, ITEM
372
+
373
+ A method to return a suitable C<#ifdef> clause. I<ITEM> is a hashref
374
+ (as passed to C<C_constant> and C<match_clause>. I<indent> is the number
375
+ of spaces to indent, defaulting to 6.
376
+
377
+ =cut
378
+
379
+ sub return_clause {
380
+
381
+ ##ifdef thingy
382
+ # *iv_return = thingy;
383
+ # return PERL_constant_ISIV;
384
+ ##else
385
+ # return PERL_constant_NOTDEF;
386
+ ##endif
387
+ my ($self, $args, $item) = @_;
388
+ my $indent = $args->{indent};
389
+
390
+ my ($name, $value, $default, $pre, $post, $def_pre, $def_post, $type)
391
+ = @$item{qw (name value default pre post def_pre def_post type)};
392
+ $value = $name unless defined $value;
393
+ my $macro = $self->macro_from_item($item);
394
+ $indent = ' ' x ($indent || 6);
395
+ unless (defined $type) {
396
+ # use Data::Dumper; print STDERR Dumper ($item);
397
+ confess "undef \$type";
398
+ }
399
+
400
+ ##ifdef thingy
401
+ my $clause = $self->macro_to_ifdef($macro);
402
+
403
+ # *iv_return = thingy;
404
+ # return PERL_constant_ISIV;
405
+ $clause
406
+ .= $self->assign ({indent=>$indent, type=>$type, pre=>$pre, post=>$post,
407
+ item=>$item}, ref $value ? @$value : $value);
408
+
409
+ if (defined $macro && $macro ne "" && $macro ne "1") {
410
+ ##else
411
+ $clause .= "#else\n";
412
+
413
+ # return PERL_constant_NOTDEF;
414
+ if (!defined $default) {
415
+ my $notdef = $self->return_statement_for_notdef();
416
+ $clause .= "$indent$notdef\n" if defined $notdef;
417
+ } else {
418
+ my @default = ref $default ? @$default : $default;
419
+ $type = shift @default;
420
+ $clause .= $self->assign ({indent=>$indent, type=>$type, pre=>$pre,
421
+ post=>$post, item=>$item}, @default);
422
+ }
423
+ }
424
+ ##endif
425
+ $clause .= $self->macro_to_endif($macro);
426
+
427
+ return $clause;
428
+ }
429
+
430
+ sub match_clause {
431
+ # $offset defined if we have checked an offset.
432
+ my ($self, $args, $item) = @_;
433
+ my ($offset, $indent) = @{$args}{qw(checked_at indent)};
434
+ $indent = ' ' x ($indent || 4);
435
+ my $body = '';
436
+ my ($no, $yes, $either, $name, $inner_indent);
437
+ if (ref $item eq 'ARRAY') {
438
+ ($yes, $no) = @$item;
439
+ $either = $yes || $no;
440
+ confess "$item is $either expecting hashref in [0] || [1]"
441
+ unless ref $either eq 'HASH';
442
+ $name = $either->{name};
443
+ } else {
444
+ confess "$item->{name} has utf8 flag '$item->{utf8}', should be false"
445
+ if $item->{utf8};
446
+ $name = $item->{name};
447
+ $inner_indent = $indent;
448
+ }
449
+
450
+ $body .= $self->memEQ_clause ({name => $name, checked_at => $offset,
451
+ indent => length $indent});
452
+ # If we've been presented with an arrayref for $item, then the user string
453
+ # contains in the range 128-255, and we need to check whether it was utf8
454
+ # (or not).
455
+ # In the worst case we have two named constants, where one's name happens
456
+ # encoded in UTF8 happens to be the same byte sequence as the second's
457
+ # encoded in (say) ISO-8859-1.
458
+ # In this case, $yes and $no both have item hashrefs.
459
+ if ($yes) {
460
+ $body .= $indent . " if (" . $self->is_utf8_param . ") {\n";
461
+ } elsif ($no) {
462
+ $body .= $indent . " if (!" . $self->is_utf8_param . ") {\n";
463
+ }
464
+ if ($either) {
465
+ $body .= $self->return_clause ({indent=>4 + length $indent}, $either);
466
+ if ($yes and $no) {
467
+ $body .= $indent . " } else {\n";
468
+ $body .= $self->return_clause ({indent=>4 + length $indent}, $no);
469
+ }
470
+ $body .= $indent . " }\n";
471
+ } else {
472
+ $body .= $self->return_clause ({indent=>2 + length $indent}, $item);
473
+ }
474
+ $body .= $indent . "}\n";
475
+ }
476
+
477
+
478
+ =item switch_clause arg_hashref, NAMELEN, ITEMHASH, ITEM...
479
+
480
+ An internal method to generate a suitable C<switch> clause, called by
481
+ C<C_constant> I<ITEM>s are in the hash ref format as given in the description
482
+ of C<C_constant>, and must all have the names of the same length, given by
483
+ I<NAMELEN>. I<ITEMHASH> is a reference to a hash, keyed by name, values being
484
+ the hashrefs in the I<ITEM> list. (No parameters are modified, and there can
485
+ be keys in the I<ITEMHASH> that are not in the list of I<ITEM>s without
486
+ causing problems - the hash is passed in to save generating it afresh for
487
+ each call).
488
+
489
+ =cut
490
+
491
+ sub switch_clause {
492
+ my ($self, $args, $namelen, $items, @items) = @_;
493
+ my ($indent, $comment) = @{$args}{qw(indent comment)};
494
+ $indent = ' ' x ($indent || 2);
495
+
496
+ local $Text::Wrap::huge = 'overflow';
497
+ local $Text::Wrap::columns = 80;
498
+
499
+ my @names = sort map {$_->{name}} @items;
500
+ my $leader = $indent . '/* ';
501
+ my $follower = ' ' x length $leader;
502
+ my $body = $indent . "/* Names all of length $namelen. */\n";
503
+ if (defined $comment) {
504
+ $body = wrap ($leader, $follower, $comment) . "\n";
505
+ $leader = $follower;
506
+ }
507
+ my @safe_names = @names;
508
+ foreach (@safe_names) {
509
+ confess sprintf "Name '$_' is length %d, not $namelen", length
510
+ unless length == $namelen;
511
+ # Argh. 5.6.1
512
+ # next unless tr/A-Za-z0-9_//c;
513
+ next if tr/A-Za-z0-9_// == length;
514
+ $_ = '"' . perl_stringify ($_) . '"';
515
+ # Ensure that the enclosing C comment doesn't end
516
+ # by turning */ into *" . "/
517
+ s!\*\/!\*"."/!gs;
518
+ # gcc -Wall doesn't like finding /* inside a comment
519
+ s!\/\*!/"."\*!gs;
520
+ }
521
+ $body .= wrap ($leader, $follower, join (" ", @safe_names) . " */") . "\n";
522
+ # Figure out what to switch on.
523
+ # (RMS, Spread of jump table, Position, Hashref)
524
+ my @best = (1e38, ~0);
525
+ # Prefer the last character over the others. (As it lets us shorten the
526
+ # memEQ clause at no cost).
527
+ foreach my $i ($namelen - 1, 0 .. ($namelen - 2)) {
528
+ my ($min, $max) = (~0, 0);
529
+ my %spread;
530
+ if (is_perl56) {
531
+ # Need proper Unicode preserving hash keys for bytes in range 128-255
532
+ # here too, for some reason. grr 5.6.1 yet again.
533
+ tie %spread, 'ExtUtils::Constant::Aaargh56Hash';
534
+ }
535
+ foreach (@names) {
536
+ my $char = substr $_, $i, 1;
537
+ my $ord = ord $char;
538
+ confess "char $ord is out of range" if $ord > 255;
539
+ $max = $ord if $ord > $max;
540
+ $min = $ord if $ord < $min;
541
+ push @{$spread{$char}}, $_;
542
+ # warn "$_ $char";
543
+ }
544
+ # I'm going to pick the character to split on that minimises the root
545
+ # mean square of the number of names in each case. Normally this should
546
+ # be the one with the most keys, but it may pick a 7 where the 8 has
547
+ # one long linear search. I'm not sure if RMS or just sum of squares is
548
+ # actually better.
549
+ # $max and $min are for the tie-breaker if the root mean squares match.
550
+ # Assuming that the compiler may be building a jump table for the
551
+ # switch() then try to minimise the size of that jump table.
552
+ # Finally use < not <= so that if it still ties the earliest part of
553
+ # the string wins. Because if that passes but the memEQ fails, it may
554
+ # only need the start of the string to bin the choice.
555
+ # I think. But I'm micro-optimising. :-)
556
+ # OK. Trump that. Now favour the last character of the string, before the
557
+ # rest.
558
+ my $ss;
559
+ $ss += @$_ * @$_ foreach values %spread;
560
+ my $rms = sqrt ($ss / keys %spread);
561
+ if ($rms < $best[0] || ($rms == $best[0] && ($max - $min) < $best[1])) {
562
+ @best = ($rms, $max - $min, $i, \%spread);
563
+ }
564
+ }
565
+ confess "Internal error. Failed to pick a switch point for @names"
566
+ unless defined $best[2];
567
+ # use Data::Dumper; print Dumper (@best);
568
+ my ($offset, $best) = @best[2,3];
569
+ $body .= $indent . "/* Offset $offset gives the best switch position. */\n";
570
+
571
+ my $do_front_chop = $offset == 0 && $namelen > 2;
572
+ if ($do_front_chop) {
573
+ $body .= $indent . "switch (*" . $self->name_param() . "++) {\n";
574
+ } else {
575
+ $body .= $indent . "switch (" . $self->name_param() . "[$offset]) {\n";
576
+ }
577
+ foreach my $char (sort keys %$best) {
578
+ confess sprintf "'$char' is %d bytes long, not 1", length $char
579
+ if length ($char) != 1;
580
+ confess sprintf "char %#X is out of range", ord $char if ord ($char) > 255;
581
+ $body .= $indent . "case '" . C_stringify ($char) . "':\n";
582
+ foreach my $thisone (sort {
583
+ # Deal with the case of an item actually being an array ref to 1 or 2
584
+ # hashrefs. Don't assign to $a or $b, as they're aliases to the
585
+ # original
586
+ my $l = ref $a eq 'ARRAY' ? ($a->[0] || $->[1]) : $a;
587
+ my $r = ref $b eq 'ARRAY' ? ($b->[0] || $->[1]) : $b;
588
+ # Sort by weight first
589
+ ($r->{weight} || 0) <=> ($l->{weight} || 0)
590
+ # Sort equal weights by name
591
+ or $l->{name} cmp $r->{name}}
592
+ # If this looks evil, maybe it is. $items is a
593
+ # hashref, and we're doing a hash slice on it
594
+ @{$items}{@{$best->{$char}}}) {
595
+ # warn "You are here";
596
+ if ($do_front_chop) {
597
+ $body .= $self->match_clause ({indent => 2 + length $indent,
598
+ checked_at => \$char}, $thisone);
599
+ } else {
600
+ $body .= $self->match_clause ({indent => 2 + length $indent,
601
+ checked_at => $offset}, $thisone);
602
+ }
603
+ }
604
+ $body .= $indent . " break;\n";
605
+ }
606
+ $body .= $indent . "}\n";
607
+ return $body;
608
+ }
609
+
610
+ sub C_constant_return_type {
611
+ "static int";
612
+ }
613
+
614
+ sub C_constant_prefix_param {
615
+ '';
616
+ }
617
+
618
+ sub C_constant_prefix_param_defintion {
619
+ '';
620
+ }
621
+
622
+ sub name_param_definition {
623
+ "const char *" . $_[0]->name_param;
624
+ }
625
+
626
+ sub namelen_param {
627
+ 'len';
628
+ }
629
+
630
+ sub namelen_param_definition {
631
+ 'size_t ' . $_[0]->namelen_param;
632
+ }
633
+
634
+ sub C_constant_other_params {
635
+ '';
636
+ }
637
+
638
+ sub C_constant_other_params_defintion {
639
+ '';
640
+ }
641
+
642
+ =item params WHAT
643
+
644
+ An "internal" method, subject to change, currently called to allow an
645
+ overriding class to cache information that will then be passed into all
646
+ the C<*param*> calls. (Yes, having to read the source to make sense of this is
647
+ considered a known bug). I<WHAT> is be a hashref of types the constant
648
+ function will return. In ExtUtils::Constant::XS this method is used to
649
+ returns a hashref keyed IV NV PV SV to show which combination of pointers will
650
+ be needed in the C argument list generated by
651
+ C_constant_other_params_definition and C_constant_other_params
652
+
653
+ =cut
654
+
655
+ sub params {
656
+ '';
657
+ }
658
+
659
+
660
+ =item dogfood arg_hashref, ITEM...
661
+
662
+ An internal function to generate the embedded perl code that will regenerate
663
+ the constant subroutines. Parameters are the same as for C_constant.
664
+
665
+ Currently the base class does nothing and returns an empty string.
666
+
667
+ =cut
668
+
669
+ sub dogfood {
670
+ ''
671
+ }
672
+
673
+ =item normalise_items args, default_type, seen_types, seen_items, ITEM...
674
+
675
+ Convert the items to a normalised form. For 8 bit and Unicode values converts
676
+ the item to an array of 1 or 2 items, both 8 bit and UTF-8 encoded.
677
+
678
+ =cut
679
+
680
+ sub normalise_items
681
+ {
682
+ my $self = shift;
683
+ my $args = shift;
684
+ my $default_type = shift;
685
+ my $what = shift;
686
+ my $items = shift;
687
+ my @new_items;
688
+ foreach my $orig (@_) {
689
+ my ($name, $item);
690
+ if (ref $orig) {
691
+ # Make a copy which is a normalised version of the ref passed in.
692
+ $name = $orig->{name};
693
+ my ($type, $macro, $value) = @$orig{qw (type macro value)};
694
+ $type ||= $default_type;
695
+ $what->{$type} = 1;
696
+ $item = {name=>$name, type=>$type};
697
+
698
+ undef $macro if defined $macro and $macro eq $name;
699
+ $item->{macro} = $macro if defined $macro;
700
+ undef $value if defined $value and $value eq $name;
701
+ $item->{value} = $value if defined $value;
702
+ foreach my $key (qw(default pre post def_pre def_post weight
703
+ not_constant)) {
704
+ my $value = $orig->{$key};
705
+ $item->{$key} = $value if defined $value;
706
+ # warn "$key $value";
707
+ }
708
+ } else {
709
+ $name = $orig;
710
+ $item = {name=>$name, type=>$default_type};
711
+ $what->{$default_type} = 1;
712
+ }
713
+ warn +(ref ($self) || $self)
714
+ . "doesn't know how to handle values of type $_ used in macro $name"
715
+ unless $self->valid_type ($item->{type});
716
+ # tr///c is broken on 5.6.1 for utf8, so my original tr/\0-\177//c
717
+ # doesn't work. Upgrade to 5.8
718
+ # if ($name !~ tr/\0-\177//c || $] < 5.005_50) {
719
+ if ($name =~ tr/\0-\177// == length $name || $] < 5.005_50
720
+ || $args->{disable_utf8_duplication}) {
721
+ # No characters outside 7 bit ASCII.
722
+ if (exists $items->{$name}) {
723
+ die "Multiple definitions for macro $name";
724
+ }
725
+ $items->{$name} = $item;
726
+ } else {
727
+ # No characters outside 8 bit. This is hardest.
728
+ if (exists $items->{$name} and ref $items->{$name} ne 'ARRAY') {
729
+ confess "Unexpected ASCII definition for macro $name";
730
+ }
731
+ # Again, 5.6.1 tr broken, so s/5\.6.*/5\.8\.0/;
732
+ # if ($name !~ tr/\0-\377//c) {
733
+ if ($name =~ tr/\0-\377// == length $name) {
734
+ # if ($] < 5.007) {
735
+ # $name = pack "C*", unpack "U*", $name;
736
+ # }
737
+ $item->{utf8} = 'no';
738
+ $items->{$name}[1] = $item;
739
+ push @new_items, $item;
740
+ # Copy item, to create the utf8 variant.
741
+ $item = {%$item};
742
+ }
743
+ # Encode the name as utf8 bytes.
744
+ unless (is_perl56) {
745
+ utf8::encode($name);
746
+ } else {
747
+ # warn "Was >$name< " . length ${name};
748
+ $name = pack 'C*', unpack 'C*', $name . pack 'U*';
749
+ # warn "Now '${name}' " . length ${name};
750
+ }
751
+ if ($items->{$name}[0]) {
752
+ die "Multiple definitions for macro $name";
753
+ }
754
+ $item->{utf8} = 'yes';
755
+ $item->{name} = $name;
756
+ $items->{$name}[0] = $item;
757
+ # We have need for the utf8 flag.
758
+ $what->{''} = 1;
759
+ }
760
+ push @new_items, $item;
761
+ }
762
+ @new_items;
763
+ }
764
+
765
+ =item C_constant arg_hashref, ITEM...
766
+
767
+ A function that returns a B<list> of C subroutine definitions that return
768
+ the value and type of constants when passed the name by the XS wrapper.
769
+ I<ITEM...> gives a list of constant names. Each can either be a string,
770
+ which is taken as a C macro name, or a reference to a hash with the following
771
+ keys
772
+
773
+ =over 8
774
+
775
+ =item name
776
+
777
+ The name of the constant, as seen by the perl code.
778
+
779
+ =item type
780
+
781
+ The type of the constant (I<IV>, I<NV> etc)
782
+
783
+ =item value
784
+
785
+ A C expression for the value of the constant, or a list of C expressions if
786
+ the type is aggregate. This defaults to the I<name> if not given.
787
+
788
+ =item macro
789
+
790
+ The C pre-processor macro to use in the C<#ifdef>. This defaults to the
791
+ I<name>, and is mainly used if I<value> is an C<enum>. If a reference an
792
+ array is passed then the first element is used in place of the C<#ifdef>
793
+ line, and the second element in place of the C<#endif>. This allows
794
+ pre-processor constructions such as
795
+
796
+ #if defined (foo)
797
+ #if !defined (bar)
798
+ ...
799
+ #endif
800
+ #endif
801
+
802
+ to be used to determine if a constant is to be defined.
803
+
804
+ A "macro" 1 signals that the constant is always defined, so the C<#if>/C<#endif>
805
+ test is omitted.
806
+
807
+ =item default
808
+
809
+ Default value to use (instead of C<croak>ing with "your vendor has not
810
+ defined...") to return if the macro isn't defined. Specify a reference to
811
+ an array with type followed by value(s).
812
+
813
+ =item pre
814
+
815
+ C code to use before the assignment of the value of the constant. This allows
816
+ you to use temporary variables to extract a value from part of a C<struct>
817
+ and return this as I<value>. This C code is places at the start of a block,
818
+ so you can declare variables in it.
819
+
820
+ =item post
821
+
822
+ C code to place between the assignment of value (to a temporary) and the
823
+ return from the function. This allows you to clear up anything in I<pre>.
824
+ Rarely needed.
825
+
826
+ =item def_pre
827
+
828
+ =item def_post
829
+
830
+ Equivalents of I<pre> and I<post> for the default value.
831
+
832
+ =item utf8
833
+
834
+ Generated internally. Is zero or undefined if name is 7 bit ASCII,
835
+ "no" if the name is 8 bit (and so should only match if SvUTF8() is false),
836
+ "yes" if the name is utf8 encoded.
837
+
838
+ The internals automatically clone any name with characters 128-255 but none
839
+ 256+ (ie one that could be either in bytes or utf8) into a second entry
840
+ which is utf8 encoded.
841
+
842
+ =item weight
843
+
844
+ Optional sorting weight for names, to determine the order of
845
+ linear testing when multiple names fall in the same case of a switch clause.
846
+ Higher comes earlier, undefined defaults to zero.
847
+
848
+ =back
849
+
850
+ In the argument hashref, I<package> is the name of the package, and is only
851
+ used in comments inside the generated C code. I<subname> defaults to
852
+ C<constant> if undefined.
853
+
854
+ I<default_type> is the type returned by C<ITEM>s that don't specify their
855
+ type. It defaults to the value of C<default_type()>. I<types> should be given
856
+ either as a comma separated list of types that the C subroutine I<subname>
857
+ will generate or as a reference to a hash. I<default_type> will be added to
858
+ the list if not present, as will any types given in the list of I<ITEM>s. The
859
+ resultant list should be the same list of types that C<XS_constant> is
860
+ given. [Otherwise C<XS_constant> and C<C_constant> may differ in the number of
861
+ parameters to the constant function. I<indent> is currently unused and
862
+ ignored. In future it may be used to pass in information used to change the C
863
+ indentation style used.] The best way to maintain consistency is to pass in a
864
+ hash reference and let this function update it.
865
+
866
+ I<breakout> governs when child functions of I<subname> are generated. If there
867
+ are I<breakout> or more I<ITEM>s with the same length of name, then the code
868
+ to switch between them is placed into a function named I<subname>_I<len>, for
869
+ example C<constant_5> for names 5 characters long. The default I<breakout> is
870
+ 3. A single C<ITEM> is always inlined.
871
+
872
+ =cut
873
+
874
+ # The parameter now BREAKOUT was previously documented as:
875
+ #
876
+ # I<NAMELEN> if defined signals that all the I<name>s of the I<ITEM>s are of
877
+ # this length, and that the constant name passed in by perl is checked and
878
+ # also of this length. It is used during recursion, and should be C<undef>
879
+ # unless the caller has checked all the lengths during code generation, and
880
+ # the generated subroutine is only to be called with a name of this length.
881
+ #
882
+ # As you can see it now performs this function during recursion by being a
883
+ # scalar reference.
884
+
885
+ sub C_constant {
886
+ my ($self, $args, @items) = @_;
887
+ my ($package, $subname, $default_type, $what, $indent, $breakout) =
888
+ @{$args}{qw(package subname default_type types indent breakout)};
889
+ $package ||= 'Foo';
890
+ $subname ||= 'constant';
891
+ # I'm not using this. But a hashref could be used for full formatting without
892
+ # breaking this API
893
+ # $indent ||= 0;
894
+
895
+ my ($namelen, $items);
896
+ if (ref $breakout) {
897
+ # We are called recursively. We trust @items to be normalised, $what to
898
+ # be a hashref, and pinch %$items from our parent to save recalculation.
899
+ ($namelen, $items) = @$breakout;
900
+ } else {
901
+ $items = {};
902
+ if (is_perl56) {
903
+ # Need proper Unicode preserving hash keys.
904
+ require ExtUtils::Constant::Aaargh56Hash;
905
+ tie %$items, 'ExtUtils::Constant::Aaargh56Hash';
906
+ }
907
+ $breakout ||= 3;
908
+ $default_type ||= $self->default_type();
909
+ if (!ref $what) {
910
+ # Convert line of the form IV,UV,NV to hash
911
+ $what = {map {$_ => 1} split /,\s*/, ($what || '')};
912
+ # Figure out what types we're dealing with, and assign all unknowns to the
913
+ # default type
914
+ }
915
+ @items = $self->normalise_items ({}, $default_type, $what, $items, @items);
916
+ # use Data::Dumper; print Dumper @items;
917
+ }
918
+ my $params = $self->params ($what);
919
+
920
+ # Probably "static int"
921
+ my ($body, @subs);
922
+ $body = $self->C_constant_return_type($params) . "\n$subname ("
923
+ # Eg "pTHX_ "
924
+ . $self->C_constant_prefix_param_defintion($params)
925
+ # Probably "const char *name"
926
+ . $self->name_param_definition($params);
927
+ # Something like ", STRLEN len"
928
+ $body .= ", " . $self->namelen_param_definition($params)
929
+ unless defined $namelen;
930
+ $body .= $self->C_constant_other_params_defintion($params);
931
+ $body .= ") {\n";
932
+
933
+ if (defined $namelen) {
934
+ # We are a child subroutine. Print the simple description
935
+ my $comment = 'When generated this function returned values for the list'
936
+ . ' of names given here. However, subsequent manual editing may have'
937
+ . ' added or removed some.';
938
+ $body .= $self->switch_clause ({indent=>2, comment=>$comment},
939
+ $namelen, $items, @items);
940
+ } else {
941
+ # We are the top level.
942
+ $body .= " /* Initially switch on the length of the name. */\n";
943
+ $body .= $self->dogfood ({package => $package, subname => $subname,
944
+ default_type => $default_type, what => $what,
945
+ indent => $indent, breakout => $breakout},
946
+ @items);
947
+ $body .= ' switch ('.$self->namelen_param().") {\n";
948
+ # Need to group names of the same length
949
+ my @by_length;
950
+ foreach (@items) {
951
+ push @{$by_length[length $_->{name}]}, $_;
952
+ }
953
+ foreach my $i (0 .. $#by_length) {
954
+ next unless $by_length[$i]; # None of this length
955
+ $body .= " case $i:\n";
956
+ if (@{$by_length[$i]} == 1) {
957
+ my $only_thing = $by_length[$i]->[0];
958
+ if ($only_thing->{utf8}) {
959
+ if ($only_thing->{utf8} eq 'yes') {
960
+ # With utf8 on flag item is passed in element 0
961
+ $body .= $self->match_clause (undef, [$only_thing]);
962
+ } else {
963
+ # With utf8 off flag item is passed in element 1
964
+ $body .= $self->match_clause (undef, [undef, $only_thing]);
965
+ }
966
+ } else {
967
+ $body .= $self->match_clause (undef, $only_thing);
968
+ }
969
+ } elsif (@{$by_length[$i]} < $breakout) {
970
+ $body .= $self->switch_clause ({indent=>4},
971
+ $i, $items, @{$by_length[$i]});
972
+ } else {
973
+ # Only use the minimal set of parameters actually needed by the types
974
+ # of the names of this length.
975
+ my $what = {};
976
+ foreach (@{$by_length[$i]}) {
977
+ $what->{$_->{type}} = 1;
978
+ $what->{''} = 1 if $_->{utf8};
979
+ }
980
+ $params = $self->params ($what);
981
+ push @subs, $self->C_constant ({package=>$package,
982
+ subname=>"${subname}_$i",
983
+ default_type => $default_type,
984
+ types => $what, indent => $indent,
985
+ breakout => [$i, $items]},
986
+ @{$by_length[$i]});
987
+ $body .= " return ${subname}_$i ("
988
+ # Eg "aTHX_ "
989
+ . $self->C_constant_prefix_param($params)
990
+ # Probably "name"
991
+ . $self->name_param($params);
992
+ $body .= $self->C_constant_other_params($params);
993
+ $body .= ");\n";
994
+ }
995
+ $body .= " break;\n";
996
+ }
997
+ $body .= " }\n";
998
+ }
999
+ my $notfound = $self->return_statement_for_notfound();
1000
+ $body .= " $notfound\n" if $notfound;
1001
+ $body .= "}\n";
1002
+ return (@subs, $body);
1003
+ }
1004
+
1005
+ 1;
1006
+ __END__
1007
+
1008
+ =back
1009
+
1010
+ =head1 BUGS
1011
+
1012
+ Not everything is documented yet.
1013
+
1014
+ Probably others.
1015
+
1016
+ =head1 AUTHOR
1017
+
1018
+ Nicholas Clark <[email protected]> based on the code in C<h2xs> by Larry Wall and
1019
+ others
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Constant/ProxySubs.pm ADDED
@@ -0,0 +1,682 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Constant::ProxySubs;
2
+
3
+ use strict;
4
+ use vars qw($VERSION @ISA %type_to_struct %type_from_struct %type_to_sv
5
+ %type_to_C_value %type_is_a_problem %type_num_args
6
+ %type_temporary);
7
+ use Carp;
8
+ require ExtUtils::Constant::XS;
9
+ use ExtUtils::Constant::Utils qw(C_stringify);
10
+ use ExtUtils::Constant::XS qw(%XS_TypeSet);
11
+
12
+ $VERSION = '0.09';
13
+ @ISA = 'ExtUtils::Constant::XS';
14
+
15
+ %type_to_struct =
16
+ (
17
+ IV => '{const char *name; I32 namelen; IV value;}',
18
+ NV => '{const char *name; I32 namelen; NV value;}',
19
+ UV => '{const char *name; I32 namelen; UV value;}',
20
+ PV => '{const char *name; I32 namelen; const char *value;}',
21
+ PVN => '{const char *name; I32 namelen; const char *value; STRLEN len;}',
22
+ YES => '{const char *name; I32 namelen;}',
23
+ NO => '{const char *name; I32 namelen;}',
24
+ UNDEF => '{const char *name; I32 namelen;}',
25
+ '' => '{const char *name; I32 namelen;} ',
26
+ );
27
+
28
+ %type_from_struct =
29
+ (
30
+ IV => sub { $_[0] . '->value' },
31
+ NV => sub { $_[0] . '->value' },
32
+ UV => sub { $_[0] . '->value' },
33
+ PV => sub { $_[0] . '->value' },
34
+ PVN => sub { $_[0] . '->value', $_[0] . '->len' },
35
+ YES => sub {},
36
+ NO => sub {},
37
+ UNDEF => sub {},
38
+ '' => sub {},
39
+ );
40
+
41
+ %type_to_sv =
42
+ (
43
+ IV => sub { "newSViv($_[0])" },
44
+ NV => sub { "newSVnv($_[0])" },
45
+ UV => sub { "newSVuv($_[0])" },
46
+ PV => sub { "newSVpv($_[0], 0)" },
47
+ PVN => sub { "newSVpvn($_[0], $_[1])" },
48
+ YES => sub { '&PL_sv_yes' },
49
+ NO => sub { '&PL_sv_no' },
50
+ UNDEF => sub { '&PL_sv_undef' },
51
+ '' => sub { '&PL_sv_yes' },
52
+ SV => sub {"SvREFCNT_inc($_[0])"},
53
+ );
54
+
55
+ %type_to_C_value =
56
+ (
57
+ YES => sub {},
58
+ NO => sub {},
59
+ UNDEF => sub {},
60
+ '' => sub {},
61
+ );
62
+
63
+ sub type_to_C_value {
64
+ my ($self, $type) = @_;
65
+ return $type_to_C_value{$type} || sub {return map {ref $_ ? @$_ : $_} @_};
66
+ }
67
+
68
+ # TODO - figure out if there is a clean way for the type_to_sv code to
69
+ # attempt s/sv_2mortal// and if it succeeds tell type_to_sv not to add
70
+ # SvREFCNT_inc
71
+ %type_is_a_problem =
72
+ (
73
+ # The documentation says *mortal SV*, but we now need a non-mortal copy.
74
+ SV => 1,
75
+ );
76
+
77
+ %type_temporary =
78
+ (
79
+ SV => ['SV *'],
80
+ PV => ['const char *'],
81
+ PVN => ['const char *', 'STRLEN'],
82
+ );
83
+ $type_temporary{$_} = [$_] foreach qw(IV UV NV);
84
+
85
+ while (my ($type, $value) = each %XS_TypeSet) {
86
+ $type_num_args{$type}
87
+ = defined $value ? ref $value ? scalar @$value : 1 : 0;
88
+ }
89
+ $type_num_args{''} = 0;
90
+
91
+ sub partition_names {
92
+ my ($self, $default_type, @items) = @_;
93
+ my (%found, @notfound, @trouble);
94
+
95
+ while (my $item = shift @items) {
96
+ my $default = delete $item->{default};
97
+ if ($default) {
98
+ # If we find a default value, convert it into a regular item and
99
+ # append it to the queue of items to process
100
+ my $default_item = {%$item};
101
+ $default_item->{invert_macro} = 1;
102
+ $default_item->{pre} = delete $item->{def_pre};
103
+ $default_item->{post} = delete $item->{def_post};
104
+ $default_item->{type} = shift @$default;
105
+ $default_item->{value} = $default;
106
+ push @items, $default_item;
107
+ } else {
108
+ # It can be "not found" unless it's the default (invert the macro)
109
+ # or the "macro" is an empty string (ie no macro)
110
+ push @notfound, $item unless $item->{invert_macro}
111
+ or !$self->macro_to_ifdef($self->macro_from_item($item));
112
+ }
113
+
114
+ if ($item->{pre} or $item->{post} or $item->{not_constant}
115
+ or $type_is_a_problem{$item->{type}}) {
116
+ push @trouble, $item;
117
+ } else {
118
+ push @{$found{$item->{type}}}, $item;
119
+ }
120
+ }
121
+ # use Data::Dumper; print Dumper \%found;
122
+ (\%found, \@notfound, \@trouble);
123
+ }
124
+
125
+ sub boottime_iterator {
126
+ my ($self, $type, $iterator, $hash, $subname, $push) = @_;
127
+ my $extractor = $type_from_struct{$type};
128
+ die "Can't find extractor code for type $type"
129
+ unless defined $extractor;
130
+ my $generator = $type_to_sv{$type};
131
+ die "Can't find generator code for type $type"
132
+ unless defined $generator;
133
+
134
+ my $athx = $self->C_constant_prefix_param();
135
+
136
+ if ($push) {
137
+ return sprintf <<"EOBOOT", &$generator(&$extractor($iterator));
138
+ while ($iterator->name) {
139
+ he = $subname($athx $hash, $iterator->name,
140
+ $iterator->namelen, %s);
141
+ av_push(push, newSVhek(HeKEY_hek(he)));
142
+ ++$iterator;
143
+ }
144
+ EOBOOT
145
+ } else {
146
+ return sprintf <<"EOBOOT", &$generator(&$extractor($iterator));
147
+ while ($iterator->name) {
148
+ $subname($athx $hash, $iterator->name,
149
+ $iterator->namelen, %s);
150
+ ++$iterator;
151
+ }
152
+ EOBOOT
153
+ }
154
+ }
155
+
156
+ sub name_len_value_macro {
157
+ my ($self, $item) = @_;
158
+ my $name = $item->{name};
159
+ my $value = $item->{value};
160
+ $value = $item->{name} unless defined $value;
161
+
162
+ my $namelen = length $name;
163
+ if ($name =~ tr/\0-\377// != $namelen) {
164
+ # the hash API signals UTF-8 by passing the length negated.
165
+ utf8::encode($name);
166
+ $namelen = -length $name;
167
+ }
168
+ $name = C_stringify($name);
169
+
170
+ my $macro = $self->macro_from_item($item);
171
+ ($name, $namelen, $value, $macro);
172
+ }
173
+
174
+ sub WriteConstants {
175
+ my $self = shift;
176
+ my $ARGS = {@_};
177
+
178
+ my ($c_fh, $xs_fh, $c_subname, $default_type, $package)
179
+ = @{$ARGS}{qw(C_FH XS_FH C_SUBNAME DEFAULT_TYPE NAME)};
180
+
181
+ my $xs_subname
182
+ = exists $ARGS->{XS_SUBNAME} ? $ARGS->{XS_SUBNAME} : 'constant';
183
+
184
+ my $options = $ARGS->{PROXYSUBS};
185
+ $options = {} unless ref $options;
186
+ my $push = $options->{push};
187
+ my $explosives = $options->{croak_on_read};
188
+ my $croak_on_error = $options->{croak_on_error};
189
+ my $autoload = $options->{autoload};
190
+ {
191
+ my $exclusive = 0;
192
+ ++$exclusive if $explosives;
193
+ ++$exclusive if $croak_on_error;
194
+ ++$exclusive if $autoload;
195
+
196
+ # Until someone patches this (with test cases):
197
+ carp ("PROXYSUBS options 'autoload', 'croak_on_read' and 'croak_on_error' cannot be used together")
198
+ if $exclusive > 1;
199
+ }
200
+ # Strictly it requires Perl_caller_cx
201
+ carp ("PROXYSUBS option 'croak_on_error' requires v5.13.5 or later")
202
+ if $croak_on_error && $^V < v5.13.5;
203
+ # Strictly this is actually 5.8.9, but it's not well tested there
204
+ my $can_do_pcs = $] >= 5.009;
205
+ # Until someone patches this (with test cases)
206
+ carp ("PROXYSUBS option 'push' requires v5.10 or later")
207
+ if $push && !$can_do_pcs;
208
+ # Until someone patches this (with test cases)
209
+ carp ("PROXYSUBS options 'push' and 'croak_on_read' cannot be used together")
210
+ if $explosives && $push;
211
+
212
+ # If anyone is insane enough to suggest a package name containing %
213
+ my $package_sprintf_safe = $package;
214
+ $package_sprintf_safe =~ s/%/%%/g;
215
+
216
+ # All the types we see
217
+ my $what = {};
218
+ # A hash to lookup items with.
219
+ my $items = {};
220
+
221
+ my @items = $self->normalise_items ({disable_utf8_duplication => 1},
222
+ $default_type, $what, $items,
223
+ @{$ARGS->{NAMES}});
224
+
225
+ # Partition the values by type. Also include any defaults in here
226
+ # Everything that doesn't have a default needs alternative code for
227
+ # "I'm missing"
228
+ # And everything that has pre or post code ends up in a private block
229
+ my ($found, $notfound, $trouble)
230
+ = $self->partition_names($default_type, @items);
231
+
232
+ my $pthx = $self->C_constant_prefix_param_defintion();
233
+ my $athx = $self->C_constant_prefix_param();
234
+ my $symbol_table = C_stringify($package) . '::';
235
+ $push = C_stringify($package . '::' . $push) if $push;
236
+ my $cast_CONSTSUB = $] < 5.010 ? '(char *)' : '';
237
+
238
+ print $c_fh $self->header();
239
+ if ($autoload || $croak_on_error) {
240
+ print $c_fh <<'EOC';
241
+
242
+ /* This allows slightly more efficient code on !USE_ITHREADS: */
243
+ #ifdef USE_ITHREADS
244
+ # define COP_FILE(c) CopFILE(c)
245
+ # define COP_FILE_F "s"
246
+ #else
247
+ # define COP_FILE(c) CopFILESV(c)
248
+ # define COP_FILE_F SVf
249
+ #endif
250
+ EOC
251
+ }
252
+
253
+ my $return_type = $push ? 'HE *' : 'void';
254
+
255
+ print $c_fh <<"EOADD";
256
+
257
+ static $return_type
258
+ ${c_subname}_add_symbol($pthx HV *hash, const char *name, I32 namelen, SV *value) {
259
+ EOADD
260
+ if (!$can_do_pcs) {
261
+ print $c_fh <<'EO_NOPCS';
262
+ if (namelen == namelen) {
263
+ EO_NOPCS
264
+ } else {
265
+ print $c_fh <<"EO_PCS";
266
+ HE *he = (HE*) hv_common_key_len(hash, name, namelen, HV_FETCH_LVALUE, NULL,
267
+ 0);
268
+ SV *sv;
269
+
270
+ if (!he) {
271
+ croak("Couldn't add key '%s' to %%$package_sprintf_safe\::",
272
+ name);
273
+ }
274
+ sv = HeVAL(he);
275
+ if (SvOK(sv) || SvTYPE(sv) == SVt_PVGV) {
276
+ /* Someone has been here before us - have to make a real sub. */
277
+ EO_PCS
278
+ }
279
+ # This piece of code is common to both
280
+ print $c_fh <<"EOADD";
281
+ newCONSTSUB(hash, ${cast_CONSTSUB}name, value);
282
+ EOADD
283
+ if ($can_do_pcs) {
284
+ print $c_fh <<'EO_PCS';
285
+ } else {
286
+ SvUPGRADE(sv, SVt_RV);
287
+ SvRV_set(sv, value);
288
+ SvROK_on(sv);
289
+ SvREADONLY_on(value);
290
+ }
291
+ EO_PCS
292
+ } else {
293
+ print $c_fh <<'EO_NOPCS';
294
+ }
295
+ EO_NOPCS
296
+ }
297
+ print $c_fh " return he;\n" if $push;
298
+ print $c_fh <<'EOADD';
299
+ }
300
+
301
+ EOADD
302
+
303
+ print $c_fh $explosives ? <<"EXPLODE" : "\n";
304
+
305
+ static int
306
+ Im_sorry_Dave(pTHX_ SV *sv, MAGIC *mg)
307
+ {
308
+ PERL_UNUSED_ARG(mg);
309
+ croak("Your vendor has not defined $package_sprintf_safe macro %"SVf
310
+ " used", sv);
311
+ NORETURN_FUNCTION_END;
312
+ }
313
+
314
+ static MGVTBL not_defined_vtbl = {
315
+ Im_sorry_Dave, /* get - I'm afraid I can't do that */
316
+ Im_sorry_Dave, /* set */
317
+ 0, /* len */
318
+ 0, /* clear */
319
+ 0, /* free */
320
+ 0, /* copy */
321
+ 0, /* dup */
322
+ };
323
+
324
+ EXPLODE
325
+
326
+ {
327
+ my $key = $symbol_table;
328
+ # Just seems tidier (and slightly more space efficient) not to have keys
329
+ # such as Fcntl::
330
+ $key =~ s/::$//;
331
+ my $key_len = length $key;
332
+
333
+ print $c_fh <<"MISSING";
334
+
335
+ #ifndef SYMBIAN
336
+
337
+ /* Store a hash of all symbols missing from the package. To avoid trampling on
338
+ the package namespace (uninvited) put each package's hash in our namespace.
339
+ To avoid creating lots of typeblogs and symbol tables for sub-packages, put
340
+ each package's hash into one hash in our namespace. */
341
+
342
+ static HV *
343
+ get_missing_hash(pTHX) {
344
+ HV *const parent
345
+ = get_hv("ExtUtils::Constant::ProxySubs::Missing", GVf_MULTI);
346
+ /* We could make a hash of hashes directly, but this would confuse anything
347
+ at Perl space that looks at us, and as we're visible in Perl space,
348
+ best to play nice. */
349
+ SV *const *const ref
350
+ = hv_fetch(parent, "$key", $key_len, TRUE);
351
+ HV *new_hv;
352
+
353
+ if (!ref)
354
+ return NULL;
355
+
356
+ if (SvROK(*ref))
357
+ return (HV*) SvRV(*ref);
358
+
359
+ new_hv = newHV();
360
+ SvUPGRADE(*ref, SVt_RV);
361
+ SvRV_set(*ref, (SV *)new_hv);
362
+ SvROK_on(*ref);
363
+ return new_hv;
364
+ }
365
+
366
+ #endif
367
+
368
+ MISSING
369
+
370
+ }
371
+
372
+ print $xs_fh <<"EOBOOT";
373
+ BOOT:
374
+ {
375
+ #if defined(dTHX) && !defined(PERL_NO_GET_CONTEXT)
376
+ dTHX;
377
+ #endif
378
+ HV *symbol_table = get_hv("$symbol_table", GV_ADD);
379
+ EOBOOT
380
+ if ($push) {
381
+ print $xs_fh <<"EOC";
382
+ AV *push = get_av(\"$push\", GV_ADD);
383
+ HE *he;
384
+ EOC
385
+ }
386
+
387
+ my %iterator;
388
+
389
+ $found->{''}
390
+ = [map {{%$_, type=>'', invert_macro => 1}} @$notfound];
391
+
392
+ foreach my $type (sort keys %$found) {
393
+ my $struct = $type_to_struct{$type};
394
+ my $type_to_value = $self->type_to_C_value($type);
395
+ my $number_of_args = $type_num_args{$type};
396
+ die "Can't find structure definition for type $type"
397
+ unless defined $struct;
398
+
399
+ my $lc_type = $type ? lc($type) : 'notfound';
400
+ my $struct_type = $lc_type . '_s';
401
+ my $array_name = 'values_for_' . $lc_type;
402
+ $iterator{$type} = 'value_for_' . $lc_type;
403
+ # Give the notfound struct file scope. The others are scoped within the
404
+ # BOOT block
405
+ my $struct_fh = $type ? $xs_fh : $c_fh;
406
+
407
+ print $c_fh "struct $struct_type $struct;\n";
408
+
409
+ print $struct_fh <<"EOBOOT";
410
+
411
+ static const struct $struct_type $array_name\[] =
412
+ {
413
+ EOBOOT
414
+
415
+
416
+ foreach my $item (@{$found->{$type}}) {
417
+ my ($name, $namelen, $value, $macro)
418
+ = $self->name_len_value_macro($item);
419
+
420
+ my $ifdef = $self->macro_to_ifdef($macro);
421
+ if (!$ifdef && $item->{invert_macro}) {
422
+ carp("Attempting to supply a default for '$name' which has no conditional macro");
423
+ next;
424
+ }
425
+ if ($item->{invert_macro}) {
426
+ print $struct_fh $self->macro_to_ifndef($macro);
427
+ print $struct_fh
428
+ " /* This is the default value: */\n" if $type;
429
+ } else {
430
+ print $struct_fh $ifdef;
431
+ }
432
+ print $struct_fh " { ", join (', ', "\"$name\"", $namelen,
433
+ &$type_to_value($value)),
434
+ " },\n",
435
+ $self->macro_to_endif($macro);
436
+ }
437
+
438
+ # Terminate the list with a NULL
439
+ print $struct_fh " { NULL, 0", (", 0" x $number_of_args), " } };\n";
440
+
441
+ print $xs_fh <<"EOBOOT" if $type;
442
+ const struct $struct_type *$iterator{$type} = $array_name;
443
+ EOBOOT
444
+ }
445
+
446
+ delete $found->{''};
447
+
448
+ my $add_symbol_subname = $c_subname . '_add_symbol';
449
+ foreach my $type (sort keys %$found) {
450
+ print $xs_fh $self->boottime_iterator($type, $iterator{$type},
451
+ 'symbol_table',
452
+ $add_symbol_subname, $push);
453
+ }
454
+
455
+ print $xs_fh <<"EOBOOT";
456
+ if (C_ARRAY_LENGTH(values_for_notfound) > 1) {
457
+ #ifndef SYMBIAN
458
+ HV *const ${c_subname}_missing = get_missing_hash(aTHX);
459
+ #endif
460
+ const struct notfound_s *value_for_notfound = values_for_notfound;
461
+ do {
462
+ EOBOOT
463
+
464
+ print $xs_fh $explosives ? <<"EXPLODE" : << "DONT";
465
+ SV *tripwire = newSV(0);
466
+
467
+ sv_magicext(tripwire, 0, PERL_MAGIC_ext, &not_defined_vtbl, 0, 0);
468
+ SvPV_set(tripwire, (char *)value_for_notfound->name);
469
+ if(value_for_notfound->namelen >= 0) {
470
+ SvCUR_set(tripwire, value_for_notfound->namelen);
471
+ } else {
472
+ SvCUR_set(tripwire, -value_for_notfound->namelen);
473
+ SvUTF8_on(tripwire);
474
+ }
475
+ SvPOKp_on(tripwire);
476
+ SvREADONLY_on(tripwire);
477
+ assert(SvLEN(tripwire) == 0);
478
+
479
+ $add_symbol_subname($athx symbol_table, value_for_notfound->name,
480
+ value_for_notfound->namelen, tripwire);
481
+ EXPLODE
482
+
483
+ /* Need to add prototypes, else parsing will vary by platform. */
484
+ HE *he = (HE*) hv_common_key_len(symbol_table,
485
+ value_for_notfound->name,
486
+ value_for_notfound->namelen,
487
+ HV_FETCH_LVALUE, NULL, 0);
488
+ SV *sv;
489
+ #ifndef SYMBIAN
490
+ HEK *hek;
491
+ #endif
492
+ if (!he) {
493
+ croak("Couldn't add key '%s' to %%$package_sprintf_safe\::",
494
+ value_for_notfound->name);
495
+ }
496
+ sv = HeVAL(he);
497
+ if (!SvOK(sv) && SvTYPE(sv) != SVt_PVGV) {
498
+ /* Nothing was here before, so mark a prototype of "" */
499
+ sv_setpvn(sv, "", 0);
500
+ } else if (SvPOK(sv) && SvCUR(sv) == 0) {
501
+ /* There is already a prototype of "" - do nothing */
502
+ } else {
503
+ /* Someone has been here before us - have to make a real
504
+ typeglob. */
505
+ /* It turns out to be incredibly hard to deal with all the
506
+ corner cases of sub foo (); and reporting errors correctly,
507
+ so lets cheat a bit. Start with a constant subroutine */
508
+ CV *cv = newCONSTSUB(symbol_table,
509
+ ${cast_CONSTSUB}value_for_notfound->name,
510
+ &PL_sv_yes);
511
+ /* and then turn it into a non constant declaration only. */
512
+ SvREFCNT_dec(CvXSUBANY(cv).any_ptr);
513
+ CvCONST_off(cv);
514
+ CvXSUB(cv) = NULL;
515
+ CvXSUBANY(cv).any_ptr = NULL;
516
+ }
517
+ #ifndef SYMBIAN
518
+ hek = HeKEY_hek(he);
519
+ if (!hv_common(${c_subname}_missing, NULL, HEK_KEY(hek),
520
+ HEK_LEN(hek), HEK_FLAGS(hek), HV_FETCH_ISSTORE,
521
+ &PL_sv_yes, HEK_HASH(hek)))
522
+ croak("Couldn't add key '%s' to missing_hash",
523
+ value_for_notfound->name);
524
+ #endif
525
+ DONT
526
+
527
+ print $xs_fh " av_push(push, newSVhek(hek));\n"
528
+ if $push;
529
+
530
+ print $xs_fh <<"EOBOOT";
531
+ } while ((++value_for_notfound)->name);
532
+ }
533
+ EOBOOT
534
+
535
+ foreach my $item (@$trouble) {
536
+ my ($name, $namelen, $value, $macro)
537
+ = $self->name_len_value_macro($item);
538
+ my $ifdef = $self->macro_to_ifdef($macro);
539
+ my $type = $item->{type};
540
+ my $type_to_value = $self->type_to_C_value($type);
541
+
542
+ print $xs_fh $ifdef;
543
+ if ($item->{invert_macro}) {
544
+ print $xs_fh
545
+ " /* This is the default value: */\n" if $type;
546
+ print $xs_fh "#else\n";
547
+ }
548
+ my $generator = $type_to_sv{$type};
549
+ die "Can't find generator code for type $type"
550
+ unless defined $generator;
551
+
552
+ print $xs_fh " {\n";
553
+ # We need to use a temporary value because some really troublesome
554
+ # items use C pre processor directives in their values, and in turn
555
+ # these don't fit nicely in the macro-ised generator functions
556
+ my $counter = 0;
557
+ printf $xs_fh " %s temp%d;\n", $_, $counter++
558
+ foreach @{$type_temporary{$type}};
559
+
560
+ print $xs_fh " $item->{pre}\n" if $item->{pre};
561
+
562
+ # And because the code in pre might be both declarations and
563
+ # statements, we can't declare and assign to the temporaries in one.
564
+ $counter = 0;
565
+ printf $xs_fh " temp%d = %s;\n", $counter++, $_
566
+ foreach &$type_to_value($value);
567
+
568
+ my @tempvarnames = map {sprintf 'temp%d', $_} 0 .. $counter - 1;
569
+ printf $xs_fh <<"EOBOOT", $name, &$generator(@tempvarnames);
570
+ ${c_subname}_add_symbol($athx symbol_table, "%s",
571
+ $namelen, %s);
572
+ EOBOOT
573
+ print $xs_fh " $item->{post}\n" if $item->{post};
574
+ print $xs_fh " }\n";
575
+
576
+ print $xs_fh $self->macro_to_endif($macro);
577
+ }
578
+
579
+ if ($] >= 5.009) {
580
+ print $xs_fh <<EOBOOT;
581
+ /* As we've been creating subroutines, we better invalidate any cached
582
+ methods */
583
+ mro_method_changed_in(symbol_table);
584
+ }
585
+ EOBOOT
586
+ } else {
587
+ print $xs_fh <<EOBOOT;
588
+ /* As we've been creating subroutines, we better invalidate any cached
589
+ methods */
590
+ ++PL_sub_generation;
591
+ }
592
+ EOBOOT
593
+ }
594
+
595
+ return if !defined $xs_subname;
596
+
597
+ if ($croak_on_error || $autoload) {
598
+ print $xs_fh $croak_on_error ? <<"EOC" : <<'EOA';
599
+
600
+ void
601
+ $xs_subname(sv)
602
+ INPUT:
603
+ SV * sv;
604
+ PREINIT:
605
+ const PERL_CONTEXT *cx = caller_cx(0, NULL);
606
+ /* cx is NULL if we've been called from the top level. PL_curcop isn't
607
+ ideal, but it's much cheaper than other ways of not going SEGV. */
608
+ const COP *cop = cx ? cx->blk_oldcop : PL_curcop;
609
+ EOC
610
+
611
+ void
612
+ AUTOLOAD()
613
+ PROTOTYPE: DISABLE
614
+ PREINIT:
615
+ SV *sv = newSVpvn_flags(SvPVX(cv), SvCUR(cv), SVs_TEMP | SvUTF8(cv));
616
+ const COP *cop = PL_curcop;
617
+ EOA
618
+ print $xs_fh <<"EOC";
619
+ PPCODE:
620
+ #ifndef SYMBIAN
621
+ /* It's not obvious how to calculate this at C pre-processor time.
622
+ However, any compiler optimiser worth its salt should be able to
623
+ remove the dead code, and hopefully the now-obviously-unused static
624
+ function too. */
625
+ HV *${c_subname}_missing = (C_ARRAY_LENGTH(values_for_notfound) > 1)
626
+ ? get_missing_hash(aTHX) : NULL;
627
+ if ((C_ARRAY_LENGTH(values_for_notfound) > 1)
628
+ ? hv_exists_ent(${c_subname}_missing, sv, 0) : 0) {
629
+ sv = newSVpvf("Your vendor has not defined $package_sprintf_safe macro %" SVf
630
+ ", used at %" COP_FILE_F " line %" UVuf "\\n",
631
+ sv, COP_FILE(cop), (UV)CopLINE(cop));
632
+ } else
633
+ #endif
634
+ {
635
+ sv = newSVpvf("%" SVf
636
+ " is not a valid $package_sprintf_safe macro at %"
637
+ COP_FILE_F " line %" UVuf "\\n",
638
+ sv, COP_FILE(cop), (UV)CopLINE(cop));
639
+ }
640
+ croak_sv(sv_2mortal(sv));
641
+ EOC
642
+ } else {
643
+ print $xs_fh $explosives ? <<"EXPLODE" : <<"DONT";
644
+
645
+ void
646
+ $xs_subname(sv)
647
+ INPUT:
648
+ SV * sv;
649
+ PPCODE:
650
+ sv = newSVpvf("Your vendor has not defined $package_sprintf_safe macro %" SVf
651
+ ", used", sv);
652
+ PUSHs(sv_2mortal(sv));
653
+ EXPLODE
654
+
655
+ void
656
+ $xs_subname(sv)
657
+ INPUT:
658
+ SV * sv;
659
+ PPCODE:
660
+ #ifndef SYMBIAN
661
+ /* It's not obvious how to calculate this at C pre-processor time.
662
+ However, any compiler optimiser worth its salt should be able to
663
+ remove the dead code, and hopefully the now-obviously-unused static
664
+ function too. */
665
+ HV *${c_subname}_missing = (C_ARRAY_LENGTH(values_for_notfound) > 1)
666
+ ? get_missing_hash(aTHX) : NULL;
667
+ if ((C_ARRAY_LENGTH(values_for_notfound) > 1)
668
+ ? hv_exists_ent(${c_subname}_missing, sv, 0) : 0) {
669
+ sv = newSVpvf("Your vendor has not defined $package_sprintf_safe macro %" SVf
670
+ ", used", sv);
671
+ } else
672
+ #endif
673
+ {
674
+ sv = newSVpvf("%" SVf " is not a valid $package_sprintf_safe macro",
675
+ sv);
676
+ }
677
+ PUSHs(sv_2mortal(sv));
678
+ DONT
679
+ }
680
+ }
681
+
682
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Constant/XS.pm ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Constant::XS;
2
+
3
+ use strict;
4
+ use vars qw($VERSION %XS_Constant %XS_TypeSet @ISA @EXPORT_OK $is_perl56);
5
+ use Carp;
6
+ use ExtUtils::Constant::Utils 'perl_stringify';
7
+ require ExtUtils::Constant::Base;
8
+
9
+
10
+ @ISA = qw(ExtUtils::Constant::Base Exporter);
11
+ @EXPORT_OK = qw(%XS_Constant %XS_TypeSet);
12
+
13
+ $VERSION = '0.03';
14
+
15
+ $is_perl56 = ($] < 5.007 && $] > 5.005_50);
16
+
17
+ =head1 NAME
18
+
19
+ ExtUtils::Constant::XS - generate C code for XS modules' constants.
20
+
21
+ =head1 SYNOPSIS
22
+
23
+ require ExtUtils::Constant::XS;
24
+
25
+ =head1 DESCRIPTION
26
+
27
+ ExtUtils::Constant::XS overrides ExtUtils::Constant::Base to generate C
28
+ code for XS modules' constants.
29
+
30
+ =head1 BUGS
31
+
32
+ Nothing is documented.
33
+
34
+ Probably others.
35
+
36
+ =head1 AUTHOR
37
+
38
+ Nicholas Clark <[email protected]> based on the code in C<h2xs> by Larry Wall and
39
+ others
40
+
41
+ =cut
42
+
43
+ # '' is used as a flag to indicate non-ascii macro names, and hence the need
44
+ # to pass in the utf8 on/off flag.
45
+ %XS_Constant = (
46
+ '' => '',
47
+ IV => 'PUSHi(iv)',
48
+ UV => 'PUSHu((UV)iv)',
49
+ NV => 'PUSHn(nv)',
50
+ PV => 'PUSHp(pv, strlen(pv))',
51
+ PVN => 'PUSHp(pv, iv)',
52
+ SV => 'PUSHs(sv)',
53
+ YES => 'PUSHs(&PL_sv_yes)',
54
+ NO => 'PUSHs(&PL_sv_no)',
55
+ UNDEF => '', # implicit undef
56
+ );
57
+
58
+ %XS_TypeSet = (
59
+ IV => '*iv_return = ',
60
+ UV => '*iv_return = (IV)',
61
+ NV => '*nv_return = ',
62
+ PV => '*pv_return = ',
63
+ PVN => ['*pv_return = ', '*iv_return = (IV)'],
64
+ SV => '*sv_return = ',
65
+ YES => undef,
66
+ NO => undef,
67
+ UNDEF => undef,
68
+ );
69
+
70
+ sub header {
71
+ my $start = 1;
72
+ my @lines;
73
+ push @lines, "#define PERL_constant_NOTFOUND\t$start\n"; $start++;
74
+ push @lines, "#define PERL_constant_NOTDEF\t$start\n"; $start++;
75
+ foreach (sort keys %XS_Constant) {
76
+ next if $_ eq '';
77
+ push @lines, "#define PERL_constant_IS$_\t$start\n"; $start++;
78
+ }
79
+ push @lines, << 'EOT';
80
+
81
+ #ifndef NVTYPE
82
+ typedef double NV; /* 5.6 and later define NVTYPE, and typedef NV to it. */
83
+ #endif
84
+ #ifndef aTHX_
85
+ #define aTHX_ /* 5.6 or later define this for threading support. */
86
+ #endif
87
+ #ifndef pTHX_
88
+ #define pTHX_ /* 5.6 or later define this for threading support. */
89
+ #endif
90
+ EOT
91
+
92
+ return join '', @lines;
93
+ }
94
+
95
+ sub valid_type {
96
+ my ($self, $type) = @_;
97
+ return exists $XS_TypeSet{$type};
98
+ }
99
+
100
+ # This might actually be a return statement
101
+ sub assignment_clause_for_type {
102
+ my $self = shift;
103
+ my $args = shift;
104
+ my $type = $args->{type};
105
+ my $typeset = $XS_TypeSet{$type};
106
+ if (ref $typeset) {
107
+ die "Type $type is aggregate, but only single value given"
108
+ if @_ == 1;
109
+ return map {"$typeset->[$_]$_[$_];"} 0 .. $#$typeset;
110
+ } elsif (defined $typeset) {
111
+ confess "Aggregate value given for type $type"
112
+ if @_ > 1;
113
+ return "$typeset$_[0];";
114
+ }
115
+ return ();
116
+ }
117
+
118
+ sub return_statement_for_type {
119
+ my ($self, $type) = @_;
120
+ # In the future may pass in an options hash
121
+ $type = $type->{type} if ref $type;
122
+ "return PERL_constant_IS$type;";
123
+ }
124
+
125
+ sub return_statement_for_notdef {
126
+ # my ($self) = @_;
127
+ "return PERL_constant_NOTDEF;";
128
+ }
129
+
130
+ sub return_statement_for_notfound {
131
+ # my ($self) = @_;
132
+ "return PERL_constant_NOTFOUND;";
133
+ }
134
+
135
+ sub default_type {
136
+ 'IV';
137
+ }
138
+
139
+ sub macro_from_name {
140
+ my ($self, $item) = @_;
141
+ my $macro = $item->{name};
142
+ $macro = $item->{value} unless defined $macro;
143
+ $macro;
144
+ }
145
+
146
+ sub macro_from_item {
147
+ my ($self, $item) = @_;
148
+ my $macro = $item->{macro};
149
+ $macro = $self->macro_from_name($item) unless defined $macro;
150
+ $macro;
151
+ }
152
+
153
+ # Keep to the traditional perl source macro
154
+ sub memEQ {
155
+ "memEQ";
156
+ }
157
+
158
+ sub params {
159
+ my ($self, $what) = @_;
160
+ foreach (sort keys %$what) {
161
+ warn "ExtUtils::Constant doesn't know how to handle values of type $_" unless defined $XS_Constant{$_};
162
+ }
163
+ my $params = {};
164
+ $params->{''} = 1 if $what->{''};
165
+ $params->{IV} = 1 if $what->{IV} || $what->{UV} || $what->{PVN};
166
+ $params->{NV} = 1 if $what->{NV};
167
+ $params->{PV} = 1 if $what->{PV} || $what->{PVN};
168
+ $params->{SV} = 1 if $what->{SV};
169
+ return $params;
170
+ }
171
+
172
+
173
+ sub C_constant_prefix_param {
174
+ "aTHX_ ";
175
+ }
176
+
177
+ sub C_constant_prefix_param_defintion {
178
+ "pTHX_ ";
179
+ }
180
+
181
+ sub namelen_param_definition {
182
+ 'STRLEN ' . $_[0] -> namelen_param;
183
+ }
184
+
185
+ sub C_constant_other_params_defintion {
186
+ my ($self, $params) = @_;
187
+ my $body = '';
188
+ $body .= ", int utf8" if $params->{''};
189
+ $body .= ", IV *iv_return" if $params->{IV};
190
+ $body .= ", NV *nv_return" if $params->{NV};
191
+ $body .= ", const char **pv_return" if $params->{PV};
192
+ $body .= ", SV **sv_return" if $params->{SV};
193
+ $body;
194
+ }
195
+
196
+ sub C_constant_other_params {
197
+ my ($self, $params) = @_;
198
+ my $body = '';
199
+ $body .= ", utf8" if $params->{''};
200
+ $body .= ", iv_return" if $params->{IV};
201
+ $body .= ", nv_return" if $params->{NV};
202
+ $body .= ", pv_return" if $params->{PV};
203
+ $body .= ", sv_return" if $params->{SV};
204
+ $body;
205
+ }
206
+
207
+ sub dogfood {
208
+ my ($self, $args, @items) = @_;
209
+ my ($package, $subname, $default_type, $what, $indent, $breakout) =
210
+ @{$args}{qw(package subname default_type what indent breakout)};
211
+ my $result = <<"EOT";
212
+ /* When generated this function returned values for the list of names given
213
+ in this section of perl code. Rather than manually editing these functions
214
+ to add or remove constants, which would result in this comment and section
215
+ of code becoming inaccurate, we recommend that you edit this section of
216
+ code, and use it to regenerate a new set of constant functions which you
217
+ then use to replace the originals.
218
+
219
+ Regenerate these constant functions by feeding this entire source file to
220
+ perl -x
221
+
222
+ #!$^X -w
223
+ use ExtUtils::Constant qw (constant_types C_constant XS_constant);
224
+
225
+ EOT
226
+ $result .= $self->dump_names ({default_type=>$default_type, what=>$what,
227
+ indent=>0, declare_types=>1},
228
+ @items);
229
+ $result .= <<'EOT';
230
+
231
+ print constant_types(), "\n"; # macro defs
232
+ EOT
233
+ $package = perl_stringify($package);
234
+ $result .=
235
+ "foreach (C_constant (\"$package\", '$subname', '$default_type', \$types, ";
236
+ # The form of the indent parameter isn't defined. (Yet)
237
+ if (defined $indent) {
238
+ require Data::Dumper;
239
+ $Data::Dumper::Terse=1;
240
+ $Data::Dumper::Terse=1; # Not used once. :-)
241
+ chomp ($indent = Data::Dumper::Dumper ($indent));
242
+ $result .= $indent;
243
+ } else {
244
+ $result .= 'undef';
245
+ }
246
+ $result .= ", $breakout" . ', @names) ) {
247
+ print $_, "\n"; # C constant subs
248
+ }
249
+ print "\n#### XS Section:\n";
250
+ print XS_constant ("' . $package . '", $types);
251
+ __END__
252
+ */
253
+
254
+ ';
255
+
256
+ $result;
257
+ }
258
+
259
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/MakeMaker/FAQ.pod ADDED
@@ -0,0 +1,666 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::MakeMaker::FAQ;
2
+
3
+ our $VERSION = '7.34';
4
+ $VERSION = eval $VERSION;
5
+
6
+ 1;
7
+ __END__
8
+
9
+ =head1 NAME
10
+
11
+ ExtUtils::MakeMaker::FAQ - Frequently Asked Questions About MakeMaker
12
+
13
+ =head1 DESCRIPTION
14
+
15
+ FAQs, tricks and tips for C<ExtUtils::MakeMaker>.
16
+
17
+
18
+ =head2 Module Installation
19
+
20
+ =over 4
21
+
22
+ =item How do I install a module into my home directory?
23
+
24
+ If you're not the Perl administrator you probably don't have
25
+ permission to install a module to its default location. Ways of handling
26
+ this with a B<lot> less manual effort on your part are L<perlbrew>
27
+ and L<local::lib>.
28
+
29
+ Otherwise, you can install it for your own use into your home directory
30
+ like so:
31
+
32
+ # Non-unix folks, replace ~ with /path/to/your/home/dir
33
+ perl Makefile.PL INSTALL_BASE=~
34
+
35
+ This will put modules into F<~/lib/perl5>, man pages into F<~/man> and
36
+ programs into F<~/bin>.
37
+
38
+ To ensure your Perl programs can see these newly installed modules,
39
+ set your C<PERL5LIB> environment variable to F<~/lib/perl5> or tell
40
+ each of your programs to look in that directory with the following:
41
+
42
+ use lib "$ENV{HOME}/lib/perl5";
43
+
44
+ or if $ENV{HOME} isn't set and you don't want to set it for some
45
+ reason, do it the long way.
46
+
47
+ use lib "/path/to/your/home/dir/lib/perl5";
48
+
49
+ =item How do I get MakeMaker and Module::Build to install to the same place?
50
+
51
+ Module::Build, as of 0.28, supports two ways to install to the same
52
+ location as MakeMaker.
53
+
54
+ We highly recommend the install_base method, its the simplest and most
55
+ closely approximates the expected behavior of an installation prefix.
56
+
57
+ 1) Use INSTALL_BASE / C<--install_base>
58
+
59
+ MakeMaker (as of 6.31) and Module::Build (as of 0.28) both can install
60
+ to the same locations using the "install_base" concept. See
61
+ L<ExtUtils::MakeMaker/INSTALL_BASE> for details. To get MM and MB to
62
+ install to the same location simply set INSTALL_BASE in MM and
63
+ C<--install_base> in MB to the same location.
64
+
65
+ perl Makefile.PL INSTALL_BASE=/whatever
66
+ perl Build.PL --install_base /whatever
67
+
68
+ This works most like other language's behavior when you specify a
69
+ prefix. We recommend this method.
70
+
71
+ 2) Use PREFIX / C<--prefix>
72
+
73
+ Module::Build 0.28 added support for C<--prefix> which works like
74
+ MakeMaker's PREFIX.
75
+
76
+ perl Makefile.PL PREFIX=/whatever
77
+ perl Build.PL --prefix /whatever
78
+
79
+ We highly discourage this method. It should only be used if you know
80
+ what you're doing and specifically need the PREFIX behavior. The
81
+ PREFIX algorithm is complicated and focused on matching the system
82
+ installation.
83
+
84
+ =item How do I keep from installing man pages?
85
+
86
+ Recent versions of MakeMaker will only install man pages on Unix-like
87
+ operating systems.
88
+
89
+ For an individual module:
90
+
91
+ perl Makefile.PL INSTALLMAN1DIR=none INSTALLMAN3DIR=none
92
+
93
+ If you want to suppress man page installation for all modules you have
94
+ to reconfigure Perl and tell it 'none' when it asks where to install
95
+ man pages.
96
+
97
+
98
+ =item How do I use a module without installing it?
99
+
100
+ Two ways. One is to build the module normally...
101
+
102
+ perl Makefile.PL
103
+ make
104
+ make test
105
+
106
+ ...and then use L<blib> to point Perl at the built but uninstalled module:
107
+
108
+ perl -Mblib script.pl
109
+ perl -Mblib -e '...'
110
+
111
+ The other is to install the module in a temporary location.
112
+
113
+ perl Makefile.PL INSTALL_BASE=~/tmp
114
+ make
115
+ make test
116
+ make install
117
+
118
+ And then set PERL5LIB to F<~/tmp/lib/perl5>. This works well when you
119
+ have multiple modules to work with. It also ensures that the module
120
+ goes through its full installation process which may modify it.
121
+ Again, L<local::lib> may assist you here.
122
+
123
+ =item How can I organize tests into subdirectories and have them run?
124
+
125
+ Let's take the following test directory structure:
126
+
127
+ t/foo/sometest.t
128
+ t/bar/othertest.t
129
+ t/bar/baz/anothertest.t
130
+
131
+ Now, inside of the C<WriteMakeFile()> function in your F<Makefile.PL>, specify
132
+ where your tests are located with the C<test> directive:
133
+
134
+ test => {TESTS => 't/*.t t/*/*.t t/*/*/*.t'}
135
+
136
+ The first entry in the string will run all tests in the top-level F<t/>
137
+ directory. The second will run all test files located in any subdirectory under
138
+ F<t/>. The third, runs all test files within any subdirectory within any other
139
+ subdirectory located under F<t/>.
140
+
141
+ Note that you do not have to use wildcards. You can specify explicitly which
142
+ subdirectories to run tests in:
143
+
144
+ test => {TESTS => 't/*.t t/foo/*.t t/bar/baz/*.t'}
145
+
146
+ =item PREFIX vs INSTALL_BASE from Module::Build::Cookbook
147
+
148
+ The behavior of PREFIX is complicated and depends closely on how your
149
+ Perl is configured. The resulting installation locations will vary
150
+ from machine to machine and even different installations of Perl on the
151
+ same machine. Because of this, its difficult to document where prefix
152
+ will place your modules.
153
+
154
+ In contrast, INSTALL_BASE has predictable, easy to explain installation
155
+ locations. Now that Module::Build and MakeMaker both have INSTALL_BASE
156
+ there is little reason to use PREFIX other than to preserve your existing
157
+ installation locations. If you are starting a fresh Perl installation we
158
+ encourage you to use INSTALL_BASE. If you have an existing installation
159
+ installed via PREFIX, consider moving it to an installation structure
160
+ matching INSTALL_BASE and using that instead.
161
+
162
+ =item Generating *.pm files with substitutions eg of $VERSION
163
+
164
+ If you want to configure your module files for local conditions, or to
165
+ automatically insert a version number, you can use EUMM's C<PL_FILES>
166
+ capability, where it will automatically run each F<*.PL> it finds to
167
+ generate its basename. For instance:
168
+
169
+ # Makefile.PL:
170
+ require 'common.pl';
171
+ my $version = get_version();
172
+ my @pms = qw(Foo.pm);
173
+ WriteMakefile(
174
+ NAME => 'Foo',
175
+ VERSION => $version,
176
+ PM => { map { ($_ => "\$(INST_LIB)/$_") } @pms },
177
+ clean => { FILES => join ' ', @pms },
178
+ );
179
+
180
+ # common.pl:
181
+ sub get_version { '0.04' }
182
+ sub process { my $v = get_version(); s/__VERSION__/$v/g; }
183
+ 1;
184
+
185
+ # Foo.pm.PL:
186
+ require 'common.pl';
187
+ $_ = join '', <DATA>;
188
+ process();
189
+ my $file = shift;
190
+ open my $fh, '>', $file or die "$file: $!";
191
+ print $fh $_;
192
+ __DATA__
193
+ package Foo;
194
+ our $VERSION = '__VERSION__';
195
+ 1;
196
+
197
+ You may notice that C<PL_FILES> is not specified above, since the default
198
+ of mapping each .PL file to its basename works well.
199
+
200
+ If the generated module were architecture-specific, you could replace
201
+ C<$(INST_LIB)> above with C<$(INST_ARCHLIB)>, although if you locate
202
+ modules under F<lib>, that would involve ensuring any C<lib/> in front
203
+ of the module location were removed.
204
+
205
+ =back
206
+
207
+ =head2 Common errors and problems
208
+
209
+ =over 4
210
+
211
+ =item "No rule to make target `/usr/lib/perl5/CORE/config.h', needed by `Makefile'"
212
+
213
+ Just what it says, you're missing that file. MakeMaker uses it to
214
+ determine if perl has been rebuilt since the Makefile was made. It's
215
+ a bit of a bug that it halts installation.
216
+
217
+ Some operating systems don't ship the CORE directory with their base
218
+ perl install. To solve the problem, you likely need to install a perl
219
+ development package such as perl-devel (CentOS, Fedora and other
220
+ Redhat systems) or perl (Ubuntu and other Debian systems).
221
+
222
+ =back
223
+
224
+ =head2 Philosophy and History
225
+
226
+ =over 4
227
+
228
+ =item Why not just use <insert other build config tool here>?
229
+
230
+ Why did MakeMaker reinvent the build configuration wheel? Why not
231
+ just use autoconf or automake or ppm or Ant or ...
232
+
233
+ There are many reasons, but the major one is cross-platform
234
+ compatibility.
235
+
236
+ Perl is one of the most ported pieces of software ever. It works on
237
+ operating systems I've never even heard of (see perlport for details).
238
+ It needs a build tool that can work on all those platforms and with
239
+ any wacky C compilers and linkers they might have.
240
+
241
+ No such build tool exists. Even make itself has wildly different
242
+ dialects. So we have to build our own.
243
+
244
+
245
+ =item What is Module::Build and how does it relate to MakeMaker?
246
+
247
+ Module::Build is a project by Ken Williams to supplant MakeMaker.
248
+ Its primary advantages are:
249
+
250
+ =over 8
251
+
252
+ =item * pure perl. no make, no shell commands
253
+
254
+ =item * easier to customize
255
+
256
+ =item * cleaner internals
257
+
258
+ =item * less cruft
259
+
260
+ =back
261
+
262
+ Module::Build was long the official heir apparent to MakeMaker. The
263
+ rate of both its development and adoption has slowed in recent years,
264
+ though, and it is unclear what the future holds for it. That said,
265
+ Module::Build set the stage for I<something> to become the heir to
266
+ MakeMaker. MakeMaker's maintainers have long said that it is a dead
267
+ end and should be kept functioning, while being cautious about extending
268
+ with new features.
269
+
270
+ =back
271
+
272
+ =head2 Module Writing
273
+
274
+ =over 4
275
+
276
+ =item How do I keep my $VERSION up to date without resetting it manually?
277
+
278
+ Often you want to manually set the $VERSION in the main module
279
+ distribution because this is the version that everybody sees on CPAN
280
+ and maybe you want to customize it a bit. But for all the other
281
+ modules in your dist, $VERSION is really just bookkeeping and all that's
282
+ important is it goes up every time the module is changed. Doing this
283
+ by hand is a pain and you often forget.
284
+
285
+ Probably the easiest way to do this is using F<perl-reversion> in
286
+ L<Perl::Version>:
287
+
288
+ perl-reversion -bump
289
+
290
+ If your version control system supports revision numbers (git doesn't
291
+ easily), the simplest way to do it automatically is to use its revision
292
+ number (you are using version control, right?).
293
+
294
+ In CVS, RCS and SVN you use $Revision$ (see the documentation of your
295
+ version control system for details). Every time the file is checked
296
+ in the $Revision$ will be updated, updating your $VERSION.
297
+
298
+ SVN uses a simple integer for $Revision$ so you can adapt it for your
299
+ $VERSION like so:
300
+
301
+ ($VERSION) = q$Revision$ =~ /(\d+)/;
302
+
303
+ In CVS and RCS version 1.9 is followed by 1.10. Since CPAN compares
304
+ version numbers numerically we use a sprintf() to convert 1.9 to 1.009
305
+ and 1.10 to 1.010 which compare properly.
306
+
307
+ $VERSION = sprintf "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/g;
308
+
309
+ If branches are involved (ie. $Revision: 1.5.3.4$) it's a little more
310
+ complicated.
311
+
312
+ # must be all on one line or MakeMaker will get confused.
313
+ $VERSION = do { my @r = (q$Revision$ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r };
314
+
315
+ In SVN, $Revision$ should be the same for every file in the project so
316
+ they would all have the same $VERSION. CVS and RCS have a different
317
+ $Revision$ per file so each file will have a different $VERSION.
318
+ Distributed version control systems, such as SVK, may have a different
319
+ $Revision$ based on who checks out the file, leading to a different $VERSION
320
+ on each machine! Finally, some distributed version control systems, such
321
+ as darcs, have no concept of revision number at all.
322
+
323
+
324
+ =item What's this F<META.yml> thing and how did it get in my F<MANIFEST>?!
325
+
326
+ F<META.yml> is a module meta-data file pioneered by Module::Build and
327
+ automatically generated as part of the 'distdir' target (and thus
328
+ 'dist'). See L<ExtUtils::MakeMaker/"Module Meta-Data">.
329
+
330
+ To shut off its generation, pass the C<NO_META> flag to C<WriteMakefile()>.
331
+
332
+
333
+ =item How do I delete everything not in my F<MANIFEST>?
334
+
335
+ Some folks are surprised that C<make distclean> does not delete
336
+ everything not listed in their MANIFEST (thus making a clean
337
+ distribution) but only tells them what they need to delete. This is
338
+ done because it is considered too dangerous. While developing your
339
+ module you might write a new file, not add it to the MANIFEST, then
340
+ run a C<distclean> and be sad because your new work was deleted.
341
+
342
+ If you really want to do this, you can use
343
+ C<ExtUtils::Manifest::manifind()> to read the MANIFEST and File::Find
344
+ to delete the files. But you have to be careful. Here's a script to
345
+ do that. Use at your own risk. Have fun blowing holes in your foot.
346
+
347
+ #!/usr/bin/perl -w
348
+
349
+ use strict;
350
+
351
+ use File::Spec;
352
+ use File::Find;
353
+ use ExtUtils::Manifest qw(maniread);
354
+
355
+ my %manifest = map {( $_ => 1 )}
356
+ grep { File::Spec->canonpath($_) }
357
+ keys %{ maniread() };
358
+
359
+ if( !keys %manifest ) {
360
+ print "No files found in MANIFEST. Stopping.\n";
361
+ exit;
362
+ }
363
+
364
+ find({
365
+ wanted => sub {
366
+ my $path = File::Spec->canonpath($_);
367
+
368
+ return unless -f $path;
369
+ return if exists $manifest{ $path };
370
+
371
+ print "unlink $path\n";
372
+ unlink $path;
373
+ },
374
+ no_chdir => 1
375
+ },
376
+ "."
377
+ );
378
+
379
+
380
+ =item Which tar should I use on Windows?
381
+
382
+ We recommend ptar from Archive::Tar not older than 1.66 with '-C' option.
383
+
384
+ =item Which zip should I use on Windows for '[ndg]make zipdist'?
385
+
386
+ We recommend InfoZIP: L<http://www.info-zip.org/Zip.html>
387
+
388
+
389
+ =back
390
+
391
+ =head2 XS
392
+
393
+ =over 4
394
+
395
+ =item How do I prevent "object version X.XX does not match bootstrap parameter Y.YY" errors?
396
+
397
+ XS code is very sensitive to the module version number and will
398
+ complain if the version number in your Perl module doesn't match. If
399
+ you change your module's version # without rerunning Makefile.PL the old
400
+ version number will remain in the Makefile, causing the XS code to be built
401
+ with the wrong number.
402
+
403
+ To avoid this, you can force the Makefile to be rebuilt whenever you
404
+ change the module containing the version number by adding this to your
405
+ WriteMakefile() arguments.
406
+
407
+ depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' }
408
+
409
+
410
+ =item How do I make two or more XS files coexist in the same directory?
411
+
412
+ Sometimes you need to have two and more XS files in the same package.
413
+ There are three ways: C<XSMULTI>, separate directories, and bootstrapping
414
+ one XS from another.
415
+
416
+ =over 8
417
+
418
+ =item XSMULTI
419
+
420
+ Structure your modules so they are all located under F<lib>, such that
421
+ C<Foo::Bar> is in F<lib/Foo/Bar.pm> and F<lib/Foo/Bar.xs>, etc. Have your
422
+ top-level C<WriteMakefile> set the variable C<XSMULTI> to a true value.
423
+
424
+ Er, that's it.
425
+
426
+ =item Separate directories
427
+
428
+ Put each XS files into separate directories, each with their own
429
+ F<Makefile.PL>. Make sure each of those F<Makefile.PL>s has the correct
430
+ C<CFLAGS>, C<INC>, C<LIBS> etc. You will need to make sure the top-level
431
+ F<Makefile.PL> refers to each of these using C<DIR>.
432
+
433
+ =item Bootstrapping
434
+
435
+ Let's assume that we have a package C<Cool::Foo>, which includes
436
+ C<Cool::Foo> and C<Cool::Bar> modules each having a separate XS
437
+ file. First we use the following I<Makefile.PL>:
438
+
439
+ use ExtUtils::MakeMaker;
440
+
441
+ WriteMakefile(
442
+ NAME => 'Cool::Foo',
443
+ VERSION_FROM => 'Foo.pm',
444
+ OBJECT => q/$(O_FILES)/,
445
+ # ... other attrs ...
446
+ );
447
+
448
+ Notice the C<OBJECT> attribute. MakeMaker generates the following
449
+ variables in I<Makefile>:
450
+
451
+ # Handy lists of source code files:
452
+ XS_FILES= Bar.xs \
453
+ Foo.xs
454
+ C_FILES = Bar.c \
455
+ Foo.c
456
+ O_FILES = Bar.o \
457
+ Foo.o
458
+
459
+ Therefore we can use the C<O_FILES> variable to tell MakeMaker to use
460
+ these objects into the shared library.
461
+
462
+ That's pretty much it. Now write I<Foo.pm> and I<Foo.xs>, I<Bar.pm>
463
+ and I<Bar.xs>, where I<Foo.pm> bootstraps the shared library and
464
+ I<Bar.pm> simply loading I<Foo.pm>.
465
+
466
+ The only issue left is to how to bootstrap I<Bar.xs>. This is done
467
+ from I<Foo.xs>:
468
+
469
+ MODULE = Cool::Foo PACKAGE = Cool::Foo
470
+
471
+ BOOT:
472
+ # boot the second XS file
473
+ boot_Cool__Bar(aTHX_ cv);
474
+
475
+ If you have more than two files, this is the place where you should
476
+ boot extra XS files from.
477
+
478
+ The following four files sum up all the details discussed so far.
479
+
480
+ Foo.pm:
481
+ -------
482
+ package Cool::Foo;
483
+
484
+ require DynaLoader;
485
+
486
+ our @ISA = qw(DynaLoader);
487
+ our $VERSION = '0.01';
488
+ bootstrap Cool::Foo $VERSION;
489
+
490
+ 1;
491
+
492
+ Bar.pm:
493
+ -------
494
+ package Cool::Bar;
495
+
496
+ use Cool::Foo; # bootstraps Bar.xs
497
+
498
+ 1;
499
+
500
+ Foo.xs:
501
+ -------
502
+ #include "EXTERN.h"
503
+ #include "perl.h"
504
+ #include "XSUB.h"
505
+
506
+ MODULE = Cool::Foo PACKAGE = Cool::Foo
507
+
508
+ BOOT:
509
+ # boot the second XS file
510
+ boot_Cool__Bar(aTHX_ cv);
511
+
512
+ MODULE = Cool::Foo PACKAGE = Cool::Foo PREFIX = cool_foo_
513
+
514
+ void
515
+ cool_foo_perl_rules()
516
+
517
+ CODE:
518
+ fprintf(stderr, "Cool::Foo says: Perl Rules\n");
519
+
520
+ Bar.xs:
521
+ -------
522
+ #include "EXTERN.h"
523
+ #include "perl.h"
524
+ #include "XSUB.h"
525
+
526
+ MODULE = Cool::Bar PACKAGE = Cool::Bar PREFIX = cool_bar_
527
+
528
+ void
529
+ cool_bar_perl_rules()
530
+
531
+ CODE:
532
+ fprintf(stderr, "Cool::Bar says: Perl Rules\n");
533
+
534
+ And of course a very basic test:
535
+
536
+ t/cool.t:
537
+ --------
538
+ use Test;
539
+ BEGIN { plan tests => 1 };
540
+ use Cool::Foo;
541
+ use Cool::Bar;
542
+ Cool::Foo::perl_rules();
543
+ Cool::Bar::perl_rules();
544
+ ok 1;
545
+
546
+ This tip has been brought to you by Nick Ing-Simmons and Stas Bekman.
547
+
548
+ An alternative way to achieve this can be seen in L<Gtk2::CodeGen>
549
+ and L<Glib::CodeGen>.
550
+
551
+ =back
552
+
553
+ =back
554
+
555
+ =head1 DESIGN
556
+
557
+ =head2 MakeMaker object hierarchy (simplified)
558
+
559
+ What most people need to know (superclasses on top.)
560
+
561
+ ExtUtils::MM_Any
562
+ |
563
+ ExtUtils::MM_Unix
564
+ |
565
+ ExtUtils::MM_{Current OS}
566
+ |
567
+ ExtUtils::MakeMaker
568
+ |
569
+ MY
570
+
571
+ The object actually used is of the class MY which allows you to
572
+ override bits of MakeMaker inside your Makefile.PL by declaring
573
+ MY::foo() methods.
574
+
575
+ =head2 MakeMaker object hierarchy (real)
576
+
577
+ Here's how it really works:
578
+
579
+ ExtUtils::MM_Any
580
+ |
581
+ ExtUtils::MM_Unix
582
+ |
583
+ ExtUtils::Liblist::Kid ExtUtils::MM_{Current OS} (if necessary)
584
+ | |
585
+ ExtUtils::Liblist ExtUtils::MakeMaker |
586
+ | | |
587
+ | | |-----------------------
588
+ ExtUtils::MM
589
+ | |
590
+ ExtUtils::MY MM (created by ExtUtils::MM)
591
+ | |
592
+ MY (created by ExtUtils::MY) |
593
+ . |
594
+ (mixin) |
595
+ . |
596
+ PACK### (created each call to ExtUtils::MakeMaker->new)
597
+
598
+ NOTE: Yes, this is a mess. See
599
+ L<http://archive.develooper.com/[email protected]/msg00134.html>
600
+ for some history.
601
+
602
+ NOTE: When ExtUtils::MM is loaded it chooses a superclass for MM from
603
+ amongst the ExtUtils::MM_* modules based on the current operating
604
+ system.
605
+
606
+ NOTE: ExtUtils::MM_{Current OS} represents one of the ExtUtils::MM_*
607
+ modules except ExtUtils::MM_Any chosen based on your operating system.
608
+
609
+ NOTE: The main object used by MakeMaker is a PACK### object, *not*
610
+ ExtUtils::MakeMaker. It is, effectively, a subclass of MY,
611
+ ExtUtils::Makemaker, ExtUtils::Liblist and ExtUtils::MM_{Current OS}
612
+
613
+ NOTE: The methods in MY are simply copied into PACK### rather than
614
+ MY being a superclass of PACK###. I don't remember the rationale.
615
+
616
+ NOTE: ExtUtils::Liblist should be removed from the inheritance hiearchy
617
+ and simply be called as functions.
618
+
619
+ NOTE: Modules like File::Spec and Exporter have been omitted for clarity.
620
+
621
+
622
+ =head2 The MM_* hierarchy
623
+
624
+ MM_Win95 MM_NW5
625
+ \ /
626
+ MM_BeOS MM_Cygwin MM_OS2 MM_VMS MM_Win32 MM_DOS MM_UWIN
627
+ \ | | | / / /
628
+ ------------------------------------------------
629
+ | |
630
+ MM_Unix |
631
+ | |
632
+ MM_Any
633
+
634
+ NOTE: Each direct MM_Unix subclass is also an MM_Any subclass. This
635
+ is a temporary hack because MM_Unix overrides some MM_Any methods with
636
+ Unix specific code. It allows the non-Unix modules to see the
637
+ original MM_Any implementations.
638
+
639
+ NOTE: Modules like File::Spec and Exporter have been omitted for clarity.
640
+
641
+ =head1 PATCHING
642
+
643
+ If you have a question you'd like to see added to the FAQ (whether or
644
+ not you have the answer) please either:
645
+
646
+ =over 2
647
+
648
+ =item * make a pull request on the MakeMaker github repository
649
+
650
+ =item * raise a issue on the MakeMaker github repository
651
+
652
+ =item * file an RT ticket
653
+
654
+ =item * email [email protected]
655
+
656
+ =back
657
+
658
+ =head1 AUTHOR
659
+
660
+ The denizens of [email protected].
661
+
662
+ =head1 SEE ALSO
663
+
664
+ L<ExtUtils::MakeMaker>
665
+
666
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/Constants.pm ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::ParseXS::Constants;
2
+ use strict;
3
+ use warnings;
4
+ use Symbol;
5
+
6
+ our $VERSION = '3.40';
7
+
8
+ =head1 NAME
9
+
10
+ ExtUtils::ParseXS::Constants - Initialization values for some globals
11
+
12
+ =head1 SYNOPSIS
13
+
14
+ use ExtUtils::ParseXS::Constants ();
15
+
16
+ $PrototypeRegexp = $ExtUtils::ParseXS::Constants::PrototypeRegexp;
17
+
18
+ =head1 DESCRIPTION
19
+
20
+ Initialization of certain non-subroutine variables in ExtUtils::ParseXS and some of its
21
+ supporting packages has been moved into this package so that those values can
22
+ be defined exactly once and then re-used in any package.
23
+
24
+ Nothing is exported. Use fully qualified variable names.
25
+
26
+ =cut
27
+
28
+ # FIXME: THESE ARE NOT CONSTANTS!
29
+ our @InitFileCode;
30
+
31
+ # Note that to reduce maintenance, $PrototypeRegexp is used
32
+ # by ExtUtils::Typemaps, too!
33
+ our $PrototypeRegexp = "[" . quotemeta('\$%&*@;[]_') . "]";
34
+ our @XSKeywords = qw(
35
+ REQUIRE BOOT CASE PREINIT INPUT INIT CODE PPCODE
36
+ OUTPUT CLEANUP ALIAS ATTRS PROTOTYPES PROTOTYPE
37
+ VERSIONCHECK INCLUDE INCLUDE_COMMAND SCOPE INTERFACE
38
+ INTERFACE_MACRO C_ARGS POSTCALL OVERLOAD FALLBACK
39
+ EXPORT_XSUB_SYMBOLS
40
+ );
41
+
42
+ our $XSKeywordsAlternation = join('|', @XSKeywords);
43
+
44
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/CountLines.pm ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::ParseXS::CountLines;
2
+ use strict;
3
+
4
+ our $VERSION = '3.40';
5
+
6
+ our $SECTION_END_MARKER;
7
+
8
+ sub TIEHANDLE {
9
+ my ($class, $cfile, $fh) = @_;
10
+ $cfile =~ s/\\/\\\\/g;
11
+ $cfile =~ s/"/\\"/g;
12
+ $SECTION_END_MARKER = qq{#line --- "$cfile"};
13
+
14
+ return bless {
15
+ buffer => '',
16
+ fh => $fh,
17
+ line_no => 1,
18
+ }, $class;
19
+ }
20
+
21
+ sub PRINT {
22
+ my $self = shift;
23
+ for (@_) {
24
+ $self->{buffer} .= $_;
25
+ while ($self->{buffer} =~ s/^([^\n]*\n)//) {
26
+ my $line = $1;
27
+ ++$self->{line_no};
28
+ $line =~ s|^\#line\s+---(?=\s)|#line $self->{line_no}|;
29
+ print {$self->{fh}} $line;
30
+ }
31
+ }
32
+ }
33
+
34
+ sub PRINTF {
35
+ my $self = shift;
36
+ my $fmt = shift;
37
+ $self->PRINT(sprintf($fmt, @_));
38
+ }
39
+
40
+ sub DESTROY {
41
+ # Not necessary if we're careful to end with a "\n"
42
+ my $self = shift;
43
+ print {$self->{fh}} $self->{buffer};
44
+ }
45
+
46
+ sub UNTIE {
47
+ # This sub does nothing, but is necessary for references to be released.
48
+ }
49
+
50
+ sub end_marker {
51
+ return $SECTION_END_MARKER;
52
+ }
53
+
54
+ 1;
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/Eval.pm ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::ParseXS::Eval;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '3.40';
6
+
7
+ =head1 NAME
8
+
9
+ ExtUtils::ParseXS::Eval - Clean package to evaluate code in
10
+
11
+ =head1 SYNOPSIS
12
+
13
+ use ExtUtils::ParseXS::Eval;
14
+ my $rv = ExtUtils::ParseXS::Eval::eval_typemap_code(
15
+ $parsexs_obj, "some Perl code"
16
+ );
17
+
18
+ =head1 SUBROUTINES
19
+
20
+ =head2 $pxs->eval_output_typemap_code($typemapcode, $other_hashref)
21
+
22
+ Sets up various bits of previously global state
23
+ (formerly ExtUtils::ParseXS package variables)
24
+ for eval'ing output typemap code that may refer to these
25
+ variables.
26
+
27
+ Warns the contents of C<$@> if any.
28
+
29
+ Not all these variables are necessarily considered "public" wrt. use in
30
+ typemaps, so beware. Variables set up from the ExtUtils::ParseXS object:
31
+
32
+ $Package $ALIAS $func_name $Full_func_name $pname
33
+
34
+ Variables set up from C<$other_hashref>:
35
+
36
+ $var $type $ntype $subtype $arg
37
+
38
+ =cut
39
+
40
+ sub eval_output_typemap_code {
41
+ my ($_pxs, $_code, $_other) = @_;
42
+
43
+ my ($Package, $ALIAS, $func_name, $Full_func_name, $pname)
44
+ = @{$_pxs}{qw(Package ALIAS func_name Full_func_name pname)};
45
+
46
+ my ($var, $type, $ntype, $subtype, $arg)
47
+ = @{$_other}{qw(var type ntype subtype arg)};
48
+
49
+ my $rv = eval $_code;
50
+ warn $@ if $@;
51
+ return $rv;
52
+ }
53
+
54
+ =head2 $pxs->eval_input_typemap_code($typemapcode, $other_hashref)
55
+
56
+ Sets up various bits of previously global state
57
+ (formerly ExtUtils::ParseXS package variables)
58
+ for eval'ing output typemap code that may refer to these
59
+ variables.
60
+
61
+ Warns the contents of C<$@> if any.
62
+
63
+ Not all these variables are necessarily considered "public" wrt. use in
64
+ typemaps, so beware. Variables set up from the ExtUtils::ParseXS object:
65
+
66
+ $Package $ALIAS $func_name $Full_func_name $pname
67
+
68
+ Variables set up from C<$other_hashref>:
69
+
70
+ $var $type $ntype $subtype $num $init $printed_name $arg $argoff
71
+
72
+ =cut
73
+
74
+ sub eval_input_typemap_code {
75
+ my ($_pxs, $_code, $_other) = @_;
76
+
77
+ my ($Package, $ALIAS, $func_name, $Full_func_name, $pname)
78
+ = @{$_pxs}{qw(Package ALIAS func_name Full_func_name pname)};
79
+
80
+ my ($var, $type, $num, $init, $printed_name, $arg, $ntype, $argoff, $subtype)
81
+ = @{$_other}{qw(var type num init printed_name arg ntype argoff subtype)};
82
+
83
+ my $rv = eval $_code;
84
+ warn $@ if $@;
85
+ return $rv;
86
+ }
87
+
88
+ =head1 TODO
89
+
90
+ Eventually, with better documentation and possible some cleanup,
91
+ this could be part of C<ExtUtils::Typemaps>.
92
+
93
+ =cut
94
+
95
+ 1;
96
+
97
+ # vim: ts=2 sw=2 et:
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/ParseXS/Utilities.pm ADDED
@@ -0,0 +1,821 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::ParseXS::Utilities;
2
+ use strict;
3
+ use warnings;
4
+ use Exporter;
5
+ use File::Spec;
6
+ use ExtUtils::ParseXS::Constants ();
7
+
8
+ our $VERSION = '3.40';
9
+
10
+ our (@ISA, @EXPORT_OK);
11
+ @ISA = qw(Exporter);
12
+ @EXPORT_OK = qw(
13
+ standard_typemap_locations
14
+ trim_whitespace
15
+ C_string
16
+ valid_proto_string
17
+ process_typemaps
18
+ map_type
19
+ standard_XS_defs
20
+ assign_func_args
21
+ analyze_preprocessor_statements
22
+ set_cond
23
+ Warn
24
+ current_line_number
25
+ blurt
26
+ death
27
+ check_conditional_preprocessor_statements
28
+ escape_file_for_line_directive
29
+ report_typemap_failure
30
+ );
31
+
32
+ =head1 NAME
33
+
34
+ ExtUtils::ParseXS::Utilities - Subroutines used with ExtUtils::ParseXS
35
+
36
+ =head1 SYNOPSIS
37
+
38
+ use ExtUtils::ParseXS::Utilities qw(
39
+ standard_typemap_locations
40
+ trim_whitespace
41
+ C_string
42
+ valid_proto_string
43
+ process_typemaps
44
+ map_type
45
+ standard_XS_defs
46
+ assign_func_args
47
+ analyze_preprocessor_statements
48
+ set_cond
49
+ Warn
50
+ blurt
51
+ death
52
+ check_conditional_preprocessor_statements
53
+ escape_file_for_line_directive
54
+ report_typemap_failure
55
+ );
56
+
57
+ =head1 SUBROUTINES
58
+
59
+ The following functions are not considered to be part of the public interface.
60
+ They are documented here for the benefit of future maintainers of this module.
61
+
62
+ =head2 C<standard_typemap_locations()>
63
+
64
+ =over 4
65
+
66
+ =item * Purpose
67
+
68
+ Provide a list of filepaths where F<typemap> files may be found. The
69
+ filepaths -- relative paths to files (not just directory paths) -- appear in this list in lowest-to-highest priority.
70
+
71
+ The highest priority is to look in the current directory.
72
+
73
+ 'typemap'
74
+
75
+ The second and third highest priorities are to look in the parent of the
76
+ current directory and a directory called F<lib/ExtUtils> underneath the parent
77
+ directory.
78
+
79
+ '../typemap',
80
+ '../lib/ExtUtils/typemap',
81
+
82
+ The fourth through ninth highest priorities are to look in the corresponding
83
+ grandparent, great-grandparent and great-great-grandparent directories.
84
+
85
+ '../../typemap',
86
+ '../../lib/ExtUtils/typemap',
87
+ '../../../typemap',
88
+ '../../../lib/ExtUtils/typemap',
89
+ '../../../../typemap',
90
+ '../../../../lib/ExtUtils/typemap',
91
+
92
+ The tenth and subsequent priorities are to look in directories named
93
+ F<ExtUtils> which are subdirectories of directories found in C<@INC> --
94
+ I<provided> a file named F<typemap> actually exists in such a directory.
95
+ Example:
96
+
97
+ '/usr/local/lib/perl5/5.10.1/ExtUtils/typemap',
98
+
99
+ However, these filepaths appear in the list returned by
100
+ C<standard_typemap_locations()> in reverse order, I<i.e.>, lowest-to-highest.
101
+
102
+ '/usr/local/lib/perl5/5.10.1/ExtUtils/typemap',
103
+ '../../../../lib/ExtUtils/typemap',
104
+ '../../../../typemap',
105
+ '../../../lib/ExtUtils/typemap',
106
+ '../../../typemap',
107
+ '../../lib/ExtUtils/typemap',
108
+ '../../typemap',
109
+ '../lib/ExtUtils/typemap',
110
+ '../typemap',
111
+ 'typemap'
112
+
113
+ =item * Arguments
114
+
115
+ my @stl = standard_typemap_locations( \@INC );
116
+
117
+ Reference to C<@INC>.
118
+
119
+ =item * Return Value
120
+
121
+ Array holding list of directories to be searched for F<typemap> files.
122
+
123
+ =back
124
+
125
+ =cut
126
+
127
+ SCOPE: {
128
+ my @tm_template;
129
+
130
+ sub standard_typemap_locations {
131
+ my $include_ref = shift;
132
+
133
+ if (not @tm_template) {
134
+ @tm_template = qw(typemap);
135
+
136
+ my $updir = File::Spec->updir();
137
+ foreach my $dir (
138
+ File::Spec->catdir(($updir) x 1),
139
+ File::Spec->catdir(($updir) x 2),
140
+ File::Spec->catdir(($updir) x 3),
141
+ File::Spec->catdir(($updir) x 4),
142
+ ) {
143
+ unshift @tm_template, File::Spec->catfile($dir, 'typemap');
144
+ unshift @tm_template, File::Spec->catfile($dir, lib => ExtUtils => 'typemap');
145
+ }
146
+ }
147
+
148
+ my @tm = @tm_template;
149
+ foreach my $dir (@{ $include_ref}) {
150
+ my $file = File::Spec->catfile($dir, ExtUtils => 'typemap');
151
+ unshift @tm, $file if -e $file;
152
+ }
153
+ return @tm;
154
+ }
155
+ } # end SCOPE
156
+
157
+ =head2 C<trim_whitespace()>
158
+
159
+ =over 4
160
+
161
+ =item * Purpose
162
+
163
+ Perform an in-place trimming of leading and trailing whitespace from the
164
+ first argument provided to the function.
165
+
166
+ =item * Argument
167
+
168
+ trim_whitespace($arg);
169
+
170
+ =item * Return Value
171
+
172
+ None. Remember: this is an I<in-place> modification of the argument.
173
+
174
+ =back
175
+
176
+ =cut
177
+
178
+ sub trim_whitespace {
179
+ $_[0] =~ s/^\s+|\s+$//go;
180
+ }
181
+
182
+ =head2 C<C_string()>
183
+
184
+ =over 4
185
+
186
+ =item * Purpose
187
+
188
+ Escape backslashes (C<\>) in prototype strings.
189
+
190
+ =item * Arguments
191
+
192
+ $ProtoThisXSUB = C_string($_);
193
+
194
+ String needing escaping.
195
+
196
+ =item * Return Value
197
+
198
+ Properly escaped string.
199
+
200
+ =back
201
+
202
+ =cut
203
+
204
+ sub C_string {
205
+ my($string) = @_;
206
+
207
+ $string =~ s[\\][\\\\]g;
208
+ $string;
209
+ }
210
+
211
+ =head2 C<valid_proto_string()>
212
+
213
+ =over 4
214
+
215
+ =item * Purpose
216
+
217
+ Validate prototype string.
218
+
219
+ =item * Arguments
220
+
221
+ String needing checking.
222
+
223
+ =item * Return Value
224
+
225
+ Upon success, returns the same string passed as argument.
226
+
227
+ Upon failure, returns C<0>.
228
+
229
+ =back
230
+
231
+ =cut
232
+
233
+ sub valid_proto_string {
234
+ my ($string) = @_;
235
+
236
+ if ( $string =~ /^$ExtUtils::ParseXS::Constants::PrototypeRegexp+$/ ) {
237
+ return $string;
238
+ }
239
+
240
+ return 0;
241
+ }
242
+
243
+ =head2 C<process_typemaps()>
244
+
245
+ =over 4
246
+
247
+ =item * Purpose
248
+
249
+ Process all typemap files.
250
+
251
+ =item * Arguments
252
+
253
+ my $typemaps_object = process_typemaps( $args{typemap}, $pwd );
254
+
255
+ List of two elements: C<typemap> element from C<%args>; current working
256
+ directory.
257
+
258
+ =item * Return Value
259
+
260
+ Upon success, returns an L<ExtUtils::Typemaps> object.
261
+
262
+ =back
263
+
264
+ =cut
265
+
266
+ sub process_typemaps {
267
+ my ($tmap, $pwd) = @_;
268
+
269
+ my @tm = ref $tmap ? @{$tmap} : ($tmap);
270
+
271
+ foreach my $typemap (@tm) {
272
+ die "Can't find $typemap in $pwd\n" unless -r $typemap;
273
+ }
274
+
275
+ push @tm, standard_typemap_locations( \@INC );
276
+
277
+ require ExtUtils::Typemaps;
278
+ my $typemap = ExtUtils::Typemaps->new;
279
+ foreach my $typemap_loc (@tm) {
280
+ next unless -f $typemap_loc;
281
+ # skip directories, binary files etc.
282
+ warn("Warning: ignoring non-text typemap file '$typemap_loc'\n"), next
283
+ unless -T $typemap_loc;
284
+
285
+ $typemap->merge(file => $typemap_loc, replace => 1);
286
+ }
287
+
288
+ return $typemap;
289
+ }
290
+
291
+ =head2 C<map_type()>
292
+
293
+ =over 4
294
+
295
+ =item * Purpose
296
+
297
+ Performs a mapping at several places inside C<PARAGRAPH> loop.
298
+
299
+ =item * Arguments
300
+
301
+ $type = map_type($self, $type, $varname);
302
+
303
+ List of three arguments.
304
+
305
+ =item * Return Value
306
+
307
+ String holding augmented version of second argument.
308
+
309
+ =back
310
+
311
+ =cut
312
+
313
+ sub map_type {
314
+ my ($self, $type, $varname) = @_;
315
+
316
+ # C++ has :: in types too so skip this
317
+ $type =~ tr/:/_/ unless $self->{RetainCplusplusHierarchicalTypes};
318
+ $type =~ s/^array\(([^,]*),(.*)\).*/$1 */s;
319
+ if ($varname) {
320
+ if ($type =~ / \( \s* \* (?= \s* \) ) /xg) {
321
+ (substr $type, pos $type, 0) = " $varname ";
322
+ }
323
+ else {
324
+ $type .= "\t$varname";
325
+ }
326
+ }
327
+ return $type;
328
+ }
329
+
330
+ =head2 C<standard_XS_defs()>
331
+
332
+ =over 4
333
+
334
+ =item * Purpose
335
+
336
+ Writes to the C<.c> output file certain preprocessor directives and function
337
+ headers needed in all such files.
338
+
339
+ =item * Arguments
340
+
341
+ None.
342
+
343
+ =item * Return Value
344
+
345
+ Returns true.
346
+
347
+ =back
348
+
349
+ =cut
350
+
351
+ sub standard_XS_defs {
352
+ print <<"EOF";
353
+ #ifndef PERL_UNUSED_VAR
354
+ # define PERL_UNUSED_VAR(var) if (0) var = var
355
+ #endif
356
+
357
+ #ifndef dVAR
358
+ # define dVAR dNOOP
359
+ #endif
360
+
361
+
362
+ /* This stuff is not part of the API! You have been warned. */
363
+ #ifndef PERL_VERSION_DECIMAL
364
+ # define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
365
+ #endif
366
+ #ifndef PERL_DECIMAL_VERSION
367
+ # define PERL_DECIMAL_VERSION \\
368
+ PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
369
+ #endif
370
+ #ifndef PERL_VERSION_GE
371
+ # define PERL_VERSION_GE(r,v,s) \\
372
+ (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
373
+ #endif
374
+ #ifndef PERL_VERSION_LE
375
+ # define PERL_VERSION_LE(r,v,s) \\
376
+ (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
377
+ #endif
378
+
379
+ /* XS_INTERNAL is the explicit static-linkage variant of the default
380
+ * XS macro.
381
+ *
382
+ * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
383
+ * "STATIC", ie. it exports XSUB symbols. You probably don't want that
384
+ * for anything but the BOOT XSUB.
385
+ *
386
+ * See XSUB.h in core!
387
+ */
388
+
389
+
390
+ /* TODO: This might be compatible further back than 5.10.0. */
391
+ #if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
392
+ # undef XS_EXTERNAL
393
+ # undef XS_INTERNAL
394
+ # if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
395
+ # define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
396
+ # define XS_INTERNAL(name) STATIC XSPROTO(name)
397
+ # endif
398
+ # if defined(__SYMBIAN32__)
399
+ # define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
400
+ # define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
401
+ # endif
402
+ # ifndef XS_EXTERNAL
403
+ # if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
404
+ # define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
405
+ # define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
406
+ # else
407
+ # ifdef __cplusplus
408
+ # define XS_EXTERNAL(name) extern "C" XSPROTO(name)
409
+ # define XS_INTERNAL(name) static XSPROTO(name)
410
+ # else
411
+ # define XS_EXTERNAL(name) XSPROTO(name)
412
+ # define XS_INTERNAL(name) STATIC XSPROTO(name)
413
+ # endif
414
+ # endif
415
+ # endif
416
+ #endif
417
+
418
+ /* perl >= 5.10.0 && perl <= 5.15.1 */
419
+
420
+
421
+ /* The XS_EXTERNAL macro is used for functions that must not be static
422
+ * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
423
+ * macro defined, the best we can do is assume XS is the same.
424
+ * Dito for XS_INTERNAL.
425
+ */
426
+ #ifndef XS_EXTERNAL
427
+ # define XS_EXTERNAL(name) XS(name)
428
+ #endif
429
+ #ifndef XS_INTERNAL
430
+ # define XS_INTERNAL(name) XS(name)
431
+ #endif
432
+
433
+ /* Now, finally, after all this mess, we want an ExtUtils::ParseXS
434
+ * internal macro that we're free to redefine for varying linkage due
435
+ * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
436
+ * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
437
+ */
438
+
439
+ #undef XS_EUPXS
440
+ #if defined(PERL_EUPXS_ALWAYS_EXPORT)
441
+ # define XS_EUPXS(name) XS_EXTERNAL(name)
442
+ #else
443
+ /* default to internal */
444
+ # define XS_EUPXS(name) XS_INTERNAL(name)
445
+ #endif
446
+
447
+ EOF
448
+
449
+ print <<"EOF";
450
+ #ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
451
+ #define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)
452
+
453
+ /* prototype to pass -Wmissing-prototypes */
454
+ STATIC void
455
+ S_croak_xs_usage(const CV *const cv, const char *const params);
456
+
457
+ STATIC void
458
+ S_croak_xs_usage(const CV *const cv, const char *const params)
459
+ {
460
+ const GV *const gv = CvGV(cv);
461
+
462
+ PERL_ARGS_ASSERT_CROAK_XS_USAGE;
463
+
464
+ if (gv) {
465
+ const char *const gvname = GvNAME(gv);
466
+ const HV *const stash = GvSTASH(gv);
467
+ const char *const hvname = stash ? HvNAME(stash) : NULL;
468
+
469
+ if (hvname)
470
+ Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
471
+ else
472
+ Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
473
+ } else {
474
+ /* Pants. I don't think that it should be possible to get here. */
475
+ Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
476
+ }
477
+ }
478
+ #undef PERL_ARGS_ASSERT_CROAK_XS_USAGE
479
+
480
+ #define croak_xs_usage S_croak_xs_usage
481
+
482
+ #endif
483
+
484
+ /* NOTE: the prototype of newXSproto() is different in versions of perls,
485
+ * so we define a portable version of newXSproto()
486
+ */
487
+ #ifdef newXS_flags
488
+ #define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
489
+ #else
490
+ #define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
491
+ #endif /* !defined(newXS_flags) */
492
+
493
+ #if PERL_VERSION_LE(5, 21, 5)
494
+ # define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
495
+ #else
496
+ # define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
497
+ #endif
498
+
499
+ EOF
500
+ return 1;
501
+ }
502
+
503
+ =head2 C<assign_func_args()>
504
+
505
+ =over 4
506
+
507
+ =item * Purpose
508
+
509
+ Perform assignment to the C<func_args> attribute.
510
+
511
+ =item * Arguments
512
+
513
+ $string = assign_func_args($self, $argsref, $class);
514
+
515
+ List of three elements. Second is an array reference; third is a string.
516
+
517
+ =item * Return Value
518
+
519
+ String.
520
+
521
+ =back
522
+
523
+ =cut
524
+
525
+ sub assign_func_args {
526
+ my ($self, $argsref, $class) = @_;
527
+ my @func_args = @{$argsref};
528
+ shift @func_args if defined($class);
529
+
530
+ for my $arg (@func_args) {
531
+ $arg =~ s/^/&/ if $self->{in_out}->{$arg};
532
+ }
533
+ return join(", ", @func_args);
534
+ }
535
+
536
+ =head2 C<analyze_preprocessor_statements()>
537
+
538
+ =over 4
539
+
540
+ =item * Purpose
541
+
542
+ Within each function inside each Xsub, print to the F<.c> output file certain
543
+ preprocessor statements.
544
+
545
+ =item * Arguments
546
+
547
+ ( $self, $XSS_work_idx, $BootCode_ref ) =
548
+ analyze_preprocessor_statements(
549
+ $self, $statement, $XSS_work_idx, $BootCode_ref
550
+ );
551
+
552
+ List of four elements.
553
+
554
+ =item * Return Value
555
+
556
+ Modifed values of three of the arguments passed to the function. In
557
+ particular, the C<XSStack> and C<InitFileCode> attributes are modified.
558
+
559
+ =back
560
+
561
+ =cut
562
+
563
+ sub analyze_preprocessor_statements {
564
+ my ($self, $statement, $XSS_work_idx, $BootCode_ref) = @_;
565
+
566
+ if ($statement eq 'if') {
567
+ $XSS_work_idx = @{ $self->{XSStack} };
568
+ push(@{ $self->{XSStack} }, {type => 'if'});
569
+ }
570
+ else {
571
+ $self->death("Error: '$statement' with no matching 'if'")
572
+ if $self->{XSStack}->[-1]{type} ne 'if';
573
+ if ($self->{XSStack}->[-1]{varname}) {
574
+ push(@{ $self->{InitFileCode} }, "#endif\n");
575
+ push(@{ $BootCode_ref }, "#endif");
576
+ }
577
+
578
+ my(@fns) = keys %{$self->{XSStack}->[-1]{functions}};
579
+ if ($statement ne 'endif') {
580
+ # Hide the functions defined in other #if branches, and reset.
581
+ @{$self->{XSStack}->[-1]{other_functions}}{@fns} = (1) x @fns;
582
+ @{$self->{XSStack}->[-1]}{qw(varname functions)} = ('', {});
583
+ }
584
+ else {
585
+ my($tmp) = pop(@{ $self->{XSStack} });
586
+ 0 while (--$XSS_work_idx
587
+ && $self->{XSStack}->[$XSS_work_idx]{type} ne 'if');
588
+ # Keep all new defined functions
589
+ push(@fns, keys %{$tmp->{other_functions}});
590
+ @{$self->{XSStack}->[$XSS_work_idx]{functions}}{@fns} = (1) x @fns;
591
+ }
592
+ }
593
+ return ($self, $XSS_work_idx, $BootCode_ref);
594
+ }
595
+
596
+ =head2 C<set_cond()>
597
+
598
+ =over 4
599
+
600
+ =item * Purpose
601
+
602
+ =item * Arguments
603
+
604
+ =item * Return Value
605
+
606
+ =back
607
+
608
+ =cut
609
+
610
+ sub set_cond {
611
+ my ($ellipsis, $min_args, $num_args) = @_;
612
+ my $cond;
613
+ if ($ellipsis) {
614
+ $cond = ($min_args ? qq(items < $min_args) : 0);
615
+ }
616
+ elsif ($min_args == $num_args) {
617
+ $cond = qq(items != $min_args);
618
+ }
619
+ else {
620
+ $cond = qq(items < $min_args || items > $num_args);
621
+ }
622
+ return $cond;
623
+ }
624
+
625
+ =head2 C<current_line_number()>
626
+
627
+ =over 4
628
+
629
+ =item * Purpose
630
+
631
+ Figures out the current line number in the XS file.
632
+
633
+ =item * Arguments
634
+
635
+ C<$self>
636
+
637
+ =item * Return Value
638
+
639
+ The current line number.
640
+
641
+ =back
642
+
643
+ =cut
644
+
645
+ sub current_line_number {
646
+ my $self = shift;
647
+ my $line_number = $self->{line_no}->[@{ $self->{line_no} } - @{ $self->{line} } -1];
648
+ return $line_number;
649
+ }
650
+
651
+ =head2 C<Warn()>
652
+
653
+ =over 4
654
+
655
+ =item * Purpose
656
+
657
+ =item * Arguments
658
+
659
+ =item * Return Value
660
+
661
+ =back
662
+
663
+ =cut
664
+
665
+ sub Warn {
666
+ my $self = shift;
667
+ my $warn_line_number = $self->current_line_number();
668
+ print STDERR "@_ in $self->{filename}, line $warn_line_number\n";
669
+ }
670
+
671
+ =head2 C<blurt()>
672
+
673
+ =over 4
674
+
675
+ =item * Purpose
676
+
677
+ =item * Arguments
678
+
679
+ =item * Return Value
680
+
681
+ =back
682
+
683
+ =cut
684
+
685
+ sub blurt {
686
+ my $self = shift;
687
+ $self->Warn(@_);
688
+ $self->{errors}++
689
+ }
690
+
691
+ =head2 C<death()>
692
+
693
+ =over 4
694
+
695
+ =item * Purpose
696
+
697
+ =item * Arguments
698
+
699
+ =item * Return Value
700
+
701
+ =back
702
+
703
+ =cut
704
+
705
+ sub death {
706
+ my $self = shift;
707
+ $self->Warn(@_);
708
+ exit 1;
709
+ }
710
+
711
+ =head2 C<check_conditional_preprocessor_statements()>
712
+
713
+ =over 4
714
+
715
+ =item * Purpose
716
+
717
+ =item * Arguments
718
+
719
+ =item * Return Value
720
+
721
+ =back
722
+
723
+ =cut
724
+
725
+ sub check_conditional_preprocessor_statements {
726
+ my ($self) = @_;
727
+ my @cpp = grep(/^\#\s*(?:if|e\w+)/, @{ $self->{line} });
728
+ if (@cpp) {
729
+ my $cpplevel;
730
+ for my $cpp (@cpp) {
731
+ if ($cpp =~ /^\#\s*if/) {
732
+ $cpplevel++;
733
+ }
734
+ elsif (!$cpplevel) {
735
+ $self->Warn("Warning: #else/elif/endif without #if in this function");
736
+ print STDERR " (precede it with a blank line if the matching #if is outside the function)\n"
737
+ if $self->{XSStack}->[-1]{type} eq 'if';
738
+ return;
739
+ }
740
+ elsif ($cpp =~ /^\#\s*endif/) {
741
+ $cpplevel--;
742
+ }
743
+ }
744
+ $self->Warn("Warning: #if without #endif in this function") if $cpplevel;
745
+ }
746
+ }
747
+
748
+ =head2 C<escape_file_for_line_directive()>
749
+
750
+ =over 4
751
+
752
+ =item * Purpose
753
+
754
+ Escapes a given code source name (typically a file name but can also
755
+ be a command that was read from) so that double-quotes and backslashes are escaped.
756
+
757
+ =item * Arguments
758
+
759
+ A string.
760
+
761
+ =item * Return Value
762
+
763
+ A string with escapes for double-quotes and backslashes.
764
+
765
+ =back
766
+
767
+ =cut
768
+
769
+ sub escape_file_for_line_directive {
770
+ my $string = shift;
771
+ $string =~ s/\\/\\\\/g;
772
+ $string =~ s/"/\\"/g;
773
+ return $string;
774
+ }
775
+
776
+ =head2 C<report_typemap_failure>
777
+
778
+ =over 4
779
+
780
+ =item * Purpose
781
+
782
+ Do error reporting for missing typemaps.
783
+
784
+ =item * Arguments
785
+
786
+ The C<ExtUtils::ParseXS> object.
787
+
788
+ An C<ExtUtils::Typemaps> object.
789
+
790
+ The string that represents the C type that was not found in the typemap.
791
+
792
+ Optionally, the string C<death> or C<blurt> to choose
793
+ whether the error is immediately fatal or not. Default: C<blurt>
794
+
795
+ =item * Return Value
796
+
797
+ Returns nothing. Depending on the arguments, this
798
+ may call C<death> or C<blurt>, the former of which is
799
+ fatal.
800
+
801
+ =back
802
+
803
+ =cut
804
+
805
+ sub report_typemap_failure {
806
+ my ($self, $tm, $ctype, $error_method) = @_;
807
+ $error_method ||= 'blurt';
808
+
809
+ my @avail_ctypes = $tm->list_mapped_ctypes;
810
+
811
+ my $err = "Could not find a typemap for C type '$ctype'.\n"
812
+ . "The following C types are mapped by the current typemap:\n'"
813
+ . join("', '", @avail_ctypes) . "'\n";
814
+
815
+ $self->$error_method($err);
816
+ return();
817
+ }
818
+
819
+ 1;
820
+
821
+ # vim: ts=2 sw=2 et:
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/Cmd.pm ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Typemaps::Cmd;
2
+ use 5.006001;
3
+ use strict;
4
+ use warnings;
5
+ our $VERSION = '3.38';
6
+
7
+ use ExtUtils::Typemaps;
8
+
9
+ require Exporter;
10
+
11
+ our @ISA = qw(Exporter);
12
+ our @EXPORT = qw(embeddable_typemap);
13
+ our %EXPORT_TAGS = (all => \@EXPORT);
14
+
15
+ sub embeddable_typemap {
16
+ my @tms = @_;
17
+
18
+ # Get typemap objects
19
+ my @tm_objs = map [$_, _intuit_typemap_source($_)], @tms;
20
+
21
+ # merge or short-circuit
22
+ my $final_tm;
23
+ if (@tm_objs == 1) {
24
+ # just one, merge would be pointless
25
+ $final_tm = shift(@tm_objs)->[1];
26
+ }
27
+ else {
28
+ # multiple, need merge
29
+ $final_tm = ExtUtils::Typemaps->new;
30
+ foreach my $other_tm (@tm_objs) {
31
+ my ($tm_ident, $tm_obj) = @$other_tm;
32
+ eval {
33
+ $final_tm->merge(typemap => $tm_obj);
34
+ 1
35
+ } or do {
36
+ my $err = $@ || 'Zombie error';
37
+ die "Failed to merge typ";
38
+ }
39
+ }
40
+ }
41
+
42
+ # stringify for embedding
43
+ return $final_tm->as_embedded_typemap();
44
+ }
45
+
46
+ sub _load_module {
47
+ my $name = shift;
48
+ return eval "require $name; 1";
49
+ }
50
+
51
+ SCOPE: {
52
+ my %sources = (
53
+ module => sub {
54
+ my $ident = shift;
55
+ my $tm;
56
+ if (/::/) { # looks like FQ module name, try that first
57
+ foreach my $module ($ident, "ExtUtils::Typemaps::$ident") {
58
+ if (_load_module($module)) {
59
+ eval { $tm = $module->new }
60
+ and return $tm;
61
+ }
62
+ }
63
+ }
64
+ else {
65
+ foreach my $module ("ExtUtils::Typemaps::$ident", "$ident") {
66
+ if (_load_module($module)) {
67
+ eval { $tm = $module->new }
68
+ and return $tm;
69
+ }
70
+ }
71
+ }
72
+ return();
73
+ },
74
+ file => sub {
75
+ my $ident = shift;
76
+ return unless -e $ident and -r _;
77
+ return ExtUtils::Typemaps->new(file => $ident);
78
+ },
79
+ );
80
+ # Try to find typemap either from module or file
81
+ sub _intuit_typemap_source {
82
+ my $identifier = shift;
83
+
84
+ my @locate_attempts;
85
+ if ($identifier =~ /::/ || $identifier !~ /[^\w_]/) {
86
+ @locate_attempts = qw(module file);
87
+ }
88
+ else {
89
+ @locate_attempts = qw(file module);
90
+ }
91
+
92
+ foreach my $source (@locate_attempts) {
93
+ my $tm = $sources{$source}->($identifier);
94
+ return $tm if defined $tm;
95
+ }
96
+
97
+ die "Unable to find typemap for '$identifier': "
98
+ . "Tried to load both as file or module and failed.\n";
99
+ }
100
+ } # end SCOPE
101
+
102
+ =head1 NAME
103
+
104
+ ExtUtils::Typemaps::Cmd - Quick commands for handling typemaps
105
+
106
+ =head1 SYNOPSIS
107
+
108
+ From XS:
109
+
110
+ INCLUDE_COMMAND: $^X -MExtUtils::Typemaps::Cmd \
111
+ -e "print embeddable_typemap(q{Excommunicated})"
112
+
113
+ Loads C<ExtUtils::Typemaps::Excommunicated>, instantiates an object,
114
+ and dumps it as an embeddable typemap for use directly in your XS file.
115
+
116
+ =head1 DESCRIPTION
117
+
118
+ This is a helper module for L<ExtUtils::Typemaps> for quick
119
+ one-liners, specifically for inclusion of shared typemaps
120
+ that live on CPAN into an XS file (see SYNOPSIS).
121
+
122
+ For this reason, the following functions are exported by default:
123
+
124
+ =head1 EXPORTED FUNCTIONS
125
+
126
+ =head2 embeddable_typemap
127
+
128
+ Given a list of identifiers, C<embeddable_typemap>
129
+ tries to load typemaps from a file of the given name(s),
130
+ or from a module that is an C<ExtUtils::Typemaps> subclass.
131
+
132
+ Returns a string representation of the merged typemaps that can
133
+ be included verbatim into XS. Example:
134
+
135
+ print embeddable_typemap(
136
+ "Excommunicated", "ExtUtils::Typemaps::Basic", "./typemap"
137
+ );
138
+
139
+ This will try to load a module C<ExtUtils::Typemaps::Excommunicated>
140
+ and use it as an C<ExtUtils::Typemaps> subclass. If that fails, it'll
141
+ try loading C<Excommunicated> as a module, if that fails, it'll try to
142
+ read a file called F<Excommunicated>. It'll work similarly for the
143
+ second argument, but the third will be loaded as a file first.
144
+
145
+ After loading all typemap files or modules, it will merge them in the
146
+ specified order and dump the result as an embeddable typemap.
147
+
148
+ =head1 SEE ALSO
149
+
150
+ L<ExtUtils::Typemaps>
151
+
152
+ L<perlxs>
153
+
154
+ =head1 AUTHOR
155
+
156
+ Steffen Mueller C<<[email protected]>>
157
+
158
+ =head1 COPYRIGHT & LICENSE
159
+
160
+ Copyright 2012 Steffen Mueller
161
+
162
+ This program is free software; you can redistribute it and/or
163
+ modify it under the same terms as Perl itself.
164
+
165
+ =cut
166
+
167
+ 1;
168
+
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/InputMap.pm ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Typemaps::InputMap;
2
+ use 5.006001;
3
+ use strict;
4
+ use warnings;
5
+ our $VERSION = '3.38';
6
+
7
+ =head1 NAME
8
+
9
+ ExtUtils::Typemaps::InputMap - Entry in the INPUT section of a typemap
10
+
11
+ =head1 SYNOPSIS
12
+
13
+ use ExtUtils::Typemaps;
14
+ ...
15
+ my $input = $typemap->get_input_map('T_NV');
16
+ my $code = $input->code();
17
+ $input->code("...");
18
+
19
+ =head1 DESCRIPTION
20
+
21
+ Refer to L<ExtUtils::Typemaps> for details.
22
+
23
+ =head1 METHODS
24
+
25
+ =cut
26
+
27
+ =head2 new
28
+
29
+ Requires C<xstype> and C<code> parameters.
30
+
31
+ =cut
32
+
33
+ sub new {
34
+ my $prot = shift;
35
+ my $class = ref($prot)||$prot;
36
+ my %args = @_;
37
+
38
+ if (!ref($prot)) {
39
+ if (not defined $args{xstype} or not defined $args{code}) {
40
+ die("Need xstype and code parameters");
41
+ }
42
+ }
43
+
44
+ my $self = bless(
45
+ (ref($prot) ? {%$prot} : {})
46
+ => $class
47
+ );
48
+
49
+ $self->{xstype} = $args{xstype} if defined $args{xstype};
50
+ $self->{code} = $args{code} if defined $args{code};
51
+ $self->{code} =~ s/^(?=\S)/\t/mg;
52
+
53
+ return $self;
54
+ }
55
+
56
+ =head2 code
57
+
58
+ Returns or sets the INPUT mapping code for this entry.
59
+
60
+ =cut
61
+
62
+ sub code {
63
+ $_[0]->{code} = $_[1] if @_ > 1;
64
+ return $_[0]->{code};
65
+ }
66
+
67
+ =head2 xstype
68
+
69
+ Returns the name of the XS type of the INPUT map.
70
+
71
+ =cut
72
+
73
+ sub xstype {
74
+ return $_[0]->{xstype};
75
+ }
76
+
77
+ =head2 cleaned_code
78
+
79
+ Returns a cleaned-up copy of the code to which certain transformations
80
+ have been applied to make it more ANSI compliant.
81
+
82
+ =cut
83
+
84
+ sub cleaned_code {
85
+ my $self = shift;
86
+ my $code = $self->code;
87
+
88
+ $code =~ s/(?:;+\s*|;*\s+)\z//s;
89
+
90
+ # Move C pre-processor instructions to column 1 to be strictly ANSI
91
+ # conformant. Some pre-processors are fussy about this.
92
+ $code =~ s/^\s+#/#/mg;
93
+ $code =~ s/\s*\z/\n/;
94
+
95
+ return $code;
96
+ }
97
+
98
+ =head1 SEE ALSO
99
+
100
+ L<ExtUtils::Typemaps>
101
+
102
+ =head1 AUTHOR
103
+
104
+ Steffen Mueller C<<[email protected]>>
105
+
106
+ =head1 COPYRIGHT & LICENSE
107
+
108
+ Copyright 2009, 2010, 2011, 2012 Steffen Mueller
109
+
110
+ This program is free software; you can redistribute it and/or
111
+ modify it under the same terms as Perl itself.
112
+
113
+ =cut
114
+
115
+ 1;
116
+
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/OutputMap.pm ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Typemaps::OutputMap;
2
+ use 5.006001;
3
+ use strict;
4
+ use warnings;
5
+ our $VERSION = '3.38';
6
+
7
+ =head1 NAME
8
+
9
+ ExtUtils::Typemaps::OutputMap - Entry in the OUTPUT section of a typemap
10
+
11
+ =head1 SYNOPSIS
12
+
13
+ use ExtUtils::Typemaps;
14
+ ...
15
+ my $output = $typemap->get_output_map('T_NV');
16
+ my $code = $output->code();
17
+ $output->code("...");
18
+
19
+ =head1 DESCRIPTION
20
+
21
+ Refer to L<ExtUtils::Typemaps> for details.
22
+
23
+ =head1 METHODS
24
+
25
+ =cut
26
+
27
+ =head2 new
28
+
29
+ Requires C<xstype> and C<code> parameters.
30
+
31
+ =cut
32
+
33
+ sub new {
34
+ my $prot = shift;
35
+ my $class = ref($prot)||$prot;
36
+ my %args = @_;
37
+
38
+ if (!ref($prot)) {
39
+ if (not defined $args{xstype} or not defined $args{code}) {
40
+ die("Need xstype and code parameters");
41
+ }
42
+ }
43
+
44
+ my $self = bless(
45
+ (ref($prot) ? {%$prot} : {})
46
+ => $class
47
+ );
48
+
49
+ $self->{xstype} = $args{xstype} if defined $args{xstype};
50
+ $self->{code} = $args{code} if defined $args{code};
51
+ $self->{code} =~ s/^(?=\S)/\t/mg;
52
+
53
+ return $self;
54
+ }
55
+
56
+ =head2 code
57
+
58
+ Returns or sets the OUTPUT mapping code for this entry.
59
+
60
+ =cut
61
+
62
+ sub code {
63
+ $_[0]->{code} = $_[1] if @_ > 1;
64
+ return $_[0]->{code};
65
+ }
66
+
67
+ =head2 xstype
68
+
69
+ Returns the name of the XS type of the OUTPUT map.
70
+
71
+ =cut
72
+
73
+ sub xstype {
74
+ return $_[0]->{xstype};
75
+ }
76
+
77
+ =head2 cleaned_code
78
+
79
+ Returns a cleaned-up copy of the code to which certain transformations
80
+ have been applied to make it more ANSI compliant.
81
+
82
+ =cut
83
+
84
+ sub cleaned_code {
85
+ my $self = shift;
86
+ my $code = $self->code;
87
+
88
+ # Move C pre-processor instructions to column 1 to be strictly ANSI
89
+ # conformant. Some pre-processors are fussy about this.
90
+ $code =~ s/^\s+#/#/mg;
91
+ $code =~ s/\s*\z/\n/;
92
+
93
+ return $code;
94
+ }
95
+
96
+ =head2 targetable
97
+
98
+ This is an obscure but effective optimization that used to
99
+ live in C<ExtUtils::ParseXS> directly. Not implementing it
100
+ should never result in incorrect use of typemaps, just less
101
+ efficient code.
102
+
103
+ In a nutshell, this will check whether the output code
104
+ involves calling C<sv_setiv>, C<sv_setuv>, C<sv_setnv>, C<sv_setpv> or
105
+ C<sv_setpvn> to set the special C<$arg> placeholder to a new value
106
+ B<AT THE END OF THE OUTPUT CODE>. If that is the case, the code is
107
+ eligible for using the C<TARG>-related macros to optimize this.
108
+ Thus the name of the method: C<targetable>.
109
+
110
+ If this optimization is applicable, C<ExtUtils::ParseXS> will
111
+ emit a C<dXSTARG;> definition at the start of the generated XSUB code,
112
+ and type (see below) dependent code to set C<TARG> and push it on
113
+ the stack at the end of the generated XSUB code.
114
+
115
+ If the optimization can not be applied, this returns undef.
116
+ If it can be applied, this method returns a hash reference containing
117
+ the following information:
118
+
119
+ type: Any of the characters i, u, n, p
120
+ with_size: Bool indicating whether this is the sv_setpvn variant
121
+ what: The code that actually evaluates to the output scalar
122
+ what_size: If "with_size", this has the string length (as code,
123
+ not constant, including leading comma)
124
+
125
+ =cut
126
+
127
+ sub targetable {
128
+ my $self = shift;
129
+ return $self->{targetable} if exists $self->{targetable};
130
+
131
+ our $bal; # ()-balanced
132
+ $bal = qr[
133
+ (?:
134
+ (?>[^()]+)
135
+ |
136
+ \( (??{ $bal }) \)
137
+ )*
138
+ ]x;
139
+ my $bal_no_comma = qr[
140
+ (?:
141
+ (?>[^(),]+)
142
+ |
143
+ \( (??{ $bal }) \)
144
+ )+
145
+ ]x;
146
+
147
+ # matches variations on (SV*)
148
+ my $sv_cast = qr[
149
+ (?:
150
+ \( \s* SV \s* \* \s* \) \s*
151
+ )?
152
+ ]x;
153
+
154
+ my $size = qr[ # Third arg (to setpvn)
155
+ , \s* (??{ $bal })
156
+ ]xo;
157
+
158
+ my $code = $self->code;
159
+
160
+ # We can still bootstrap compile 're', because in code re.pm is
161
+ # available to miniperl, and does not attempt to load the XS code.
162
+ use re 'eval';
163
+
164
+ my ($type, $with_size, $arg, $sarg) =
165
+ ($code =~
166
+ m[^
167
+ \s+
168
+ sv_set([iunp])v(n)? # Type, is_setpvn
169
+ \s*
170
+ \( \s*
171
+ $sv_cast \$arg \s* , \s*
172
+ ( $bal_no_comma ) # Set from
173
+ ( $size )? # Possible sizeof set-from
174
+ \s* \) \s* ; \s* $
175
+ ]xo
176
+ );
177
+
178
+ my $rv = undef;
179
+ if ($type) {
180
+ $rv = {
181
+ type => $type,
182
+ with_size => $with_size,
183
+ what => $arg,
184
+ what_size => $sarg,
185
+ };
186
+ }
187
+ $self->{targetable} = $rv;
188
+ return $rv;
189
+ }
190
+
191
+ =head1 SEE ALSO
192
+
193
+ L<ExtUtils::Typemaps>
194
+
195
+ =head1 AUTHOR
196
+
197
+ Steffen Mueller C<<[email protected]>>
198
+
199
+ =head1 COPYRIGHT & LICENSE
200
+
201
+ Copyright 2009, 2010, 2011, 2012 Steffen Mueller
202
+
203
+ This program is free software; you can redistribute it and/or
204
+ modify it under the same terms as Perl itself.
205
+
206
+ =cut
207
+
208
+ 1;
209
+
my_container_sandbox/usr/share/perl/5.30.0/ExtUtils/Typemaps/Type.pm ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ExtUtils::Typemaps::Type;
2
+ use 5.006001;
3
+ use strict;
4
+ use warnings;
5
+ require ExtUtils::Typemaps;
6
+
7
+ our $VERSION = '3.38';
8
+
9
+ =head1 NAME
10
+
11
+ ExtUtils::Typemaps::Type - Entry in the TYPEMAP section of a typemap
12
+
13
+ =head1 SYNOPSIS
14
+
15
+ use ExtUtils::Typemaps;
16
+ ...
17
+ my $type = $typemap->get_type_map('char*');
18
+ my $input = $typemap->get_input_map($type->xstype);
19
+
20
+ =head1 DESCRIPTION
21
+
22
+ Refer to L<ExtUtils::Typemaps> for details.
23
+ Object associates C<ctype> with C<xstype>, which is the index
24
+ into the in- and output mapping tables.
25
+
26
+ =head1 METHODS
27
+
28
+ =cut
29
+
30
+ =head2 new
31
+
32
+ Requires C<xstype> and C<ctype> parameters.
33
+
34
+ Optionally takes C<prototype> parameter.
35
+
36
+ =cut
37
+
38
+ sub new {
39
+ my $prot = shift;
40
+ my $class = ref($prot)||$prot;
41
+ my %args = @_;
42
+
43
+ if (!ref($prot)) {
44
+ if (not defined $args{xstype} or not defined $args{ctype}) {
45
+ die("Need xstype and ctype parameters");
46
+ }
47
+ }
48
+
49
+ my $self = bless(
50
+ (ref($prot) ? {%$prot} : {proto => ''})
51
+ => $class
52
+ );
53
+
54
+ $self->{xstype} = $args{xstype} if defined $args{xstype};
55
+ $self->{ctype} = $args{ctype} if defined $args{ctype};
56
+ $self->{tidy_ctype} = ExtUtils::Typemaps::tidy_type($self->{ctype});
57
+ $self->{proto} = $args{'prototype'} if defined $args{'prototype'};
58
+
59
+ return $self;
60
+ }
61
+
62
+ =head2 proto
63
+
64
+ Returns or sets the prototype.
65
+
66
+ =cut
67
+
68
+ sub proto {
69
+ $_[0]->{proto} = $_[1] if @_ > 1;
70
+ return $_[0]->{proto};
71
+ }
72
+
73
+ =head2 xstype
74
+
75
+ Returns the name of the XS type that this C type is associated to.
76
+
77
+ =cut
78
+
79
+ sub xstype {
80
+ return $_[0]->{xstype};
81
+ }
82
+
83
+ =head2 ctype
84
+
85
+ Returns the name of the C type as it was set on construction.
86
+
87
+ =cut
88
+
89
+ sub ctype {
90
+ return defined($_[0]->{ctype}) ? $_[0]->{ctype} : $_[0]->{tidy_ctype};
91
+ }
92
+
93
+ =head2 tidy_ctype
94
+
95
+ Returns the canonicalized name of the C type.
96
+
97
+ =cut
98
+
99
+ sub tidy_ctype {
100
+ return $_[0]->{tidy_ctype};
101
+ }
102
+
103
+ =head1 SEE ALSO
104
+
105
+ L<ExtUtils::Typemaps>
106
+
107
+ =head1 AUTHOR
108
+
109
+ Steffen Mueller C<<[email protected]>>
110
+
111
+ =head1 COPYRIGHT & LICENSE
112
+
113
+ Copyright 2009, 2010, 2011, 2012 Steffen Mueller
114
+
115
+ This program is free software; you can redistribute it and/or
116
+ modify it under the same terms as Perl itself.
117
+
118
+ =cut
119
+
120
+ 1;
121
+
my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Breakage.pm ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::API::Breakage;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ use Test2::Util qw/pkg_to_file/;
9
+
10
+ our @EXPORT_OK = qw{
11
+ upgrade_suggested
12
+ upgrade_required
13
+ known_broken
14
+ };
15
+ BEGIN { require Exporter; our @ISA = qw(Exporter) }
16
+
17
+ sub upgrade_suggested {
18
+ return (
19
+ 'Test::Exception' => '0.42',
20
+ 'Test::FITesque' => '0.04',
21
+ 'Test::Module::Used' => '0.2.5',
22
+ 'Test::Moose::More' => '0.025',
23
+ );
24
+ }
25
+
26
+ sub upgrade_required {
27
+ return (
28
+ 'Test::Builder::Clutch' => '0.07',
29
+ 'Test::Dist::VersionSync' => '1.1.4',
30
+ 'Test::Modern' => '0.012',
31
+ 'Test::SharedFork' => '0.34',
32
+ 'Test::Alien' => '0.04',
33
+ 'Test::UseAllModules' => '0.14',
34
+ 'Test::More::Prefix' => '0.005',
35
+
36
+ 'Test2::Tools::EventDumper' => 0.000007,
37
+ 'Test2::Harness' => 0.000013,
38
+
39
+ 'Test::DBIx::Class::Schema' => '1.0.9',
40
+ 'Test::Clustericious::Cluster' => '0.30',
41
+ );
42
+ }
43
+
44
+ sub known_broken {
45
+ return (
46
+ 'Net::BitTorrent' => '0.052',
47
+ 'Test::Able' => '0.11',
48
+ 'Test::Aggregate' => '0.373',
49
+ 'Test::Flatten' => '0.11',
50
+ 'Test::Group' => '0.20',
51
+ 'Test::ParallelSubtest' => '0.05',
52
+ 'Test::Pretty' => '0.32',
53
+ 'Test::Wrapper' => '0.3.0',
54
+
55
+ 'Log::Dispatch::Config::TestLog' => '0.02',
56
+ );
57
+ }
58
+
59
+ # Not reportable:
60
+ # Device::Chip => 0.07 - Tests will not pass, but not broken if already installed, also no fixed version we can upgrade to.
61
+
62
+ sub report {
63
+ my $class = shift;
64
+ my ($require) = @_;
65
+
66
+ my %suggest = __PACKAGE__->upgrade_suggested();
67
+ my %required = __PACKAGE__->upgrade_required();
68
+ my %broken = __PACKAGE__->known_broken();
69
+
70
+ my @warn;
71
+ for my $mod (keys %suggest) {
72
+ my $file = pkg_to_file($mod);
73
+ next unless $INC{$file} || ($require && eval { require $file; 1 });
74
+ my $want = $suggest{$mod};
75
+ next if eval { $mod->VERSION($want); 1 };
76
+ push @warn => " * Module '$mod' is outdated, we recommed updating above $want.";
77
+ }
78
+
79
+ for my $mod (keys %required) {
80
+ my $file = pkg_to_file($mod);
81
+ next unless $INC{$file} || ($require && eval { require $file; 1 });
82
+ my $want = $required{$mod};
83
+ next if eval { $mod->VERSION($want); 1 };
84
+ push @warn => " * Module '$mod' is outdated and known to be broken, please update to $want or higher.";
85
+ }
86
+
87
+ for my $mod (keys %broken) {
88
+ my $file = pkg_to_file($mod);
89
+ next unless $INC{$file} || ($require && eval { require $file; 1 });
90
+ my $tested = $broken{$mod};
91
+ push @warn => " * Module '$mod' is known to be broken in version $tested and below, newer versions have not been tested. You have: " . $mod->VERSION;
92
+ }
93
+
94
+ return @warn;
95
+ }
96
+
97
+ 1;
98
+
99
+ __END__
100
+
101
+
102
+ =pod
103
+
104
+ =encoding UTF-8
105
+
106
+ =head1 NAME
107
+
108
+ Test2::API::Breakage - What breaks at what version
109
+
110
+ =head1 DESCRIPTION
111
+
112
+ This module provides lists of modules that are broken, or have been broken in
113
+ the past, when upgrading L<Test::Builder> to use L<Test2>.
114
+
115
+ =head1 FUNCTIONS
116
+
117
+ These can be imported, or called as methods on the class.
118
+
119
+ =over 4
120
+
121
+ =item %mod_ver = upgrade_suggested()
122
+
123
+ =item %mod_ver = Test2::API::Breakage->upgrade_suggested()
124
+
125
+ This returns key/value pairs. The key is the module name, the value is the
126
+ version number. If the installed version of the module is at or below the
127
+ specified one then an upgrade would be a good idea, but not strictly necessary.
128
+
129
+ =item %mod_ver = upgrade_required()
130
+
131
+ =item %mod_ver = Test2::API::Breakage->upgrade_required()
132
+
133
+ This returns key/value pairs. The key is the module name, the value is the
134
+ version number. If the installed version of the module is at or below the
135
+ specified one then an upgrade is required for the module to work properly.
136
+
137
+ =item %mod_ver = known_broken()
138
+
139
+ =item %mod_ver = Test2::API::Breakage->known_broken()
140
+
141
+ This returns key/value pairs. The key is the module name, the value is the
142
+ version number. If the installed version of the module is at or below the
143
+ specified one then the module will not work. A newer version may work, but is
144
+ not tested or verified.
145
+
146
+ =back
147
+
148
+ =head1 SOURCE
149
+
150
+ The source code repository for Test2 can be found at
151
+ F<http://github.com/Test-More/test-more/>.
152
+
153
+ =head1 MAINTAINERS
154
+
155
+ =over 4
156
+
157
+ =item Chad Granum E<lt>[email protected]<gt>
158
+
159
+ =back
160
+
161
+ =head1 AUTHORS
162
+
163
+ =over 4
164
+
165
+ =item Chad Granum E<lt>[email protected]<gt>
166
+
167
+ =back
168
+
169
+ =head1 COPYRIGHT
170
+
171
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
172
+
173
+ This program is free software; you can redistribute it and/or
174
+ modify it under the same terms as Perl itself.
175
+
176
+ See F<http://dev.perl.org/licenses/>
177
+
178
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Context.pm ADDED
@@ -0,0 +1,1013 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::API::Context;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ use Carp qw/confess croak/;
9
+ use Scalar::Util qw/weaken blessed/;
10
+ use Test2::Util qw/get_tid try pkg_to_file get_tid/;
11
+
12
+ use Test2::EventFacet::Trace();
13
+ use Test2::API();
14
+
15
+ # Preload some key event types
16
+ my %LOADED = (
17
+ map {
18
+ my $pkg = "Test2::Event::$_";
19
+ my $file = "Test2/Event/$_.pm";
20
+ require $file unless $INC{$file};
21
+ ( $pkg => $pkg, $_ => $pkg )
22
+ } qw/Ok Diag Note Plan Bail Exception Waiting Skip Subtest Pass Fail V2/
23
+ );
24
+
25
+ use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
26
+ use Test2::Util::HashBase qw{
27
+ stack hub trace _on_release _depth _is_canon _is_spawn _aborted
28
+ errno eval_error child_error thrown
29
+ };
30
+
31
+ # Private, not package vars
32
+ # It is safe to cache these.
33
+ my $ON_RELEASE = Test2::API::_context_release_callbacks_ref();
34
+ my $CONTEXTS = Test2::API::_contexts_ref();
35
+
36
+ sub init {
37
+ my $self = shift;
38
+
39
+ confess "The 'trace' attribute is required"
40
+ unless $self->{+TRACE};
41
+
42
+ confess "The 'hub' attribute is required"
43
+ unless $self->{+HUB};
44
+
45
+ $self->{+_DEPTH} = 0 unless defined $self->{+_DEPTH};
46
+
47
+ $self->{+ERRNO} = $! unless exists $self->{+ERRNO};
48
+ $self->{+EVAL_ERROR} = $@ unless exists $self->{+EVAL_ERROR};
49
+ $self->{+CHILD_ERROR} = $? unless exists $self->{+CHILD_ERROR};
50
+ }
51
+
52
+ sub snapshot { bless {%{$_[0]}, _is_canon => undef, _is_spawn => undef, _aborted => undef}, __PACKAGE__ }
53
+
54
+ sub restore_error_vars {
55
+ my $self = shift;
56
+ ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR};
57
+ }
58
+
59
+ sub DESTROY {
60
+ return unless $_[0]->{+_IS_CANON} || $_[0]->{+_IS_SPAWN};
61
+ return if $_[0]->{+_ABORTED} && ${$_[0]->{+_ABORTED}};
62
+ my ($self) = @_;
63
+
64
+ my $hub = $self->{+HUB};
65
+ my $hid = $hub->{hid};
66
+
67
+ # Do not show the warning if it looks like an exception has been thrown, or
68
+ # if the context is not local to this process or thread.
69
+ {
70
+ # Sometimes $@ is uninitialized, not a problem in this case so do not
71
+ # show the warning about using eq.
72
+ no warnings 'uninitialized';
73
+ if($self->{+EVAL_ERROR} eq $@ && $hub->is_local) {
74
+ my $frame = $self->{+_IS_SPAWN} || $self->{+TRACE}->frame;
75
+ warn <<" EOT";
76
+ A context appears to have been destroyed without first calling release().
77
+ Based on \$@ it does not look like an exception was thrown (this is not always
78
+ a reliable test)
79
+
80
+ This is a problem because the global error variables (\$!, \$@, and \$?) will
81
+ not be restored. In addition some release callbacks will not work properly from
82
+ inside a DESTROY method.
83
+
84
+ Here are the context creation details, just in case a tool forgot to call
85
+ release():
86
+ File: $frame->[1]
87
+ Line: $frame->[2]
88
+ Tool: $frame->[3]
89
+
90
+ Cleaning up the CONTEXT stack...
91
+ EOT
92
+ }
93
+ }
94
+
95
+ return if $self->{+_IS_SPAWN};
96
+
97
+ # Remove the key itself to avoid a slow memory leak
98
+ delete $CONTEXTS->{$hid};
99
+ $self->{+_IS_CANON} = undef;
100
+
101
+ if (my $cbk = $self->{+_ON_RELEASE}) {
102
+ $_->($self) for reverse @$cbk;
103
+ }
104
+ if (my $hcbk = $hub->{_context_release}) {
105
+ $_->($self) for reverse @$hcbk;
106
+ }
107
+ $_->($self) for reverse @$ON_RELEASE;
108
+ }
109
+
110
+ # release exists to implement behaviors like die-on-fail. In die-on-fail you
111
+ # want to die after a failure, but only after diagnostics have been reported.
112
+ # The ideal time for the die to happen is when the context is released.
113
+ # Unfortunately die does not work in a DESTROY block.
114
+ sub release {
115
+ my ($self) = @_;
116
+
117
+ ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} and return if $self->{+THROWN};
118
+
119
+ ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} and return $self->{+_IS_SPAWN} = undef
120
+ if $self->{+_IS_SPAWN};
121
+
122
+ croak "release() should not be called on context that is neither canon nor a child"
123
+ unless $self->{+_IS_CANON};
124
+
125
+ my $hub = $self->{+HUB};
126
+ my $hid = $hub->{hid};
127
+
128
+ croak "context thinks it is canon, but it is not"
129
+ unless $CONTEXTS->{$hid} && $CONTEXTS->{$hid} == $self;
130
+
131
+ # Remove the key itself to avoid a slow memory leak
132
+ $self->{+_IS_CANON} = undef;
133
+ delete $CONTEXTS->{$hid};
134
+
135
+ if (my $cbk = $self->{+_ON_RELEASE}) {
136
+ $_->($self) for reverse @$cbk;
137
+ }
138
+ if (my $hcbk = $hub->{_context_release}) {
139
+ $_->($self) for reverse @$hcbk;
140
+ }
141
+ $_->($self) for reverse @$ON_RELEASE;
142
+
143
+ # Do this last so that nothing else changes them.
144
+ # If one of the hooks dies then these do not get restored, this is
145
+ # intentional
146
+ ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR};
147
+
148
+ return;
149
+ }
150
+
151
+ sub do_in_context {
152
+ my $self = shift;
153
+ my ($sub, @args) = @_;
154
+
155
+ # We need to update the pid/tid and error vars.
156
+ my $clone = $self->snapshot;
157
+ @$clone{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} = ($!, $@, $?);
158
+ $clone->{+TRACE} = $clone->{+TRACE}->snapshot(pid => $$, tid => get_tid());
159
+
160
+ my $hub = $clone->{+HUB};
161
+ my $hid = $hub->hid;
162
+
163
+ my $old = $CONTEXTS->{$hid};
164
+
165
+ $clone->{+_IS_CANON} = 1;
166
+ $CONTEXTS->{$hid} = $clone;
167
+ weaken($CONTEXTS->{$hid});
168
+ my ($ok, $err) = &try($sub, @args);
169
+ my ($rok, $rerr) = try { $clone->release };
170
+ delete $clone->{+_IS_CANON};
171
+
172
+ if ($old) {
173
+ $CONTEXTS->{$hid} = $old;
174
+ weaken($CONTEXTS->{$hid});
175
+ }
176
+ else {
177
+ delete $CONTEXTS->{$hid};
178
+ }
179
+
180
+ die $err unless $ok;
181
+ die $rerr unless $rok;
182
+ }
183
+
184
+ sub done_testing {
185
+ my $self = shift;
186
+ $self->hub->finalize($self->trace, 1);
187
+ return;
188
+ }
189
+
190
+ sub throw {
191
+ my ($self, $msg) = @_;
192
+ $self->{+THROWN} = 1;
193
+ ${$self->{+_ABORTED}}++ if $self->{+_ABORTED};
194
+ $self->release if $self->{+_IS_CANON} || $self->{+_IS_SPAWN};
195
+ $self->trace->throw($msg);
196
+ }
197
+
198
+ sub alert {
199
+ my ($self, $msg) = @_;
200
+ $self->trace->alert($msg);
201
+ }
202
+
203
+ sub send_ev2_and_release {
204
+ my $self = shift;
205
+ my $out = $self->send_ev2(@_);
206
+ $self->release;
207
+ return $out;
208
+ }
209
+
210
+ sub send_ev2 {
211
+ my $self = shift;
212
+
213
+ my $e;
214
+ {
215
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
216
+ $e = Test2::Event::V2->new(
217
+ trace => $self->{+TRACE}->snapshot,
218
+ @_,
219
+ );
220
+ }
221
+
222
+ if ($self->{+_ABORTED}) {
223
+ my $f = $e->facet_data;
224
+ ${$self->{+_ABORTED}}++ if $f->{control}->{halt} || defined($f->{control}->{terminate}) || defined($e->terminate);
225
+ }
226
+ $self->{+HUB}->send($e);
227
+ }
228
+
229
+ sub build_ev2 {
230
+ my $self = shift;
231
+
232
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
233
+ Test2::Event::V2->new(
234
+ trace => $self->{+TRACE}->snapshot,
235
+ @_,
236
+ );
237
+ }
238
+
239
+ sub send_event_and_release {
240
+ my $self = shift;
241
+ my $out = $self->send_event(@_);
242
+ $self->release;
243
+ return $out;
244
+ }
245
+
246
+ sub send_event {
247
+ my $self = shift;
248
+ my $event = shift;
249
+ my %args = @_;
250
+
251
+ my $pkg = $LOADED{$event} || $self->_parse_event($event);
252
+
253
+ my $e;
254
+ {
255
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
256
+ $e = $pkg->new(
257
+ trace => $self->{+TRACE}->snapshot,
258
+ %args,
259
+ );
260
+ }
261
+
262
+ if ($self->{+_ABORTED}) {
263
+ my $f = $e->facet_data;
264
+ ${$self->{+_ABORTED}}++ if $f->{control}->{halt} || defined($f->{control}->{terminate}) || defined($e->terminate);
265
+ }
266
+ $self->{+HUB}->send($e);
267
+ }
268
+
269
+ sub build_event {
270
+ my $self = shift;
271
+ my $event = shift;
272
+ my %args = @_;
273
+
274
+ my $pkg = $LOADED{$event} || $self->_parse_event($event);
275
+
276
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
277
+ $pkg->new(
278
+ trace => $self->{+TRACE}->snapshot,
279
+ %args,
280
+ );
281
+ }
282
+
283
+ sub pass {
284
+ my $self = shift;
285
+ my ($name) = @_;
286
+
287
+ my $e = bless(
288
+ {
289
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
290
+ name => $name,
291
+ },
292
+ "Test2::Event::Pass"
293
+ );
294
+
295
+ $self->{+HUB}->send($e);
296
+ return $e;
297
+ }
298
+
299
+ sub pass_and_release {
300
+ my $self = shift;
301
+ my ($name) = @_;
302
+
303
+ my $e = bless(
304
+ {
305
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
306
+ name => $name,
307
+ },
308
+ "Test2::Event::Pass"
309
+ );
310
+
311
+ $self->{+HUB}->send($e);
312
+ $self->release;
313
+ return 1;
314
+ }
315
+
316
+ sub fail {
317
+ my $self = shift;
318
+ my ($name, @diag) = @_;
319
+
320
+ my $e = bless(
321
+ {
322
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
323
+ name => $name,
324
+ },
325
+ "Test2::Event::Fail"
326
+ );
327
+
328
+ for my $msg (@diag) {
329
+ if (ref($msg) eq 'Test2::EventFacet::Info::Table') {
330
+ $e->add_info({tag => 'DIAG', debug => 1, $msg->info_args});
331
+ }
332
+ else {
333
+ $e->add_info({tag => 'DIAG', debug => 1, details => $msg});
334
+ }
335
+ }
336
+
337
+ $self->{+HUB}->send($e);
338
+ return $e;
339
+ }
340
+
341
+ sub fail_and_release {
342
+ my $self = shift;
343
+ my ($name, @diag) = @_;
344
+
345
+ my $e = bless(
346
+ {
347
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
348
+ name => $name,
349
+ },
350
+ "Test2::Event::Fail"
351
+ );
352
+
353
+ for my $msg (@diag) {
354
+ if (ref($msg) eq 'Test2::EventFacet::Info::Table') {
355
+ $e->add_info({tag => 'DIAG', debug => 1, $msg->info_args});
356
+ }
357
+ else {
358
+ $e->add_info({tag => 'DIAG', debug => 1, details => $msg});
359
+ }
360
+ }
361
+
362
+ $self->{+HUB}->send($e);
363
+ $self->release;
364
+ return 0;
365
+ }
366
+
367
+ sub ok {
368
+ my $self = shift;
369
+ my ($pass, $name, $on_fail) = @_;
370
+
371
+ my $hub = $self->{+HUB};
372
+
373
+ my $e = bless {
374
+ trace => bless( {%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
375
+ pass => $pass,
376
+ name => $name,
377
+ }, 'Test2::Event::Ok';
378
+ $e->init;
379
+
380
+ $hub->send($e);
381
+ return $e if $pass;
382
+
383
+ $self->failure_diag($e);
384
+
385
+ if ($on_fail && @$on_fail) {
386
+ $self->diag($_) for @$on_fail;
387
+ }
388
+
389
+ return $e;
390
+ }
391
+
392
+ sub failure_diag {
393
+ my $self = shift;
394
+ my ($e) = @_;
395
+
396
+ # Figure out the debug info, this is typically the file name and line
397
+ # number, but can also be a custom message. If no trace object is provided
398
+ # then we have nothing useful to display.
399
+ my $name = $e->name;
400
+ my $trace = $e->trace;
401
+ my $debug = $trace ? $trace->debug : "[No trace info available]";
402
+
403
+ # Create the initial diagnostics. If the test has a name we put the debug
404
+ # info on a second line, this behavior is inherited from Test::Builder.
405
+ my $msg = defined($name)
406
+ ? qq[Failed test '$name'\n$debug.\n]
407
+ : qq[Failed test $debug.\n];
408
+
409
+ $self->diag($msg);
410
+ }
411
+
412
+ sub skip {
413
+ my $self = shift;
414
+ my ($name, $reason, @extra) = @_;
415
+ $self->send_event(
416
+ 'Skip',
417
+ name => $name,
418
+ reason => $reason,
419
+ pass => 1,
420
+ @extra,
421
+ );
422
+ }
423
+
424
+ sub note {
425
+ my $self = shift;
426
+ my ($message) = @_;
427
+ $self->send_event('Note', message => $message);
428
+ }
429
+
430
+ sub diag {
431
+ my $self = shift;
432
+ my ($message) = @_;
433
+ my $hub = $self->{+HUB};
434
+ $self->send_event(
435
+ 'Diag',
436
+ message => $message,
437
+ );
438
+ }
439
+
440
+ sub plan {
441
+ my ($self, $max, $directive, $reason) = @_;
442
+ $self->send_event('Plan', max => $max, directive => $directive, reason => $reason);
443
+ }
444
+
445
+ sub bail {
446
+ my ($self, $reason) = @_;
447
+ $self->send_event('Bail', reason => $reason);
448
+ }
449
+
450
+ sub _parse_event {
451
+ my $self = shift;
452
+ my $event = shift;
453
+
454
+ my $pkg;
455
+ if ($event =~ m/^\+(.*)/) {
456
+ $pkg = $1;
457
+ }
458
+ else {
459
+ $pkg = "Test2::Event::$event";
460
+ }
461
+
462
+ unless ($LOADED{$pkg}) {
463
+ my $file = pkg_to_file($pkg);
464
+ my ($ok, $err) = try { require $file };
465
+ $self->throw("Could not load event module '$pkg': $err")
466
+ unless $ok;
467
+
468
+ $LOADED{$pkg} = $pkg;
469
+ }
470
+
471
+ confess "'$pkg' is not a subclass of 'Test2::Event'"
472
+ unless $pkg->isa('Test2::Event');
473
+
474
+ $LOADED{$event} = $pkg;
475
+
476
+ return $pkg;
477
+ }
478
+
479
+ 1;
480
+
481
+ __END__
482
+
483
+ =pod
484
+
485
+ =encoding UTF-8
486
+
487
+ =head1 NAME
488
+
489
+ Test2::API::Context - Object to represent a testing context.
490
+
491
+ =head1 DESCRIPTION
492
+
493
+ The context object is the primary interface for authors of testing tools
494
+ written with L<Test2>. The context object represents the context in
495
+ which a test takes place (File and Line Number), and provides a quick way to
496
+ generate events from that context. The context object also takes care of
497
+ sending events to the correct L<Test2::Hub> instance.
498
+
499
+ =head1 SYNOPSIS
500
+
501
+ In general you will not be creating contexts directly. To obtain a context you
502
+ should always use C<context()> which is exported by the L<Test2::API> module.
503
+
504
+ use Test2::API qw/context/;
505
+
506
+ sub my_ok {
507
+ my ($bool, $name) = @_;
508
+ my $ctx = context();
509
+
510
+ if ($bool) {
511
+ $ctx->pass($name);
512
+ }
513
+ else {
514
+ $ctx->fail($name);
515
+ }
516
+
517
+ $ctx->release; # You MUST do this!
518
+ return $bool;
519
+ }
520
+
521
+ Context objects make it easy to wrap other tools that also use context. Once
522
+ you grab a context, any tool you call before releasing your context will
523
+ inherit it:
524
+
525
+ sub wrapper {
526
+ my ($bool, $name) = @_;
527
+ my $ctx = context();
528
+ $ctx->diag("wrapping my_ok");
529
+
530
+ my $out = my_ok($bool, $name);
531
+ $ctx->release; # You MUST do this!
532
+ return $out;
533
+ }
534
+
535
+ =head1 CRITICAL DETAILS
536
+
537
+ =over 4
538
+
539
+ =item you MUST always use the context() sub from Test2::API
540
+
541
+ Creating your own context via C<< Test2::API::Context->new() >> will almost never
542
+ produce a desirable result. Use C<context()> which is exported by L<Test2::API>.
543
+
544
+ There are a handful of cases where a tool author may want to create a new
545
+ context by hand, which is why the C<new> method exists. Unless you really know
546
+ what you are doing you should avoid this.
547
+
548
+ =item You MUST always release the context when done with it
549
+
550
+ Releasing the context tells the system you are done with it. This gives it a
551
+ chance to run any necessary callbacks or cleanup tasks. If you forget to
552
+ release the context it will try to detect the problem and warn you about it.
553
+
554
+ =item You MUST NOT pass context objects around
555
+
556
+ When you obtain a context object it is made specifically for your tool and any
557
+ tools nested within. If you pass a context around you run the risk of polluting
558
+ other tools with incorrect context information.
559
+
560
+ If you are certain that you want a different tool to use the same context you
561
+ may pass it a snapshot. C<< $ctx->snapshot >> will give you a shallow clone of
562
+ the context that is safe to pass around or store.
563
+
564
+ =item You MUST NOT store or cache a context for later
565
+
566
+ As long as a context exists for a given hub, all tools that try to get a
567
+ context will get the existing instance. If you try to store the context you
568
+ will pollute other tools with incorrect context information.
569
+
570
+ If you are certain that you want to save the context for later, you can use a
571
+ snapshot. C<< $ctx->snapshot >> will give you a shallow clone of the context
572
+ that is safe to pass around or store.
573
+
574
+ C<context()> has some mechanisms to protect you if you do cause a context to
575
+ persist beyond the scope in which it was obtained. In practice you should not
576
+ rely on these protections, and they are fairly noisy with warnings.
577
+
578
+ =item You SHOULD obtain your context as soon as possible in a given tool
579
+
580
+ You never know what tools you call from within your own tool will need a
581
+ context. Obtaining the context early ensures that nested tools can find the
582
+ context you want them to find.
583
+
584
+ =back
585
+
586
+ =head1 METHODS
587
+
588
+ =over 4
589
+
590
+ =item $ctx->done_testing;
591
+
592
+ Note that testing is finished. If no plan has been set this will generate a
593
+ Plan event.
594
+
595
+ =item $clone = $ctx->snapshot()
596
+
597
+ This will return a shallow clone of the context. The shallow clone is safe to
598
+ store for later.
599
+
600
+ =item $ctx->release()
601
+
602
+ This will release the context. This runs cleanup tasks, and several important
603
+ hooks. It will also restore C<$!>, C<$?>, and C<$@> to what they were when the
604
+ context was created.
605
+
606
+ B<Note:> If a context is acquired more than once an internal refcount is kept.
607
+ C<release()> decrements the ref count, none of the other actions of
608
+ C<release()> will occur unless the refcount hits 0. This means only the last
609
+ call to C<release()> will reset C<$?>, C<$!>, C<$@>,and run the cleanup tasks.
610
+
611
+ =item $ctx->throw($message)
612
+
613
+ This will throw an exception reporting to the file and line number of the
614
+ context. This will also release the context for you.
615
+
616
+ =item $ctx->alert($message)
617
+
618
+ This will issue a warning from the file and line number of the context.
619
+
620
+ =item $stack = $ctx->stack()
621
+
622
+ This will return the L<Test2::API::Stack> instance the context used to find
623
+ the current hub.
624
+
625
+ =item $hub = $ctx->hub()
626
+
627
+ This will return the L<Test2::Hub> instance the context recognizes as the
628
+ current one to which all events should be sent.
629
+
630
+ =item $dbg = $ctx->trace()
631
+
632
+ This will return the L<Test2::EventFacet::Trace> instance used by the context.
633
+
634
+ =item $ctx->do_in_context(\&code, @args);
635
+
636
+ Sometimes you have a context that is not current, and you want things to use it
637
+ as the current one. In these cases you can call
638
+ C<< $ctx->do_in_context(sub { ... }) >>. The codeblock will be run, and
639
+ anything inside of it that looks for a context will find the one on which the
640
+ method was called.
641
+
642
+ This B<DOES NOT> affect context on other hubs, only the hub used by the context
643
+ will be affected.
644
+
645
+ my $ctx = ...;
646
+ $ctx->do_in_context(sub {
647
+ my $ctx = context(); # returns the $ctx the sub is called on
648
+ });
649
+
650
+ B<Note:> The context will actually be cloned, the clone will be used instead of
651
+ the original. This allows the thread id, process id, and error variables to be correct without
652
+ modifying the original context.
653
+
654
+ =item $ctx->restore_error_vars()
655
+
656
+ This will set C<$!>, C<$?>, and C<$@> to what they were when the context was
657
+ created. There is no localization or anything done here, calling this method
658
+ will actually set these vars.
659
+
660
+ =item $! = $ctx->errno()
661
+
662
+ The (numeric) value of C<$!> when the context was created.
663
+
664
+ =item $? = $ctx->child_error()
665
+
666
+ The value of C<$?> when the context was created.
667
+
668
+ =item $@ = $ctx->eval_error()
669
+
670
+ The value of C<$@> when the context was created.
671
+
672
+ =back
673
+
674
+ =head2 EVENT PRODUCTION METHODS
675
+
676
+ B<Which one do I use?>
677
+
678
+ The C<pass*> and C<fail*> are optimal if they meet your situation, using one of
679
+ them will always be the most optimal. That said they are optimal by eliminating
680
+ many features.
681
+
682
+ Method such as C<ok>, and C<note> are shortcuts for generating common 1-task
683
+ events based on the old API, however they are forward compatible, and easy to
684
+ use. If these meet your needs then go ahead and use them, but please check back
685
+ often for alternatives that may be added.
686
+
687
+ If you want to generate new style events, events that do many things at once,
688
+ then you want the C<*ev2*> methods. These let you directly specify which facets
689
+ you wish to use.
690
+
691
+ =over 4
692
+
693
+ =item $event = $ctx->pass()
694
+
695
+ =item $event = $ctx->pass($name)
696
+
697
+ This will send and return an L<Test2::Event::Pass> event. You may optionally
698
+ provide a C<$name> for the assertion.
699
+
700
+ The L<Test2::Event::Pass> is a specially crafted and optimized event, using
701
+ this will help the performance of passing tests.
702
+
703
+ =item $true = $ctx->pass_and_release()
704
+
705
+ =item $true = $ctx->pass_and_release($name)
706
+
707
+ This is a combination of C<pass()> and C<release()>. You can use this if you do
708
+ not plan to do anything with the context after sending the event. This helps
709
+ write more clear and compact code.
710
+
711
+ sub shorthand {
712
+ my ($bool, $name) = @_;
713
+ my $ctx = context();
714
+ return $ctx->pass_and_release($name) if $bool;
715
+
716
+ ... Handle a failure ...
717
+ }
718
+
719
+ sub longform {
720
+ my ($bool, $name) = @_;
721
+ my $ctx = context();
722
+
723
+ if ($bool) {
724
+ $ctx->pass($name);
725
+ $ctx->release;
726
+ return 1;
727
+ }
728
+
729
+ ... Handle a failure ...
730
+ }
731
+
732
+ =item my $event = $ctx->fail()
733
+
734
+ =item my $event = $ctx->fail($name)
735
+
736
+ =item my $event = $ctx->fail($name, @diagnostics)
737
+
738
+ This lets you send an L<Test2::Event::Fail> event. You may optionally provide a
739
+ C<$name> and C<@diagnostics> messages.
740
+
741
+ Diagnostics messages can be simple strings, data structures, or instances of
742
+ L<Test2::EventFacet::Info::Table> (which are converted inline into the
743
+ L<Test2::EventFacet::Info> structure).
744
+
745
+ =item my $false = $ctx->fail_and_release()
746
+
747
+ =item my $false = $ctx->fail_and_release($name)
748
+
749
+ =item my $false = $ctx->fail_and_release($name, @diagnostics)
750
+
751
+ This is a combination of C<fail()> and C<release()>. This can be used to write
752
+ clearer and shorter code.
753
+
754
+ sub shorthand {
755
+ my ($bool, $name) = @_;
756
+ my $ctx = context();
757
+ return $ctx->fail_and_release($name) unless $bool;
758
+
759
+ ... Handle a success ...
760
+ }
761
+
762
+ sub longform {
763
+ my ($bool, $name) = @_;
764
+ my $ctx = context();
765
+
766
+ unless ($bool) {
767
+ $ctx->pass($name);
768
+ $ctx->release;
769
+ return 1;
770
+ }
771
+
772
+ ... Handle a success ...
773
+ }
774
+
775
+
776
+ =item $event = $ctx->ok($bool, $name)
777
+
778
+ =item $event = $ctx->ok($bool, $name, \@on_fail)
779
+
780
+ B<NOTE:> Use of this method is discouraged in favor of C<pass()> and C<fail()>
781
+ which produce L<Test2::Event::Pass> and L<Test2::Event::Fail> events. These
782
+ newer event types are faster and less crufty.
783
+
784
+ This will create an L<Test2::Event::Ok> object for you. If C<$bool> is false
785
+ then an L<Test2::Event::Diag> event will be sent as well with details about the
786
+ failure. If you do not want automatic diagnostics you should use the
787
+ C<send_event()> method directly.
788
+
789
+ The third argument C<\@on_fail>) is an optional set of diagnostics to be sent in
790
+ the event of a test failure. Unlike with C<fail()> these diagnostics must be
791
+ plain strings, data structures are not supported.
792
+
793
+ =item $event = $ctx->note($message)
794
+
795
+ Send an L<Test2::Event::Note>. This event prints a message to STDOUT.
796
+
797
+ =item $event = $ctx->diag($message)
798
+
799
+ Send an L<Test2::Event::Diag>. This event prints a message to STDERR.
800
+
801
+ =item $event = $ctx->plan($max)
802
+
803
+ =item $event = $ctx->plan(0, 'SKIP', $reason)
804
+
805
+ This can be used to send an L<Test2::Event::Plan> event. This event
806
+ usually takes either a number of tests you expect to run. Optionally you can
807
+ set the expected count to 0 and give the 'SKIP' directive with a reason to
808
+ cause all tests to be skipped.
809
+
810
+ =item $event = $ctx->skip($name, $reason);
811
+
812
+ Send an L<Test2::Event::Skip> event.
813
+
814
+ =item $event = $ctx->bail($reason)
815
+
816
+ This sends an L<Test2::Event::Bail> event. This event will completely
817
+ terminate all testing.
818
+
819
+ =item $event = $ctx->send_ev2(%facets)
820
+
821
+ This lets you build and send a V2 event directly from facets. The event is
822
+ returned after it is sent.
823
+
824
+ This example sends a single assertion, a note (comment for stdout in
825
+ Test::Builder talk) and sets the plan to 1.
826
+
827
+ my $event = $ctx->send_event(
828
+ plan => {count => 1},
829
+ assert => {pass => 1, details => "A passing assert"},
830
+ info => [{tag => 'NOTE', details => "This is a note"}],
831
+ );
832
+
833
+ =item $event = $ctx->build_e2(%facets)
834
+
835
+ This is the same as C<send_ev2()>, except it builds and returns the event
836
+ without sending it.
837
+
838
+ =item $event = $ctx->send_ev2_and_release($Type, %parameters)
839
+
840
+ This is a combination of C<send_ev2()> and C<release()>.
841
+
842
+ sub shorthand {
843
+ my $ctx = context();
844
+ return $ctx->send_ev2_and_release(assert => {pass => 1, details => 'foo'});
845
+ }
846
+
847
+ sub longform {
848
+ my $ctx = context();
849
+ my $event = $ctx->send_ev2(assert => {pass => 1, details => 'foo'});
850
+ $ctx->release;
851
+ return $event;
852
+ }
853
+
854
+ =item $event = $ctx->send_event($Type, %parameters)
855
+
856
+ B<It is better to use send_ev2() in new code.>
857
+
858
+ This lets you build and send an event of any type. The C<$Type> argument should
859
+ be the event package name with C<Test2::Event::> left off, or a fully
860
+ qualified package name prefixed with a '+'. The event is returned after it is
861
+ sent.
862
+
863
+ my $event = $ctx->send_event('Ok', ...);
864
+
865
+ or
866
+
867
+ my $event = $ctx->send_event('+Test2::Event::Ok', ...);
868
+
869
+ =item $event = $ctx->build_event($Type, %parameters)
870
+
871
+ B<It is better to use build_ev2() in new code.>
872
+
873
+ This is the same as C<send_event()>, except it builds and returns the event
874
+ without sending it.
875
+
876
+ =item $event = $ctx->send_event_and_release($Type, %parameters)
877
+
878
+ B<It is better to use send_ev2_and_release() in new code.>
879
+
880
+ This is a combination of C<send_event()> and C<release()>.
881
+
882
+ sub shorthand {
883
+ my $ctx = context();
884
+ return $ctx->send_event_and_release(Pass => { name => 'foo' });
885
+ }
886
+
887
+ sub longform {
888
+ my $ctx = context();
889
+ my $event = $ctx->send_event(Pass => { name => 'foo' });
890
+ $ctx->release;
891
+ return $event;
892
+ }
893
+
894
+ =back
895
+
896
+ =head1 HOOKS
897
+
898
+ There are 2 types of hooks, init hooks, and release hooks. As the names
899
+ suggest, these hooks are triggered when contexts are created or released.
900
+
901
+ =head2 INIT HOOKS
902
+
903
+ These are called whenever a context is initialized. That means when a new
904
+ instance is created. These hooks are B<NOT> called every time something
905
+ requests a context, just when a new one is created.
906
+
907
+ =head3 GLOBAL
908
+
909
+ This is how you add a global init callback. Global callbacks happen for every
910
+ context for any hub or stack.
911
+
912
+ Test2::API::test2_add_callback_context_init(sub {
913
+ my $ctx = shift;
914
+ ...
915
+ });
916
+
917
+ =head3 PER HUB
918
+
919
+ This is how you add an init callback for all contexts created for a given hub.
920
+ These callbacks will not run for other hubs.
921
+
922
+ $hub->add_context_init(sub {
923
+ my $ctx = shift;
924
+ ...
925
+ });
926
+
927
+ =head3 PER CONTEXT
928
+
929
+ This is how you specify an init hook that will only run if your call to
930
+ C<context()> generates a new context. The callback will be ignored if
931
+ C<context()> is returning an existing context.
932
+
933
+ my $ctx = context(on_init => sub {
934
+ my $ctx = shift;
935
+ ...
936
+ });
937
+
938
+ =head2 RELEASE HOOKS
939
+
940
+ These are called whenever a context is released. That means when the last
941
+ reference to the instance is about to be destroyed. These hooks are B<NOT>
942
+ called every time C<< $ctx->release >> is called.
943
+
944
+ =head3 GLOBAL
945
+
946
+ This is how you add a global release callback. Global callbacks happen for every
947
+ context for any hub or stack.
948
+
949
+ Test2::API::test2_add_callback_context_release(sub {
950
+ my $ctx = shift;
951
+ ...
952
+ });
953
+
954
+ =head3 PER HUB
955
+
956
+ This is how you add a release callback for all contexts created for a given
957
+ hub. These callbacks will not run for other hubs.
958
+
959
+ $hub->add_context_release(sub {
960
+ my $ctx = shift;
961
+ ...
962
+ });
963
+
964
+ =head3 PER CONTEXT
965
+
966
+ This is how you add release callbacks directly to a context. The callback will
967
+ B<ALWAYS> be added to the context that gets returned, it does not matter if a
968
+ new one is generated, or if an existing one is returned.
969
+
970
+ my $ctx = context(on_release => sub {
971
+ my $ctx = shift;
972
+ ...
973
+ });
974
+
975
+ =head1 THIRD PARTY META-DATA
976
+
977
+ This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
978
+ way for you to attach meta-data to instances of this class. This is useful for
979
+ tools, plugins, and other extensions.
980
+
981
+ =head1 SOURCE
982
+
983
+ The source code repository for Test2 can be found at
984
+ F<http://github.com/Test-More/test-more/>.
985
+
986
+ =head1 MAINTAINERS
987
+
988
+ =over 4
989
+
990
+ =item Chad Granum E<lt>[email protected]<gt>
991
+
992
+ =back
993
+
994
+ =head1 AUTHORS
995
+
996
+ =over 4
997
+
998
+ =item Chad Granum E<lt>[email protected]<gt>
999
+
1000
+ =item Kent Fredric E<lt>[email protected]<gt>
1001
+
1002
+ =back
1003
+
1004
+ =head1 COPYRIGHT
1005
+
1006
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
1007
+
1008
+ This program is free software; you can redistribute it and/or
1009
+ modify it under the same terms as Perl itself.
1010
+
1011
+ See F<http://dev.perl.org/licenses/>
1012
+
1013
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Instance.pm ADDED
@@ -0,0 +1,822 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::API::Instance;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ our @CARP_NOT = qw/Test2::API Test2::API::Instance Test2::IPC::Driver Test2::Formatter/;
8
+ use Carp qw/confess carp/;
9
+ use Scalar::Util qw/reftype/;
10
+
11
+ use Test2::Util qw/get_tid USE_THREADS CAN_FORK pkg_to_file try CAN_SIGSYS/;
12
+
13
+ use Test2::EventFacet::Trace();
14
+ use Test2::API::Stack();
15
+
16
+ use Test2::Util::HashBase qw{
17
+ _pid _tid
18
+ no_wait
19
+ finalized loaded
20
+ ipc stack formatter
21
+ contexts
22
+
23
+ add_uuid_via
24
+
25
+ -preload
26
+
27
+ ipc_disabled
28
+ ipc_polling
29
+ ipc_drivers
30
+ ipc_timeout
31
+ formatters
32
+
33
+ exit_callbacks
34
+ post_load_callbacks
35
+ context_acquire_callbacks
36
+ context_init_callbacks
37
+ context_release_callbacks
38
+ pre_subtest_callbacks
39
+ };
40
+
41
+ sub DEFAULT_IPC_TIMEOUT() { 30 }
42
+
43
+ sub pid { $_[0]->{+_PID} }
44
+ sub tid { $_[0]->{+_TID} }
45
+
46
+ # Wrap around the getters that should call _finalize.
47
+ BEGIN {
48
+ for my $finalizer (IPC, FORMATTER) {
49
+ my $orig = __PACKAGE__->can($finalizer);
50
+ my $new = sub {
51
+ my $self = shift;
52
+ $self->_finalize unless $self->{+FINALIZED};
53
+ $self->$orig;
54
+ };
55
+
56
+ no strict 'refs';
57
+ no warnings 'redefine';
58
+ *{$finalizer} = $new;
59
+ }
60
+ }
61
+
62
+ sub has_ipc { !!$_[0]->{+IPC} }
63
+
64
+ sub import {
65
+ my $class = shift;
66
+ return unless @_;
67
+ my ($ref) = @_;
68
+ $$ref = $class->new;
69
+ }
70
+
71
+ sub init { $_[0]->reset }
72
+
73
+ sub start_preload {
74
+ my $self = shift;
75
+
76
+ confess "preload cannot be started, Test2::API has already been initialized"
77
+ if $self->{+FINALIZED} || $self->{+LOADED};
78
+
79
+ return $self->{+PRELOAD} = 1;
80
+ }
81
+
82
+ sub stop_preload {
83
+ my $self = shift;
84
+
85
+ return 0 unless $self->{+PRELOAD};
86
+ $self->{+PRELOAD} = 0;
87
+
88
+ $self->post_preload_reset();
89
+
90
+ return 1;
91
+ }
92
+
93
+ sub post_preload_reset {
94
+ my $self = shift;
95
+
96
+ delete $self->{+_PID};
97
+ delete $self->{+_TID};
98
+
99
+ $self->{+ADD_UUID_VIA} = undef unless exists $self->{+ADD_UUID_VIA};
100
+
101
+ $self->{+CONTEXTS} = {};
102
+
103
+ $self->{+FORMATTERS} = [];
104
+
105
+ $self->{+FINALIZED} = undef;
106
+ $self->{+IPC} = undef;
107
+ $self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0;
108
+
109
+ $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
110
+
111
+ $self->{+LOADED} = 0;
112
+
113
+ $self->{+STACK} ||= Test2::API::Stack->new;
114
+ }
115
+
116
+ sub reset {
117
+ my $self = shift;
118
+
119
+ delete $self->{+_PID};
120
+ delete $self->{+_TID};
121
+
122
+ $self->{+ADD_UUID_VIA} = undef;
123
+
124
+ $self->{+CONTEXTS} = {};
125
+
126
+ $self->{+IPC_DRIVERS} = [];
127
+ $self->{+IPC_POLLING} = undef;
128
+
129
+ $self->{+FORMATTERS} = [];
130
+ $self->{+FORMATTER} = undef;
131
+
132
+ $self->{+FINALIZED} = undef;
133
+ $self->{+IPC} = undef;
134
+ $self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0;
135
+
136
+ $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
137
+
138
+ $self->{+NO_WAIT} = 0;
139
+ $self->{+LOADED} = 0;
140
+
141
+ $self->{+EXIT_CALLBACKS} = [];
142
+ $self->{+POST_LOAD_CALLBACKS} = [];
143
+ $self->{+CONTEXT_ACQUIRE_CALLBACKS} = [];
144
+ $self->{+CONTEXT_INIT_CALLBACKS} = [];
145
+ $self->{+CONTEXT_RELEASE_CALLBACKS} = [];
146
+ $self->{+PRE_SUBTEST_CALLBACKS} = [];
147
+
148
+ $self->{+STACK} = Test2::API::Stack->new;
149
+ }
150
+
151
+ sub _finalize {
152
+ my $self = shift;
153
+ my ($caller) = @_;
154
+ $caller ||= [caller(1)];
155
+
156
+ confess "Attempt to initialize Test2::API during preload"
157
+ if $self->{+PRELOAD};
158
+
159
+ $self->{+FINALIZED} = $caller;
160
+
161
+ $self->{+_PID} = $$ unless defined $self->{+_PID};
162
+ $self->{+_TID} = get_tid() unless defined $self->{+_TID};
163
+
164
+ unless ($self->{+FORMATTER}) {
165
+ my ($formatter, $source);
166
+ if ($ENV{T2_FORMATTER}) {
167
+ $source = "set by the 'T2_FORMATTER' environment variable";
168
+
169
+ if ($ENV{T2_FORMATTER} =~ m/^(\+)?(.*)$/) {
170
+ $formatter = $1 ? $2 : "Test2::Formatter::$2"
171
+ }
172
+ else {
173
+ $formatter = '';
174
+ }
175
+ }
176
+ elsif (@{$self->{+FORMATTERS}}) {
177
+ ($formatter) = @{$self->{+FORMATTERS}};
178
+ $source = "Most recently added";
179
+ }
180
+ else {
181
+ $formatter = 'Test2::Formatter::TAP';
182
+ $source = 'default formatter';
183
+ }
184
+
185
+ unless (ref($formatter) || $formatter->can('write')) {
186
+ my $file = pkg_to_file($formatter);
187
+ my ($ok, $err) = try { require $file };
188
+ unless ($ok) {
189
+ my $line = "* COULD NOT LOAD FORMATTER '$formatter' ($source) *";
190
+ my $border = '*' x length($line);
191
+ die "\n\n $border\n $line\n $border\n\n$err";
192
+ }
193
+ }
194
+
195
+ $self->{+FORMATTER} = $formatter;
196
+ }
197
+
198
+ # Turn on IPC if threads are on, drivers are registered, or the Test2::IPC
199
+ # module is loaded.
200
+ return if $self->{+IPC_DISABLED};
201
+ return unless USE_THREADS || $INC{'Test2/IPC.pm'} || @{$self->{+IPC_DRIVERS}};
202
+
203
+ # Turn on polling by default, people expect it.
204
+ $self->enable_ipc_polling;
205
+
206
+ unless (@{$self->{+IPC_DRIVERS}}) {
207
+ my ($ok, $error) = try { require Test2::IPC::Driver::Files };
208
+ die $error unless $ok;
209
+ push @{$self->{+IPC_DRIVERS}} => 'Test2::IPC::Driver::Files';
210
+ }
211
+
212
+ for my $driver (@{$self->{+IPC_DRIVERS}}) {
213
+ next unless $driver->can('is_viable') && $driver->is_viable;
214
+ $self->{+IPC} = $driver->new or next;
215
+ return;
216
+ }
217
+
218
+ die "IPC has been requested, but no viable drivers were found. Aborting...\n";
219
+ }
220
+
221
+ sub formatter_set { $_[0]->{+FORMATTER} ? 1 : 0 }
222
+
223
+ sub add_formatter {
224
+ my $self = shift;
225
+ my ($formatter) = @_;
226
+ unshift @{$self->{+FORMATTERS}} => $formatter;
227
+
228
+ return unless $self->{+FINALIZED};
229
+
230
+ # Why is the @CARP_NOT entry not enough?
231
+ local %Carp::Internal = %Carp::Internal;
232
+ $Carp::Internal{'Test2::Formatter'} = 1;
233
+
234
+ carp "Formatter $formatter loaded too late to be used as the global formatter";
235
+ }
236
+
237
+ sub add_context_acquire_callback {
238
+ my $self = shift;
239
+ my ($code) = @_;
240
+
241
+ my $rtype = reftype($code) || "";
242
+
243
+ confess "Context-acquire callbacks must be coderefs"
244
+ unless $code && $rtype eq 'CODE';
245
+
246
+ push @{$self->{+CONTEXT_ACQUIRE_CALLBACKS}} => $code;
247
+ }
248
+
249
+ sub add_context_init_callback {
250
+ my $self = shift;
251
+ my ($code) = @_;
252
+
253
+ my $rtype = reftype($code) || "";
254
+
255
+ confess "Context-init callbacks must be coderefs"
256
+ unless $code && $rtype eq 'CODE';
257
+
258
+ push @{$self->{+CONTEXT_INIT_CALLBACKS}} => $code;
259
+ }
260
+
261
+ sub add_context_release_callback {
262
+ my $self = shift;
263
+ my ($code) = @_;
264
+
265
+ my $rtype = reftype($code) || "";
266
+
267
+ confess "Context-release callbacks must be coderefs"
268
+ unless $code && $rtype eq 'CODE';
269
+
270
+ push @{$self->{+CONTEXT_RELEASE_CALLBACKS}} => $code;
271
+ }
272
+
273
+ sub add_post_load_callback {
274
+ my $self = shift;
275
+ my ($code) = @_;
276
+
277
+ my $rtype = reftype($code) || "";
278
+
279
+ confess "Post-load callbacks must be coderefs"
280
+ unless $code && $rtype eq 'CODE';
281
+
282
+ push @{$self->{+POST_LOAD_CALLBACKS}} => $code;
283
+ $code->() if $self->{+LOADED};
284
+ }
285
+
286
+ sub add_pre_subtest_callback {
287
+ my $self = shift;
288
+ my ($code) = @_;
289
+
290
+ my $rtype = reftype($code) || "";
291
+
292
+ confess "Pre-subtest callbacks must be coderefs"
293
+ unless $code && $rtype eq 'CODE';
294
+
295
+ push @{$self->{+PRE_SUBTEST_CALLBACKS}} => $code;
296
+ }
297
+
298
+ sub load {
299
+ my $self = shift;
300
+ unless ($self->{+LOADED}) {
301
+ confess "Attempt to initialize Test2::API during preload"
302
+ if $self->{+PRELOAD};
303
+
304
+ $self->{+_PID} = $$ unless defined $self->{+_PID};
305
+ $self->{+_TID} = get_tid() unless defined $self->{+_TID};
306
+
307
+ # This is for https://github.com/Test-More/test-more/issues/16
308
+ # and https://rt.perl.org/Public/Bug/Display.html?id=127774
309
+ # END blocks run in reverse order. This insures the END block is loaded
310
+ # as late as possible. It will not solve all cases, but it helps.
311
+ eval "END { Test2::API::test2_set_is_end() }; 1" or die $@;
312
+
313
+ $self->{+LOADED} = 1;
314
+ $_->() for @{$self->{+POST_LOAD_CALLBACKS}};
315
+ }
316
+ return $self->{+LOADED};
317
+ }
318
+
319
+ sub add_exit_callback {
320
+ my $self = shift;
321
+ my ($code) = @_;
322
+ my $rtype = reftype($code) || "";
323
+
324
+ confess "End callbacks must be coderefs"
325
+ unless $code && $rtype eq 'CODE';
326
+
327
+ push @{$self->{+EXIT_CALLBACKS}} => $code;
328
+ }
329
+
330
+ sub ipc_disable {
331
+ my $self = shift;
332
+
333
+ confess "Attempt to disable IPC after it has been initialized"
334
+ if $self->{+IPC};
335
+
336
+ $self->{+IPC_DISABLED} = 1;
337
+ }
338
+
339
+ sub add_ipc_driver {
340
+ my $self = shift;
341
+ my ($driver) = @_;
342
+ unshift @{$self->{+IPC_DRIVERS}} => $driver;
343
+
344
+ return unless $self->{+FINALIZED};
345
+
346
+ # Why is the @CARP_NOT entry not enough?
347
+ local %Carp::Internal = %Carp::Internal;
348
+ $Carp::Internal{'Test2::IPC::Driver'} = 1;
349
+
350
+ carp "IPC driver $driver loaded too late to be used as the global ipc driver";
351
+ }
352
+
353
+ sub enable_ipc_polling {
354
+ my $self = shift;
355
+
356
+ $self->{+_PID} = $$ unless defined $self->{+_PID};
357
+ $self->{+_TID} = get_tid() unless defined $self->{+_TID};
358
+
359
+ $self->add_context_init_callback(
360
+ # This is called every time a context is created, it needs to be fast.
361
+ # $_[0] is a context object
362
+ sub {
363
+ return unless $self->{+IPC_POLLING};
364
+ return unless $self->{+IPC};
365
+ return unless $self->{+IPC}->pending();
366
+ return $_[0]->{hub}->cull;
367
+ }
368
+ ) unless defined $self->ipc_polling;
369
+
370
+ $self->set_ipc_polling(1);
371
+ }
372
+
373
+ sub get_ipc_pending {
374
+ my $self = shift;
375
+ return -1 unless $self->{+IPC};
376
+ $self->{+IPC}->pending();
377
+ }
378
+
379
+ sub _check_pid {
380
+ my $self = shift;
381
+ my ($pid) = @_;
382
+ return kill(0, $pid);
383
+ }
384
+
385
+ sub set_ipc_pending {
386
+ my $self = shift;
387
+ return unless $self->{+IPC};
388
+ my ($val) = @_;
389
+
390
+ confess "value is required for set_ipc_pending"
391
+ unless $val;
392
+
393
+ $self->{+IPC}->set_pending($val);
394
+ }
395
+
396
+ sub disable_ipc_polling {
397
+ my $self = shift;
398
+ return unless defined $self->{+IPC_POLLING};
399
+ $self->{+IPC_POLLING} = 0;
400
+ }
401
+
402
+ sub _ipc_wait {
403
+ my ($timeout) = @_;
404
+ my $fail = 0;
405
+
406
+ $timeout = DEFAULT_IPC_TIMEOUT() unless defined $timeout;
407
+
408
+ my $ok = eval {
409
+ if (CAN_FORK) {
410
+ local $SIG{ALRM} = sub { die "Timeout waiting on child processes" };
411
+ alarm $timeout;
412
+
413
+ while (1) {
414
+ my $pid = CORE::wait();
415
+ my $err = $?;
416
+ last if $pid == -1;
417
+ next unless $err;
418
+ $fail++;
419
+
420
+ my $sig = $err & 127;
421
+ my $exit = $err >> 8;
422
+ warn "Process $pid did not exit cleanly (wstat: $err, exit: $exit, sig: $sig)\n";
423
+ }
424
+
425
+ alarm 0;
426
+ }
427
+
428
+ if (USE_THREADS) {
429
+ my $start = time;
430
+
431
+ while (1) {
432
+ last unless threads->list();
433
+ die "Timeout waiting on child thread" if time - $start >= $timeout;
434
+ sleep 1;
435
+ for my $t (threads->list) {
436
+ # threads older than 1.34 do not have this :-(
437
+ next if $t->can('is_joinable') && !$t->is_joinable;
438
+ $t->join;
439
+ # In older threads we cannot check if a thread had an error unless
440
+ # we control it and its return.
441
+ my $err = $t->can('error') ? $t->error : undef;
442
+ next unless $err;
443
+ my $tid = $t->tid();
444
+ $fail++;
445
+ chomp($err);
446
+ warn "Thread $tid did not end cleanly: $err\n";
447
+ }
448
+ }
449
+ }
450
+
451
+ 1;
452
+ };
453
+ my $error = $@;
454
+
455
+ return 0 if $ok && !$fail;
456
+ warn $error unless $ok;
457
+ return 255;
458
+ }
459
+
460
+ sub set_exit {
461
+ my $self = shift;
462
+
463
+ return if $self->{+PRELOAD};
464
+
465
+ my $exit = $?;
466
+ my $new_exit = $exit;
467
+
468
+ if ($INC{'Test/Builder.pm'} && $Test::Builder::VERSION ne $Test2::API::VERSION) {
469
+ print STDERR <<" EOT";
470
+
471
+ ********************************************************************************
472
+ * *
473
+ * Test::Builder -- Test2::API version mismatch detected *
474
+ * *
475
+ ********************************************************************************
476
+ Test2::API Version: $Test2::API::VERSION
477
+ Test::Builder Version: $Test::Builder::VERSION
478
+
479
+ This is not a supported configuration, you will have problems.
480
+
481
+ EOT
482
+ }
483
+
484
+ for my $ctx (values %{$self->{+CONTEXTS}}) {
485
+ next unless $ctx;
486
+
487
+ next if $ctx->_aborted && ${$ctx->_aborted};
488
+
489
+ # Only worry about contexts in this PID
490
+ my $trace = $ctx->trace || next;
491
+ next unless $trace->pid && $trace->pid == $$;
492
+
493
+ # Do not worry about contexts that have no hub
494
+ my $hub = $ctx->hub || next;
495
+
496
+ # Do not worry if the state came to a sudden end.
497
+ next if $hub->bailed_out;
498
+ next if defined $hub->skip_reason;
499
+
500
+ # now we worry
501
+ $trace->alert("context object was never released! This means a testing tool is behaving very badly");
502
+
503
+ $exit = 255;
504
+ $new_exit = 255;
505
+ }
506
+
507
+ if (!defined($self->{+_PID}) or !defined($self->{+_TID}) or $self->{+_PID} != $$ or $self->{+_TID} != get_tid()) {
508
+ $? = $exit;
509
+ return;
510
+ }
511
+
512
+ my @hubs = $self->{+STACK} ? $self->{+STACK}->all : ();
513
+
514
+ if (@hubs and $self->{+IPC} and !$self->{+NO_WAIT}) {
515
+ local $?;
516
+ my %seen;
517
+ for my $hub (reverse @hubs) {
518
+ my $ipc = $hub->ipc or next;
519
+ next if $seen{$ipc}++;
520
+ $ipc->waiting();
521
+ }
522
+
523
+ my $ipc_exit = _ipc_wait($self->{+IPC_TIMEOUT});
524
+ $new_exit ||= $ipc_exit;
525
+ }
526
+
527
+ # None of this is necessary if we never got a root hub
528
+ if(my $root = shift @hubs) {
529
+ my $trace = Test2::EventFacet::Trace->new(
530
+ frame => [__PACKAGE__, __FILE__, 0, __PACKAGE__ . '::END'],
531
+ detail => __PACKAGE__ . ' END Block finalization',
532
+ );
533
+ my $ctx = Test2::API::Context->new(
534
+ trace => $trace,
535
+ hub => $root,
536
+ );
537
+
538
+ if (@hubs) {
539
+ $ctx->diag("Test ended with extra hubs on the stack!");
540
+ $new_exit = 255;
541
+ }
542
+
543
+ unless ($root->no_ending) {
544
+ local $?;
545
+ $root->finalize($trace) unless $root->ended;
546
+ $_->($ctx, $exit, \$new_exit) for @{$self->{+EXIT_CALLBACKS}};
547
+ $new_exit ||= $root->failed;
548
+ $new_exit ||= 255 unless $root->is_passing;
549
+ }
550
+ }
551
+
552
+ $new_exit = 255 if $new_exit > 255;
553
+
554
+ if ($new_exit && eval { require Test2::API::Breakage; 1 }) {
555
+ my @warn = Test2::API::Breakage->report();
556
+
557
+ if (@warn) {
558
+ print STDERR "\nYou have loaded versions of test modules known to have problems with Test2.\nThis could explain some test failures.\n";
559
+ print STDERR "$_\n" for @warn;
560
+ print STDERR "\n";
561
+ }
562
+ }
563
+
564
+ $? = $new_exit;
565
+ }
566
+
567
+ 1;
568
+
569
+ __END__
570
+
571
+ =pod
572
+
573
+ =encoding UTF-8
574
+
575
+ =head1 NAME
576
+
577
+ Test2::API::Instance - Object used by Test2::API under the hood
578
+
579
+ =head1 DESCRIPTION
580
+
581
+ This object encapsulates the global shared state tracked by
582
+ L<Test2>. A single global instance of this package is stored (and
583
+ obscured) by the L<Test2::API> package.
584
+
585
+ There is no reason to directly use this package. This package is documented for
586
+ completeness. This package can change, or go away completely at any time.
587
+ Directly using, or monkeypatching this package is not supported in any way
588
+ shape or form.
589
+
590
+ =head1 SYNOPSIS
591
+
592
+ use Test2::API::Instance;
593
+
594
+ my $obj = Test2::API::Instance->new;
595
+
596
+ =over 4
597
+
598
+ =item $pid = $obj->pid
599
+
600
+ PID of this instance.
601
+
602
+ =item $obj->tid
603
+
604
+ Thread ID of this instance.
605
+
606
+ =item $obj->reset()
607
+
608
+ Reset the object to defaults.
609
+
610
+ =item $obj->load()
611
+
612
+ Set the internal state to loaded, and run and stored post-load callbacks.
613
+
614
+ =item $bool = $obj->loaded
615
+
616
+ Check if the state is set to loaded.
617
+
618
+ =item $arrayref = $obj->post_load_callbacks
619
+
620
+ Get the post-load callbacks.
621
+
622
+ =item $obj->add_post_load_callback(sub { ... })
623
+
624
+ Add a post-load callback. If C<load()> has already been called then the callback will
625
+ be immediately executed. If C<load()> has not been called then the callback will be
626
+ stored and executed later when C<load()> is called.
627
+
628
+ =item $hashref = $obj->contexts()
629
+
630
+ Get a hashref of all active contexts keyed by hub id.
631
+
632
+ =item $arrayref = $obj->context_acquire_callbacks
633
+
634
+ Get all context acquire callbacks.
635
+
636
+ =item $arrayref = $obj->context_init_callbacks
637
+
638
+ Get all context init callbacks.
639
+
640
+ =item $arrayref = $obj->context_release_callbacks
641
+
642
+ Get all context release callbacks.
643
+
644
+ =item $arrayref = $obj->pre_subtest_callbacks
645
+
646
+ Get all pre-subtest callbacks.
647
+
648
+ =item $obj->add_context_init_callback(sub { ... })
649
+
650
+ Add a context init callback. Subs are called every time a context is created. Subs
651
+ get the newly created context as their only argument.
652
+
653
+ =item $obj->add_context_release_callback(sub { ... })
654
+
655
+ Add a context release callback. Subs are called every time a context is released. Subs
656
+ get the released context as their only argument. These callbacks should not
657
+ call release on the context.
658
+
659
+ =item $obj->add_pre_subtest_callback(sub { ... })
660
+
661
+ Add a pre-subtest callback. Subs are called every time a subtest is
662
+ going to be run. Subs get the subtest name, coderef, and any
663
+ arguments.
664
+
665
+ =item $obj->set_exit()
666
+
667
+ This is intended to be called in an C<END { ... }> block. This will look at
668
+ test state and set $?. This will also call any end callbacks, and wait on child
669
+ processes/threads.
670
+
671
+ =item $obj->set_ipc_pending($val)
672
+
673
+ Tell other processes and threads there is a pending event. C<$val> should be a
674
+ unique value no other thread/process will generate.
675
+
676
+ B<Note:> This will also make the current process see a pending event.
677
+
678
+ =item $pending = $obj->get_ipc_pending()
679
+
680
+ This returns -1 if it is not possible to know.
681
+
682
+ This returns 0 if there are no pending events.
683
+
684
+ This returns 1 if there are pending events.
685
+
686
+ =item $timeout = $obj->ipc_timeout;
687
+
688
+ =item $obj->set_ipc_timeout($timeout);
689
+
690
+ How long to wait for child processes and threads before aborting.
691
+
692
+ =item $drivers = $obj->ipc_drivers
693
+
694
+ Get the list of IPC drivers.
695
+
696
+ =item $obj->add_ipc_driver($DRIVER_CLASS)
697
+
698
+ Add an IPC driver to the list. The most recently added IPC driver will become
699
+ the global one during initialization. If a driver is added after initialization
700
+ has occurred a warning will be generated:
701
+
702
+ "IPC driver $driver loaded too late to be used as the global ipc driver"
703
+
704
+ =item $bool = $obj->ipc_polling
705
+
706
+ Check if polling is enabled.
707
+
708
+ =item $obj->enable_ipc_polling
709
+
710
+ Turn on polling. This will cull events from other processes and threads every
711
+ time a context is created.
712
+
713
+ =item $obj->disable_ipc_polling
714
+
715
+ Turn off IPC polling.
716
+
717
+ =item $bool = $obj->no_wait
718
+
719
+ =item $bool = $obj->set_no_wait($bool)
720
+
721
+ Get/Set no_wait. This option is used to turn off process/thread waiting at exit.
722
+
723
+ =item $arrayref = $obj->exit_callbacks
724
+
725
+ Get the exit callbacks.
726
+
727
+ =item $obj->add_exit_callback(sub { ... })
728
+
729
+ Add an exit callback. This callback will be called by C<set_exit()>.
730
+
731
+ =item $bool = $obj->finalized
732
+
733
+ Check if the object is finalized. Finalization happens when either C<ipc()>,
734
+ C<stack()>, or C<format()> are called on the object. Once finalization happens
735
+ these fields are considered unchangeable (not enforced here, enforced by
736
+ L<Test2>).
737
+
738
+ =item $ipc = $obj->ipc
739
+
740
+ Get the one true IPC instance.
741
+
742
+ =item $obj->ipc_disable
743
+
744
+ Turn IPC off
745
+
746
+ =item $bool = $obj->ipc_disabled
747
+
748
+ Check if IPC is disabled
749
+
750
+ =item $stack = $obj->stack
751
+
752
+ Get the one true hub stack.
753
+
754
+ =item $formatter = $obj->formatter
755
+
756
+ Get the global formatter. By default this is the C<'Test2::Formatter::TAP'>
757
+ package. This could be any package that implements the C<write()> method. This
758
+ can also be an instantiated object.
759
+
760
+ =item $bool = $obj->formatter_set()
761
+
762
+ Check if a formatter has been set.
763
+
764
+ =item $obj->add_formatter($class)
765
+
766
+ =item $obj->add_formatter($obj)
767
+
768
+ Add a formatter. The most recently added formatter will become the global one
769
+ during initialization. If a formatter is added after initialization has occurred
770
+ a warning will be generated:
771
+
772
+ "Formatter $formatter loaded too late to be used as the global formatter"
773
+
774
+ =item $obj->set_add_uuid_via(sub { ... })
775
+
776
+ =item $sub = $obj->add_uuid_via()
777
+
778
+ This allows you to provide a UUID generator. If provided UUIDs will be attached
779
+ to all events, hubs, and contexts. This is useful for storing, tracking, and
780
+ linking these objects.
781
+
782
+ The sub you provide should always return a unique identifier. Most things will
783
+ expect a proper UUID string, however nothing in Test2::API enforces this.
784
+
785
+ The sub will receive exactly 1 argument, the type of thing being tagged
786
+ 'context', 'hub', or 'event'. In the future additional things may be tagged, in
787
+ which case new strings will be passed in. These are purely informative, you can
788
+ (and usually should) ignore them.
789
+
790
+ =back
791
+
792
+ =head1 SOURCE
793
+
794
+ The source code repository for Test2 can be found at
795
+ F<http://github.com/Test-More/test-more/>.
796
+
797
+ =head1 MAINTAINERS
798
+
799
+ =over 4
800
+
801
+ =item Chad Granum E<lt>[email protected]<gt>
802
+
803
+ =back
804
+
805
+ =head1 AUTHORS
806
+
807
+ =over 4
808
+
809
+ =item Chad Granum E<lt>[email protected]<gt>
810
+
811
+ =back
812
+
813
+ =head1 COPYRIGHT
814
+
815
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
816
+
817
+ This program is free software; you can redistribute it and/or
818
+ modify it under the same terms as Perl itself.
819
+
820
+ See F<http://dev.perl.org/licenses/>
821
+
822
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/API/Stack.pm ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::API::Stack;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ use Test2::Hub();
9
+
10
+ use Carp qw/confess/;
11
+
12
+ sub new {
13
+ my $class = shift;
14
+ return bless [], $class;
15
+ }
16
+
17
+ sub new_hub {
18
+ my $self = shift;
19
+ my %params = @_;
20
+
21
+ my $class = delete $params{class} || 'Test2::Hub';
22
+
23
+ my $hub = $class->new(%params);
24
+
25
+ if (@$self) {
26
+ $hub->inherit($self->[-1], %params);
27
+ }
28
+ else {
29
+ require Test2::API;
30
+ $hub->format(Test2::API::test2_formatter()->new_root)
31
+ unless $hub->format || exists($params{formatter});
32
+
33
+ my $ipc = Test2::API::test2_ipc();
34
+ if ($ipc && !$hub->ipc && !exists($params{ipc})) {
35
+ $hub->set_ipc($ipc);
36
+ $ipc->add_hub($hub->hid);
37
+ }
38
+ }
39
+
40
+ push @$self => $hub;
41
+
42
+ $hub;
43
+ }
44
+
45
+ sub top {
46
+ my $self = shift;
47
+ return $self->new_hub unless @$self;
48
+ return $self->[-1];
49
+ }
50
+
51
+ sub peek {
52
+ my $self = shift;
53
+ return @$self ? $self->[-1] : undef;
54
+ }
55
+
56
+ sub cull {
57
+ my $self = shift;
58
+ $_->cull for reverse @$self;
59
+ }
60
+
61
+ sub all {
62
+ my $self = shift;
63
+ return @$self;
64
+ }
65
+
66
+ sub clear {
67
+ my $self = shift;
68
+ @$self = ();
69
+ }
70
+
71
+ # Do these last without keywords in order to prevent them from getting used
72
+ # when we want the real push/pop.
73
+
74
+ {
75
+ no warnings 'once';
76
+
77
+ *push = sub {
78
+ my $self = shift;
79
+ my ($hub) = @_;
80
+ $hub->inherit($self->[-1]) if @$self;
81
+ push @$self => $hub;
82
+ };
83
+
84
+ *pop = sub {
85
+ my $self = shift;
86
+ my ($hub) = @_;
87
+ confess "No hubs on the stack"
88
+ unless @$self;
89
+ confess "You cannot pop the root hub"
90
+ if 1 == @$self;
91
+ confess "Hub stack mismatch, attempted to pop incorrect hub"
92
+ unless $self->[-1] == $hub;
93
+ pop @$self;
94
+ };
95
+ }
96
+
97
+ 1;
98
+
99
+ __END__
100
+
101
+ =pod
102
+
103
+ =encoding UTF-8
104
+
105
+ =head1 NAME
106
+
107
+ Test2::API::Stack - Object to manage a stack of L<Test2::Hub>
108
+ instances.
109
+
110
+ =head1 ***INTERNALS NOTE***
111
+
112
+ B<The internals of this package are subject to change at any time!> The public
113
+ methods provided will not change in backwards incompatible ways, but the
114
+ underlying implementation details might. B<Do not break encapsulation here!>
115
+
116
+ =head1 DESCRIPTION
117
+
118
+ This module is used to represent and manage a stack of L<Test2::Hub>
119
+ objects. Hubs are usually in a stack so that you can push a new hub into place
120
+ that can intercept and handle events differently than the primary hub.
121
+
122
+ =head1 SYNOPSIS
123
+
124
+ my $stack = Test2::API::Stack->new;
125
+ my $hub = $stack->top;
126
+
127
+ =head1 METHODS
128
+
129
+ =over 4
130
+
131
+ =item $stack = Test2::API::Stack->new()
132
+
133
+ This will create a new empty stack instance. All arguments are ignored.
134
+
135
+ =item $hub = $stack->new_hub()
136
+
137
+ =item $hub = $stack->new_hub(%params)
138
+
139
+ =item $hub = $stack->new_hub(%params, class => $class)
140
+
141
+ This will generate a new hub and push it to the top of the stack. Optionally
142
+ you can provide arguments that will be passed into the constructor for the
143
+ L<Test2::Hub> object.
144
+
145
+ If you specify the C<< 'class' => $class >> argument, the new hub will be an
146
+ instance of the specified class.
147
+
148
+ Unless your parameters specify C<'formatter'> or C<'ipc'> arguments, the
149
+ formatter and IPC instance will be inherited from the current top hub. You can
150
+ set the parameters to C<undef> to avoid having a formatter or IPC instance.
151
+
152
+ If there is no top hub, and you do not ask to leave IPC and formatter undef,
153
+ then a new formatter will be created, and the IPC instance from
154
+ L<Test2::API> will be used.
155
+
156
+ =item $hub = $stack->top()
157
+
158
+ This will return the top hub from the stack. If there is no top hub yet this
159
+ will create it.
160
+
161
+ =item $hub = $stack->peek()
162
+
163
+ This will return the top hub from the stack. If there is no top hub yet this
164
+ will return undef.
165
+
166
+ =item $stack->cull
167
+
168
+ This will call C<< $hub->cull >> on all hubs in the stack.
169
+
170
+ =item @hubs = $stack->all
171
+
172
+ This will return all the hubs in the stack as a list.
173
+
174
+ =item $stack->clear
175
+
176
+ This will completely remove all hubs from the stack. Normally you do not want
177
+ to do this, but there are a few valid reasons for it.
178
+
179
+ =item $stack->push($hub)
180
+
181
+ This will push the new hub onto the stack.
182
+
183
+ =item $stack->pop($hub)
184
+
185
+ This will pop a hub from the stack, if the hub at the top of the stack does not
186
+ match the hub you expect (passed in as an argument) it will throw an exception.
187
+
188
+ =back
189
+
190
+ =head1 SOURCE
191
+
192
+ The source code repository for Test2 can be found at
193
+ F<http://github.com/Test-More/test-more/>.
194
+
195
+ =head1 MAINTAINERS
196
+
197
+ =over 4
198
+
199
+ =item Chad Granum E<lt>[email protected]<gt>
200
+
201
+ =back
202
+
203
+ =head1 AUTHORS
204
+
205
+ =over 4
206
+
207
+ =item Chad Granum E<lt>[email protected]<gt>
208
+
209
+ =back
210
+
211
+ =head1 COPYRIGHT
212
+
213
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
214
+
215
+ This program is free software; you can redistribute it and/or
216
+ modify it under the same terms as Perl itself.
217
+
218
+ See F<http://dev.perl.org/licenses/>
219
+
220
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Diag.pm ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Diag;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
9
+ use Test2::Util::HashBase qw/message/;
10
+
11
+ sub init {
12
+ $_[0]->{+MESSAGE} = 'undef' unless defined $_[0]->{+MESSAGE};
13
+ }
14
+
15
+ sub summary { $_[0]->{+MESSAGE} }
16
+
17
+ sub diagnostics { 1 }
18
+
19
+ sub facet_data {
20
+ my $self = shift;
21
+
22
+ my $out = $self->common_facet_data;
23
+
24
+ $out->{info} = [
25
+ {
26
+ tag => 'DIAG',
27
+ debug => 1,
28
+ details => $self->{+MESSAGE},
29
+ }
30
+ ];
31
+
32
+ return $out;
33
+ }
34
+
35
+ 1;
36
+
37
+ __END__
38
+
39
+ =pod
40
+
41
+ =encoding UTF-8
42
+
43
+ =head1 NAME
44
+
45
+ Test2::Event::Diag - Diag event type
46
+
47
+ =head1 DESCRIPTION
48
+
49
+ Diagnostics messages, typically rendered to STDERR.
50
+
51
+ =head1 SYNOPSIS
52
+
53
+ use Test2::API qw/context/;
54
+ use Test2::Event::Diag;
55
+
56
+ my $ctx = context();
57
+ my $event = $ctx->diag($message);
58
+
59
+ =head1 ACCESSORS
60
+
61
+ =over 4
62
+
63
+ =item $diag->message
64
+
65
+ The message for the diag.
66
+
67
+ =back
68
+
69
+ =head1 SOURCE
70
+
71
+ The source code repository for Test2 can be found at
72
+ F<http://github.com/Test-More/test-more/>.
73
+
74
+ =head1 MAINTAINERS
75
+
76
+ =over 4
77
+
78
+ =item Chad Granum E<lt>[email protected]<gt>
79
+
80
+ =back
81
+
82
+ =head1 AUTHORS
83
+
84
+ =over 4
85
+
86
+ =item Chad Granum E<lt>[email protected]<gt>
87
+
88
+ =back
89
+
90
+ =head1 COPYRIGHT
91
+
92
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
93
+
94
+ This program is free software; you can redistribute it and/or
95
+ modify it under the same terms as Perl itself.
96
+
97
+ See F<http://dev.perl.org/licenses/>
98
+
99
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Encoding.pm ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Encoding;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ use Carp qw/croak/;
8
+
9
+ BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
10
+ use Test2::Util::HashBase qw/encoding/;
11
+
12
+ sub init {
13
+ my $self = shift;
14
+ defined $self->{+ENCODING} or croak "'encoding' is a required attribute";
15
+ }
16
+
17
+ sub summary { 'Encoding set to ' . $_[0]->{+ENCODING} }
18
+
19
+ sub facet_data {
20
+ my $self = shift;
21
+ my $out = $self->common_facet_data;
22
+ $out->{control}->{encoding} = $self->{+ENCODING};
23
+ $out->{about}->{details} = $self->summary;
24
+ return $out;
25
+ }
26
+
27
+
28
+ 1;
29
+
30
+ __END__
31
+
32
+ =pod
33
+
34
+ =encoding UTF-8
35
+
36
+ =head1 NAME
37
+
38
+ Test2::Event::Encoding - Set the encoding for the output stream
39
+
40
+ =head1 DESCRIPTION
41
+
42
+ The encoding event is generated when a test file wants to specify the encoding
43
+ to be used when formatting its output. This event is intended to be produced
44
+ by formatter classes and used for interpreting test names, message contents,
45
+ etc.
46
+
47
+ =head1 SYNOPSIS
48
+
49
+ use Test2::API qw/context/;
50
+ use Test2::Event::Encoding;
51
+
52
+ my $ctx = context();
53
+ my $event = $ctx->send_event('Encoding', encoding => 'UTF-8');
54
+
55
+ =head1 METHODS
56
+
57
+ Inherits from L<Test2::Event>. Also defines:
58
+
59
+ =over 4
60
+
61
+ =item $encoding = $e->encoding
62
+
63
+ The encoding being specified.
64
+
65
+ =back
66
+
67
+ =head1 SOURCE
68
+
69
+ The source code repository for Test2 can be found at
70
+ F<http://github.com/Test-More/test-more/>.
71
+
72
+ =head1 MAINTAINERS
73
+
74
+ =over 4
75
+
76
+ =item Chad Granum E<lt>[email protected]<gt>
77
+
78
+ =back
79
+
80
+ =head1 AUTHORS
81
+
82
+ =over 4
83
+
84
+ =item Chad Granum E<lt>[email protected]<gt>
85
+
86
+ =back
87
+
88
+ =head1 COPYRIGHT
89
+
90
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
91
+
92
+ This program is free software; you can redistribute it and/or
93
+ modify it under the same terms as Perl itself.
94
+
95
+ See F<http://dev.perl.org/licenses/>
96
+
97
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Fail.pm ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Fail;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ use Test2::EventFacet::Info;
8
+
9
+ BEGIN {
10
+ require Test2::Event;
11
+ our @ISA = qw(Test2::Event);
12
+ *META_KEY = \&Test2::Util::ExternalMeta::META_KEY;
13
+ }
14
+
15
+ use Test2::Util::HashBase qw{ -name -info };
16
+
17
+ #############
18
+ # Old API
19
+ sub summary { "fail" }
20
+ sub increments_count { 1 }
21
+ sub diagnostics { 0 }
22
+ sub no_display { 0 }
23
+ sub subtest_id { undef }
24
+ sub terminate { () }
25
+ sub global { () }
26
+ sub sets_plan { () }
27
+
28
+ sub causes_fail {
29
+ my $self = shift;
30
+ return 0 if $self->{+AMNESTY} && @{$self->{+AMNESTY}};
31
+ return 1;
32
+ }
33
+
34
+ #############
35
+ # New API
36
+
37
+ sub add_info {
38
+ my $self = shift;
39
+
40
+ for my $in (@_) {
41
+ $in = {%$in} if ref($in) ne 'ARRAY';
42
+ $in = Test2::EventFacet::Info->new($in);
43
+
44
+ push @{$self->{+INFO}} => $in;
45
+ }
46
+ }
47
+
48
+ sub facet_data {
49
+ my $self = shift;
50
+ my $out = $self->common_facet_data;
51
+
52
+ $out->{about}->{details} = 'fail';
53
+
54
+ $out->{assert} = {pass => 0, details => $self->{+NAME}};
55
+
56
+ $out->{info} = [map {{ %{$_} }} @{$self->{+INFO}}] if $self->{+INFO};
57
+
58
+ return $out;
59
+ }
60
+
61
+ 1;
62
+
63
+ __END__
64
+
65
+ =pod
66
+
67
+ =encoding UTF-8
68
+
69
+ =head1 NAME
70
+
71
+ Test2::Event::Fail - Event for a simple failed assertion
72
+
73
+ =head1 DESCRIPTION
74
+
75
+ This is an optimal representation of a failed assertion.
76
+
77
+ =head1 SYNOPSIS
78
+
79
+ use Test2::API qw/context/;
80
+
81
+ sub fail {
82
+ my ($name) = @_;
83
+ my $ctx = context();
84
+ $ctx->fail($name);
85
+ $ctx->release;
86
+ }
87
+
88
+ =head1 SOURCE
89
+
90
+ The source code repository for Test2 can be found at
91
+ F<http://github.com/Test-More/test-more/>.
92
+
93
+ =head1 MAINTAINERS
94
+
95
+ =over 4
96
+
97
+ =item Chad Granum E<lt>[email protected]<gt>
98
+
99
+ =back
100
+
101
+ =head1 AUTHORS
102
+
103
+ =over 4
104
+
105
+ =item Chad Granum E<lt>[email protected]<gt>
106
+
107
+ =back
108
+
109
+ =head1 COPYRIGHT
110
+
111
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
112
+
113
+ This program is free software; you can redistribute it and/or
114
+ modify it under the same terms as Perl itself.
115
+
116
+ See F<http://dev.perl.org/licenses/>
117
+
118
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Generic.pm ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Generic;
2
+ use strict;
3
+ use warnings;
4
+
5
+ use Carp qw/croak/;
6
+ use Scalar::Util qw/reftype/;
7
+
8
+ our $VERSION = '1.302162';
9
+
10
+ BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
11
+ use Test2::Util::HashBase;
12
+
13
+ my @FIELDS = qw{
14
+ causes_fail increments_count diagnostics no_display callback terminate
15
+ global sets_plan summary facet_data
16
+ };
17
+ my %DEFAULTS = (
18
+ causes_fail => 0,
19
+ increments_count => 0,
20
+ diagnostics => 0,
21
+ no_display => 0,
22
+ );
23
+
24
+ sub init {
25
+ my $self = shift;
26
+
27
+ for my $field (@FIELDS) {
28
+ my $val = defined $self->{$field} ? delete $self->{$field} : $DEFAULTS{$field};
29
+ next unless defined $val;
30
+
31
+ my $set = "set_$field";
32
+ $self->$set($val);
33
+ }
34
+ }
35
+
36
+ for my $field (@FIELDS) {
37
+ no strict 'refs';
38
+
39
+ *$field = sub { exists $_[0]->{$field} ? $_[0]->{$field} : () }
40
+ unless exists &{$field};
41
+
42
+ *{"set_$field"} = sub { $_[0]->{$field} = $_[1] }
43
+ unless exists &{"set_$field"};
44
+ }
45
+
46
+ sub can {
47
+ my $self = shift;
48
+ my ($name) = @_;
49
+ return $self->SUPER::can($name) unless $name eq 'callback';
50
+ return $self->{callback} || \&Test2::Event::callback;
51
+ }
52
+
53
+ sub facet_data {
54
+ my $self = shift;
55
+ return $self->{facet_data} || $self->SUPER::facet_data();
56
+ }
57
+
58
+ sub summary {
59
+ my $self = shift;
60
+ return $self->{summary} if defined $self->{summary};
61
+ $self->SUPER::summary();
62
+ }
63
+
64
+ sub sets_plan {
65
+ my $self = shift;
66
+ return unless $self->{sets_plan};
67
+ return @{$self->{sets_plan}};
68
+ }
69
+
70
+ sub callback {
71
+ my $self = shift;
72
+ my $cb = $self->{callback} || return;
73
+ $self->$cb(@_);
74
+ }
75
+
76
+ sub set_global {
77
+ my $self = shift;
78
+ my ($bool) = @_;
79
+
80
+ if(!defined $bool) {
81
+ delete $self->{global};
82
+ return undef;
83
+ }
84
+
85
+ $self->{global} = $bool;
86
+ }
87
+
88
+ sub set_callback {
89
+ my $self = shift;
90
+ my ($cb) = @_;
91
+
92
+ if(!defined $cb) {
93
+ delete $self->{callback};
94
+ return undef;
95
+ }
96
+
97
+ croak "callback must be a code reference"
98
+ unless ref($cb) && reftype($cb) eq 'CODE';
99
+
100
+ $self->{callback} = $cb;
101
+ }
102
+
103
+ sub set_terminate {
104
+ my $self = shift;
105
+ my ($exit) = @_;
106
+
107
+ if(!defined $exit) {
108
+ delete $self->{terminate};
109
+ return undef;
110
+ }
111
+
112
+ croak "terminate must be a positive integer"
113
+ unless $exit =~ m/^\d+$/;
114
+
115
+ $self->{terminate} = $exit;
116
+ }
117
+
118
+ sub set_sets_plan {
119
+ my $self = shift;
120
+ my ($plan) = @_;
121
+
122
+ if(!defined $plan) {
123
+ delete $self->{sets_plan};
124
+ return undef;
125
+ }
126
+
127
+ croak "'sets_plan' must be an array reference"
128
+ unless ref($plan) && reftype($plan) eq 'ARRAY';
129
+
130
+ $self->{sets_plan} = $plan;
131
+ }
132
+
133
+ 1;
134
+
135
+ __END__
136
+
137
+ =pod
138
+
139
+ =encoding UTF-8
140
+
141
+ =head1 NAME
142
+
143
+ Test2::Event::Generic - Generic event type.
144
+
145
+ =head1 DESCRIPTION
146
+
147
+ This is a generic event that lets you customize all fields in the event API.
148
+ This is useful if you have need for a custom event that does not make sense as
149
+ a published reusable event subclass.
150
+
151
+ =head1 SYNOPSIS
152
+
153
+ use Test2::API qw/context/;
154
+
155
+ sub send_custom_fail {
156
+ my $ctx = shift;
157
+
158
+ $ctx->send_event('Generic', causes_fail => 1, summary => 'The sky is falling');
159
+
160
+ $ctx->release;
161
+ }
162
+
163
+ send_custom_fail();
164
+
165
+ =head1 METHODS
166
+
167
+ =over 4
168
+
169
+ =item $e->facet_data($data)
170
+
171
+ =item $data = $e->facet_data
172
+
173
+ Get or set the facet data (see L<Test2::Event>). If no facet_data is set then
174
+ C<< Test2::Event->facet_data >> will be called to produce facets from the other
175
+ data.
176
+
177
+ =item $e->callback($hub)
178
+
179
+ Call the custom callback if one is set, otherwise this does nothing.
180
+
181
+ =item $e->set_callback(sub { ... })
182
+
183
+ Set the custom callback. The custom callback must be a coderef. The first
184
+ argument to your callback will be the event itself, the second will be the
185
+ L<Test2::Event::Hub> that is using the callback.
186
+
187
+ =item $bool = $e->causes_fail
188
+
189
+ =item $e->set_causes_fail($bool)
190
+
191
+ Get/Set the C<causes_fail> attribute. This defaults to C<0>.
192
+
193
+ =item $bool = $e->diagnostics
194
+
195
+ =item $e->set_diagnostics($bool)
196
+
197
+ Get/Set the C<diagnostics> attribute. This defaults to C<0>.
198
+
199
+ =item $bool_or_undef = $e->global
200
+
201
+ =item @bool_or_empty = $e->global
202
+
203
+ =item $e->set_global($bool_or_undef)
204
+
205
+ Get/Set the C<diagnostics> attribute. This defaults to an empty list which is
206
+ undef in scalar context.
207
+
208
+ =item $bool = $e->increments_count
209
+
210
+ =item $e->set_increments_count($bool)
211
+
212
+ Get/Set the C<increments_count> attribute. This defaults to C<0>.
213
+
214
+ =item $bool = $e->no_display
215
+
216
+ =item $e->set_no_display($bool)
217
+
218
+ Get/Set the C<no_display> attribute. This defaults to C<0>.
219
+
220
+ =item @plan = $e->sets_plan
221
+
222
+ Get the plan if this event sets one. The plan is a list of up to 3 items:
223
+ C<($count, $directive, $reason)>. C<$count> must be defined, the others may be
224
+ undef, or may not exist at all.
225
+
226
+ =item $e->set_sets_plan(\@plan)
227
+
228
+ Set the plan. You must pass in an arrayref with up to 3 elements.
229
+
230
+ =item $summary = $e->summary
231
+
232
+ =item $e->set_summary($summary_or_undef)
233
+
234
+ Get/Set the summary. This will default to the event package
235
+ C<'Test2::Event::Generic'>. You can set it to any value. Setting this to
236
+ C<undef> will reset it to the default.
237
+
238
+ =item $int_or_undef = $e->terminate
239
+
240
+ =item @int_or_empty = $e->terminate
241
+
242
+ =item $e->set_terminate($int_or_undef)
243
+
244
+ This will get/set the C<terminate> attribute. This defaults to undef in scalar
245
+ context, or an empty list in list context. Setting this to undef will clear it
246
+ completely. This must be set to a positive integer (0 or larger).
247
+
248
+ =back
249
+
250
+ =head1 SOURCE
251
+
252
+ The source code repository for Test2 can be found at
253
+ F<http://github.com/Test-More/test-more/>.
254
+
255
+ =head1 MAINTAINERS
256
+
257
+ =over 4
258
+
259
+ =item Chad Granum E<lt>[email protected]<gt>
260
+
261
+ =back
262
+
263
+ =head1 AUTHORS
264
+
265
+ =over 4
266
+
267
+ =item Chad Granum E<lt>[email protected]<gt>
268
+
269
+ =back
270
+
271
+ =head1 COPYRIGHT
272
+
273
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
274
+
275
+ This program is free software; you can redistribute it and/or
276
+ modify it under the same terms as Perl itself.
277
+
278
+ See F<http://dev.perl.org/licenses/>
279
+
280
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Note.pm ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Note;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
9
+ use Test2::Util::HashBase qw/message/;
10
+
11
+ sub init {
12
+ $_[0]->{+MESSAGE} = 'undef' unless defined $_[0]->{+MESSAGE};
13
+ }
14
+
15
+ sub summary { $_[0]->{+MESSAGE} }
16
+
17
+ sub facet_data {
18
+ my $self = shift;
19
+
20
+ my $out = $self->common_facet_data;
21
+
22
+ $out->{info} = [
23
+ {
24
+ tag => 'NOTE',
25
+ debug => 0,
26
+ details => $self->{+MESSAGE},
27
+ }
28
+ ];
29
+
30
+ return $out;
31
+ }
32
+
33
+ 1;
34
+
35
+ __END__
36
+
37
+ =pod
38
+
39
+ =encoding UTF-8
40
+
41
+ =head1 NAME
42
+
43
+ Test2::Event::Note - Note event type
44
+
45
+ =head1 DESCRIPTION
46
+
47
+ Notes, typically rendered to STDOUT.
48
+
49
+ =head1 SYNOPSIS
50
+
51
+ use Test2::API qw/context/;
52
+ use Test2::Event::Note;
53
+
54
+ my $ctx = context();
55
+ my $event = $ctx->Note($message);
56
+
57
+ =head1 ACCESSORS
58
+
59
+ =over 4
60
+
61
+ =item $note->message
62
+
63
+ The message for the note.
64
+
65
+ =back
66
+
67
+ =head1 SOURCE
68
+
69
+ The source code repository for Test2 can be found at
70
+ F<http://github.com/Test-More/test-more/>.
71
+
72
+ =head1 MAINTAINERS
73
+
74
+ =over 4
75
+
76
+ =item Chad Granum E<lt>[email protected]<gt>
77
+
78
+ =back
79
+
80
+ =head1 AUTHORS
81
+
82
+ =over 4
83
+
84
+ =item Chad Granum E<lt>[email protected]<gt>
85
+
86
+ =back
87
+
88
+ =head1 COPYRIGHT
89
+
90
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
91
+
92
+ This program is free software; you can redistribute it and/or
93
+ modify it under the same terms as Perl itself.
94
+
95
+ See F<http://dev.perl.org/licenses/>
96
+
97
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Pass.pm ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Pass;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ use Test2::EventFacet::Info;
8
+
9
+ BEGIN {
10
+ require Test2::Event;
11
+ our @ISA = qw(Test2::Event);
12
+ *META_KEY = \&Test2::Util::ExternalMeta::META_KEY;
13
+ }
14
+
15
+ use Test2::Util::HashBase qw{ -name -info };
16
+
17
+ ##############
18
+ # Old API
19
+ sub summary { "pass" }
20
+ sub increments_count { 1 }
21
+ sub causes_fail { 0 }
22
+ sub diagnostics { 0 }
23
+ sub no_display { 0 }
24
+ sub subtest_id { undef }
25
+ sub terminate { () }
26
+ sub global { () }
27
+ sub sets_plan { () }
28
+
29
+ ##############
30
+ # New API
31
+
32
+ sub add_info {
33
+ my $self = shift;
34
+
35
+ for my $in (@_) {
36
+ $in = {%$in} if ref($in) ne 'ARRAY';
37
+ $in = Test2::EventFacet::Info->new($in);
38
+
39
+ push @{$self->{+INFO}} => $in;
40
+ }
41
+ }
42
+
43
+ sub facet_data {
44
+ my $self = shift;
45
+
46
+ my $out = $self->common_facet_data;
47
+
48
+ $out->{about}->{details} = 'pass';
49
+
50
+ $out->{assert} = {pass => 1, details => $self->{+NAME}};
51
+
52
+ $out->{info} = [map {{ %{$_} }} @{$self->{+INFO}}] if $self->{+INFO};
53
+
54
+ return $out;
55
+ }
56
+
57
+ 1;
58
+
59
+ __END__
60
+
61
+ =pod
62
+
63
+ =encoding UTF-8
64
+
65
+ =head1 NAME
66
+
67
+ Test2::Event::Pass - Event for a simple passing assertion
68
+
69
+ =head1 DESCRIPTION
70
+
71
+ This is an optimal representation of a passing assertion.
72
+
73
+ =head1 SYNOPSIS
74
+
75
+ use Test2::API qw/context/;
76
+
77
+ sub pass {
78
+ my ($name) = @_;
79
+ my $ctx = context();
80
+ $ctx->pass($name);
81
+ $ctx->release;
82
+ }
83
+
84
+ =head1 SOURCE
85
+
86
+ The source code repository for Test2 can be found at
87
+ F<http://github.com/Test-More/test-more/>.
88
+
89
+ =head1 MAINTAINERS
90
+
91
+ =over 4
92
+
93
+ =item Chad Granum E<lt>[email protected]<gt>
94
+
95
+ =back
96
+
97
+ =head1 AUTHORS
98
+
99
+ =over 4
100
+
101
+ =item Chad Granum E<lt>[email protected]<gt>
102
+
103
+ =back
104
+
105
+ =head1 COPYRIGHT
106
+
107
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
108
+
109
+ This program is free software; you can redistribute it and/or
110
+ modify it under the same terms as Perl itself.
111
+
112
+ See F<http://dev.perl.org/licenses/>
113
+
114
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Plan.pm ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Plan;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
9
+ use Test2::Util::HashBase qw{max directive reason};
10
+
11
+ use Carp qw/confess/;
12
+
13
+ my %ALLOWED = (
14
+ 'SKIP' => 1,
15
+ 'NO PLAN' => 1,
16
+ );
17
+
18
+ sub init {
19
+ if ($_[0]->{+DIRECTIVE}) {
20
+ $_[0]->{+DIRECTIVE} = 'SKIP' if $_[0]->{+DIRECTIVE} eq 'skip_all';
21
+ $_[0]->{+DIRECTIVE} = 'NO PLAN' if $_[0]->{+DIRECTIVE} eq 'no_plan';
22
+
23
+ confess "'" . $_[0]->{+DIRECTIVE} . "' is not a valid plan directive"
24
+ unless $ALLOWED{$_[0]->{+DIRECTIVE}};
25
+ }
26
+ else {
27
+ confess "Cannot have a reason without a directive!"
28
+ if defined $_[0]->{+REASON};
29
+
30
+ confess "No number of tests specified"
31
+ unless defined $_[0]->{+MAX};
32
+
33
+ confess "Plan test count '" . $_[0]->{+MAX} . "' does not appear to be a valid positive integer"
34
+ unless $_[0]->{+MAX} =~ m/^\d+$/;
35
+
36
+ $_[0]->{+DIRECTIVE} = '';
37
+ }
38
+ }
39
+
40
+ sub sets_plan {
41
+ my $self = shift;
42
+ return (
43
+ $self->{+MAX},
44
+ $self->{+DIRECTIVE},
45
+ $self->{+REASON},
46
+ );
47
+ }
48
+
49
+ sub terminate {
50
+ my $self = shift;
51
+ # On skip_all we want to terminate the hub
52
+ return 0 if $self->{+DIRECTIVE} && $self->{+DIRECTIVE} eq 'SKIP';
53
+ return undef;
54
+ }
55
+
56
+ sub summary {
57
+ my $self = shift;
58
+ my $max = $self->{+MAX};
59
+ my $directive = $self->{+DIRECTIVE};
60
+ my $reason = $self->{+REASON};
61
+
62
+ return "Plan is $max assertions"
63
+ if $max || !$directive;
64
+
65
+ return "Plan is '$directive', $reason"
66
+ if $reason;
67
+
68
+ return "Plan is '$directive'";
69
+ }
70
+
71
+ sub facet_data {
72
+ my $self = shift;
73
+
74
+ my $out = $self->common_facet_data;
75
+
76
+ $out->{control}->{terminate} = $self->{+DIRECTIVE} eq 'SKIP' ? 0 : undef
77
+ unless defined $out->{control}->{terminate};
78
+
79
+ $out->{plan} = {count => $self->{+MAX}};
80
+ $out->{plan}->{details} = $self->{+REASON} if defined $self->{+REASON};
81
+
82
+ if (my $dir = $self->{+DIRECTIVE}) {
83
+ $out->{plan}->{skip} = 1 if $dir eq 'SKIP';
84
+ $out->{plan}->{none} = 1 if $dir eq 'NO PLAN';
85
+ }
86
+
87
+ return $out;
88
+ }
89
+
90
+
91
+ 1;
92
+
93
+ __END__
94
+
95
+ =pod
96
+
97
+ =encoding UTF-8
98
+
99
+ =head1 NAME
100
+
101
+ Test2::Event::Plan - The event of a plan
102
+
103
+ =head1 DESCRIPTION
104
+
105
+ Plan events are fired off whenever a plan is declared, done testing is called,
106
+ or a subtext completes.
107
+
108
+ =head1 SYNOPSIS
109
+
110
+ use Test2::API qw/context/;
111
+ use Test2::Event::Plan;
112
+
113
+ my $ctx = context();
114
+
115
+ # Plan for 10 tests to run
116
+ my $event = $ctx->plan(10);
117
+
118
+ # Plan to skip all tests (will exit 0)
119
+ $ctx->plan(0, skip_all => "These tests need to be skipped");
120
+
121
+ =head1 ACCESSORS
122
+
123
+ =over 4
124
+
125
+ =item $num = $plan->max
126
+
127
+ Get the number of expected tests
128
+
129
+ =item $dir = $plan->directive
130
+
131
+ Get the directive (such as TODO, skip_all, or no_plan).
132
+
133
+ =item $reason = $plan->reason
134
+
135
+ Get the reason for the directive.
136
+
137
+ =back
138
+
139
+ =head1 SOURCE
140
+
141
+ The source code repository for Test2 can be found at
142
+ F<http://github.com/Test-More/test-more/>.
143
+
144
+ =head1 MAINTAINERS
145
+
146
+ =over 4
147
+
148
+ =item Chad Granum E<lt>[email protected]<gt>
149
+
150
+ =back
151
+
152
+ =head1 AUTHORS
153
+
154
+ =over 4
155
+
156
+ =item Chad Granum E<lt>[email protected]<gt>
157
+
158
+ =back
159
+
160
+ =head1 COPYRIGHT
161
+
162
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
163
+
164
+ This program is free software; you can redistribute it and/or
165
+ modify it under the same terms as Perl itself.
166
+
167
+ See F<http://dev.perl.org/licenses/>
168
+
169
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Skip.pm ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Skip;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ BEGIN { require Test2::Event::Ok; our @ISA = qw(Test2::Event::Ok) }
9
+ use Test2::Util::HashBase qw{reason};
10
+
11
+ sub init {
12
+ my $self = shift;
13
+ $self->SUPER::init;
14
+ $self->{+EFFECTIVE_PASS} = 1;
15
+ }
16
+
17
+ sub causes_fail { 0 }
18
+
19
+ sub summary {
20
+ my $self = shift;
21
+ my $out = $self->SUPER::summary(@_);
22
+
23
+ if (my $reason = $self->reason) {
24
+ $out .= " (SKIP: $reason)";
25
+ }
26
+ else {
27
+ $out .= " (SKIP)";
28
+ }
29
+
30
+ return $out;
31
+ }
32
+
33
+ sub extra_amnesty {
34
+ my $self = shift;
35
+
36
+ my @out;
37
+
38
+ push @out => {
39
+ tag => 'TODO',
40
+ details => $self->{+TODO},
41
+ } if defined $self->{+TODO};
42
+
43
+ push @out => {
44
+ tag => 'skip',
45
+ details => $self->{+REASON},
46
+ inherited => 0,
47
+ };
48
+
49
+ return @out;
50
+ }
51
+
52
+ 1;
53
+
54
+ __END__
55
+
56
+ =pod
57
+
58
+ =encoding UTF-8
59
+
60
+ =head1 NAME
61
+
62
+ Test2::Event::Skip - Skip event type
63
+
64
+ =head1 DESCRIPTION
65
+
66
+ Skip events bump test counts just like L<Test2::Event::Ok> events, but
67
+ they can never fail.
68
+
69
+ =head1 SYNOPSIS
70
+
71
+ use Test2::API qw/context/;
72
+ use Test2::Event::Skip;
73
+
74
+ my $ctx = context();
75
+ my $event = $ctx->skip($name, $reason);
76
+
77
+ or:
78
+
79
+ my $ctx = context();
80
+ my $event = $ctx->send_event(
81
+ 'Skip',
82
+ name => $name,
83
+ reason => $reason,
84
+ );
85
+
86
+ =head1 ACCESSORS
87
+
88
+ =over 4
89
+
90
+ =item $reason = $e->reason
91
+
92
+ The original true/false value of whatever was passed into the event (but
93
+ reduced down to 1 or 0).
94
+
95
+ =back
96
+
97
+ =head1 SOURCE
98
+
99
+ The source code repository for Test2 can be found at
100
+ F<http://github.com/Test-More/test-more/>.
101
+
102
+ =head1 MAINTAINERS
103
+
104
+ =over 4
105
+
106
+ =item Chad Granum E<lt>[email protected]<gt>
107
+
108
+ =back
109
+
110
+ =head1 AUTHORS
111
+
112
+ =over 4
113
+
114
+ =item Chad Granum E<lt>[email protected]<gt>
115
+
116
+ =back
117
+
118
+ =head1 COPYRIGHT
119
+
120
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
121
+
122
+ This program is free software; you can redistribute it and/or
123
+ modify it under the same terms as Perl itself.
124
+
125
+ See F<http://www.perl.com/perl/misc/Artistic.html>
126
+
127
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Subtest.pm ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Subtest;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ BEGIN { require Test2::Event::Ok; our @ISA = qw(Test2::Event::Ok) }
8
+ use Test2::Util::HashBase qw{subevents buffered subtest_id subtest_uuid};
9
+
10
+ sub init {
11
+ my $self = shift;
12
+ $self->SUPER::init();
13
+ $self->{+SUBEVENTS} ||= [];
14
+ if ($self->{+EFFECTIVE_PASS}) {
15
+ $_->set_effective_pass(1) for grep { $_->can('effective_pass') } @{$self->{+SUBEVENTS}};
16
+ }
17
+ }
18
+
19
+ {
20
+ no warnings 'redefine';
21
+
22
+ sub set_subevents {
23
+ my $self = shift;
24
+ my @subevents = @_;
25
+
26
+ if ($self->{+EFFECTIVE_PASS}) {
27
+ $_->set_effective_pass(1) for grep { $_->can('effective_pass') } @subevents;
28
+ }
29
+
30
+ $self->{+SUBEVENTS} = \@subevents;
31
+ }
32
+
33
+ sub set_effective_pass {
34
+ my $self = shift;
35
+ my ($pass) = @_;
36
+
37
+ if ($pass) {
38
+ $_->set_effective_pass(1) for grep { $_->can('effective_pass') } @{$self->{+SUBEVENTS}};
39
+ }
40
+ elsif ($self->{+EFFECTIVE_PASS} && !$pass) {
41
+ for my $s (grep { $_->can('effective_pass') } @{$self->{+SUBEVENTS}}) {
42
+ $_->set_effective_pass(0) unless $s->can('todo') && defined $s->todo;
43
+ }
44
+ }
45
+
46
+ $self->{+EFFECTIVE_PASS} = $pass;
47
+ }
48
+ }
49
+
50
+ sub summary {
51
+ my $self = shift;
52
+
53
+ my $name = $self->{+NAME} || "Nameless Subtest";
54
+
55
+ my $todo = $self->{+TODO};
56
+ if ($todo) {
57
+ $name .= " (TODO: $todo)";
58
+ }
59
+ elsif (defined $todo) {
60
+ $name .= " (TODO)";
61
+ }
62
+
63
+ return $name;
64
+ }
65
+
66
+ sub facet_data {
67
+ my $self = shift;
68
+
69
+ my $out = $self->SUPER::facet_data();
70
+
71
+ $out->{parent} = {
72
+ hid => $self->subtest_id,
73
+ children => [map {$_->facet_data} @{$self->{+SUBEVENTS}}],
74
+ buffered => $self->{+BUFFERED},
75
+ };
76
+
77
+ return $out;
78
+ }
79
+
80
+ sub add_amnesty {
81
+ my $self = shift;
82
+
83
+ for my $am (@_) {
84
+ $am = {%$am} if ref($am) ne 'ARRAY';
85
+ $am = Test2::EventFacet::Amnesty->new($am);
86
+
87
+ push @{$self->{+AMNESTY}} => $am;
88
+
89
+ for my $e (@{$self->{+SUBEVENTS}}) {
90
+ $e->add_amnesty($am->clone(inherited => 1));
91
+ }
92
+ }
93
+ }
94
+
95
+
96
+ 1;
97
+
98
+ __END__
99
+
100
+ =pod
101
+
102
+ =encoding UTF-8
103
+
104
+ =head1 NAME
105
+
106
+ Test2::Event::Subtest - Event for subtest types
107
+
108
+ =head1 DESCRIPTION
109
+
110
+ This class represents a subtest. This class is a subclass of
111
+ L<Test2::Event::Ok>.
112
+
113
+ =head1 ACCESSORS
114
+
115
+ This class inherits from L<Test2::Event::Ok>.
116
+
117
+ =over 4
118
+
119
+ =item $arrayref = $e->subevents
120
+
121
+ Returns the arrayref containing all the events from the subtest
122
+
123
+ =item $bool = $e->buffered
124
+
125
+ True if the subtest is buffered, that is all subevents render at once. If this
126
+ is false it means all subevents render as they are produced.
127
+
128
+ =back
129
+
130
+ =head1 SOURCE
131
+
132
+ The source code repository for Test2 can be found at
133
+ F<http://github.com/Test-More/test-more/>.
134
+
135
+ =head1 MAINTAINERS
136
+
137
+ =over 4
138
+
139
+ =item Chad Granum E<lt>[email protected]<gt>
140
+
141
+ =back
142
+
143
+ =head1 AUTHORS
144
+
145
+ =over 4
146
+
147
+ =item Chad Granum E<lt>[email protected]<gt>
148
+
149
+ =back
150
+
151
+ =head1 COPYRIGHT
152
+
153
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
154
+
155
+ This program is free software; you can redistribute it and/or
156
+ modify it under the same terms as Perl itself.
157
+
158
+ See F<http://dev.perl.org/licenses/>
159
+
160
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/V2.pm ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::V2;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ use Scalar::Util qw/reftype/;
8
+ use Carp qw/croak/;
9
+
10
+ BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
11
+
12
+ use Test2::Util::Facets2Legacy qw{
13
+ causes_fail diagnostics global increments_count no_display sets_plan
14
+ subtest_id summary terminate
15
+ };
16
+
17
+ use Test2::Util::HashBase qw/-about/;
18
+
19
+ sub non_facet_keys {
20
+ return (
21
+ +UUID,
22
+ Test2::Util::ExternalMeta::META_KEY(),
23
+ );
24
+ }
25
+
26
+ sub init {
27
+ my $self = shift;
28
+
29
+ my $uuid;
30
+ if ($uuid = $self->{+UUID}) {
31
+ croak "uuid '$uuid' passed to constructor, but uuid '$self->{+ABOUT}->{uuid}' is already set in the 'about' facet"
32
+ if $self->{+ABOUT}->{uuid} && $self->{+ABOUT}->{uuid} ne $uuid;
33
+
34
+ $self->{+ABOUT}->{uuid} = $uuid;
35
+ }
36
+ elsif ($uuid = $self->{+ABOUT}->{uuid}) {
37
+ $self->SUPER::set_uuid($uuid);
38
+ }
39
+
40
+ # Clone the trace, make sure it is blessed
41
+ if (my $trace = $self->{+TRACE}) {
42
+ $self->{+TRACE} = Test2::EventFacet::Trace->new(%$trace);
43
+ }
44
+ }
45
+
46
+ sub set_uuid {
47
+ my $self = shift;
48
+ my ($uuid) = @_;
49
+ $self->{+ABOUT}->{uuid} = $uuid;
50
+ $self->SUPER::set_uuid($uuid);
51
+ }
52
+
53
+ sub facet_data {
54
+ my $self = shift;
55
+ my $f = { %{$self} };
56
+
57
+ delete $f->{$_} for $self->non_facet_keys;
58
+
59
+ my %out;
60
+ for my $k (keys %$f) {
61
+ next if substr($k, 0, 1) eq '_';
62
+
63
+ my $data = $f->{$k};
64
+ my $is_list = reftype($data) eq 'ARRAY';
65
+ $out{$k} = $is_list ? [ map { {%{$_}} } @$data ] : {%$data};
66
+ }
67
+
68
+ if (my $meta = $self->meta_facet_data) {
69
+ $out{meta} = {%$meta, %{$out{meta} || {}}};
70
+ }
71
+
72
+ return \%out;
73
+ }
74
+
75
+ 1;
76
+
77
+ __END__
78
+
79
+ =pod
80
+
81
+ =encoding UTF-8
82
+
83
+ =head1 NAME
84
+
85
+ Test2::Event::V2 - Second generation event.
86
+
87
+ =head1 DESCRIPTION
88
+
89
+ This is the event type that should be used instead of L<Test2::Event> or its
90
+ legacy subclasses.
91
+
92
+ =head1 SYNOPSIS
93
+
94
+ =head2 USING A CONTEXT
95
+
96
+ use Test2::API qw/context/;
97
+
98
+ sub my_tool {
99
+ my $ctx = context();
100
+
101
+ my $event = $ctx->send_ev2(info => [{tag => 'NOTE', details => "This is a note"}]);
102
+
103
+ $ctx->release;
104
+
105
+ return $event;
106
+ }
107
+
108
+ =head2 USING THE CONSTRUCTOR
109
+
110
+ use Test2::Event::V2;
111
+
112
+ my $e = Test2::Event::V2->new(
113
+ trace => {frame => [$PKG, $FILE, $LINE, $SUBNAME]},
114
+ info => [{tag => 'NOTE', details => "This is a note"}],
115
+ );
116
+
117
+ =head1 METHODS
118
+
119
+ This class inherits from L<Test2::Event>.
120
+
121
+ =over 4
122
+
123
+ =item $fd = $e->facet_data()
124
+
125
+ This will return a hashref of facet data. Each facet hash will be a shallow
126
+ copy of the original.
127
+
128
+ =item $about = $e->about()
129
+
130
+ This will return the 'about' facet hashref.
131
+
132
+ B<NOTE:> This will return the internal hashref, not a copy.
133
+
134
+ =item $trace = $e->trace()
135
+
136
+ This will return the 'trace' facet, normally blessed (but this is not enforced
137
+ when the trace is set using C<set_trace()>.
138
+
139
+ B<NOTE:> This will return the internal trace, not a copy.
140
+
141
+ =back
142
+
143
+ =head2 MUTATION
144
+
145
+ =over 4
146
+
147
+ =item $e->add_amnesty({...})
148
+
149
+ Inherited from L<Test2::Event>. This can be used to add 'amnesty' facets to an
150
+ existing event. Each new item is added to the B<END> of the list.
151
+
152
+ B<NOTE:> Items B<ARE> blessed when added.
153
+
154
+ =item $e->add_hub({...})
155
+
156
+ Inherited from L<Test2::Event>. This is used by hubs to stamp events as they
157
+ pass through. New items are added to the B<START> of the list.
158
+
159
+ B<NOTE:> Items B<ARE NOT> blessed when added.
160
+
161
+ =item $e->set_uuid($UUID)
162
+
163
+ Inherited from L<Test2::Event>, overridden to also vivify/mutate the 'about'
164
+ facet.
165
+
166
+ =item $e->set_trace($trace)
167
+
168
+ Inherited from L<Test2::Event> which allows you to change the trace.
169
+
170
+ B<Note:> This method does not bless/clone the trace for you. Many things will
171
+ expect the trace to be blessed, so you should probably do that.
172
+
173
+ =back
174
+
175
+ =head2 LEGACY SUPPORT METHODS
176
+
177
+ These are all imported from L<Test2::Util::Facets2Legacy>, see that module or
178
+ L<Test2::Event> for documentation on what they do.
179
+
180
+ =over 4
181
+
182
+ =item causes_fail
183
+
184
+ =item diagnostics
185
+
186
+ =item global
187
+
188
+ =item increments_count
189
+
190
+ =item no_display
191
+
192
+ =item sets_plan
193
+
194
+ =item subtest_id
195
+
196
+ =item summary
197
+
198
+ =item terminate
199
+
200
+ =back
201
+
202
+ =head1 THIRD PARTY META-DATA
203
+
204
+ This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
205
+ way for you to attach meta-data to instances of this class. This is useful for
206
+ tools, plugins, and other extensions.
207
+
208
+ =head1 SOURCE
209
+
210
+ The source code repository for Test2 can be found at
211
+ F<http://github.com/Test-More/test-more/>.
212
+
213
+ =head1 MAINTAINERS
214
+
215
+ =over 4
216
+
217
+ =item Chad Granum E<lt>[email protected]<gt>
218
+
219
+ =back
220
+
221
+ =head1 AUTHORS
222
+
223
+ =over 4
224
+
225
+ =item Chad Granum E<lt>[email protected]<gt>
226
+
227
+ =back
228
+
229
+ =head1 COPYRIGHT
230
+
231
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
232
+
233
+ This program is free software; you can redistribute it and/or
234
+ modify it under the same terms as Perl itself.
235
+
236
+ See F<http://dev.perl.org/licenses/>
237
+
238
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Event/Waiting.pm ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Event::Waiting;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+
8
+ BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
9
+ use Test2::Util::HashBase;
10
+
11
+ sub global { 1 };
12
+
13
+ sub summary { "IPC is waiting for children to finish..." }
14
+
15
+ sub facet_data {
16
+ my $self = shift;
17
+
18
+ my $out = $self->common_facet_data;
19
+
20
+ push @{$out->{info}} => {
21
+ tag => 'INFO',
22
+ debug => 0,
23
+ details => $self->summary,
24
+ };
25
+
26
+ return $out;
27
+ }
28
+
29
+ 1;
30
+
31
+ __END__
32
+
33
+ =pod
34
+
35
+ =encoding UTF-8
36
+
37
+ =head1 NAME
38
+
39
+ Test2::Event::Waiting - Tell all procs/threads it is time to be done
40
+
41
+ =head1 DESCRIPTION
42
+
43
+ This event has no data of its own. This event is sent out by the IPC system
44
+ when the main process/thread is ready to end.
45
+
46
+ =head1 SOURCE
47
+
48
+ The source code repository for Test2 can be found at
49
+ F<http://github.com/Test-More/test-more/>.
50
+
51
+ =head1 MAINTAINERS
52
+
53
+ =over 4
54
+
55
+ =item Chad Granum E<lt>[email protected]<gt>
56
+
57
+ =back
58
+
59
+ =head1 AUTHORS
60
+
61
+ =over 4
62
+
63
+ =item Chad Granum E<lt>[email protected]<gt>
64
+
65
+ =back
66
+
67
+ =head1 COPYRIGHT
68
+
69
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
70
+
71
+ This program is free software; you can redistribute it and/or
72
+ modify it under the same terms as Perl itself.
73
+
74
+ See F<http://dev.perl.org/licenses/>
75
+
76
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/About.pm ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::About;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
8
+ use Test2::Util::HashBase qw{ -package -no_display -uuid -eid };
9
+
10
+ 1;
11
+
12
+ __END__
13
+
14
+ =pod
15
+
16
+ =encoding UTF-8
17
+
18
+ =head1 NAME
19
+
20
+ Test2::EventFacet::About - Facet with event details.
21
+
22
+ =head1 DESCRIPTION
23
+
24
+ This facet has information about the event, such as event package.
25
+
26
+ =head1 FIELDS
27
+
28
+ =over 4
29
+
30
+ =item $string = $about->{details}
31
+
32
+ =item $string = $about->details()
33
+
34
+ Summary about the event.
35
+
36
+ =item $package = $about->{package}
37
+
38
+ =item $package = $about->package()
39
+
40
+ Event package name.
41
+
42
+ =item $bool = $about->{no_display}
43
+
44
+ =item $bool = $about->no_display()
45
+
46
+ True if the event should be skipped by formatters.
47
+
48
+ =item $uuid = $about->{uuid}
49
+
50
+ =item $uuid = $about->uuid()
51
+
52
+ Will be set to a uuid if uuid tagging was enabled.
53
+
54
+ =item $uuid = $about->{eid}
55
+
56
+ =item $uuid = $about->eid()
57
+
58
+ A unique (for the test job) identifier for the event.
59
+
60
+ =back
61
+
62
+ =head1 SOURCE
63
+
64
+ The source code repository for Test2 can be found at
65
+ F<http://github.com/Test-More/test-more/>.
66
+
67
+ =head1 MAINTAINERS
68
+
69
+ =over 4
70
+
71
+ =item Chad Granum E<lt>[email protected]<gt>
72
+
73
+ =back
74
+
75
+ =head1 AUTHORS
76
+
77
+ =over 4
78
+
79
+ =item Chad Granum E<lt>[email protected]<gt>
80
+
81
+ =back
82
+
83
+ =head1 COPYRIGHT
84
+
85
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
86
+
87
+ This program is free software; you can redistribute it and/or
88
+ modify it under the same terms as Perl itself.
89
+
90
+ See F<http://dev.perl.org/licenses/>
91
+
92
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Amnesty.pm ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Amnesty;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ sub is_list { 1 }
8
+
9
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
10
+ use Test2::Util::HashBase qw{ -tag -inherited };
11
+
12
+ 1;
13
+
14
+ __END__
15
+
16
+ =pod
17
+
18
+ =encoding UTF-8
19
+
20
+ =head1 NAME
21
+
22
+ Test2::EventFacet::Amnesty - Facet for assertion amnesty.
23
+
24
+ =head1 DESCRIPTION
25
+
26
+ This package represents what is expected in units of amnesty.
27
+
28
+ =head1 NOTES
29
+
30
+ This facet appears in a list instead of being a single item.
31
+
32
+ =head1 FIELDS
33
+
34
+ =over 4
35
+
36
+ =item $string = $amnesty->{details}
37
+
38
+ =item $string = $amnesty->details()
39
+
40
+ Human readable explanation of why amnesty was granted.
41
+
42
+ Example: I<Not implemented yet, will fix>
43
+
44
+ =item $short_string = $amnesty->{tag}
45
+
46
+ =item $short_string = $amnesty->tag()
47
+
48
+ Short string (usually 10 characters or less, not enforced, but may be truncated
49
+ by renderers) categorizing the amnesty.
50
+
51
+ =item $bool = $amnesty->{inherited}
52
+
53
+ =item $bool = $amnesty->inherited()
54
+
55
+ This will be true if the amnesty was granted to a parent event and inherited by
56
+ this event, which is a child, such as an assertion within a subtest that is
57
+ marked todo.
58
+
59
+ =back
60
+
61
+ =head1 SOURCE
62
+
63
+ The source code repository for Test2 can be found at
64
+ F<http://github.com/Test-More/test-more/>.
65
+
66
+ =head1 MAINTAINERS
67
+
68
+ =over 4
69
+
70
+ =item Chad Granum E<lt>[email protected]<gt>
71
+
72
+ =back
73
+
74
+ =head1 AUTHORS
75
+
76
+ =over 4
77
+
78
+ =item Chad Granum E<lt>[email protected]<gt>
79
+
80
+ =back
81
+
82
+ =head1 COPYRIGHT
83
+
84
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
85
+
86
+ This program is free software; you can redistribute it and/or
87
+ modify it under the same terms as Perl itself.
88
+
89
+ See F<http://dev.perl.org/licenses/>
90
+
91
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Assert.pm ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Assert;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
8
+ use Test2::Util::HashBase qw{ -pass -no_debug -number };
9
+
10
+ 1;
11
+
12
+ __END__
13
+
14
+ =pod
15
+
16
+ =encoding UTF-8
17
+
18
+ =head1 NAME
19
+
20
+ Test2::EventFacet::Assert - Facet representing an assertion.
21
+
22
+ =head1 DESCRIPTION
23
+
24
+ The assertion facet is provided by any event representing an assertion that was
25
+ made.
26
+
27
+ =head1 FIELDS
28
+
29
+ =over 4
30
+
31
+ =item $string = $assert->{details}
32
+
33
+ =item $string = $assert->details()
34
+
35
+ Human readable description of the assertion.
36
+
37
+ =item $bool = $assert->{pass}
38
+
39
+ =item $bool = $assert->pass()
40
+
41
+ True if the assertion passed.
42
+
43
+ =item $bool = $assert->{no_debug}
44
+
45
+ =item $bool = $assert->no_debug()
46
+
47
+ Set this to true if you have provided custom diagnostics and do not want the
48
+ defaults to be displayed.
49
+
50
+ =item $int = $assert->{number}
51
+
52
+ =item $int = $assert->number()
53
+
54
+ (Optional) assertion number. This may be omitted or ignored. This is usually
55
+ only useful when parsing/processing TAP.
56
+
57
+ B<Note>: This is not set by the Test2 system, assertion number is not known
58
+ until AFTER the assertion has been processed. This attribute is part of the
59
+ spec only for harnesses.
60
+
61
+ =back
62
+
63
+ =head1 SOURCE
64
+
65
+ The source code repository for Test2 can be found at
66
+ F<http://github.com/Test-More/test-more/>.
67
+
68
+ =head1 MAINTAINERS
69
+
70
+ =over 4
71
+
72
+ =item Chad Granum E<lt>[email protected]<gt>
73
+
74
+ =back
75
+
76
+ =head1 AUTHORS
77
+
78
+ =over 4
79
+
80
+ =item Chad Granum E<lt>[email protected]<gt>
81
+
82
+ =back
83
+
84
+ =head1 COPYRIGHT
85
+
86
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
87
+
88
+ This program is free software; you can redistribute it and/or
89
+ modify it under the same terms as Perl itself.
90
+
91
+ See F<http://dev.perl.org/licenses/>
92
+
93
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Control.pm ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Control;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
8
+ use Test2::Util::HashBase qw{ -global -terminate -halt -has_callback -encoding };
9
+
10
+ 1;
11
+
12
+ __END__
13
+
14
+ =pod
15
+
16
+ =encoding UTF-8
17
+
18
+ =head1 NAME
19
+
20
+ Test2::EventFacet::Control - Facet for hub actions and behaviors.
21
+
22
+ =head1 DESCRIPTION
23
+
24
+ This facet is used when the event needs to give instructions to the Test2
25
+ internals.
26
+
27
+ =head1 FIELDS
28
+
29
+ =over 4
30
+
31
+ =item $string = $control->{details}
32
+
33
+ =item $string = $control->details()
34
+
35
+ Human readable explanation for the special behavior.
36
+
37
+ =item $bool = $control->{global}
38
+
39
+ =item $bool = $control->global()
40
+
41
+ True if the event is global in nature and should be seen by all hubs.
42
+
43
+ =item $exit = $control->{terminate}
44
+
45
+ =item $exit = $control->terminate()
46
+
47
+ Defined if the test should immediately exit, the value is the exit code and may
48
+ be C<0>.
49
+
50
+ =item $bool = $control->{halt}
51
+
52
+ =item $bool = $control->halt()
53
+
54
+ True if all testing should be halted immediately.
55
+
56
+ =item $bool = $control->{has_callback}
57
+
58
+ =item $bool = $control->has_callback()
59
+
60
+ True if the C<callback($hub)> method on the event should be called.
61
+
62
+ =item $encoding = $control->{encoding}
63
+
64
+ =item $encoding = $control->encoding()
65
+
66
+ This can be used to change the encoding from this event onward.
67
+
68
+ =back
69
+
70
+ =head1 SOURCE
71
+
72
+ The source code repository for Test2 can be found at
73
+ F<http://github.com/Test-More/test-more/>.
74
+
75
+ =head1 MAINTAINERS
76
+
77
+ =over 4
78
+
79
+ =item Chad Granum E<lt>[email protected]<gt>
80
+
81
+ =back
82
+
83
+ =head1 AUTHORS
84
+
85
+ =over 4
86
+
87
+ =item Chad Granum E<lt>[email protected]<gt>
88
+
89
+ =back
90
+
91
+ =head1 COPYRIGHT
92
+
93
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
94
+
95
+ This program is free software; you can redistribute it and/or
96
+ modify it under the same terms as Perl itself.
97
+
98
+ See F<http://dev.perl.org/licenses/>
99
+
100
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Error.pm ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Error;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ sub facet_key { 'errors' }
8
+ sub is_list { 1 }
9
+
10
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
11
+ use Test2::Util::HashBase qw{ -tag -fail };
12
+
13
+ 1;
14
+
15
+ __END__
16
+
17
+ =pod
18
+
19
+ =encoding UTF-8
20
+
21
+ =head1 NAME
22
+
23
+ Test2::EventFacet::Error - Facet for errors that need to be shown.
24
+
25
+ =head1 DESCRIPTION
26
+
27
+ This facet is used when an event needs to convey errors.
28
+
29
+ =head1 NOTES
30
+
31
+ This facet has the hash key C<'errors'>, and is a list of facets instead of a
32
+ single item.
33
+
34
+ =head1 FIELDS
35
+
36
+ =over 4
37
+
38
+ =item $string = $error->{details}
39
+
40
+ =item $string = $error->details()
41
+
42
+ Explanation of the error, or the error itself (such as an exception). In perl
43
+ exceptions may be blessed objects, so this field may contain a blessed object.
44
+
45
+ =item $short_string = $error->{tag}
46
+
47
+ =item $short_string = $error->tag()
48
+
49
+ Short tag to categorize the error. This is usually 10 characters or less,
50
+ formatters may truncate longer tags.
51
+
52
+ =item $bool = $error->{fail}
53
+
54
+ =item $bool = $error->fail()
55
+
56
+ Not all errors are fatal, some are displayed having already been handled. Set
57
+ this to true if you want the error to cause the test to fail. Without this the
58
+ error is simply a diagnostics message that has no effect on the overall
59
+ pass/fail result.
60
+
61
+ =back
62
+
63
+ =head1 SOURCE
64
+
65
+ The source code repository for Test2 can be found at
66
+ F<http://github.com/Test-More/test-more/>.
67
+
68
+ =head1 MAINTAINERS
69
+
70
+ =over 4
71
+
72
+ =item Chad Granum E<lt>[email protected]<gt>
73
+
74
+ =back
75
+
76
+ =head1 AUTHORS
77
+
78
+ =over 4
79
+
80
+ =item Chad Granum E<lt>[email protected]<gt>
81
+
82
+ =back
83
+
84
+ =head1 COPYRIGHT
85
+
86
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
87
+
88
+ This program is free software; you can redistribute it and/or
89
+ modify it under the same terms as Perl itself.
90
+
91
+ See F<http://dev.perl.org/licenses/>
92
+
93
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Hub.pm ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Hub;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ sub is_list { 1 }
8
+ sub facet_key { 'hubs' }
9
+
10
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
11
+ use Test2::Util::HashBase qw{-pid -tid -hid -nested -buffered -uuid -ipc};
12
+
13
+ 1;
14
+
15
+ __END__
16
+
17
+ =pod
18
+
19
+ =encoding UTF-8
20
+
21
+ =head1 NAME
22
+
23
+ Test2::EventFacet::Hub - Facet for the hubs an event passes through.
24
+
25
+ =head1 DESCRIPTION
26
+
27
+ These are a record of the hubs an event passes through. Most recent hub is the
28
+ first one in the list.
29
+
30
+ =head1 FACET FIELDS
31
+
32
+ =over 4
33
+
34
+ =item $string = $trace->{details}
35
+
36
+ =item $string = $trace->details()
37
+
38
+ The hub class or subclass
39
+
40
+ =item $int = $trace->{pid}
41
+
42
+ =item $int = $trace->pid()
43
+
44
+ PID of the hub this event was sent to.
45
+
46
+ =item $int = $trace->{tid}
47
+
48
+ =item $int = $trace->tid()
49
+
50
+ The thread ID of the hub the event was sent to.
51
+
52
+ =item $hid = $trace->{hid}
53
+
54
+ =item $hid = $trace->hid()
55
+
56
+ The ID of the hub that the event was send to.
57
+
58
+ =item $huuid = $trace->{huuid}
59
+
60
+ =item $huuid = $trace->huuid()
61
+
62
+ The UUID of the hub that the event was sent to.
63
+
64
+ =item $int = $trace->{nested}
65
+
66
+ =item $int = $trace->nested()
67
+
68
+ How deeply nested the hub was.
69
+
70
+ =item $bool = $trace->{buffered}
71
+
72
+ =item $bool = $trace->buffered()
73
+
74
+ True if the event was buffered and not sent to the formatter independent of a
75
+ parent (This should never be set when nested is C<0> or C<undef>).
76
+
77
+ =back
78
+
79
+ =head1 SOURCE
80
+
81
+ The source code repository for Test2 can be found at
82
+ F<http://github.com/Test-More/test-more/>.
83
+
84
+ =head1 MAINTAINERS
85
+
86
+ =over 4
87
+
88
+ =item Chad Granum E<lt>[email protected]<gt>
89
+
90
+ =back
91
+
92
+ =head1 AUTHORS
93
+
94
+ =over 4
95
+
96
+ =item Chad Granum E<lt>[email protected]<gt>
97
+
98
+ =back
99
+
100
+ =head1 COPYRIGHT
101
+
102
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
103
+
104
+ This program is free software; you can redistribute it and/or
105
+ modify it under the same terms as Perl itself.
106
+
107
+ See F<http://dev.perl.org/licenses/>
108
+
109
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Info.pm ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Info;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ sub is_list { 1 }
8
+
9
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
10
+ use Test2::Util::HashBase qw{-tag -debug -important -table};
11
+
12
+ 1;
13
+
14
+ __END__
15
+
16
+ =pod
17
+
18
+ =encoding UTF-8
19
+
20
+ =head1 NAME
21
+
22
+ Test2::EventFacet::Info - Facet for information a developer might care about.
23
+
24
+ =head1 DESCRIPTION
25
+
26
+ This facet represents messages intended for humans that will help them either
27
+ understand a result, or diagnose a failure.
28
+
29
+ =head1 NOTES
30
+
31
+ This facet appears in a list instead of being a single item.
32
+
33
+ =head1 FIELDS
34
+
35
+ =over 4
36
+
37
+ =item $string_or_structure = $info->{details}
38
+
39
+ =item $string_or_structure = $info->details()
40
+
41
+ Human readable string or data structure, this is the information to display.
42
+ Formatters are free to render the structures however they please. This may
43
+ contain a blessed object.
44
+
45
+ If the C<table> attribute (see below) is set then a renderer may choose to
46
+ display the table instead of the details.
47
+
48
+ =item $structure = $info->{table}
49
+
50
+ =item $structure = $info->table()
51
+
52
+ If the data the C<info> facet needs to convey can be represented as a table
53
+ then the data may be placed in this attribute in a more raw form for better
54
+ display. The data must also be represented in the C<details> attribute for
55
+ renderers which do not support rendering tables directly.
56
+
57
+ The table structure:
58
+
59
+ my %table = {
60
+ header => [ 'column 1 header', 'column 2 header', ... ], # Optional
61
+
62
+ rows => [
63
+ ['row 1 column 1', 'row 1, column 2', ... ],
64
+ ['row 2 column 1', 'row 2, column 2', ... ],
65
+ ...
66
+ ],
67
+
68
+ # Allow the renderer to hide empty columns when true, Optional
69
+ collapse => $BOOL,
70
+
71
+ # List by name or number columns that should never be collapsed
72
+ no_collapse => \@LIST,
73
+ }
74
+
75
+ =item $short_string = $info->{tag}
76
+
77
+ =item $short_string = $info->tag()
78
+
79
+ Short tag to categorize the info. This is usually 10 characters or less,
80
+ formatters may truncate longer tags.
81
+
82
+ =item $bool = $info->{debug}
83
+
84
+ =item $bool = $info->debug()
85
+
86
+ Set this to true if the message is critical, or explains a failure. This is
87
+ info that should be displayed by formatters even in less-verbose modes.
88
+
89
+ When false the information is not considered critical and may not be rendered
90
+ in less-verbose modes.
91
+
92
+ =item $bool = $info->{important}
93
+
94
+ =item $bool = $info->important
95
+
96
+ This should be set for non debug messages that are still important enough to
97
+ show when a formatter is in quiet mode. A formatter should send these to STDOUT
98
+ not STDERR, but should show them even in non-verbose mode.
99
+
100
+ =back
101
+
102
+ =head1 SOURCE
103
+
104
+ The source code repository for Test2 can be found at
105
+ F<http://github.com/Test-More/test-more/>.
106
+
107
+ =head1 MAINTAINERS
108
+
109
+ =over 4
110
+
111
+ =item Chad Granum E<lt>[email protected]<gt>
112
+
113
+ =back
114
+
115
+ =head1 AUTHORS
116
+
117
+ =over 4
118
+
119
+ =item Chad Granum E<lt>[email protected]<gt>
120
+
121
+ =back
122
+
123
+ =head1 COPYRIGHT
124
+
125
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
126
+
127
+ This program is free software; you can redistribute it and/or
128
+ modify it under the same terms as Perl itself.
129
+
130
+ See F<http://dev.perl.org/licenses/>
131
+
132
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Meta.pm ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Meta;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
8
+ use vars qw/$AUTOLOAD/;
9
+
10
+ # replace set_details
11
+ {
12
+ no warnings 'redefine';
13
+ sub set_details { $_[0]->{'set_details'} }
14
+ }
15
+
16
+ sub can {
17
+ my $self = shift;
18
+ my ($name) = @_;
19
+
20
+ my $existing = $self->SUPER::can($name);
21
+ return $existing if $existing;
22
+
23
+ # Only vivify when called on an instance, do not vivify for a class. There
24
+ # are a lot of magic class methods used in things like serialization (or
25
+ # the forks.pm module) which cause problems when vivified.
26
+ return undef unless ref($self);
27
+
28
+ my $sub = sub { $_[0]->{$name} };
29
+ {
30
+ no strict 'refs';
31
+ *$name = $sub;
32
+ }
33
+
34
+ return $sub;
35
+ }
36
+
37
+ sub AUTOLOAD {
38
+ my $name = $AUTOLOAD;
39
+ $name =~ s/^.*:://g;
40
+ my $sub = $_[0]->can($name);
41
+ goto &$sub;
42
+ }
43
+
44
+ 1;
45
+
46
+ __END__
47
+
48
+ =pod
49
+
50
+ =encoding UTF-8
51
+
52
+ =head1 NAME
53
+
54
+ Test2::EventFacet::Meta - Facet for meta-data
55
+
56
+ =head1 DESCRIPTION
57
+
58
+ This facet can contain any random meta-data that has been attached to the
59
+ event.
60
+
61
+ =head1 METHODS AND FIELDS
62
+
63
+ Any/all fields and accessors are autovivified into existence. There is no way
64
+ to know what metadata may be added, so any is allowed.
65
+
66
+ =over 4
67
+
68
+ =item $anything = $meta->{anything}
69
+
70
+ =item $anything = $meta->anything()
71
+
72
+ =back
73
+
74
+ =head1 SOURCE
75
+
76
+ The source code repository for Test2 can be found at
77
+ F<http://github.com/Test-More/test-more/>.
78
+
79
+ =head1 MAINTAINERS
80
+
81
+ =over 4
82
+
83
+ =item Chad Granum E<lt>[email protected]<gt>
84
+
85
+ =back
86
+
87
+ =head1 AUTHORS
88
+
89
+ =over 4
90
+
91
+ =item Chad Granum E<lt>[email protected]<gt>
92
+
93
+ =back
94
+
95
+ =head1 COPYRIGHT
96
+
97
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
98
+
99
+ This program is free software; you can redistribute it and/or
100
+ modify it under the same terms as Perl itself.
101
+
102
+ See F<http://dev.perl.org/licenses/>
103
+
104
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Parent.pm ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Parent;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ use Carp qw/confess/;
8
+
9
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
10
+ use Test2::Util::HashBase qw{ -hid -children -buffered };
11
+
12
+ sub init {
13
+ confess "Attribute 'hid' must be set"
14
+ unless defined $_[0]->{+HID};
15
+
16
+ $_[0]->{+CHILDREN} ||= [];
17
+ }
18
+
19
+ 1;
20
+
21
+ __END__
22
+
23
+ =pod
24
+
25
+ =encoding UTF-8
26
+
27
+ =head1 NAME
28
+
29
+ Test2::EventFacet::Parent - Facet for events contains other events
30
+
31
+ =head1 DESCRIPTION
32
+
33
+ This facet is used when an event contains other events, such as a subtest.
34
+
35
+ =head1 FIELDS
36
+
37
+ =over 4
38
+
39
+ =item $string = $parent->{details}
40
+
41
+ =item $string = $parent->details()
42
+
43
+ Human readable description of the event.
44
+
45
+ =item $hid = $parent->{hid}
46
+
47
+ =item $hid = $parent->hid()
48
+
49
+ Hub ID of the hub that is represented in the parent-child relationship.
50
+
51
+ =item $arrayref = $parent->{children}
52
+
53
+ =item $arrayref = $parent->children()
54
+
55
+ Arrayref containing the facet-data hashes of events nested under this one.
56
+
57
+ I<To get the actual events you need to get them from the parent event directly>
58
+
59
+ =item $bool = $parent->{buffered}
60
+
61
+ =item $bool = $parent->buffered()
62
+
63
+ True if the subtest is buffered (meaning the formatter has probably not seen
64
+ them yet).
65
+
66
+ =back
67
+
68
+ =head1 SOURCE
69
+
70
+ The source code repository for Test2 can be found at
71
+ F<http://github.com/Test-More/test-more/>.
72
+
73
+ =head1 MAINTAINERS
74
+
75
+ =over 4
76
+
77
+ =item Chad Granum E<lt>[email protected]<gt>
78
+
79
+ =back
80
+
81
+ =head1 AUTHORS
82
+
83
+ =over 4
84
+
85
+ =item Chad Granum E<lt>[email protected]<gt>
86
+
87
+ =back
88
+
89
+ =head1 COPYRIGHT
90
+
91
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
92
+
93
+ This program is free software; you can redistribute it and/or
94
+ modify it under the same terms as Perl itself.
95
+
96
+ See F<http://dev.perl.org/licenses/>
97
+
98
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Plan.pm ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Plan;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
8
+ use Test2::Util::HashBase qw{ -count -skip -none };
9
+
10
+ 1;
11
+
12
+ __END__
13
+
14
+ =pod
15
+
16
+ =encoding UTF-8
17
+
18
+ =head1 NAME
19
+
20
+ Test2::EventFacet::Plan - Facet for setting the plan
21
+
22
+ =head1 DESCRIPTION
23
+
24
+ Events use this facet when they need to set the plan.
25
+
26
+ =head1 FIELDS
27
+
28
+ =over 4
29
+
30
+ =item $string = $plan->{details}
31
+
32
+ =item $string = $plan->details()
33
+
34
+ Human readable explanation for the plan being set. This is normally not
35
+ rendered by most formatters except when the C<skip> field is also set.
36
+
37
+ =item $positive_int = $plan->{count}
38
+
39
+ =item $positive_int = $plan->count()
40
+
41
+ Set the number of expected assertions. This should usually be set to C<0> when
42
+ C<skip> or C<none> are also set.
43
+
44
+ =item $bool = $plan->{skip}
45
+
46
+ =item $bool = $plan->skip()
47
+
48
+ When true the entire test should be skipped. This is usually paired with an
49
+ explanation in the C<details> field, and a C<control> facet that has
50
+ C<terminate> set to C<0>.
51
+
52
+ =item $bool = $plan->{none}
53
+
54
+ =item $bool = $plan->none()
55
+
56
+ This is mainly used by legacy L<Test::Builder> tests which set the plan to C<no
57
+ plan>, a construct that predates the much better C<done_testing()>.
58
+
59
+ If you are using this in non-legacy code you may need to reconsider the course
60
+ of your life, maybe a hermitage would suite you?
61
+
62
+ =back
63
+
64
+ =head1 SOURCE
65
+
66
+ The source code repository for Test2 can be found at
67
+ F<http://github.com/Test-More/test-more/>.
68
+
69
+ =head1 MAINTAINERS
70
+
71
+ =over 4
72
+
73
+ =item Chad Granum E<lt>[email protected]<gt>
74
+
75
+ =back
76
+
77
+ =head1 AUTHORS
78
+
79
+ =over 4
80
+
81
+ =item Chad Granum E<lt>[email protected]<gt>
82
+
83
+ =back
84
+
85
+ =head1 COPYRIGHT
86
+
87
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
88
+
89
+ This program is free software; you can redistribute it and/or
90
+ modify it under the same terms as Perl itself.
91
+
92
+ See F<http://dev.perl.org/licenses/>
93
+
94
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Render.pm ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Render;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ sub is_list { 1 }
8
+
9
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
10
+ use Test2::Util::HashBase qw{ -tag -facet -mode };
11
+
12
+ 1;
13
+
14
+ __END__
15
+
16
+ =pod
17
+
18
+ =encoding UTF-8
19
+
20
+ =head1 NAME
21
+
22
+ Test2::EventFacet::Render - Facet that dictates how to render an event.
23
+
24
+ =head1 DESCRIPTION
25
+
26
+ This facet is used to dictate how the event should be rendered by the standard
27
+ test2 rendering tools. If this facet is present then ONLY what is specified by
28
+ it will be rendered. It is assumed that anything important or note-worthy will
29
+ be present here, no other facets will be considered for rendering/display.
30
+
31
+ This facet is a list type, you can add as many items as needed.
32
+
33
+ =head1 FIELDS
34
+
35
+ =over 4
36
+
37
+ =item $string = $render->[#]->{details}
38
+
39
+ =item $string = $render->[#]->details()
40
+
41
+ Human readable text for display.
42
+
43
+ =item $string = $render->[#]->{tag}
44
+
45
+ =item $string = $render->[#]->tag()
46
+
47
+ Tag that should prefix/identify the main text.
48
+
49
+ =item $string = $render->[#]->{facet}
50
+
51
+ =item $string = $render->[#]->facet()
52
+
53
+ Optional, if the display text was generated from another facet this should
54
+ state what facet it was.
55
+
56
+ =item $mode = $render->[#]->{mode}
57
+
58
+ =item $mode = $render->[#]->mode()
59
+
60
+ =over 4
61
+
62
+ =item calculated
63
+
64
+ Calculated means the facet was generated from another facet. Calculated facets
65
+ may be cleared and regenerated whenever the event state changes.
66
+
67
+ =item replace
68
+
69
+ Replace means the facet is intended to replace the normal rendering of the
70
+ event.
71
+
72
+ =back
73
+
74
+ =back
75
+
76
+ =head1 SOURCE
77
+
78
+ The source code repository for Test2 can be found at
79
+ F<http://github.com/Test-More/test-more/>.
80
+
81
+ =head1 MAINTAINERS
82
+
83
+ =over 4
84
+
85
+ =item Chad Granum E<lt>[email protected]<gt>
86
+
87
+ =back
88
+
89
+ =head1 AUTHORS
90
+
91
+ =over 4
92
+
93
+ =item Chad Granum E<lt>[email protected]<gt>
94
+
95
+ =back
96
+
97
+ =head1 COPYRIGHT
98
+
99
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
100
+
101
+ This program is free software; you can redistribute it and/or
102
+ modify it under the same terms as Perl itself.
103
+
104
+ See F<http://dev.perl.org/licenses/>
105
+
106
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/EventFacet/Trace.pm ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::EventFacet::Trace;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
8
+
9
+ use Test2::Util qw/get_tid pkg_to_file gen_uid/;
10
+ use Carp qw/confess/;
11
+
12
+ use Test2::Util::HashBase qw{^frame ^pid ^tid ^cid -hid -nested details -buffered -uuid -huuid};
13
+
14
+ {
15
+ no warnings 'once';
16
+ *DETAIL = \&DETAILS;
17
+ *detail = \&details;
18
+ *set_detail = \&set_details;
19
+ }
20
+
21
+ sub init {
22
+ confess "The 'frame' attribute is required"
23
+ unless $_[0]->{+FRAME};
24
+
25
+ $_[0]->{+DETAILS} = delete $_[0]->{detail} if $_[0]->{detail};
26
+
27
+ unless (defined($_[0]->{+PID}) || defined($_[0]->{+TID}) || defined($_[0]->{+CID})) {
28
+ $_[0]->{+PID} = $$ unless defined $_[0]->{+PID};
29
+ $_[0]->{+TID} = get_tid() unless defined $_[0]->{+TID};
30
+ }
31
+ }
32
+
33
+ sub snapshot {
34
+ my ($orig, @override) = @_;
35
+ bless {%$orig, @override}, __PACKAGE__;
36
+ }
37
+
38
+ sub signature {
39
+ my $self = shift;
40
+
41
+ # Signature is only valid if all of these fields are defined, there is no
42
+ # signature if any is missing. '0' is ok, but '' is not.
43
+ return join ':' => map { (defined($_) && length($_)) ? $_ : return undef } (
44
+ $self->{+CID},
45
+ $self->{+PID},
46
+ $self->{+TID},
47
+ $self->{+FRAME}->[1],
48
+ $self->{+FRAME}->[2],
49
+ );
50
+ }
51
+
52
+ sub debug {
53
+ my $self = shift;
54
+ return $self->{+DETAILS} if $self->{+DETAILS};
55
+ my ($pkg, $file, $line) = $self->call;
56
+ return "at $file line $line";
57
+ }
58
+
59
+ sub alert {
60
+ my $self = shift;
61
+ my ($msg) = @_;
62
+ warn $msg . ' ' . $self->debug . ".\n";
63
+ }
64
+
65
+ sub throw {
66
+ my $self = shift;
67
+ my ($msg) = @_;
68
+ die $msg . ' ' . $self->debug . ".\n";
69
+ }
70
+
71
+ sub call { @{$_[0]->{+FRAME}} }
72
+
73
+ sub package { $_[0]->{+FRAME}->[0] }
74
+ sub file { $_[0]->{+FRAME}->[1] }
75
+ sub line { $_[0]->{+FRAME}->[2] }
76
+ sub subname { $_[0]->{+FRAME}->[3] }
77
+
78
+ 1;
79
+
80
+ __END__
81
+
82
+ =pod
83
+
84
+ =encoding UTF-8
85
+
86
+ =head1 NAME
87
+
88
+ Test2::EventFacet::Trace - Debug information for events
89
+
90
+ =head1 DESCRIPTION
91
+
92
+ The L<Test2::API::Context> object, as well as all L<Test2::Event> types need to
93
+ have access to information about where they were created. This object
94
+ represents that information.
95
+
96
+ =head1 SYNOPSIS
97
+
98
+ use Test2::EventFacet::Trace;
99
+
100
+ my $trace = Test2::EventFacet::Trace->new(
101
+ frame => [$package, $file, $line, $subname],
102
+ );
103
+
104
+ =head1 FACET FIELDS
105
+
106
+ =over 4
107
+
108
+ =item $string = $trace->{details}
109
+
110
+ =item $string = $trace->details()
111
+
112
+ Used as a custom trace message that will be used INSTEAD of
113
+ C<< at <FILE> line <LINE> >> when calling C<< $trace->debug >>.
114
+
115
+ =item $frame = $trace->{frame}
116
+
117
+ =item $frame = $trace->frame()
118
+
119
+ Get the call frame arrayref.
120
+
121
+ =item $int = $trace->{pid}
122
+
123
+ =item $int = $trace->pid()
124
+
125
+ The process ID in which the event was generated.
126
+
127
+ =item $int = $trace->{tid}
128
+
129
+ =item $int = $trace->tid()
130
+
131
+ The thread ID in which the event was generated.
132
+
133
+ =item $id = $trace->{cid}
134
+
135
+ =item $id = $trace->cid()
136
+
137
+ The ID of the context that was used to create the event.
138
+
139
+ =item $uuid = $trace->{uuid}
140
+
141
+ =item $uuid = $trace->uuid()
142
+
143
+ The UUID of the context that was used to create the event. (If uuid tagging was
144
+ enabled)
145
+
146
+ =back
147
+
148
+ =head2 DISCOURAGED HUB RELATED FIELDS
149
+
150
+ These fields were not always set properly by tools. These are B<MOSTLY>
151
+ deprecated by the L<Test2::EventFacet::Hub> facets. These fields are not
152
+ required, and may only reflect the hub that was current when the event was
153
+ created, which is not necessarily the same as the hub the event was sent
154
+ through.
155
+
156
+ Some tools did do a good job setting these to the correct hub, but you cannot
157
+ always rely on that. Use the 'hubs' facet list instead.
158
+
159
+ =over 4
160
+
161
+ =item $hid = $trace->{hid}
162
+
163
+ =item $hid = $trace->hid()
164
+
165
+ The ID of the hub that was current when the event was created.
166
+
167
+ =item $huuid = $trace->{huuid}
168
+
169
+ =item $huuid = $trace->huuid()
170
+
171
+ The UUID of the hub that was current when the event was created. (If uuid
172
+ tagging was enabled).
173
+
174
+ =item $int = $trace->{nested}
175
+
176
+ =item $int = $trace->nested()
177
+
178
+ How deeply nested the event is.
179
+
180
+ =item $bool = $trace->{buffered}
181
+
182
+ =item $bool = $trace->buffered()
183
+
184
+ True if the event was buffered and not sent to the formatter independent of a
185
+ parent (This should never be set when nested is C<0> or C<undef>).
186
+
187
+ =back
188
+
189
+ =head1 METHODS
190
+
191
+ B<Note:> All facet frames are also methods.
192
+
193
+ =over 4
194
+
195
+ =item $trace->set_detail($msg)
196
+
197
+ =item $msg = $trace->detail
198
+
199
+ Used to get/set a custom trace message that will be used INSTEAD of
200
+ C<< at <FILE> line <LINE> >> when calling C<< $trace->debug >>.
201
+
202
+ C<detail()> is an alias to the C<details> facet field for backwards
203
+ compatibility.
204
+
205
+ =item $str = $trace->debug
206
+
207
+ Typically returns the string C<< at <FILE> line <LINE> >>. If C<detail> is set
208
+ then its value will be returned instead.
209
+
210
+ =item $trace->alert($MESSAGE)
211
+
212
+ This issues a warning at the frame (filename and line number where
213
+ errors should be reported).
214
+
215
+ =item $trace->throw($MESSAGE)
216
+
217
+ This throws an exception at the frame (filename and line number where
218
+ errors should be reported).
219
+
220
+ =item ($package, $file, $line, $subname) = $trace->call()
221
+
222
+ Get the caller details for the debug-info. This is where errors should be
223
+ reported.
224
+
225
+ =item $pkg = $trace->package
226
+
227
+ Get the debug-info package.
228
+
229
+ =item $file = $trace->file
230
+
231
+ Get the debug-info filename.
232
+
233
+ =item $line = $trace->line
234
+
235
+ Get the debug-info line number.
236
+
237
+ =item $subname = $trace->subname
238
+
239
+ Get the debug-info subroutine name.
240
+
241
+ =item $sig = trace->signature
242
+
243
+ Get a signature string that identifies this trace. This is used to check if
244
+ multiple events are related. The signature includes pid, tid, file, line
245
+ number, and the cid.
246
+
247
+ =back
248
+
249
+ =head1 SOURCE
250
+
251
+ The source code repository for Test2 can be found at
252
+ F<http://github.com/Test-More/test-more/>.
253
+
254
+ =head1 MAINTAINERS
255
+
256
+ =over 4
257
+
258
+ =item Chad Granum E<lt>[email protected]<gt>
259
+
260
+ =back
261
+
262
+ =head1 AUTHORS
263
+
264
+ =over 4
265
+
266
+ =item Chad Granum E<lt>[email protected]<gt>
267
+
268
+ =back
269
+
270
+ =head1 COPYRIGHT
271
+
272
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
273
+
274
+ This program is free software; you can redistribute it and/or
275
+ modify it under the same terms as Perl itself.
276
+
277
+ See F<http://dev.perl.org/licenses/>
278
+
279
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Formatter/TAP.pm ADDED
@@ -0,0 +1,524 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Formatter::TAP;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ use Test2::Util qw/clone_io/;
8
+
9
+ use Test2::Util::HashBase qw{
10
+ no_numbers handles _encoding _last_fh
11
+ -made_assertion
12
+ };
13
+
14
+ sub OUT_STD() { 0 }
15
+ sub OUT_ERR() { 1 }
16
+
17
+ BEGIN { require Test2::Formatter; our @ISA = qw(Test2::Formatter) }
18
+
19
+ # Not constants because this is a method, and can be overriden
20
+ BEGIN {
21
+ local $SIG{__DIE__} = 'DEFAULT';
22
+ local $@;
23
+ if (($INC{'Term/Table.pm'} && $INC{'Term/Table/Util.pm'}) || eval { require Term::Table; require Term::Table::Util; 1 }) {
24
+ *supports_tables = sub { 1 };
25
+ }
26
+ else {
27
+ *supports_tables = sub { 0 };
28
+ }
29
+ }
30
+
31
+ sub _autoflush {
32
+ my($fh) = pop;
33
+ my $old_fh = select $fh;
34
+ $| = 1;
35
+ select $old_fh;
36
+ }
37
+
38
+ _autoflush(\*STDOUT);
39
+ _autoflush(\*STDERR);
40
+
41
+ sub hide_buffered { 1 }
42
+
43
+ sub init {
44
+ my $self = shift;
45
+
46
+ $self->{+HANDLES} ||= $self->_open_handles;
47
+ if(my $enc = delete $self->{encoding}) {
48
+ $self->encoding($enc);
49
+ }
50
+ }
51
+
52
+ sub _open_handles {
53
+ my $self = shift;
54
+
55
+ require Test2::API;
56
+ my $out = clone_io(Test2::API::test2_stdout());
57
+ my $err = clone_io(Test2::API::test2_stderr());
58
+
59
+ _autoflush($out);
60
+ _autoflush($err);
61
+
62
+ return [$out, $err];
63
+ }
64
+
65
+ sub encoding {
66
+ my $self = shift;
67
+
68
+ if ($] ge "5.007003" and @_) {
69
+ my ($enc) = @_;
70
+ my $handles = $self->{+HANDLES};
71
+
72
+ # https://rt.perl.org/Public/Bug/Display.html?id=31923
73
+ # If utf8 is requested we use ':utf8' instead of ':encoding(utf8)' in
74
+ # order to avoid the thread segfault.
75
+ if ($enc =~ m/^utf-?8$/i) {
76
+ binmode($_, ":utf8") for @$handles;
77
+ }
78
+ else {
79
+ binmode($_, ":encoding($enc)") for @$handles;
80
+ }
81
+ $self->{+_ENCODING} = $enc;
82
+ }
83
+
84
+ return $self->{+_ENCODING};
85
+ }
86
+
87
+ if ($^C) {
88
+ no warnings 'redefine';
89
+ *write = sub {};
90
+ }
91
+ sub write {
92
+ my ($self, $e, $num, $f) = @_;
93
+
94
+ # The most common case, a pass event with no amnesty and a normal name.
95
+ return if $self->print_optimal_pass($e, $num);
96
+
97
+ $f ||= $e->facet_data;
98
+
99
+ $self->encoding($f->{control}->{encoding}) if $f->{control}->{encoding};
100
+
101
+ my @tap = $self->event_tap($f, $num) or return;
102
+
103
+ $self->{+MADE_ASSERTION} = 1 if $f->{assert};
104
+
105
+ my $nesting = $f->{trace}->{nested} || 0;
106
+ my $handles = $self->{+HANDLES};
107
+ my $indent = ' ' x $nesting;
108
+
109
+ # Local is expensive! Only do it if we really need to.
110
+ local($\, $,) = (undef, '') if $\ || $,;
111
+ for my $set (@tap) {
112
+ no warnings 'uninitialized';
113
+ my ($hid, $msg) = @$set;
114
+ next unless $msg;
115
+ my $io = $handles->[$hid] or next;
116
+
117
+ print $io "\n"
118
+ if $ENV{HARNESS_ACTIVE}
119
+ && $hid == OUT_ERR
120
+ && $self->{+_LAST_FH} != $io
121
+ && $msg =~ m/^#\s*Failed( \(TODO\))? test /;
122
+
123
+ $msg =~ s/^/$indent/mg if $nesting;
124
+ print $io $msg;
125
+ $self->{+_LAST_FH} = $io;
126
+ }
127
+ }
128
+
129
+ sub print_optimal_pass {
130
+ my ($self, $e, $num) = @_;
131
+
132
+ my $type = ref($e);
133
+
134
+ # Only optimal if this is a Pass or a passing Ok
135
+ return unless $type eq 'Test2::Event::Pass' || ($type eq 'Test2::Event::Ok' && $e->{pass});
136
+
137
+ # Amnesty requires further processing (todo is a form of amnesty)
138
+ return if ($e->{amnesty} && @{$e->{amnesty}}) || defined($e->{todo});
139
+
140
+ # A name with a newline or hash symbol needs extra processing
141
+ return if defined($e->{name}) && (-1 != index($e->{name}, "\n") || -1 != index($e->{name}, '#'));
142
+
143
+ my $ok = 'ok';
144
+ $ok .= " $num" if $num && !$self->{+NO_NUMBERS};
145
+ $ok .= defined($e->{name}) ? " - $e->{name}\n" : "\n";
146
+
147
+ if (my $nesting = $e->{trace}->{nested}) {
148
+ my $indent = ' ' x $nesting;
149
+ $ok = "$indent$ok";
150
+ }
151
+
152
+ my $io = $self->{+HANDLES}->[OUT_STD];
153
+
154
+ local($\, $,) = (undef, '') if $\ || $,;
155
+ print $io $ok;
156
+ $self->{+_LAST_FH} = $io;
157
+
158
+ return 1;
159
+ }
160
+
161
+ sub event_tap {
162
+ my ($self, $f, $num) = @_;
163
+
164
+ my @tap;
165
+
166
+ # If this IS the first event the plan should come first
167
+ # (plan must be before or after assertions, not in the middle)
168
+ push @tap => $self->plan_tap($f) if $f->{plan} && !$self->{+MADE_ASSERTION};
169
+
170
+ # The assertion is most important, if present.
171
+ if ($f->{assert}) {
172
+ push @tap => $self->assert_tap($f, $num);
173
+ push @tap => $self->debug_tap($f, $num) unless $f->{assert}->{no_debug} || $f->{assert}->{pass};
174
+ }
175
+
176
+ # Almost as important as an assertion
177
+ push @tap => $self->error_tap($f) if $f->{errors};
178
+
179
+ # Now lets see the diagnostics messages
180
+ push @tap => $self->info_tap($f) if $f->{info};
181
+
182
+ # If this IS NOT the first event the plan should come last
183
+ # (plan must be before or after assertions, not in the middle)
184
+ push @tap => $self->plan_tap($f) if $self->{+MADE_ASSERTION} && $f->{plan};
185
+
186
+ # Bail out
187
+ push @tap => $self->halt_tap($f) if $f->{control}->{halt};
188
+
189
+ return @tap if @tap;
190
+ return @tap if $f->{control}->{halt};
191
+ return @tap if grep { $f->{$_} } qw/assert plan info errors/;
192
+
193
+ # Use the summary as a fallback if nothing else is usable.
194
+ return $self->summary_tap($f, $num);
195
+ }
196
+
197
+ sub error_tap {
198
+ my $self = shift;
199
+ my ($f) = @_;
200
+
201
+ my $IO = ($f->{amnesty} && @{$f->{amnesty}}) ? OUT_STD : OUT_ERR;
202
+
203
+ return map {
204
+ my $details = $_->{details};
205
+
206
+ my $msg;
207
+ if (ref($details)) {
208
+ require Data::Dumper;
209
+ my $dumper = Data::Dumper->new([$details])->Indent(2)->Terse(1)->Pad('# ')->Useqq(1)->Sortkeys(1);
210
+ chomp($msg = $dumper->Dump);
211
+ }
212
+ else {
213
+ chomp($msg = $details);
214
+ $msg =~ s/^/# /;
215
+ $msg =~ s/\n/\n# /g;
216
+ }
217
+
218
+ [$IO, "$msg\n"];
219
+ } @{$f->{errors}};
220
+ }
221
+
222
+ sub plan_tap {
223
+ my $self = shift;
224
+ my ($f) = @_;
225
+ my $plan = $f->{plan} or return;
226
+
227
+ return if $plan->{none};
228
+
229
+ if ($plan->{skip}) {
230
+ my $reason = $plan->{details} or return [OUT_STD, "1..0 # SKIP\n"];
231
+ chomp($reason);
232
+ return [OUT_STD, '1..0 # SKIP ' . $reason . "\n"];
233
+ }
234
+
235
+ return [OUT_STD, "1.." . $plan->{count} . "\n"];
236
+ }
237
+
238
+ sub no_subtest_space { 0 }
239
+ sub assert_tap {
240
+ my $self = shift;
241
+ my ($f, $num) = @_;
242
+
243
+ my $assert = $f->{assert} or return;
244
+ my $pass = $assert->{pass};
245
+ my $name = $assert->{details};
246
+
247
+ my $ok = $pass ? 'ok' : 'not ok';
248
+ $ok .= " $num" if $num && !$self->{+NO_NUMBERS};
249
+
250
+ # The regex form is ~250ms, the index form is ~50ms
251
+ my @extra;
252
+ defined($name) && (
253
+ (index($name, "\n") != -1 && (($name, @extra) = split(/\n\r?/, $name, -1))),
254
+ ((index($name, "#" ) != -1 || substr($name, -1) eq '\\') && (($name =~ s|\\|\\\\|g), ($name =~ s|#|\\#|g)))
255
+ );
256
+
257
+ my $extra_space = @extra ? ' ' x (length($ok) + 2) : '';
258
+ my $extra_indent = '';
259
+
260
+ my ($directives, $reason, $is_skip);
261
+ if ($f->{amnesty}) {
262
+ my %directives;
263
+
264
+ for my $am (@{$f->{amnesty}}) {
265
+ next if $am->{inherited};
266
+ my $tag = $am->{tag} or next;
267
+ $is_skip = 1 if $tag eq 'skip';
268
+
269
+ $directives{$tag} ||= $am->{details};
270
+ }
271
+
272
+ my %seen;
273
+ my @order = grep { !$seen{$_}++ } sort keys %directives;
274
+
275
+ $directives = ' # ' . join ' & ' => @order;
276
+
277
+ for my $tag ('skip', @order) {
278
+ next unless defined($directives{$tag}) && length($directives{$tag});
279
+ $reason = $directives{$tag};
280
+ last;
281
+ }
282
+ }
283
+
284
+ $ok .= " - $name" if defined $name && !($is_skip && !$name);
285
+
286
+ my @subtap;
287
+ if ($f->{parent} && $f->{parent}->{buffered}) {
288
+ $ok .= ' {';
289
+
290
+ # In a verbose harness we indent the extra since they will appear
291
+ # inside the subtest braces. This helps readability. In a non-verbose
292
+ # harness we do not do this because it is less readable.
293
+ if ($ENV{HARNESS_IS_VERBOSE} || !$ENV{HARNESS_ACTIVE}) {
294
+ $extra_indent = " ";
295
+ $extra_space = ' ';
296
+ }
297
+
298
+ # Render the sub-events, we use our own counter for these.
299
+ my $count = 0;
300
+ @subtap = map {
301
+ my $f2 = $_;
302
+
303
+ # Bump the count for any event that should bump it.
304
+ $count++ if $f2->{assert};
305
+
306
+ # This indents all output lines generated for the sub-events.
307
+ # index 0 is the filehandle, index 1 is the message we want to indent.
308
+ map { $_->[1] =~ s/^(.*\S.*)$/ $1/mg; $_ } $self->event_tap($f2, $count);
309
+ } @{$f->{parent}->{children}};
310
+
311
+ push @subtap => [OUT_STD, "}\n"];
312
+ }
313
+
314
+ if ($directives) {
315
+ $directives = ' # TODO & SKIP' if $directives eq ' # TODO & skip';
316
+ $ok .= $directives;
317
+ $ok .= " $reason" if defined($reason);
318
+ }
319
+
320
+ $extra_space = ' ' if $self->no_subtest_space;
321
+
322
+ my @out = ([OUT_STD, "$ok\n"]);
323
+ push @out => map {[OUT_STD, "${extra_indent}#${extra_space}$_\n"]} @extra if @extra;
324
+ push @out => @subtap;
325
+
326
+ return @out;
327
+ }
328
+
329
+ sub debug_tap {
330
+ my ($self, $f, $num) = @_;
331
+
332
+ # Figure out the debug info, this is typically the file name and line
333
+ # number, but can also be a custom message. If no trace object is provided
334
+ # then we have nothing useful to display.
335
+ my $name = $f->{assert}->{details};
336
+ my $trace = $f->{trace};
337
+
338
+ my $debug = "[No trace info available]";
339
+ if ($trace->{details}) {
340
+ $debug = $trace->{details};
341
+ }
342
+ elsif ($trace->{frame}) {
343
+ my ($pkg, $file, $line) = @{$trace->{frame}};
344
+ $debug = "at $file line $line." if $file && $line;
345
+ }
346
+
347
+ my $amnesty = $f->{amnesty} && @{$f->{amnesty}}
348
+ ? ' (with amnesty)'
349
+ : '';
350
+
351
+ # Create the initial diagnostics. If the test has a name we put the debug
352
+ # info on a second line, this behavior is inherited from Test::Builder.
353
+ my $msg = defined($name)
354
+ ? qq[# Failed test${amnesty} '$name'\n# $debug\n]
355
+ : qq[# Failed test${amnesty} $debug\n];
356
+
357
+ my $IO = $f->{amnesty} && @{$f->{amnesty}} ? OUT_STD : OUT_ERR;
358
+
359
+ return [$IO, $msg];
360
+ }
361
+
362
+ sub halt_tap {
363
+ my ($self, $f) = @_;
364
+
365
+ return if $f->{trace}->{nested} && !$f->{trace}->{buffered};
366
+ my $details = $f->{control}->{details};
367
+
368
+ return [OUT_STD, "Bail out!\n"] unless defined($details) && length($details);
369
+ return [OUT_STD, "Bail out! $details\n"];
370
+ }
371
+
372
+ sub info_tap {
373
+ my ($self, $f) = @_;
374
+
375
+ return map {
376
+ my $details = $_->{details};
377
+ my $table = $_->{table};
378
+
379
+ my $IO = $_->{debug} && !($f->{amnesty} && @{$f->{amnesty}}) ? OUT_ERR : OUT_STD;
380
+
381
+ my $msg;
382
+ if ($table && $self->supports_tables) {
383
+ $msg = join "\n" => map { "# $_" } Term::Table->new(
384
+ header => $table->{header},
385
+ rows => $table->{rows},
386
+ collapse => $table->{collapse},
387
+ no_collapse => $table->{no_collapse},
388
+ sanitize => 1,
389
+ mark_tail => 1,
390
+ max_width => $self->calc_table_size($f),
391
+ )->render();
392
+ }
393
+ elsif (ref($details)) {
394
+ require Data::Dumper;
395
+ my $dumper = Data::Dumper->new([$details])->Indent(2)->Terse(1)->Pad('# ')->Useqq(1)->Sortkeys(1);
396
+ chomp($msg = $dumper->Dump);
397
+ }
398
+ else {
399
+ chomp($msg = $details);
400
+ $msg =~ s/^/# /;
401
+ $msg =~ s/\n/\n# /g;
402
+ }
403
+
404
+ [$IO, "$msg\n"];
405
+ } @{$f->{info}};
406
+ }
407
+
408
+ sub summary_tap {
409
+ my ($self, $f, $num) = @_;
410
+
411
+ return if $f->{about}->{no_display};
412
+
413
+ my $summary = $f->{about}->{details} or return;
414
+ chomp($summary);
415
+ $summary =~ s/^/# /smg;
416
+
417
+ return [OUT_STD, "$summary\n"];
418
+ }
419
+
420
+ sub calc_table_size {
421
+ my $self = shift;
422
+ my ($f) = @_;
423
+
424
+ my $term = Term::Table::Util::term_size();
425
+ my $nesting = 2 + (($f->{trace}->{nested} || 0) * 4); # 4 spaces per level, also '# ' prefix
426
+ my $total = $term - $nesting;
427
+
428
+ # Sane minimum width, any smaller and we are asking for pain
429
+ return 50 if $total < 50;
430
+
431
+ return $total;
432
+ }
433
+
434
+ 1;
435
+
436
+ __END__
437
+
438
+ =pod
439
+
440
+ =encoding UTF-8
441
+
442
+ =head1 NAME
443
+
444
+ Test2::Formatter::TAP - Standard TAP formatter
445
+
446
+ =head1 DESCRIPTION
447
+
448
+ This is what takes events and turns them into TAP.
449
+
450
+ =head1 SYNOPSIS
451
+
452
+ use Test2::Formatter::TAP;
453
+ my $tap = Test2::Formatter::TAP->new();
454
+
455
+ # Switch to utf8
456
+ $tap->encoding('utf8');
457
+
458
+ $tap->write($event, $number); # Output an event
459
+
460
+ =head1 METHODS
461
+
462
+ =over 4
463
+
464
+ =item $bool = $tap->no_numbers
465
+
466
+ =item $tap->set_no_numbers($bool)
467
+
468
+ Use to turn numbers on and off.
469
+
470
+ =item $arrayref = $tap->handles
471
+
472
+ =item $tap->set_handles(\@handles);
473
+
474
+ Can be used to get/set the filehandles. Indexes are identified by the
475
+ C<OUT_STD> and C<OUT_ERR> constants.
476
+
477
+ =item $encoding = $tap->encoding
478
+
479
+ =item $tap->encoding($encoding)
480
+
481
+ Get or set the encoding. By default no encoding is set, the original settings
482
+ of STDOUT and STDERR are used.
483
+
484
+ This directly modifies the stored filehandles, it does not create new ones.
485
+
486
+ =item $tap->write($e, $num)
487
+
488
+ Write an event to the console.
489
+
490
+ =back
491
+
492
+ =head1 SOURCE
493
+
494
+ The source code repository for Test2 can be found at
495
+ F<http://github.com/Test-More/test-more/>.
496
+
497
+ =head1 MAINTAINERS
498
+
499
+ =over 4
500
+
501
+ =item Chad Granum E<lt>[email protected]<gt>
502
+
503
+ =back
504
+
505
+ =head1 AUTHORS
506
+
507
+ =over 4
508
+
509
+ =item Chad Granum E<lt>[email protected]<gt>
510
+
511
+ =item Kent Fredric E<lt>[email protected]<gt>
512
+
513
+ =back
514
+
515
+ =head1 COPYRIGHT
516
+
517
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
518
+
519
+ This program is free software; you can redistribute it and/or
520
+ modify it under the same terms as Perl itself.
521
+
522
+ See F<http://dev.perl.org/licenses/>
523
+
524
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Tools/Tiny.pm ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Tools::Tiny;
2
+ use strict;
3
+ use warnings;
4
+
5
+ BEGIN {
6
+ if ($] lt "5.008") {
7
+ require Test::Builder::IO::Scalar;
8
+ }
9
+ }
10
+
11
+ use Scalar::Util qw/blessed/;
12
+
13
+ use Test2::Util qw/try/;
14
+ use Test2::API qw/context run_subtest test2_stack/;
15
+
16
+ use Test2::Hub::Interceptor();
17
+ use Test2::Hub::Interceptor::Terminator();
18
+
19
+ our $VERSION = '1.302162';
20
+
21
+ BEGIN { require Exporter; our @ISA = qw(Exporter) }
22
+ our @EXPORT = qw{
23
+ ok is isnt like unlike is_deeply diag note skip_all todo plan done_testing
24
+ warnings exception tests capture
25
+ };
26
+
27
+ sub ok($;$@) {
28
+ my ($bool, $name, @diag) = @_;
29
+ my $ctx = context();
30
+
31
+ return $ctx->pass_and_release($name) if $bool;
32
+ return $ctx->fail_and_release($name, @diag);
33
+ }
34
+
35
+ sub is($$;$@) {
36
+ my ($got, $want, $name, @diag) = @_;
37
+ my $ctx = context();
38
+
39
+ my $bool;
40
+ if (defined($got) && defined($want)) {
41
+ $bool = "$got" eq "$want";
42
+ }
43
+ elsif (defined($got) xor defined($want)) {
44
+ $bool = 0;
45
+ }
46
+ else { # Both are undef
47
+ $bool = 1;
48
+ }
49
+
50
+ return $ctx->pass_and_release($name) if $bool;
51
+
52
+ $got = '*NOT DEFINED*' unless defined $got;
53
+ $want = '*NOT DEFINED*' unless defined $want;
54
+ unshift @diag => (
55
+ "GOT: $got",
56
+ "EXPECTED: $want",
57
+ );
58
+
59
+ return $ctx->fail_and_release($name, @diag);
60
+ }
61
+
62
+ sub isnt($$;$@) {
63
+ my ($got, $want, $name, @diag) = @_;
64
+ my $ctx = context();
65
+
66
+ my $bool;
67
+ if (defined($got) && defined($want)) {
68
+ $bool = "$got" ne "$want";
69
+ }
70
+ elsif (defined($got) xor defined($want)) {
71
+ $bool = 1;
72
+ }
73
+ else { # Both are undef
74
+ $bool = 0;
75
+ }
76
+
77
+ return $ctx->pass_and_release($name) if $bool;
78
+
79
+ unshift @diag => "Strings are the same (they should not be)"
80
+ unless $bool;
81
+
82
+ return $ctx->fail_and_release($name, @diag);
83
+ }
84
+
85
+ sub like($$;$@) {
86
+ my ($thing, $pattern, $name, @diag) = @_;
87
+ my $ctx = context();
88
+
89
+ my $bool;
90
+ if (defined($thing)) {
91
+ $bool = "$thing" =~ $pattern;
92
+ unshift @diag => (
93
+ "Value: $thing",
94
+ "Does not match: $pattern"
95
+ ) unless $bool;
96
+ }
97
+ else {
98
+ $bool = 0;
99
+ unshift @diag => "Got an undefined value.";
100
+ }
101
+
102
+ return $ctx->pass_and_release($name) if $bool;
103
+ return $ctx->fail_and_release($name, @diag);
104
+ }
105
+
106
+ sub unlike($$;$@) {
107
+ my ($thing, $pattern, $name, @diag) = @_;
108
+ my $ctx = context();
109
+
110
+ my $bool;
111
+ if (defined($thing)) {
112
+ $bool = "$thing" !~ $pattern;
113
+ unshift @diag => (
114
+ "Unexpected pattern match (it should not match)",
115
+ "Value: $thing",
116
+ "Matches: $pattern"
117
+ ) unless $bool;
118
+ }
119
+ else {
120
+ $bool = 0;
121
+ unshift @diag => "Got an undefined value.";
122
+ }
123
+
124
+ return $ctx->pass_and_release($name) if $bool;
125
+ return $ctx->fail_and_release($name, @diag);
126
+ }
127
+
128
+ sub is_deeply($$;$@) {
129
+ my ($got, $want, $name, @diag) = @_;
130
+ my $ctx = context();
131
+
132
+ no warnings 'once';
133
+ require Data::Dumper;
134
+
135
+ # Otherwise numbers might be unquoted
136
+ local $Data::Dumper::Useperl = 1;
137
+
138
+ local $Data::Dumper::Sortkeys = 1;
139
+ local $Data::Dumper::Deparse = 1;
140
+ local $Data::Dumper::Freezer = 'XXX';
141
+ local *UNIVERSAL::XXX = sub {
142
+ my ($thing) = @_;
143
+ if (ref($thing)) {
144
+ $thing = {%$thing} if "$thing" =~ m/=HASH/;
145
+ $thing = [@$thing] if "$thing" =~ m/=ARRAY/;
146
+ $thing = \"$$thing" if "$thing" =~ m/=SCALAR/;
147
+ }
148
+ $_[0] = $thing;
149
+ };
150
+
151
+ my $g = Data::Dumper::Dumper($got);
152
+ my $w = Data::Dumper::Dumper($want);
153
+
154
+ my $bool = $g eq $w;
155
+
156
+ return $ctx->pass_and_release($name) if $bool;
157
+ return $ctx->fail_and_release($name, $g, $w, @diag);
158
+ }
159
+
160
+ sub diag {
161
+ my $ctx = context();
162
+ $ctx->diag(join '', @_);
163
+ $ctx->release;
164
+ }
165
+
166
+ sub note {
167
+ my $ctx = context();
168
+ $ctx->note(join '', @_);
169
+ $ctx->release;
170
+ }
171
+
172
+ sub skip_all {
173
+ my ($reason) = @_;
174
+ my $ctx = context();
175
+ $ctx->plan(0, SKIP => $reason);
176
+ $ctx->release if $ctx;
177
+ }
178
+
179
+ sub todo {
180
+ my ($reason, $sub) = @_;
181
+ my $ctx = context();
182
+
183
+ # This code is mostly copied from Test2::Todo in the Test2-Suite
184
+ # distribution.
185
+ my $hub = test2_stack->top;
186
+ my $filter = $hub->pre_filter(
187
+ sub {
188
+ my ($active_hub, $event) = @_;
189
+ if ($active_hub == $hub) {
190
+ $event->set_todo($reason) if $event->can('set_todo');
191
+ $event->add_amnesty({tag => 'TODO', details => $reason});
192
+ }
193
+ else {
194
+ $event->add_amnesty({tag => 'TODO', details => $reason, inherited => 1});
195
+ }
196
+ return $event;
197
+ },
198
+ inherit => 1,
199
+ todo => $reason,
200
+ );
201
+ $sub->();
202
+ $hub->pre_unfilter($filter);
203
+
204
+ $ctx->release if $ctx;
205
+ }
206
+
207
+ sub plan {
208
+ my ($max) = @_;
209
+ my $ctx = context();
210
+ $ctx->plan($max);
211
+ $ctx->release;
212
+ }
213
+
214
+ sub done_testing {
215
+ my $ctx = context();
216
+ $ctx->done_testing;
217
+ $ctx->release;
218
+ }
219
+
220
+ sub warnings(&) {
221
+ my $code = shift;
222
+ my @warnings;
223
+ local $SIG{__WARN__} = sub { push @warnings => @_ };
224
+ $code->();
225
+ return \@warnings;
226
+ }
227
+
228
+ sub exception(&) {
229
+ my $code = shift;
230
+ local ($@, $!, $SIG{__DIE__});
231
+ my $ok = eval { $code->(); 1 };
232
+ my $error = $@ || 'SQUASHED ERROR';
233
+ return $ok ? undef : $error;
234
+ }
235
+
236
+ sub tests {
237
+ my ($name, $code) = @_;
238
+ my $ctx = context();
239
+
240
+ my $be = caller->can('before_each');
241
+
242
+ $be->($name) if $be;
243
+
244
+ my $bool = run_subtest($name, $code, 1);
245
+
246
+ $ctx->release;
247
+
248
+ return $bool;
249
+ }
250
+
251
+ sub capture(&) {
252
+ my $code = shift;
253
+
254
+ my ($err, $out) = ("", "");
255
+
256
+ my $handles = test2_stack->top->format->handles;
257
+ my ($ok, $e);
258
+ {
259
+ my ($out_fh, $err_fh);
260
+
261
+ ($ok, $e) = try {
262
+ # Scalar refs as filehandles were added in 5.8.
263
+ if ($] ge "5.008") {
264
+ open($out_fh, '>', \$out) or die "Failed to open a temporary STDOUT: $!";
265
+ open($err_fh, '>', \$err) or die "Failed to open a temporary STDERR: $!";
266
+ }
267
+ # Emulate scalar ref filehandles with a tie.
268
+ else {
269
+ $out_fh = Test::Builder::IO::Scalar->new(\$out) or die "Failed to open a temporary STDOUT";
270
+ $err_fh = Test::Builder::IO::Scalar->new(\$err) or die "Failed to open a temporary STDERR";
271
+ }
272
+
273
+ test2_stack->top->format->set_handles([$out_fh, $err_fh, $out_fh]);
274
+
275
+ $code->();
276
+ };
277
+ }
278
+ test2_stack->top->format->set_handles($handles);
279
+
280
+ die $e unless $ok;
281
+
282
+ $err =~ s/ $/_/mg;
283
+ $out =~ s/ $/_/mg;
284
+
285
+ return {
286
+ STDOUT => $out,
287
+ STDERR => $err,
288
+ };
289
+ }
290
+
291
+ 1;
292
+
293
+ __END__
294
+
295
+ =pod
296
+
297
+ =encoding UTF-8
298
+
299
+ =head1 NAME
300
+
301
+ Test2::Tools::Tiny - Tiny set of tools for unfortunate souls who cannot use
302
+ L<Test2::Suite>.
303
+
304
+ =head1 DESCRIPTION
305
+
306
+ You should really look at L<Test2::Suite>. This package is some very basic
307
+ essential tools implemented using L<Test2>. This exists only so that L<Test2>
308
+ and other tools required by L<Test2::Suite> can be tested. This is the package
309
+ L<Test2> uses to test itself.
310
+
311
+ =head1 USE Test2::Suite INSTEAD
312
+
313
+ Use L<Test2::Suite> if at all possible.
314
+
315
+ =head1 EXPORTS
316
+
317
+ =over 4
318
+
319
+ =item ok($bool, $name)
320
+
321
+ =item ok($bool, $name, @diag)
322
+
323
+ Run a simple assertion.
324
+
325
+ =item is($got, $want, $name)
326
+
327
+ =item is($got, $want, $name, @diag)
328
+
329
+ Assert that 2 strings are the same.
330
+
331
+ =item isnt($got, $do_not_want, $name)
332
+
333
+ =item isnt($got, $do_not_want, $name, @diag)
334
+
335
+ Assert that 2 strings are not the same.
336
+
337
+ =item like($got, $regex, $name)
338
+
339
+ =item like($got, $regex, $name, @diag)
340
+
341
+ Check that the input string matches the regex.
342
+
343
+ =item unlike($got, $regex, $name)
344
+
345
+ =item unlike($got, $regex, $name, @diag)
346
+
347
+ Check that the input string does not match the regex.
348
+
349
+ =item is_deeply($got, $want, $name)
350
+
351
+ =item is_deeply($got, $want, $name, @diag)
352
+
353
+ Check 2 data structures. Please note that this is a I<DUMB> implementation that
354
+ compares the output of L<Data::Dumper> against both structures.
355
+
356
+ =item diag($msg)
357
+
358
+ Issue a diagnostics message to STDERR.
359
+
360
+ =item note($msg)
361
+
362
+ Issue a diagnostics message to STDOUT.
363
+
364
+ =item skip_all($reason)
365
+
366
+ Skip all tests.
367
+
368
+ =item todo $reason => sub { ... }
369
+
370
+ Run a block in TODO mode.
371
+
372
+ =item plan($count)
373
+
374
+ Set the plan.
375
+
376
+ =item done_testing()
377
+
378
+ Set the plan to the current test count.
379
+
380
+ =item $warnings = warnings { ... }
381
+
382
+ Capture an arrayref of warnings from the block.
383
+
384
+ =item $exception = exception { ... }
385
+
386
+ Capture an exception.
387
+
388
+ =item tests $name => sub { ... }
389
+
390
+ Run a subtest.
391
+
392
+ =item $output = capture { ... }
393
+
394
+ Capture STDOUT and STDERR output.
395
+
396
+ Result looks like this:
397
+
398
+ {
399
+ STDOUT => "...",
400
+ STDERR => "...",
401
+ }
402
+
403
+ =back
404
+
405
+ =head1 SOURCE
406
+
407
+ The source code repository for Test2 can be found at
408
+ F<http://github.com/Test-More/test-more/>.
409
+
410
+ =head1 MAINTAINERS
411
+
412
+ =over 4
413
+
414
+ =item Chad Granum E<lt>[email protected]<gt>
415
+
416
+ =back
417
+
418
+ =head1 AUTHORS
419
+
420
+ =over 4
421
+
422
+ =item Chad Granum E<lt>[email protected]<gt>
423
+
424
+ =back
425
+
426
+ =head1 COPYRIGHT
427
+
428
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
429
+
430
+ This program is free software; you can redistribute it and/or
431
+ modify it under the same terms as Perl itself.
432
+
433
+ See F<http://dev.perl.org/licenses/>
434
+
435
+ =cut
my_container_sandbox/usr/share/perl/5.30.0/Test2/Util/HashBase.pm ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package Test2::Util::HashBase;
2
+ use strict;
3
+ use warnings;
4
+
5
+ our $VERSION = '1.302162';
6
+
7
+ #################################################################
8
+ # #
9
+ # This is a generated file! Do not modify this file directly! #
10
+ # Use hashbase_inc.pl script to regenerate this file. #
11
+ # The script is part of the Object::HashBase distribution. #
12
+ # Note: You can modify the version number above this comment #
13
+ # if needed, that is fine. #
14
+ # #
15
+ #################################################################
16
+
17
+ {
18
+ no warnings 'once';
19
+ $Test2::Util::HashBase::HB_VERSION = '0.006';
20
+ *Test2::Util::HashBase::ATTR_SUBS = \%Object::HashBase::ATTR_SUBS;
21
+ *Test2::Util::HashBase::ATTR_LIST = \%Object::HashBase::ATTR_LIST;
22
+ *Test2::Util::HashBase::VERSION = \%Object::HashBase::VERSION;
23
+ *Test2::Util::HashBase::CAN_CACHE = \%Object::HashBase::CAN_CACHE;
24
+ }
25
+
26
+
27
+ require Carp;
28
+ {
29
+ no warnings 'once';
30
+ $Carp::Internal{+__PACKAGE__} = 1;
31
+ }
32
+
33
+ BEGIN {
34
+ # these are not strictly equivalent, but for out use we don't care
35
+ # about order
36
+ *_isa = ($] >= 5.010 && require mro) ? \&mro::get_linear_isa : sub {
37
+ no strict 'refs';
38
+ my @packages = ($_[0]);
39
+ my %seen;
40
+ for my $package (@packages) {
41
+ push @packages, grep !$seen{$_}++, @{"$package\::ISA"};
42
+ }
43
+ return \@packages;
44
+ }
45
+ }
46
+
47
+ my %STRIP = (
48
+ '^' => 1,
49
+ '-' => 1,
50
+ );
51
+
52
+ sub import {
53
+ my $class = shift;
54
+ my $into = caller;
55
+
56
+ # Make sure we list the OLDEST version used to create this class.
57
+ my $ver = $Test2::Util::HashBase::HB_VERSION || $Test2::Util::HashBase::VERSION;
58
+ $Test2::Util::HashBase::VERSION{$into} = $ver if !$Test2::Util::HashBase::VERSION{$into} || $Test2::Util::HashBase::VERSION{$into} > $ver;
59
+
60
+ my $isa = _isa($into);
61
+ my $attr_list = $Test2::Util::HashBase::ATTR_LIST{$into} ||= [];
62
+ my $attr_subs = $Test2::Util::HashBase::ATTR_SUBS{$into} ||= {};
63
+
64
+ my %subs = (
65
+ ($into->can('new') ? () : (new => \&_new)),
66
+ (map %{$Test2::Util::HashBase::ATTR_SUBS{$_} || {}}, @{$isa}[1 .. $#$isa]),
67
+ (
68
+ map {
69
+ my $p = substr($_, 0, 1);
70
+ my $x = $_;
71
+ substr($x, 0, 1) = '' if $STRIP{$p};
72
+ push @$attr_list => $x;
73
+ my ($sub, $attr) = (uc $x, $x);
74
+ $sub => ($attr_subs->{$sub} = sub() { $attr }),
75
+ $attr => sub { $_[0]->{$attr} },
76
+ $p eq '-' ? ("set_$attr" => sub { Carp::croak("'$attr' is read-only") })
77
+ : $p eq '^' ? ("set_$attr" => sub { Carp::carp("set_$attr() is deprecated"); $_[0]->{$attr} = $_[1] })
78
+ : ("set_$attr" => sub { $_[0]->{$attr} = $_[1] }),
79
+ } @_
80
+ ),
81
+ );
82
+
83
+ no strict 'refs';
84
+ *{"$into\::$_"} = $subs{$_} for keys %subs;
85
+ }
86
+
87
+ sub attr_list {
88
+ my $class = shift;
89
+
90
+ my $isa = _isa($class);
91
+
92
+ my %seen;
93
+ my @list = grep { !$seen{$_}++ } map {
94
+ my @out;
95
+
96
+ if (0.004 > ($Test2::Util::HashBase::VERSION{$_} || 0)) {
97
+ Carp::carp("$_ uses an inlined version of Test2::Util::HashBase too old to support attr_list()");
98
+ }
99
+ else {
100
+ my $list = $Test2::Util::HashBase::ATTR_LIST{$_};
101
+ @out = $list ? @$list : ()
102
+ }
103
+
104
+ @out;
105
+ } reverse @$isa;
106
+
107
+ return @list;
108
+ }
109
+
110
+ sub _new {
111
+ my $class = shift;
112
+
113
+ my $self;
114
+
115
+ if (@_ == 1) {
116
+ my $arg = shift;
117
+ my $type = ref($arg);
118
+
119
+ if ($type eq 'HASH') {
120
+ $self = bless({%$arg}, $class)
121
+ }
122
+ else {
123
+ Carp::croak("Not sure what to do with '$type' in $class constructor")
124
+ unless $type eq 'ARRAY';
125
+
126
+ my %proto;
127
+ my @attributes = attr_list($class);
128
+ while (@$arg) {
129
+ my $val = shift @$arg;
130
+ my $key = shift @attributes or Carp::croak("Too many arguments for $class constructor");
131
+ $proto{$key} = $val;
132
+ }
133
+
134
+ $self = bless(\%proto, $class);
135
+ }
136
+ }
137
+ else {
138
+ $self = bless({@_}, $class);
139
+ }
140
+
141
+ $Test2::Util::HashBase::CAN_CACHE{$class} = $self->can('init')
142
+ unless exists $Test2::Util::HashBase::CAN_CACHE{$class};
143
+
144
+ $self->init if $Test2::Util::HashBase::CAN_CACHE{$class};
145
+
146
+ $self;
147
+ }
148
+
149
+ 1;
150
+
151
+ __END__
152
+
153
+ =pod
154
+
155
+ =encoding UTF-8
156
+
157
+ =head1 NAME
158
+
159
+ Test2::Util::HashBase - Build hash based classes.
160
+
161
+ =head1 SYNOPSIS
162
+
163
+ A class:
164
+
165
+ package My::Class;
166
+ use strict;
167
+ use warnings;
168
+
169
+ # Generate 3 accessors
170
+ use Test2::Util::HashBase qw/foo -bar ^baz/;
171
+
172
+ # Chance to initialize defaults
173
+ sub init {
174
+ my $self = shift; # No other args
175
+ $self->{+FOO} ||= "foo";
176
+ $self->{+BAR} ||= "bar";
177
+ $self->{+BAZ} ||= "baz";
178
+ }
179
+
180
+ sub print {
181
+ print join ", " => map { $self->{$_} } FOO, BAR, BAZ;
182
+ }
183
+
184
+ Subclass it
185
+
186
+ package My::Subclass;
187
+ use strict;
188
+ use warnings;
189
+
190
+ # Note, you should subclass before loading HashBase.
191
+ use base 'My::Class';
192
+ use Test2::Util::HashBase qw/bat/;
193
+
194
+ sub init {
195
+ my $self = shift;
196
+
197
+ # We get the constants from the base class for free.
198
+ $self->{+FOO} ||= 'SubFoo';
199
+ $self->{+BAT} ||= 'bat';
200
+
201
+ $self->SUPER::init();
202
+ }
203
+
204
+ use it:
205
+
206
+ package main;
207
+ use strict;
208
+ use warnings;
209
+ use My::Class;
210
+
211
+ # These are all functionally identical
212
+ my $one = My::Class->new(foo => 'MyFoo', bar => 'MyBar');
213
+ my $two = My::Class->new({foo => 'MyFoo', bar => 'MyBar'});
214
+ my $three = My::Class->new(['MyFoo', 'MyBar']);
215
+
216
+ # Accessors!
217
+ my $foo = $one->foo; # 'MyFoo'
218
+ my $bar = $one->bar; # 'MyBar'
219
+ my $baz = $one->baz; # Defaulted to: 'baz'
220
+
221
+ # Setters!
222
+ $one->set_foo('A Foo');
223
+
224
+ #'-bar' means read-only, so the setter will throw an exception (but is defined).
225
+ $one->set_bar('A bar');
226
+
227
+ # '^baz' means deprecated setter, this will warn about the setter being
228
+ # deprecated.
229
+ $one->set_baz('A Baz');
230
+
231
+ $one->{+FOO} = 'xxx';
232
+
233
+ =head1 DESCRIPTION
234
+
235
+ This package is used to generate classes based on hashrefs. Using this class
236
+ will give you a C<new()> method, as well as generating accessors you request.
237
+ Generated accessors will be getters, C<set_ACCESSOR> setters will also be
238
+ generated for you. You also get constants for each accessor (all caps) which
239
+ return the key into the hash for that accessor. Single inheritance is also
240
+ supported.
241
+
242
+ =head1 THIS IS A BUNDLED COPY OF HASHBASE
243
+
244
+ This is a bundled copy of L<Object::HashBase>. This file was generated using
245
+ the
246
+ C</home/exodist/perl5/perlbrew/perls/main/bin/hashbase_inc.pl>
247
+ script.
248
+
249
+ =head1 METHODS
250
+
251
+ =head2 PROVIDED BY HASH BASE
252
+
253
+ =over 4
254
+
255
+ =item $it = $class->new(%PAIRS)
256
+
257
+ =item $it = $class->new(\%PAIRS)
258
+
259
+ =item $it = $class->new(\@ORDERED_VALUES)
260
+
261
+ Create a new instance.
262
+
263
+ HashBase will not export C<new()> if there is already a C<new()> method in your
264
+ packages inheritance chain.
265
+
266
+ B<If you do not want this method you can define your own> you just have to
267
+ declare it before loading L<Test2::Util::HashBase>.
268
+
269
+ package My::Package;
270
+
271
+ # predeclare new() so that HashBase does not give us one.
272
+ sub new;
273
+
274
+ use Test2::Util::HashBase qw/foo bar baz/;
275
+
276
+ # Now we define our own new method.
277
+ sub new { ... }
278
+
279
+ This makes it so that HashBase sees that you have your own C<new()> method.
280
+ Alternatively you can define the method before loading HashBase instead of just
281
+ declaring it, but that scatters your use statements.
282
+
283
+ The most common way to create an object is to pass in key/value pairs where
284
+ each key is an attribute and each value is what you want assigned to that
285
+ attribute. No checking is done to verify the attributes or values are valid,
286
+ you may do that in C<init()> if desired.
287
+
288
+ If you would like, you can pass in a hashref instead of pairs. When you do so
289
+ the hashref will be copied, and the copy will be returned blessed as an object.
290
+ There is no way to ask HashBase to bless a specific hashref.
291
+
292
+ In some cases an object may only have 1 or 2 attributes, in which case a
293
+ hashref may be too verbose for your liking. In these cases you can pass in an
294
+ arrayref with only values. The values will be assigned to attributes in the
295
+ order the attributes were listed. When there is inheritance involved the
296
+ attributes from parent classes will come before subclasses.
297
+
298
+ =back
299
+
300
+ =head2 HOOKS
301
+
302
+ =over 4
303
+
304
+ =item $self->init()
305
+
306
+ This gives you the chance to set some default values to your fields. The only
307
+ argument is C<$self> with its indexes already set from the constructor.
308
+
309
+ B<Note:> Test2::Util::HashBase checks for an init using C<< $class->can('init') >>
310
+ during construction. It DOES NOT call C<can()> on the created object. Also note
311
+ that the result of the check is cached, it is only ever checked once, the first
312
+ time an instance of your class is created. This means that adding an C<init()>
313
+ method AFTER the first construction will result in it being ignored.
314
+
315
+ =back
316
+
317
+ =head1 ACCESSORS
318
+
319
+ =head2 READ/WRITE
320
+
321
+ To generate accessors you list them when using the module:
322
+
323
+ use Test2::Util::HashBase qw/foo/;
324
+
325
+ This will generate the following subs in your namespace:
326
+
327
+ =over 4
328
+
329
+ =item foo()
330
+
331
+ Getter, used to get the value of the C<foo> field.
332
+
333
+ =item set_foo()
334
+
335
+ Setter, used to set the value of the C<foo> field.
336
+
337
+ =item FOO()
338
+
339
+ Constant, returns the field C<foo>'s key into the class hashref. Subclasses will
340
+ also get this function as a constant, not simply a method, that means it is
341
+ copied into the subclass namespace.
342
+
343
+ The main reason for using these constants is to help avoid spelling mistakes
344
+ and similar typos. It will not help you if you forget to prefix the '+' though.
345
+
346
+ =back
347
+
348
+ =head2 READ ONLY
349
+
350
+ use Test2::Util::HashBase qw/-foo/;
351
+
352
+ =over 4
353
+
354
+ =item set_foo()
355
+
356
+ Throws an exception telling you the attribute is read-only. This is exported to
357
+ override any active setters for the attribute in a parent class.
358
+
359
+ =back
360
+
361
+ =head2 DEPRECATED SETTER
362
+
363
+ use Test2::Util::HashBase qw/^foo/;
364
+
365
+ =over 4
366
+
367
+ =item set_foo()
368
+
369
+ This will set the value, but it will also warn you that the method is
370
+ deprecated.
371
+
372
+ =back
373
+
374
+ =head1 SUBCLASSING
375
+
376
+ You can subclass an existing HashBase class.
377
+
378
+ use base 'Another::HashBase::Class';
379
+ use Test2::Util::HashBase qw/foo bar baz/;
380
+
381
+ The base class is added to C<@ISA> for you, and all constants from base classes
382
+ are added to subclasses automatically.
383
+
384
+ =head1 GETTING A LIST OF ATTRIBUTES FOR A CLASS
385
+
386
+ Test2::Util::HashBase provides a function for retrieving a list of attributes for an
387
+ Test2::Util::HashBase class.
388
+
389
+ =over 4
390
+
391
+ =item @list = Test2::Util::HashBase::attr_list($class)
392
+
393
+ =item @list = $class->Test2::Util::HashBase::attr_list()
394
+
395
+ Either form above will work. This will return a list of attributes defined on
396
+ the object. This list is returned in the attribute definition order, parent
397
+ class attributes are listed before subclass attributes. Duplicate attributes
398
+ will be removed before the list is returned.
399
+
400
+ B<Note:> This list is used in the C<< $class->new(\@ARRAY) >> constructor to
401
+ determine the attribute to which each value will be paired.
402
+
403
+ =back
404
+
405
+ =head1 SOURCE
406
+
407
+ The source code repository for HashBase can be found at
408
+ F<http://github.com/Test-More/HashBase/>.
409
+
410
+ =head1 MAINTAINERS
411
+
412
+ =over 4
413
+
414
+ =item Chad Granum E<lt>[email protected]<gt>
415
+
416
+ =back
417
+
418
+ =head1 AUTHORS
419
+
420
+ =over 4
421
+
422
+ =item Chad Granum E<lt>[email protected]<gt>
423
+
424
+ =back
425
+
426
+ =head1 COPYRIGHT
427
+
428
+ Copyright 2019 Chad Granum E<lt>[email protected]<gt>.
429
+
430
+ This program is free software; you can redistribute it and/or
431
+ modify it under the same terms as Perl itself.
432
+
433
+ See F<http://dev.perl.org/licenses/>
434
+
435
+ =cut