Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #2 from toddr/master

Different patches from bug tracker
  • Loading branch information...
commit d971407e60c26e735e26c72b3a509a165df08a5f 2 parents 8b0a6dd + ade7d56
Alexandr Ciornii authored
Showing with 474 additions and 456 deletions.
  1. +8 −0 Changes
  2. +9 −8 Expat/Expat.pm
  3. +3 −3 Parser.pm
  4. +454 −445 inc/Devel/CheckLib.pm
8 Changes
View
@@ -1,5 +1,13 @@
Revision history for Perl extension XML::Parser.
+2.40_01 2011-05-24 (by Todd Rinaldo)
+ - better installation instructions
+ - Small spelling patches from Debian package - Thanks Nicholas Bamber
+ - RT 68399 - Upgrade Devel::CheckLib to 0.93 to make it
+ perl 5.14 compliant - qw()
+ - RT 67207 - Stop doing tied on globs - Thanks sprout
+ - RT 31319 - Fix doc links in POD for XML/Parser.pm
+
2.40 2010-09-16 (by Alexandr Ciornii)
- Add windows-1251.enc, ibm866.enc, koi8-r.enc (Russian)
- Add windows-1255.enc (Hebrew)
17 Expat/Expat.pm
View
@@ -10,7 +10,7 @@ use Carp;
require DynaLoader;
@ISA = qw(DynaLoader);
-$VERSION = "2.40";
+$VERSION = "2.40_01";
$have_File_Spec = $INC{'File/Spec.pm'} || do 'File/Spec.pm';
@@ -442,12 +442,12 @@ sub parse {
my $result = 0;
if (defined $arg) {
+ local *@;
if (ref($arg) and UNIVERSAL::isa($arg, 'IO::Handle')) {
$ioref = $arg;
- } elsif (tied($arg)) {
- my $class = ref($arg);
- no strict 'refs';
- $ioref = $arg if defined &{"${class}::TIEHANDLE"};
+ } elsif ($] < 5.008 and defined tied($arg)) {
+ require IO::Handle;
+ $ioref = $arg;
}
else {
require IO::Handle;
@@ -455,20 +455,21 @@ sub parse {
no strict 'refs';
$ioref = *{$arg}{IO} if defined *{$arg};
};
- undef $@;
}
}
if (defined($ioref)) {
my $delim = $self->{Stream_Delimiter};
my $prev_rs;
+ my $ioclass = ref $ioref;
+ $ioclass = "IO::Handle" if !length $ioclass;
- $prev_rs = ref($ioref)->input_record_separator("\n$delim\n")
+ $prev_rs = $ioclass->input_record_separator("\n$delim\n")
if defined($delim);
$result = ParseStream($parser, $ioref, $delim);
- ref($ioref)->input_record_separator($prev_rs)
+ $ioclass->input_record_separator($prev_rs)
if defined($delim);
} else {
$result = ParseString($parser, $arg);
6 Parser.pm
View
@@ -16,7 +16,7 @@ use Carp;
BEGIN {
require XML::Parser::Expat;
- $VERSION = '2.40';
+ $VERSION = '2.40_01';
die "Parser.pm and Expat.pm versions don't match"
unless $VERSION eq $XML::Parser::Expat::VERSION;
}
@@ -375,8 +375,8 @@ These options are then passed on to the Expat object on each parse call.
They can also be given as extra arguments to the parse methods, in which
case they override options given at XML::Parser creation time.
-The behavior of the parser is controlled either by C<L</Style>> and/or
-C<L</Handlers>> options, or by L</setHandlers> method. These all provide
+The behavior of the parser is controlled either by C<L</STYLES>> and/or
+C<L</HANDLERS>> options, or by L</setHandlers> method. These all provide
mechanisms for XML::Parser to set the handlers needed by XML::Parser::Expat.
If neither C<Style> nor C<Handlers> are specified, then parsing just
checks the document for being well-formed.
899 inc/Devel/CheckLib.pm
View
@@ -1,445 +1,454 @@
-# $Id: CheckLib.pm,v 1.25 2008/10/27 12:16:23 drhyde Exp $
-
-package #
-Devel::CheckLib;
-
-use strict;
-use vars qw($VERSION @ISA @EXPORT);
-$VERSION = '0.7';
-use Config;
-
-use File::Spec;
-use File::Temp;
-
-require Exporter;
-@ISA = qw(Exporter);
-@EXPORT = qw(assert_lib check_lib_or_exit check_lib);
-
-# localising prevents the warningness leaking out of this module
-local $^W = 1; # use warnings is a 5.6-ism
-
-_findcc(); # bomb out early if there's no compiler
-
-=head1 NAME
-
-Devel::CheckLib - check that a library is available
-
-=head1 DESCRIPTION
-
-Devel::CheckLib is a perl module that checks whether a particular C
-library and its headers are available.
-
-=head1 SYNOPSIS
-
- use Devel::CheckLib;
-
- check_lib_or_exit( lib => 'jpeg', header => 'jpeglib.h' );
- check_lib_or_exit( lib => [ 'iconv', 'jpeg' ] );
-
- # or prompt for path to library and then do this:
- check_lib_or_exit( lib => 'jpeg', libpath => $additional_path );
-
-=head1 USING IT IN Makefile.PL or Build.PL
-
-If you want to use this from Makefile.PL or Build.PL, do
-not simply copy the module into your distribution as this may cause
-problems when PAUSE and search.cpan.org index the distro. Instead, use
-the use-devel-checklib script.
-
-=head1 HOW IT WORKS
-
-You pass named parameters to a function, describing to it how to build
-and link to the libraries.
-
-It works by trying to compile some code - which defaults to this:
-
- int main(void) { return 0; }
-
-and linking it to the specified libraries. If something pops out the end
-which looks executable, it gets executed, and if main() returns 0 we know
-that it worked. That tiny program is
-built once for each library that you specify, and (without linking) once
-for each header file.
-
-If you want to check for the presence of particular functions in a
-library, or even that those functions return particular results, then
-you can pass your own function body for main() thus:
-
- check_lib_or_exit(
- function => 'foo();if(libversion() > 5) return 0; else return 1;'
- incpath => ...
- libpath => ...
- lib => ...
- header => ...
- );
-
-In that case, it will fail to build if either foo() or libversion() don't
-exist, and main() will return the wrong value if libversion()'s return
-value isn't what you want.
-
-=head1 FUNCTIONS
-
-All of these take the same named parameters and are exported by default.
-To avoid exporting them, C<use Devel::CheckLib ()>.
-
-=head2 assert_lib
-
-This takes several named parameters, all of which are optional, and dies
-with an error message if any of the libraries listed can
-not be found. B<Note>: dying in a Makefile.PL or Build.PL may provoke
-a 'FAIL' report from CPAN Testers' automated smoke testers. Use
-C<check_lib_or_exit> instead.
-
-The named parameters are:
-
-=over
-
-=item lib
-
-Must be either a string with the name of a single
-library or a reference to an array of strings of library names. Depending
-on the compiler found, library names will be fed to the compiler either as
-C<-l> arguments or as C<.lib> file names. (E.g. C<-ljpeg> or C<jpeg.lib>)
-
-=item libpath
-
-a string or an array of strings
-representing additional paths to search for libraries.
-
-=item LIBS
-
-a C<ExtUtils::MakeMaker>-style space-seperated list of
-libraries (each preceded by '-l') and directories (preceded by '-L').
-
-This can also be supplied on the command-line.
-
-=back
-
-And libraries are no use without header files, so ...
-
-=over
-
-=item header
-
-Must be either a string with the name of a single
-header file or a reference to an array of strings of header file names.
-
-=item incpath
-
-a string or an array of strings
-representing additional paths to search for headers.
-
-=item INC
-
-a C<ExtUtils::MakeMaker>-style space-seperated list of
-incpaths, each preceded by '-I'.
-
-This can also be supplied on the command-line.
-
-=back
-
-=head2 check_lib_or_exit
-
-This behaves exactly the same as C<assert_lib()> except that instead of
-dieing, it warns (with exactly the same error message) and exits.
-This is intended for use in Makefile.PL / Build.PL
-when you might want to prompt the user for various paths and
-things before checking that what they've told you is sane.
-
-If any library or header is missing, it exits with an exit value of 0 to avoid
-causing a CPAN Testers 'FAIL' report. CPAN Testers should ignore this
-result -- which is what you want if an external library dependency is not
-available.
-
-=head2 check_lib
-
-This behaves exactly the same as C<assert_lib()> except that it is silent,
-returning false instead of dieing, or true otherwise.
-
-=cut
-
-sub check_lib_or_exit {
- eval 'assert_lib(@_)';
- if($@) {
- warn $@;
- exit;
- }
-}
-
-sub check_lib {
- eval 'assert_lib(@_)';
- return $@ ? 0 : 1;
-}
-
-sub assert_lib {
- my %args = @_;
- my (@libs, @libpaths, @headers, @incpaths);
-
- # FIXME: these four just SCREAM "refactor" at me
- @libs = (ref($args{lib}) ? @{$args{lib}} : $args{lib})
- if $args{lib};
- @libpaths = (ref($args{libpath}) ? @{$args{libpath}} : $args{libpath})
- if $args{libpath};
- @headers = (ref($args{header}) ? @{$args{header}} : $args{header})
- if $args{header};
- @incpaths = (ref($args{incpath}) ? @{$args{incpath}} : $args{incpath})
- if $args{incpath};
-
- # work-a-like for Makefile.PL's LIBS and INC arguments
- # if given as command-line argument, append to %args
- for my $arg (@ARGV) {
- for my $mm_attr_key qw(LIBS INC) {
- if (my ($mm_attr_value) = $arg =~ /\A $mm_attr_key = (.*)/x) {
- # it is tempting to put some \s* into the expression, but the
- # MM command-line parser only accepts LIBS etc. followed by =,
- # so we should not be any more lenient with whitespace than that
- $args{$mm_attr_key} .= " $mm_attr_value";
- }
- }
- }
-
- # using special form of split to trim whitespace
- if(defined($args{LIBS})) {
- foreach my $arg (split(' ', $args{LIBS})) {
- die("LIBS argument badly-formed: $arg\n") unless($arg =~ /^-l/i);
- push @{$arg =~ /^-l/ ? \@libs : \@libpaths}, substr($arg, 2);
- }
- }
- if(defined($args{INC})) {
- foreach my $arg (split(' ', $args{INC})) {
- die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/);
- push @incpaths, substr($arg, 2);
- }
- }
-
- my @cc = _findcc();
- my @missing;
- my @wrongresult;
-
- # first figure out which headers we can't find ...
- for my $header (@headers) {
- my($ch, $cfile) = File::Temp::tempfile(
- 'assertlibXXXXXXXX', SUFFIX => '.c'
- );
- print $ch qq{#include <$header>\nint main(void) { return 0; }\n};
- close($ch);
- my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
- my @sys_cmd;
- # FIXME: re-factor - almost identical code later when linking
- if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
- require Win32;
- @sys_cmd = (
- @cc,
- $cfile,
- "/Fe$exefile",
- (map { '/I'.Win32::GetShortPathName($_) } @incpaths)
- );
- } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
- @sys_cmd = (
- @cc,
- (map { "-I$_" } @incpaths),
- "-o$exefile",
- $cfile
- );
- } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
- @sys_cmd = (
- @cc,
- $cfile,
- (map { "-I$_" } @incpaths),
- "-o", "$exefile"
- );
- }
- warn "# @sys_cmd\n" if $args{debug};
- my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
- push @missing, $header if $rv != 0 || ! -x $exefile;
- _cleanup_exe($exefile);
- unlink $cfile;
- }
-
- # now do each library in turn with headers
- my($ch, $cfile) = File::Temp::tempfile(
- 'assertlibXXXXXXXX', SUFFIX => '.c'
- );
- print $ch qq{#include <$_>\n} foreach (@headers);
- print $ch "int main(void) { ".($args{function} || 'return 0;')." }\n";
- close($ch);
- for my $lib ( @libs ) {
- my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
- my @sys_cmd;
- if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
- require Win32;
- my @libpath = map {
- q{/libpath:} . Win32::GetShortPathName($_)
- } @libpaths;
- # this is horribly sensitive to the order of arguments
- @sys_cmd = (
- @cc,
- $cfile,
- "${lib}.lib",
- "/Fe$exefile",
- (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
- "/link",
- (map {'/libpath:'.Win32::GetShortPathName($_)} @libpaths),
- );
- } elsif($Config{cc} eq 'CC/DECC') { # VMS
- } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
- @sys_cmd = (
- @cc,
- "-o$exefile",
- "-l$lib",
- (map { "-I$_" } @incpaths),
- (map { "-L$_" } @libpaths),
- $cfile);
- } else { # Unix-ish
- # gcc, Sun, AIX (gcc, cc)
- @sys_cmd = (
- @cc,
- $cfile,
- "-o", "$exefile",
- "-l$lib",
- (map { "-I$_" } @incpaths),
- (map { "-L$_" } @libpaths)
- );
- }
- warn "# @sys_cmd\n" if $args{debug};
- my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
- push @missing, $lib if $rv != 0 || ! -x $exefile;
- push @wrongresult, $lib if $rv == 0 && -x $exefile && system(File::Spec->rel2abs($exefile)) != 0;
- _cleanup_exe($exefile);
- }
- unlink $cfile;
-
- my $miss_string = join( q{, }, map { qq{'$_'} } @missing );
- die("Can't link/include $miss_string\n") if @missing;
- my $wrong_string = join( q{, }, map { qq{'$_'} } @wrongresult);
- die("wrong result: $wrong_string\n") if @wrongresult;
-}
-
-sub _cleanup_exe {
- my ($exefile) = @_;
- my $ofile = $exefile;
- $ofile =~ s/$Config{_exe}$/$Config{_o}/;
- unlink $exefile if -f $exefile;
- unlink $ofile if -f $ofile;
- unlink "$exefile\.manifest" if -f "$exefile\.manifest";
- return
-}
-
-sub _findcc {
- my @paths = split(/$Config{path_sep}/, $ENV{PATH});
- my @cc = split(/\s+/, $Config{cc});
- return @cc if -x $cc[0];
- foreach my $path (@paths) {
- my $compiler = File::Spec->catfile($path, $cc[0]) . $Config{_exe};
- return ($compiler, @cc[1 .. $#cc]) if -x $compiler;
- }
- die("Couldn't find your C compiler\n");
-}
-
-# code substantially borrowed from IPC::Run3
-sub _quiet_system {
- my (@cmd) = @_;
-
- # save handles
- local *STDOUT_SAVE;
- local *STDERR_SAVE;
- open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT";
- open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR";
-
- # redirect to nowhere
- local *DEV_NULL;
- open DEV_NULL, ">" . File::Spec->devnull
- or die "CheckLib: $! opening handle to null device";
- open STDOUT, ">&" . fileno DEV_NULL
- or die "CheckLib: $! redirecting STDOUT to null handle";
- open STDERR, ">&" . fileno DEV_NULL
- or die "CheckLib: $! redirecting STDERR to null handle";
-
- # run system command
- my $rv = system(@cmd);
-
- # restore handles
- open STDOUT, ">&" . fileno STDOUT_SAVE
- or die "CheckLib: $! restoring STDOUT handle";
- open STDERR, ">&" . fileno STDERR_SAVE
- or die "CheckLib: $! restoring STDERR handle";
-
- return $rv;
-}
-
-=head1 PLATFORMS SUPPORTED
-
-You must have a C compiler installed. We check for C<$Config{cc}>,
-both literally as it is in Config.pm and also in the $PATH.
-
-It has been tested with varying degrees on rigourousness on:
-
-=over
-
-=item gcc (on Linux, *BSD, Mac OS X, Solaris, Cygwin)
-
-=item Sun's compiler tools on Solaris
-
-=item IBM's tools on AIX
-
-=item SGI's tools on Irix 6.5
-
-=item Microsoft's tools on Windows
-
-=item MinGW on Windows (with Strawberry Perl)
-
-=item Borland's tools on Windows
-
-=item QNX
-
-=back
-
-=head1 WARNINGS, BUGS and FEEDBACK
-
-This is a very early release intended primarily for feedback from
-people who have discussed it. The interface may change and it has
-not been adequately tested.
-
-Feedback is most welcome, including constructive criticism.
-Bug reports should be made using L<http://rt.cpan.org/> or by email.
-
-When submitting a bug report, please include the output from running:
-
- perl -V
- perl -MDevel::CheckLib -e0
-
-=head1 SEE ALSO
-
-L<Devel::CheckOS>
-
-L<Probe::Perl>
-
-=head1 AUTHORS
-
-David Cantrell E<lt>david@cantrell.org.ukE<gt>
-
-David Golden E<lt>dagolden@cpan.orgE<gt>
-
-Yasuhiro Matsumoto E<lt>mattn@cpan.orgE<gt>
-
-Thanks to the cpan-testers-discuss mailing list for prompting us to write it
-in the first place;
-
-to Chris Williams for help with Borland support;
-
-to Tony Cook for help with Microsoft compiler command-line options
-
-=head1 COPYRIGHT and LICENCE
-
-Copyright 2007 David Cantrell. Portions copyright 2007 David Golden.
-
-This module is free-as-in-speech software, and may be used, distributed,
-and modified under the same conditions as perl itself.
-
-=head1 CONSPIRACY
-
-This module is also free-as-in-mason software.
-
-=cut
-
-1;
+# $Id: CheckLib.pm,v 1.25 2008/10/27 12:16:23 drhyde Exp $
+
+package Devel::CheckLib;
+
+use 5.00405; #postfix foreach
+use strict;
+use vars qw($VERSION @ISA @EXPORT);
+$VERSION = '0.93';
+use Config qw(%Config);
+use Text::ParseWords 'quotewords';
+
+use File::Spec;
+use File::Temp;
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(assert_lib check_lib_or_exit check_lib);
+
+# localising prevents the warningness leaking out of this module
+local $^W = 1; # use warnings is a 5.6-ism
+
+_findcc(); # bomb out early if there's no compiler
+
+=head1 NAME
+
+Devel::CheckLib - check that a library is available
+
+=head1 DESCRIPTION
+
+Devel::CheckLib is a perl module that checks whether a particular C
+library and its headers are available.
+
+=head1 SYNOPSIS
+
+ use Devel::CheckLib;
+
+ check_lib_or_exit( lib => 'jpeg', header => 'jpeglib.h' );
+ check_lib_or_exit( lib => [ 'iconv', 'jpeg' ] );
+
+ # or prompt for path to library and then do this:
+ check_lib_or_exit( lib => 'jpeg', libpath => $additional_path );
+
+=head1 USING IT IN Makefile.PL or Build.PL
+
+If you want to use this from Makefile.PL or Build.PL, do
+not simply copy the module into your distribution as this may cause
+problems when PAUSE and search.cpan.org index the distro. Instead, use
+the use-devel-checklib script.
+
+=head1 HOW IT WORKS
+
+You pass named parameters to a function, describing to it how to build
+and link to the libraries.
+
+It works by trying to compile some code - which defaults to this:
+
+ int main(void) { return 0; }
+
+and linking it to the specified libraries. If something pops out the end
+which looks executable, it gets executed, and if main() returns 0 we know
+that it worked. That tiny program is
+built once for each library that you specify, and (without linking) once
+for each header file.
+
+If you want to check for the presence of particular functions in a
+library, or even that those functions return particular results, then
+you can pass your own function body for main() thus:
+
+ check_lib_or_exit(
+ function => 'foo();if(libversion() > 5) return 0; else return 1;'
+ incpath => ...
+ libpath => ...
+ lib => ...
+ header => ...
+ );
+
+In that case, it will fail to build if either foo() or libversion() don't
+exist, and main() will return the wrong value if libversion()'s return
+value isn't what you want.
+
+=head1 FUNCTIONS
+
+All of these take the same named parameters and are exported by default.
+To avoid exporting them, C<use Devel::CheckLib ()>.
+
+=head2 assert_lib
+
+This takes several named parameters, all of which are optional, and dies
+with an error message if any of the libraries listed can
+not be found. B<Note>: dying in a Makefile.PL or Build.PL may provoke
+a 'FAIL' report from CPAN Testers' automated smoke testers. Use
+C<check_lib_or_exit> instead.
+
+The named parameters are:
+
+=over
+
+=item lib
+
+Must be either a string with the name of a single
+library or a reference to an array of strings of library names. Depending
+on the compiler found, library names will be fed to the compiler either as
+C<-l> arguments or as C<.lib> file names. (E.g. C<-ljpeg> or C<jpeg.lib>)
+
+=item libpath
+
+a string or an array of strings
+representing additional paths to search for libraries.
+
+=item LIBS
+
+a C<ExtUtils::MakeMaker>-style space-seperated list of
+libraries (each preceded by '-l') and directories (preceded by '-L').
+
+This can also be supplied on the command-line.
+
+=back
+
+And libraries are no use without header files, so ...
+
+=over
+
+=item header
+
+Must be either a string with the name of a single
+header file or a reference to an array of strings of header file names.
+
+=item incpath
+
+a string or an array of strings
+representing additional paths to search for headers.
+
+=item INC
+
+a C<ExtUtils::MakeMaker>-style space-seperated list of
+incpaths, each preceded by '-I'.
+
+This can also be supplied on the command-line.
+
+=back
+
+=head2 check_lib_or_exit
+
+This behaves exactly the same as C<assert_lib()> except that instead of
+dieing, it warns (with exactly the same error message) and exits.
+This is intended for use in Makefile.PL / Build.PL
+when you might want to prompt the user for various paths and
+things before checking that what they've told you is sane.
+
+If any library or header is missing, it exits with an exit value of 0 to avoid
+causing a CPAN Testers 'FAIL' report. CPAN Testers should ignore this
+result -- which is what you want if an external library dependency is not
+available.
+
+=head2 check_lib
+
+This behaves exactly the same as C<assert_lib()> except that it is silent,
+returning false instead of dieing, or true otherwise.
+
+=cut
+
+sub check_lib_or_exit {
+ eval 'assert_lib(@_)';
+ if($@) {
+ warn $@;
+ exit;
+ }
+}
+
+sub check_lib {
+ eval 'assert_lib(@_)';
+ return $@ ? 0 : 1;
+}
+
+sub assert_lib {
+ my %args = @_;
+ my (@libs, @libpaths, @headers, @incpaths);
+
+ # FIXME: these four just SCREAM "refactor" at me
+ @libs = (ref($args{lib}) ? @{$args{lib}} : $args{lib})
+ if $args{lib};
+ @libpaths = (ref($args{libpath}) ? @{$args{libpath}} : $args{libpath})
+ if $args{libpath};
+ @headers = (ref($args{header}) ? @{$args{header}} : $args{header})
+ if $args{header};
+ @incpaths = (ref($args{incpath}) ? @{$args{incpath}} : $args{incpath})
+ if $args{incpath};
+
+ # work-a-like for Makefile.PL's LIBS and INC arguments
+ # if given as command-line argument, append to %args
+ for my $arg (@ARGV) {
+ for my $mm_attr_key (qw(LIBS INC)) {
+ if (my ($mm_attr_value) = $arg =~ /\A $mm_attr_key = (.*)/x) {
+ # it is tempting to put some \s* into the expression, but the
+ # MM command-line parser only accepts LIBS etc. followed by =,
+ # so we should not be any more lenient with whitespace than that
+ $args{$mm_attr_key} .= " $mm_attr_value";
+ }
+ }
+ }
+
+ # using special form of split to trim whitespace
+ if(defined($args{LIBS})) {
+ foreach my $arg (split(' ', $args{LIBS})) {
+ die("LIBS argument badly-formed: $arg\n") unless($arg =~ /^-l/i);
+ push @{$arg =~ /^-l/ ? \@libs : \@libpaths}, substr($arg, 2);
+ }
+ }
+ if(defined($args{INC})) {
+ foreach my $arg (split(' ', $args{INC})) {
+ die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/);
+ push @incpaths, substr($arg, 2);
+ }
+ }
+
+ my @cc = _findcc();
+ my @missing;
+ my @wrongresult;
+ my @use_headers;
+
+ # first figure out which headers we can't find ...
+ for my $header (@headers) {
+ push @use_headers, $header;
+ my($ch, $cfile) = File::Temp::tempfile(
+ 'assertlibXXXXXXXX', SUFFIX => '.c'
+ );
+ print $ch qq{#include <$_>\n} for @use_headers;
+ print $ch qq{int main(void) { return 0; }\n};
+ close($ch);
+ my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
+ my @sys_cmd;
+ # FIXME: re-factor - almost identical code later when linking
+ if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
+ require Win32;
+ @sys_cmd = (
+ @cc,
+ $cfile,
+ "/Fe$exefile",
+ (map { '/I'.Win32::GetShortPathName($_) } @incpaths)
+ );
+ } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
+ @sys_cmd = (
+ @cc,
+ (map { "-I$_" } @incpaths),
+ "-o$exefile",
+ $cfile
+ );
+ } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
+ @sys_cmd = (
+ @cc,
+ $cfile,
+ (map { "-I$_" } @incpaths),
+ "-o", "$exefile"
+ );
+ }
+ warn "# @sys_cmd\n" if $args{debug};
+ my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
+ push @missing, $header if $rv != 0 || ! -x $exefile;
+ _cleanup_exe($exefile);
+ unlink $cfile;
+ }
+
+ # now do each library in turn with headers
+ my($ch, $cfile) = File::Temp::tempfile(
+ 'assertlibXXXXXXXX', SUFFIX => '.c'
+ );
+ print $ch qq{#include <$_>\n} foreach (@headers);
+ print $ch "int main(void) { ".($args{function} || 'return 0;')." }\n";
+ close($ch);
+ for my $lib ( @libs ) {
+ my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
+ my @sys_cmd;
+ if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
+ require Win32;
+ my @libpath = map {
+ q{/libpath:} . Win32::GetShortPathName($_)
+ } @libpaths;
+ # this is horribly sensitive to the order of arguments
+ @sys_cmd = (
+ @cc,
+ $cfile,
+ "${lib}.lib",
+ "/Fe$exefile",
+ (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
+ "/link",
+ (map {'/libpath:'.Win32::GetShortPathName($_)} @libpaths),
+ );
+ } elsif($Config{cc} eq 'CC/DECC') { # VMS
+ } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
+ @sys_cmd = (
+ @cc,
+ "-o$exefile",
+ "-l$lib",
+ (map { "-I$_" } @incpaths),
+ (map { "-L$_" } @libpaths),
+ $cfile);
+ } else { # Unix-ish
+ # gcc, Sun, AIX (gcc, cc)
+ @sys_cmd = (
+ @cc,
+ $cfile,
+ "-o", "$exefile",
+ "-l$lib",
+ (map { "-I$_" } @incpaths),
+ (map { "-L$_" } @libpaths)
+ );
+ }
+ warn "# @sys_cmd\n" if $args{debug};
+ my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
+ push @missing, $lib if $rv != 0 || ! -x $exefile;
+ my $absexefile = File::Spec->rel2abs($exefile);
+ $absexefile = '"'.$absexefile.'"' if $absexefile =~ m/\s/;
+ push @wrongresult, $lib if $rv == 0 && -x $exefile && system($absexefile) != 0;
+ _cleanup_exe($exefile);
+ }
+ unlink $cfile;
+
+ my $miss_string = join( q{, }, map { qq{'$_'} } @missing );
+ die("Can't link/include $miss_string\n") if @missing;
+ my $wrong_string = join( q{, }, map { qq{'$_'} } @wrongresult);
+ die("wrong result: $wrong_string\n") if @wrongresult;
+}
+
+sub _cleanup_exe {
+ my ($exefile) = @_;
+ my $ofile = $exefile;
+ $ofile =~ s/$Config{_exe}$/$Config{_o}/;
+ unlink $exefile if -f $exefile;
+ unlink $ofile if -f $ofile;
+ unlink "$exefile\.manifest" if -f "$exefile\.manifest";
+ return
+}
+
+sub _findcc {
+ # Need to use $keep=1 to work with MSWin32 backslashes and quotes
+ my @Config_ccflags_ldflags = @Config{qw(ccflags ldflags)}; # use copy so ASPerl will compile
+ my @flags = grep { length } map { quotewords('\s+', 1, $_ || ()) } @Config_ccflags_ldflags;
+ my @paths = split(/$Config{path_sep}/, $ENV{PATH});
+ my @cc = split(/\s+/, $Config{cc});
+ return (@cc, @flags) if -x $cc[0];
+ foreach my $path (@paths) {
+ my $compiler = File::Spec->catfile($path, $cc[0]) . $Config{_exe};
+ return ($compiler, @cc[1 .. $#cc], @flags) if -x $compiler;
+ }
+ die("Couldn't find your C compiler\n");
+}
+
+# code substantially borrowed from IPC::Run3
+sub _quiet_system {
+ my (@cmd) = @_;
+
+ # save handles
+ local *STDOUT_SAVE;
+ local *STDERR_SAVE;
+ open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT";
+ open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR";
+
+ # redirect to nowhere
+ local *DEV_NULL;
+ open DEV_NULL, ">" . File::Spec->devnull
+ or die "CheckLib: $! opening handle to null device";
+ open STDOUT, ">&" . fileno DEV_NULL
+ or die "CheckLib: $! redirecting STDOUT to null handle";
+ open STDERR, ">&" . fileno DEV_NULL
+ or die "CheckLib: $! redirecting STDERR to null handle";
+
+ # run system command
+ my $rv = system(@cmd);
+
+ # restore handles
+ open STDOUT, ">&" . fileno STDOUT_SAVE
+ or die "CheckLib: $! restoring STDOUT handle";
+ open STDERR, ">&" . fileno STDERR_SAVE
+ or die "CheckLib: $! restoring STDERR handle";
+
+ return $rv;
+}
+
+=head1 PLATFORMS SUPPORTED
+
+You must have a C compiler installed. We check for C<$Config{cc}>,
+both literally as it is in Config.pm and also in the $PATH.
+
+It has been tested with varying degrees on rigourousness on:
+
+=over
+
+=item gcc (on Linux, *BSD, Mac OS X, Solaris, Cygwin)
+
+=item Sun's compiler tools on Solaris
+
+=item IBM's tools on AIX
+
+=item SGI's tools on Irix 6.5
+
+=item Microsoft's tools on Windows
+
+=item MinGW on Windows (with Strawberry Perl)
+
+=item Borland's tools on Windows
+
+=item QNX
+
+=back
+
+=head1 WARNINGS, BUGS and FEEDBACK
+
+This is a very early release intended primarily for feedback from
+people who have discussed it. The interface may change and it has
+not been adequately tested.
+
+Feedback is most welcome, including constructive criticism.
+Bug reports should be made using L<http://rt.cpan.org/> or by email.
+
+When submitting a bug report, please include the output from running:
+
+ perl -V
+ perl -MDevel::CheckLib -e0
+
+=head1 SEE ALSO
+
+L<Devel::CheckOS>
+
+L<Probe::Perl>
+
+=head1 AUTHORS
+
+David Cantrell E<lt>david@cantrell.org.ukE<gt>
+
+David Golden E<lt>dagolden@cpan.orgE<gt>
+
+Yasuhiro Matsumoto E<lt>mattn@cpan.orgE<gt>
+
+Thanks to the cpan-testers-discuss mailing list for prompting us to write it
+in the first place;
+
+to Chris Williams for help with Borland support;
+
+to Tony Cook for help with Microsoft compiler command-line options
+
+=head1 COPYRIGHT and LICENCE
+
+Copyright 2007 David Cantrell. Portions copyright 2007 David Golden.
+
+This module is free-as-in-speech software, and may be used, distributed,
+and modified under the same conditions as perl itself.
+
+=head1 CONSPIRACY
+
+This module is also free-as-in-mason software.
+
+=cut
+
+1;
Please sign in to comment.
Something went wrong with that request. Please try again.