exiftool-vendored.exe 12.82.0 → 12.82.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +6 -0
  2. package/bin/exiftool.exe +0 -0
  3. package/bin/exiftool_files/Licenses_Strawberry_Perl.zip +0 -0
  4. package/bin/exiftool_files/lib/Archive/Zip/Archive.pm +399 -65
  5. package/bin/exiftool_files/lib/Archive/Zip/DirectoryMember.pm +1 -1
  6. package/bin/exiftool_files/lib/Archive/Zip/FileMember.pm +1 -1
  7. package/bin/exiftool_files/lib/Archive/Zip/Member.pm +499 -195
  8. package/bin/exiftool_files/lib/Archive/Zip/NewFileMember.pm +1 -1
  9. package/bin/exiftool_files/lib/Archive/Zip/StringMember.pm +2 -2
  10. package/bin/exiftool_files/lib/Archive/Zip/ZipFileMember.pm +79 -20
  11. package/bin/exiftool_files/lib/Archive/Zip.pm +179 -29
  12. package/bin/exiftool_files/lib/AutoLoader.pm +453 -0
  13. package/bin/exiftool_files/lib/B/Deparse.pm +209 -137
  14. package/bin/exiftool_files/lib/B.pm +1 -1
  15. package/bin/exiftool_files/lib/Benchmark.pm +1123 -0
  16. package/bin/exiftool_files/lib/Class/Struct.pm +2 -2
  17. package/bin/exiftool_files/lib/Compress/Raw/Bzip2.pm +14 -9
  18. package/bin/exiftool_files/lib/Compress/Raw/Lzma.pm +982 -0
  19. package/bin/exiftool_files/lib/Compress/Raw/Zlib.pm +91 -86
  20. package/bin/exiftool_files/lib/Compress/Zlib.pm +105 -100
  21. package/bin/exiftool_files/lib/Config.pm +9 -9
  22. package/bin/exiftool_files/lib/Config_heavy.pl +36 -33
  23. package/bin/exiftool_files/lib/CryptX.pm +2 -82
  24. package/bin/exiftool_files/lib/Data/Dumper.pm +2 -2
  25. package/bin/exiftool_files/lib/Digest/MD5.pm +12 -9
  26. package/bin/exiftool_files/lib/Digest/Perl/MD5.pm +1 -191
  27. package/bin/exiftool_files/lib/Digest/base.pm +26 -20
  28. package/bin/exiftool_files/lib/DynaLoader.pm +7 -4
  29. package/bin/exiftool_files/lib/Encode.pm +3 -3
  30. package/bin/exiftool_files/lib/Errno.pm +13 -13
  31. package/bin/exiftool_files/lib/Exporter/Heavy.pm +2 -2
  32. package/bin/exiftool_files/lib/Exporter.pm +1 -1
  33. package/bin/exiftool_files/lib/ExtUtils/Command/MM.pm +323 -0
  34. package/bin/exiftool_files/lib/ExtUtils/Command.pm +382 -0
  35. package/bin/exiftool_files/lib/File/Find.pm +1 -1
  36. package/bin/exiftool_files/lib/File/Glob.pm +1 -8
  37. package/bin/exiftool_files/lib/File/GlobMapper.pm +2 -2
  38. package/bin/exiftool_files/lib/File/HomeDir/Darwin/Carbon.pm +2 -40
  39. package/bin/exiftool_files/lib/File/HomeDir/Darwin/Cocoa.pm +2 -34
  40. package/bin/exiftool_files/lib/File/HomeDir/Darwin.pm +2 -28
  41. package/bin/exiftool_files/lib/File/HomeDir/Driver.pm +2 -35
  42. package/bin/exiftool_files/lib/File/HomeDir/FreeDesktop.pm +2 -62
  43. package/bin/exiftool_files/lib/File/HomeDir/MacOS9.pm +2 -53
  44. package/bin/exiftool_files/lib/File/HomeDir/Test.pm +2 -43
  45. package/bin/exiftool_files/lib/File/HomeDir/Unix.pm +2 -53
  46. package/bin/exiftool_files/lib/File/HomeDir/Windows.pm +2 -69
  47. package/bin/exiftool_files/lib/File/HomeDir.pm +5 -416
  48. package/bin/exiftool_files/lib/File/Path.pm +3 -3
  49. package/bin/exiftool_files/lib/File/Spec/Win32.pm +2 -2
  50. package/bin/exiftool_files/lib/File/Temp.pm +70 -35
  51. package/bin/exiftool_files/lib/File/Which.pm +1 -240
  52. package/bin/exiftool_files/lib/File/stat.pm +3 -2
  53. package/bin/exiftool_files/lib/IO/Compress/Adapter/Bzip2.pm +16 -17
  54. package/bin/exiftool_files/lib/IO/Compress/Adapter/Deflate.pm +19 -20
  55. package/bin/exiftool_files/lib/IO/Compress/Base/Common.pm +5 -5
  56. package/bin/exiftool_files/lib/IO/Compress/Base.pm +35 -26
  57. package/bin/exiftool_files/lib/IO/Compress/Brotli.pm +159 -0
  58. package/bin/exiftool_files/lib/IO/Compress/Bzip2.pm +50 -25
  59. package/bin/exiftool_files/lib/IO/Compress/Gzip/Constants.pm +6 -6
  60. package/bin/exiftool_files/lib/IO/Compress/Gzip.pm +58 -32
  61. package/bin/exiftool_files/lib/IO/Compress/RawDeflate.pm +63 -38
  62. package/bin/exiftool_files/lib/IO/Compress/Zlib/Extra.pm +20 -20
  63. package/bin/exiftool_files/lib/IO/Dir.pm +1 -1
  64. package/bin/exiftool_files/lib/IO/File.pm +1 -1
  65. package/bin/exiftool_files/lib/IO/Handle.pm +1 -21
  66. package/bin/exiftool_files/lib/IO/Pipe.pm +1 -1
  67. package/bin/exiftool_files/lib/IO/Seekable.pm +1 -1
  68. package/bin/exiftool_files/lib/IO/Select.pm +16 -2
  69. package/bin/exiftool_files/lib/IO/Socket/INET.pm +14 -9
  70. package/bin/exiftool_files/lib/IO/Socket/UNIX.pm +17 -1
  71. package/bin/exiftool_files/lib/IO/Socket.pm +474 -126
  72. package/bin/exiftool_files/lib/IO/String.pm +425 -0
  73. package/bin/exiftool_files/lib/IO/Uncompress/Adapter/Inflate.pm +13 -14
  74. package/bin/exiftool_files/lib/IO/Uncompress/Base.pm +142 -132
  75. package/bin/exiftool_files/lib/IO/Uncompress/Brotli.pm +119 -0
  76. package/bin/exiftool_files/lib/IO/Uncompress/Gunzip.pm +43 -37
  77. package/bin/exiftool_files/lib/IO/Uncompress/RawInflate.pm +49 -43
  78. package/bin/exiftool_files/lib/IO.pm +2 -2
  79. package/bin/exiftool_files/lib/List/Util.pm +97 -8
  80. package/bin/exiftool_files/lib/MIME/Base64.pm +5 -5
  81. package/bin/exiftool_files/lib/MIME/Charset/_Compat.pm +106 -0
  82. package/bin/exiftool_files/lib/MIME/Charset.pm +1303 -0
  83. package/bin/exiftool_files/lib/Math/BigFloat.pm +444 -27
  84. package/bin/exiftool_files/lib/Math/BigInt/Calc.pm +296 -313
  85. package/bin/exiftool_files/lib/Math/BigInt/FastCalc.pm +1 -1
  86. package/bin/exiftool_files/lib/Math/BigInt/GMP.pm +2 -115
  87. package/bin/exiftool_files/lib/Math/BigInt/LTM.pm +2 -24
  88. package/bin/exiftool_files/lib/Math/BigInt/Lib.pm +61 -32
  89. package/bin/exiftool_files/lib/Math/BigInt.pm +292 -107
  90. package/bin/exiftool_files/lib/POSIX.pm +1 -1
  91. package/bin/exiftool_files/lib/PerlIO/scalar.pm +41 -0
  92. package/bin/exiftool_files/lib/PerlIO.pm +397 -0
  93. package/bin/exiftool_files/lib/Portable/CPAN.pm +94 -94
  94. package/bin/exiftool_files/lib/Portable/Config.pm +94 -94
  95. package/bin/exiftool_files/lib/Portable/FileSpec.pm +180 -180
  96. package/bin/exiftool_files/lib/Portable/HomeDir.pm +110 -110
  97. package/bin/exiftool_files/lib/Portable/LoadYaml.pm +430 -430
  98. package/bin/exiftool_files/lib/Portable/minicpan.pm +55 -55
  99. package/bin/exiftool_files/lib/Portable.pm +246 -320
  100. package/bin/exiftool_files/lib/Scalar/Util.pm +9 -4
  101. package/bin/exiftool_files/lib/Socket.pm +16 -12
  102. package/bin/exiftool_files/lib/Storable.pm +1444 -1441
  103. package/bin/exiftool_files/lib/TAP/Base.pm +133 -0
  104. package/bin/exiftool_files/lib/TAP/Formatter/Base.pm +467 -0
  105. package/bin/exiftool_files/lib/TAP/Formatter/Color.pm +116 -0
  106. package/bin/exiftool_files/lib/TAP/Formatter/Console/ParallelSession.pm +201 -0
  107. package/bin/exiftool_files/lib/TAP/Formatter/Console/Session.pm +205 -0
  108. package/bin/exiftool_files/lib/TAP/Formatter/Console.pm +100 -0
  109. package/bin/exiftool_files/lib/TAP/Formatter/File/Session.pm +95 -0
  110. package/bin/exiftool_files/lib/TAP/Formatter/File.pm +56 -0
  111. package/bin/exiftool_files/lib/TAP/Formatter/Session.pm +220 -0
  112. package/bin/exiftool_files/lib/TAP/Harness/Beyond.pod +426 -0
  113. package/bin/exiftool_files/lib/TAP/Harness/Env.pm +215 -0
  114. package/bin/exiftool_files/lib/TAP/Harness.pm +1054 -0
  115. package/bin/exiftool_files/lib/TAP/Object.pm +155 -0
  116. package/bin/exiftool_files/lib/TAP/Parser/Aggregator.pm +414 -0
  117. package/bin/exiftool_files/lib/TAP/Parser/Grammar.pm +584 -0
  118. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Array.pm +100 -0
  119. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Process.pm +378 -0
  120. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Stream.pm +116 -0
  121. package/bin/exiftool_files/lib/TAP/Parser/Iterator.pm +162 -0
  122. package/bin/exiftool_files/lib/TAP/Parser/IteratorFactory.pm +339 -0
  123. package/bin/exiftool_files/lib/TAP/Parser/Multiplexer.pm +194 -0
  124. package/bin/exiftool_files/lib/TAP/Parser/Result/Bailout.pm +62 -0
  125. package/bin/exiftool_files/lib/TAP/Parser/Result/Comment.pm +60 -0
  126. package/bin/exiftool_files/lib/TAP/Parser/Result/Plan.pm +119 -0
  127. package/bin/exiftool_files/lib/TAP/Parser/Result/Pragma.pm +62 -0
  128. package/bin/exiftool_files/lib/TAP/Parser/Result/Test.pm +271 -0
  129. package/bin/exiftool_files/lib/TAP/Parser/Result/Unknown.pm +48 -0
  130. package/bin/exiftool_files/lib/TAP/Parser/Result/Version.pm +62 -0
  131. package/bin/exiftool_files/lib/TAP/Parser/Result/YAML.pm +61 -0
  132. package/bin/exiftool_files/lib/TAP/Parser/Result.pm +297 -0
  133. package/bin/exiftool_files/lib/TAP/Parser/ResultFactory.pm +183 -0
  134. package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Job.pm +127 -0
  135. package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Spinner.pm +61 -0
  136. package/bin/exiftool_files/lib/TAP/Parser/Scheduler.pm +448 -0
  137. package/bin/exiftool_files/lib/TAP/Parser/Source.pm +381 -0
  138. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Executable.pm +184 -0
  139. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/File.pm +136 -0
  140. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Handle.pm +124 -0
  141. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Perl.pm +370 -0
  142. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/RawTAP.pm +130 -0
  143. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler.pm +191 -0
  144. package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Reader.pm +332 -0
  145. package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Writer.pm +254 -0
  146. package/bin/exiftool_files/lib/TAP/Parser.pm +1931 -0
  147. package/bin/exiftool_files/lib/Test/Builder/Formatter.pm +107 -0
  148. package/bin/exiftool_files/lib/Test/Builder/IO/Scalar.pm +659 -0
  149. package/bin/exiftool_files/lib/Test/Builder/Module.pm +182 -0
  150. package/bin/exiftool_files/lib/Test/Builder/Tester/Color.pm +51 -0
  151. package/bin/exiftool_files/lib/Test/Builder/Tester.pm +675 -0
  152. package/bin/exiftool_files/lib/Test/Builder/TodoDiag.pm +68 -0
  153. package/bin/exiftool_files/lib/Test/Builder.pm +2653 -0
  154. package/bin/exiftool_files/lib/Test/Harness.pm +618 -0
  155. package/bin/exiftool_files/lib/Test/More.pm +1997 -0
  156. package/bin/exiftool_files/lib/Test/Simple.pm +220 -0
  157. package/bin/exiftool_files/lib/Test/Tester/Capture.pm +241 -0
  158. package/bin/exiftool_files/lib/Test/Tester/CaptureRunner.pm +79 -0
  159. package/bin/exiftool_files/lib/Test/Tester/Delegate.pm +45 -0
  160. package/bin/exiftool_files/lib/Test/Tester.pm +695 -0
  161. package/bin/exiftool_files/lib/Test/Tutorial.pod +618 -0
  162. package/bin/exiftool_files/lib/Test/use/ok.pm +64 -0
  163. package/bin/exiftool_files/lib/Text/ParseWords.pm +303 -0
  164. package/bin/exiftool_files/lib/Tie/StdHandle.pm +2 -2
  165. package/bin/exiftool_files/lib/Time/HiRes.pm +73 -68
  166. package/bin/exiftool_files/lib/Time/Local.pm +82 -35
  167. package/bin/exiftool_files/lib/Time/Piece.pm +19 -4
  168. package/bin/exiftool_files/lib/Time/Seconds.pm +1 -1
  169. package/bin/exiftool_files/lib/UNIVERSAL.pm +203 -0
  170. package/bin/exiftool_files/lib/Unicode/GCString.pm +60 -0
  171. package/bin/exiftool_files/lib/Unicode/LineBreak/Constants.pm +68 -0
  172. package/bin/exiftool_files/lib/Unicode/LineBreak.pm +248 -0
  173. package/bin/exiftool_files/lib/Win32/API/Struct.pm +1 -177
  174. package/bin/exiftool_files/lib/Win32/API/Type.pm +1 -100
  175. package/bin/exiftool_files/lib/Win32/API.pm +1 -830
  176. package/bin/exiftool_files/lib/Win32/FindFile.pm +2 -123
  177. package/bin/exiftool_files/lib/Win32.pm +213 -89
  178. package/bin/exiftool_files/lib/Win32API/File.pm +1 -1
  179. package/bin/exiftool_files/lib/auto/B/B.xs.dll +0 -0
  180. package/bin/exiftool_files/lib/auto/Compress/Raw/Bzip2/Bzip2.xs.dll +0 -0
  181. package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/Lzma.xs.dll +0 -0
  182. package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/autosplit.ix +3 -0
  183. package/bin/exiftool_files/lib/auto/Compress/Raw/Zlib/Zlib.xs.dll +0 -0
  184. package/bin/exiftool_files/lib/auto/CryptX/CryptX.xs.dll +0 -0
  185. package/bin/exiftool_files/lib/auto/Cwd/Cwd.xs.dll +0 -0
  186. package/bin/exiftool_files/lib/auto/Data/Dumper/Dumper.xs.dll +0 -0
  187. package/bin/exiftool_files/lib/auto/Digest/MD5/MD5.xs.dll +0 -0
  188. package/bin/exiftool_files/lib/auto/Digest/SHA/SHA.xs.dll +0 -0
  189. package/bin/exiftool_files/lib/auto/Encode/Encode.xs.dll +0 -0
  190. package/bin/exiftool_files/lib/auto/Fcntl/Fcntl.xs.dll +0 -0
  191. package/bin/exiftool_files/lib/auto/File/Glob/Glob.xs.dll +0 -0
  192. package/bin/exiftool_files/lib/auto/IO/Compress/Brotli/Brotli.xs.dll +0 -0
  193. package/bin/exiftool_files/lib/auto/IO/IO.xs.dll +0 -0
  194. package/bin/exiftool_files/lib/auto/List/Util/Util.xs.dll +0 -0
  195. package/bin/exiftool_files/lib/auto/MIME/Base64/Base64.xs.dll +0 -0
  196. package/bin/exiftool_files/lib/auto/Math/BigInt/FastCalc/FastCalc.xs.dll +0 -0
  197. package/bin/exiftool_files/lib/auto/Math/BigInt/GMP/GMP.xs.dll +0 -0
  198. package/bin/exiftool_files/lib/auto/POSIX/POSIX.xs.dll +0 -0
  199. package/bin/exiftool_files/lib/auto/PerlIO/scalar/scalar.xs.dll +0 -0
  200. package/bin/exiftool_files/lib/auto/Socket/Socket.xs.dll +0 -0
  201. package/bin/exiftool_files/lib/auto/Storable/Storable.xs.dll +0 -0
  202. package/bin/exiftool_files/lib/auto/Time/HiRes/HiRes.xs.dll +0 -0
  203. package/bin/exiftool_files/lib/auto/Time/Piece/Piece.xs.dll +0 -0
  204. package/bin/exiftool_files/lib/auto/Unicode/LineBreak/LineBreak.xs.dll +0 -0
  205. package/bin/exiftool_files/lib/auto/Win32/API/API.xs.dll +0 -0
  206. package/bin/exiftool_files/lib/auto/Win32/FindFile/FindFile.xs.dll +0 -0
  207. package/bin/exiftool_files/lib/auto/Win32/Win32.xs.dll +0 -0
  208. package/bin/exiftool_files/lib/auto/Win32API/File/File.xs.dll +0 -0
  209. package/bin/exiftool_files/lib/auto/mro/mro.xs.dll +0 -0
  210. package/bin/exiftool_files/lib/auto/re/re.xs.dll +0 -0
  211. package/bin/exiftool_files/lib/feature.pm +49 -17
  212. package/bin/exiftool_files/lib/mro.pm +4 -20
  213. package/bin/exiftool_files/lib/overload.pm +15 -15
  214. package/bin/exiftool_files/lib/parent.pm +10 -2
  215. package/bin/exiftool_files/lib/re.pm +91 -33
  216. package/bin/exiftool_files/lib/warnings.pm +17 -6
  217. package/bin/exiftool_files/libgcc_s_seh-1.dll +0 -0
  218. package/bin/exiftool_files/liblzma-5__.dll +0 -0
  219. package/bin/exiftool_files/libstdc++-6.dll +0 -0
  220. package/bin/exiftool_files/libwinpthread-1.dll +0 -0
  221. package/bin/exiftool_files/perl.exe +0 -0
  222. package/bin/exiftool_files/perl532.dll +0 -0
  223. package/package.json +5 -3
  224. package/bin/exiftool_files/libgcc_s_dw2-1.dll +0 -0
  225. package/bin/exiftool_files/perl530.dll +0 -0
@@ -0,0 +1,339 @@
1
+ package TAP::Parser::IteratorFactory;
2
+
3
+ use strict;
4
+ use warnings;
5
+
6
+ use Carp qw( confess );
7
+ use File::Basename qw( fileparse );
8
+
9
+ use base 'TAP::Object';
10
+
11
+ use constant handlers => [];
12
+
13
+ =head1 NAME
14
+
15
+ TAP::Parser::IteratorFactory - Figures out which SourceHandler objects to use for a given Source
16
+
17
+ =head1 VERSION
18
+
19
+ Version 3.42
20
+
21
+ =cut
22
+
23
+ our $VERSION = '3.42';
24
+
25
+ =head1 SYNOPSIS
26
+
27
+ use TAP::Parser::IteratorFactory;
28
+ my $factory = TAP::Parser::IteratorFactory->new({ %config });
29
+ my $iterator = $factory->make_iterator( $filename );
30
+
31
+ =head1 DESCRIPTION
32
+
33
+ This is a factory class that takes a L<TAP::Parser::Source> and runs it through all the
34
+ registered L<TAP::Parser::SourceHandler>s to see which one should handle the source.
35
+
36
+ If you're a plugin author, you'll be interested in how to L</register_handler>s,
37
+ how L</detect_source> works.
38
+
39
+ =head1 METHODS
40
+
41
+ =head2 Class Methods
42
+
43
+ =head3 C<new>
44
+
45
+ Creates a new factory class:
46
+
47
+ my $sf = TAP::Parser::IteratorFactory->new( $config );
48
+
49
+ C<$config> is optional. If given, sets L</config> and calls L</load_handlers>.
50
+
51
+ =cut
52
+
53
+ sub _initialize {
54
+ my ( $self, $config ) = @_;
55
+ $self->config( $config || {} )->load_handlers;
56
+ return $self;
57
+ }
58
+
59
+ =head3 C<register_handler>
60
+
61
+ Registers a new L<TAP::Parser::SourceHandler> with this factory.
62
+
63
+ __PACKAGE__->register_handler( $handler_class );
64
+
65
+ =head3 C<handlers>
66
+
67
+ List of handlers that have been registered.
68
+
69
+ =cut
70
+
71
+ sub register_handler {
72
+ my ( $class, $dclass ) = @_;
73
+
74
+ confess("$dclass must implement can_handle & make_iterator methods!")
75
+ unless UNIVERSAL::can( $dclass, 'can_handle' )
76
+ && UNIVERSAL::can( $dclass, 'make_iterator' );
77
+
78
+ my $handlers = $class->handlers;
79
+ push @{$handlers}, $dclass
80
+ unless grep { $_ eq $dclass } @{$handlers};
81
+
82
+ return $class;
83
+ }
84
+
85
+ ##############################################################################
86
+
87
+ =head2 Instance Methods
88
+
89
+ =head3 C<config>
90
+
91
+ my $cfg = $sf->config;
92
+ $sf->config({ Perl => { %config } });
93
+
94
+ Chaining getter/setter for the configuration of the available source handlers.
95
+ This is a hashref keyed on handler class whose values contain config to be passed
96
+ onto the handlers during detection & creation. Class names may be fully qualified
97
+ or abbreviated, eg:
98
+
99
+ # these are equivalent
100
+ $sf->config({ 'TAP::Parser::SourceHandler::Perl' => { %config } });
101
+ $sf->config({ 'Perl' => { %config } });
102
+
103
+ =cut
104
+
105
+ sub config {
106
+ my $self = shift;
107
+ return $self->{config} unless @_;
108
+ unless ( 'HASH' eq ref $_[0] ) {
109
+ $self->_croak('Argument to &config must be a hash reference');
110
+ }
111
+ $self->{config} = shift;
112
+ return $self;
113
+ }
114
+
115
+ sub _last_handler {
116
+ my $self = shift;
117
+ return $self->{last_handler} unless @_;
118
+ $self->{last_handler} = shift;
119
+ return $self;
120
+ }
121
+
122
+ sub _testing {
123
+ my $self = shift;
124
+ return $self->{testing} unless @_;
125
+ $self->{testing} = shift;
126
+ return $self;
127
+ }
128
+
129
+ ##############################################################################
130
+
131
+ =head3 C<load_handlers>
132
+
133
+ $sf->load_handlers;
134
+
135
+ Loads the handler classes defined in L</config>. For example, given a config:
136
+
137
+ $sf->config({
138
+ MySourceHandler => { some => 'config' },
139
+ });
140
+
141
+ C<load_handlers> will attempt to load the C<MySourceHandler> class by looking in
142
+ C<@INC> for it in this order:
143
+
144
+ TAP::Parser::SourceHandler::MySourceHandler
145
+ MySourceHandler
146
+
147
+ C<croak>s on error.
148
+
149
+ =cut
150
+
151
+ sub load_handlers {
152
+ my ($self) = @_;
153
+ for my $handler ( keys %{ $self->config } ) {
154
+ my $sclass = $self->_load_handler($handler);
155
+
156
+ # TODO: store which class we loaded anywhere?
157
+ }
158
+ return $self;
159
+ }
160
+
161
+ sub _load_handler {
162
+ my ( $self, $handler ) = @_;
163
+
164
+ my @errors;
165
+ for my $dclass ( "TAP::Parser::SourceHandler::$handler", $handler ) {
166
+ return $dclass
167
+ if UNIVERSAL::can( $dclass, 'can_handle' )
168
+ && UNIVERSAL::can( $dclass, 'make_iterator' );
169
+
170
+ eval "use $dclass";
171
+ if ( my $e = $@ ) {
172
+ push @errors, $e;
173
+ next;
174
+ }
175
+
176
+ return $dclass
177
+ if UNIVERSAL::can( $dclass, 'can_handle' )
178
+ && UNIVERSAL::can( $dclass, 'make_iterator' );
179
+ push @errors,
180
+ "handler '$dclass' does not implement can_handle & make_iterator";
181
+ }
182
+
183
+ $self->_croak(
184
+ "Cannot load handler '$handler': " . join( "\n", @errors ) );
185
+ }
186
+
187
+ ##############################################################################
188
+
189
+ =head3 C<make_iterator>
190
+
191
+ my $iterator = $src_factory->make_iterator( $source );
192
+
193
+ Given a L<TAP::Parser::Source>, finds the most suitable L<TAP::Parser::SourceHandler>
194
+ to use to create a L<TAP::Parser::Iterator> (see L</detect_source>). Dies on error.
195
+
196
+ =cut
197
+
198
+ sub make_iterator {
199
+ my ( $self, $source ) = @_;
200
+
201
+ $self->_croak('no raw source defined!') unless defined $source->raw;
202
+
203
+ $source->config( $self->config )->assemble_meta;
204
+
205
+ # is the raw source already an object?
206
+ return $source->raw
207
+ if ( $source->meta->{is_object}
208
+ && UNIVERSAL::isa( $source->raw, 'TAP::Parser::SourceHandler' ) );
209
+
210
+ # figure out what kind of source it is
211
+ my $sd_class = $self->detect_source($source);
212
+ $self->_last_handler($sd_class);
213
+
214
+ return if $self->_testing;
215
+
216
+ # create it
217
+ my $iterator = $sd_class->make_iterator($source);
218
+
219
+ return $iterator;
220
+ }
221
+
222
+ =head3 C<detect_source>
223
+
224
+ Given a L<TAP::Parser::Source>, detects what kind of source it is and
225
+ returns I<one> L<TAP::Parser::SourceHandler> (the most confident one). Dies
226
+ on error.
227
+
228
+ The detection algorithm works something like this:
229
+
230
+ for (@registered_handlers) {
231
+ # ask them how confident they are about handling this source
232
+ $confidence{$handler} = $handler->can_handle( $source )
233
+ }
234
+ # choose the most confident handler
235
+
236
+ Ties are handled by choosing the first handler.
237
+
238
+ =cut
239
+
240
+ sub detect_source {
241
+ my ( $self, $source ) = @_;
242
+
243
+ confess('no raw source ref defined!') unless defined $source->raw;
244
+
245
+ # find a list of handlers that can handle this source:
246
+ my %confidence_for;
247
+ for my $handler ( @{ $self->handlers } ) {
248
+ my $confidence = $handler->can_handle($source);
249
+ # warn "handler: $handler: $confidence\n";
250
+ $confidence_for{$handler} = $confidence if $confidence;
251
+ }
252
+
253
+ if ( !%confidence_for ) {
254
+ # error: can't detect source
255
+ my $raw_source_short = substr( ${ $source->raw }, 0, 50 );
256
+ confess("Cannot detect source of '$raw_source_short'!");
257
+ return;
258
+ }
259
+
260
+ # if multiple handlers can handle it, choose the most confident one
261
+ my @handlers =
262
+ sort { $confidence_for{$b} <=> $confidence_for{$a} }
263
+ keys %confidence_for;
264
+
265
+ # Check for a tie.
266
+ if( @handlers > 1 &&
267
+ $confidence_for{$handlers[0]} == $confidence_for{$handlers[1]}
268
+ ) {
269
+ my $filename = $source->meta->{file}{basename};
270
+ die("There is a tie between $handlers[0] and $handlers[1].\n".
271
+ "Both voted $confidence_for{$handlers[0]} on $filename.\n");
272
+ }
273
+
274
+ # this is really useful for debugging handlers:
275
+ if ( $ENV{TAP_HARNESS_SOURCE_FACTORY_VOTES} ) {
276
+ warn(
277
+ "votes: ",
278
+ join( ', ', map {"$_: $confidence_for{$_}"} @handlers ),
279
+ "\n"
280
+ );
281
+ }
282
+
283
+ # return 1st
284
+ return $handlers[0];
285
+ }
286
+
287
+ 1;
288
+
289
+ __END__
290
+
291
+ =head1 SUBCLASSING
292
+
293
+ Please see L<TAP::Parser/SUBCLASSING> for a subclassing overview.
294
+
295
+ =head2 Example
296
+
297
+ If we've done things right, you'll probably want to write a new source,
298
+ rather than sub-classing this (see L<TAP::Parser::SourceHandler> for that).
299
+
300
+ But in case you find the need to...
301
+
302
+ package MyIteratorFactory;
303
+
304
+ use strict;
305
+
306
+ use base 'TAP::Parser::IteratorFactory';
307
+
308
+ # override source detection algorithm
309
+ sub detect_source {
310
+ my ($self, $raw_source_ref, $meta) = @_;
311
+ # do detective work, using $meta and whatever else...
312
+ }
313
+
314
+ 1;
315
+
316
+ =head1 AUTHORS
317
+
318
+ Steve Purkis
319
+
320
+ =head1 ATTRIBUTION
321
+
322
+ Originally ripped off from L<Test::Harness>.
323
+
324
+ Moved out of L<TAP::Parser> & converted to a factory class to support
325
+ extensible TAP source detective work by Steve Purkis.
326
+
327
+ =head1 SEE ALSO
328
+
329
+ L<TAP::Object>,
330
+ L<TAP::Parser>,
331
+ L<TAP::Parser::SourceHandler>,
332
+ L<TAP::Parser::SourceHandler::File>,
333
+ L<TAP::Parser::SourceHandler::Perl>,
334
+ L<TAP::Parser::SourceHandler::RawTAP>,
335
+ L<TAP::Parser::SourceHandler::Handle>,
336
+ L<TAP::Parser::SourceHandler::Executable>
337
+
338
+ =cut
339
+
@@ -0,0 +1,194 @@
1
+ package TAP::Parser::Multiplexer;
2
+
3
+ use strict;
4
+ use warnings;
5
+
6
+ use IO::Select;
7
+
8
+ use base 'TAP::Object';
9
+
10
+ use constant IS_WIN32 => $^O =~ /^(MS)?Win32$/;
11
+ use constant IS_VMS => $^O eq 'VMS';
12
+ use constant SELECT_OK => !( IS_VMS || IS_WIN32 );
13
+
14
+ =head1 NAME
15
+
16
+ TAP::Parser::Multiplexer - Multiplex multiple TAP::Parsers
17
+
18
+ =head1 VERSION
19
+
20
+ Version 3.42
21
+
22
+ =cut
23
+
24
+ our $VERSION = '3.42';
25
+
26
+ =head1 SYNOPSIS
27
+
28
+ use TAP::Parser::Multiplexer;
29
+
30
+ my $mux = TAP::Parser::Multiplexer->new;
31
+ $mux->add( $parser1, $stash1 );
32
+ $mux->add( $parser2, $stash2 );
33
+ while ( my ( $parser, $stash, $result ) = $mux->next ) {
34
+ # do stuff
35
+ }
36
+
37
+ =head1 DESCRIPTION
38
+
39
+ C<TAP::Parser::Multiplexer> gathers input from multiple TAP::Parsers.
40
+ Internally it calls select on the input file handles for those parsers
41
+ to wait for one or more of them to have input available.
42
+
43
+ See L<TAP::Harness> for an example of its use.
44
+
45
+ =head1 METHODS
46
+
47
+ =head2 Class Methods
48
+
49
+ =head3 C<new>
50
+
51
+ my $mux = TAP::Parser::Multiplexer->new;
52
+
53
+ Returns a new C<TAP::Parser::Multiplexer> object.
54
+
55
+ =cut
56
+
57
+ # new() implementation supplied by TAP::Object
58
+
59
+ sub _initialize {
60
+ my $self = shift;
61
+ $self->{select} = IO::Select->new;
62
+ $self->{avid} = []; # Parsers that can't select
63
+ $self->{count} = 0;
64
+ return $self;
65
+ }
66
+
67
+ ##############################################################################
68
+
69
+ =head2 Instance Methods
70
+
71
+ =head3 C<add>
72
+
73
+ $mux->add( $parser, $stash );
74
+
75
+ Add a TAP::Parser to the multiplexer. C<$stash> is an optional opaque
76
+ reference that will be returned from C<next> along with the parser and
77
+ the next result.
78
+
79
+ =cut
80
+
81
+ sub add {
82
+ my ( $self, $parser, $stash ) = @_;
83
+
84
+ if ( SELECT_OK && ( my @handles = $parser->get_select_handles ) ) {
85
+ my $sel = $self->{select};
86
+
87
+ # We have to turn handles into file numbers here because by
88
+ # the time we want to remove them from our IO::Select they
89
+ # will already have been closed by the iterator.
90
+ my @filenos = map { fileno $_ } @handles;
91
+ for my $h (@handles) {
92
+ $sel->add( [ $h, $parser, $stash, @filenos ] );
93
+ }
94
+
95
+ $self->{count}++;
96
+ }
97
+ else {
98
+ push @{ $self->{avid} }, [ $parser, $stash ];
99
+ }
100
+ }
101
+
102
+ =head3 C<parsers>
103
+
104
+ my $count = $mux->parsers;
105
+
106
+ Returns the number of parsers. Parsers are removed from the multiplexer
107
+ when their input is exhausted.
108
+
109
+ =cut
110
+
111
+ sub parsers {
112
+ my $self = shift;
113
+ return $self->{count} + scalar @{ $self->{avid} };
114
+ }
115
+
116
+ sub _iter {
117
+ my $self = shift;
118
+
119
+ my $sel = $self->{select};
120
+ my $avid = $self->{avid};
121
+ my @ready = ();
122
+
123
+ return sub {
124
+
125
+ # Drain all the non-selectable parsers first
126
+ if (@$avid) {
127
+ my ( $parser, $stash ) = @{ $avid->[0] };
128
+ my $result = $parser->next;
129
+ shift @$avid unless defined $result;
130
+ return ( $parser, $stash, $result );
131
+ }
132
+
133
+ unless (@ready) {
134
+ return unless $sel->count;
135
+ @ready = $sel->can_read;
136
+ }
137
+
138
+ my ( $h, $parser, $stash, @handles ) = @{ shift @ready };
139
+ my $result = $parser->next;
140
+
141
+ unless ( defined $result ) {
142
+ $sel->remove(@handles);
143
+ $self->{count}--;
144
+
145
+ # Force another can_read - we may now have removed a handle
146
+ # thought to have been ready.
147
+ @ready = ();
148
+ }
149
+
150
+ return ( $parser, $stash, $result );
151
+ };
152
+ }
153
+
154
+ =head3 C<next>
155
+
156
+ Return a result from the next available parser. Returns a list
157
+ containing the parser from which the result came, the stash that
158
+ corresponds with that parser and the result.
159
+
160
+ my ( $parser, $stash, $result ) = $mux->next;
161
+
162
+ If C<$result> is undefined the corresponding parser has reached the end
163
+ of its input (and will automatically be removed from the multiplexer).
164
+
165
+ When all parsers are exhausted an empty list will be returned.
166
+
167
+ if ( my ( $parser, $stash, $result ) = $mux->next ) {
168
+ if ( ! defined $result ) {
169
+ # End of this parser
170
+ }
171
+ else {
172
+ # Process result
173
+ }
174
+ }
175
+ else {
176
+ # All parsers finished
177
+ }
178
+
179
+ =cut
180
+
181
+ sub next {
182
+ my $self = shift;
183
+ return ( $self->{_iter} ||= $self->_iter )->();
184
+ }
185
+
186
+ =head1 See Also
187
+
188
+ L<TAP::Parser>
189
+
190
+ L<TAP::Harness>
191
+
192
+ =cut
193
+
194
+ 1;
@@ -0,0 +1,62 @@
1
+ package TAP::Parser::Result::Bailout;
2
+
3
+ use strict;
4
+ use warnings;
5
+
6
+ use base 'TAP::Parser::Result';
7
+
8
+ =head1 NAME
9
+
10
+ TAP::Parser::Result::Bailout - Bailout result token.
11
+
12
+ =head1 VERSION
13
+
14
+ Version 3.42
15
+
16
+ =cut
17
+
18
+ our $VERSION = '3.42';
19
+
20
+ =head1 DESCRIPTION
21
+
22
+ This is a subclass of L<TAP::Parser::Result>. A token of this class will be
23
+ returned if a bail out line is encountered.
24
+
25
+ 1..5
26
+ ok 1 - woo hooo!
27
+ Bail out! Well, so much for "woo hooo!"
28
+
29
+ =head1 OVERRIDDEN METHODS
30
+
31
+ Mainly listed here to shut up the pitiful screams of the pod coverage tests.
32
+ They keep me awake at night.
33
+
34
+ =over 4
35
+
36
+ =item * C<as_string>
37
+
38
+ =back
39
+
40
+ =cut
41
+
42
+ ##############################################################################
43
+
44
+ =head2 Instance Methods
45
+
46
+ =head3 C<explanation>
47
+
48
+ if ( $result->is_bailout ) {
49
+ my $explanation = $result->explanation;
50
+ print "We bailed out because ($explanation)";
51
+ }
52
+
53
+ If, and only if, a token is a bailout token, you can get an "explanation" via
54
+ this method. The explanation is the text after the mystical "Bail out!" words
55
+ which appear in the tap output.
56
+
57
+ =cut
58
+
59
+ sub explanation { shift->{bailout} }
60
+ sub as_string { shift->{bailout} }
61
+
62
+ 1;
@@ -0,0 +1,60 @@
1
+ package TAP::Parser::Result::Comment;
2
+
3
+ use strict;
4
+ use warnings;
5
+
6
+ use base 'TAP::Parser::Result';
7
+
8
+ =head1 NAME
9
+
10
+ TAP::Parser::Result::Comment - Comment result token.
11
+
12
+ =head1 VERSION
13
+
14
+ Version 3.42
15
+
16
+ =cut
17
+
18
+ our $VERSION = '3.42';
19
+
20
+ =head1 DESCRIPTION
21
+
22
+ This is a subclass of L<TAP::Parser::Result>. A token of this class will be
23
+ returned if a comment line is encountered.
24
+
25
+ 1..1
26
+ ok 1 - woo hooo!
27
+ # this is a comment
28
+
29
+ =head1 OVERRIDDEN METHODS
30
+
31
+ Mainly listed here to shut up the pitiful screams of the pod coverage tests.
32
+ They keep me awake at night.
33
+
34
+ =over 4
35
+
36
+ =item * C<as_string>
37
+
38
+ Note that this method merely returns the comment preceded by a '# '.
39
+
40
+ =back
41
+
42
+ =cut
43
+
44
+ ##############################################################################
45
+
46
+ =head2 Instance Methods
47
+
48
+ =head3 C<comment>
49
+
50
+ if ( $result->is_comment ) {
51
+ my $comment = $result->comment;
52
+ print "I have something to say: $comment";
53
+ }
54
+
55
+ =cut
56
+
57
+ sub comment { shift->{comment} }
58
+ sub as_string { shift->{raw} }
59
+
60
+ 1;