# This forces PL files to create target in same directory as PL file.
# This is so that make depend always knows where to find PL derivatives.
-chdir(dirname($0));
-($file = basename($0)) =~ s/\.PL$//;
-$file =~ s/\.pl$//
- if ($^O eq 'VMS' or $^O eq 'os2'); # "case-forgiving"
+chdir dirname($0);
+$file = basename($0, '.PL');
+$file .= '.com' if $^O eq 'VMS';
open OUT,">$file" or die "Can't create $file: $!";
# You can use $Config{...} to use Configure variables.
print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
- eval 'exec perl -S \$0 "\$@"'
- if 0;
+$Config{startperl}
+ eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+ if \$running_under_some_shell;
!GROK!THIS!
# In the following, perl variables are not expanded during extraction.
=head1 SYNOPSIS
-B<h2xs> [B<-AOPXcf>] [B<-v> version] [B<-n> module_name] [B<-p> prefix] [B<-s> sub] [headerfile [extra_libraries]]
+B<h2xs> [B<-AOPXcdf>] [B<-v> version] [B<-n> module_name] [B<-p> prefix] [B<-s> sub] [headerfile ... [extra_libraries]]
B<h2xs> B<-h>
=head1 DESCRIPTION
-I<h2xs> builds a Perl extension from any C header file. The extension will
-include functions which can be used to retrieve the value of any #define
-statement which was in the C header.
+I<h2xs> builds a Perl extension from C header files. The extension
+will include functions which can be used to retrieve the value of any
+#define statement which was in the C header files.
The I<module_name> will be used for the name of the extension. If
-module_name is not supplied then the name of the header file will be used,
-with the first character capitalized.
+module_name is not supplied then the name of the first header file
+will be used, with the first character capitalized.
If the extension might need extra libraries, they should be included
here. The extension Makefile.PL will take care of checking whether
Omit all autoload facilities. This is the same as B<-c> but also removes the
S<C<require AutoLoader>> statement from the .pm file.
+=item B<-F>
+
+Additional flags to specify to C preprocessor when scanning header for
+function declarations. Should not be used without B<-x>.
+
=item B<-O>
Allows a pre-existing extension directory to be overwritten.
Omit the autogenerated stub POD section.
+=item B<-X>
+
+Omit the XS portion. Used to generate templates for a module which is not
+XS-based.
+
=item B<-c>
Omit C<constant()> from the .xs file and corresponding specialised
C<AUTOLOAD> from the .pm file.
+=item B<-d>
+
+Turn on debugging messages.
+
=item B<-f>
Allows an extension to be created for a header even if that header is
Specify a version number for this extension. This version number is added
to the templates. The default is 0.01.
-=item B<-X>
-
-Omit the XS portion. Used to generate templates for a module which is not
-XS-based.
-
=item B<-x>
Automatically generate XSUBs basing on function declarations in the
header file. The package C<C::Scan> should be installed. If this
option is specified, the name of the header file may look like
C<NAME1,NAME2>. In this case NAME1 is used instead of the specified string,
-but XSUBS are emited only for the declarations included from file NAME2.
+but XSUBs are emitted only for the declarations included from file NAME2.
Note that some types of arguments/return-values for functions may
result in XSUB-declarations/typemap-entries which need
hand-editing. Such may be objects which cannot be converted from/to a
pointer (like C<long long>), pointers to functions, or arrays.
-=item B<-F>
-
-Additional flags to specify to C preprocessor when scanning header for
-function declarations. Should not be used without B<-x>.
-
=back
=head1 EXAMPLES
=cut
-my( $H2XS_VERSION ) = ' $Revision: 1.16 $ ' =~ /\$Revision:\s+([^\s]+)/;
+my( $H2XS_VERSION ) = ' $Revision: 1.18 $ ' =~ /\$Revision:\s+([^\s]+)/;
my $TEMPLATE_VERSION = '0.01';
use Getopt::Std;
sub usage{
warn "@_\n" if @_;
- die "h2xs [-AOPXcfh] [-v version] [-n module_name] [-p prefix] [-s subs] [headerfile [extra_libraries]]
+ die "h2xs [-AOPXcdfh] [-v version] [-n module_name] [-p prefix] [-s subs] [headerfile [extra_libraries]]
version: $H2XS_VERSION
- -f Force creation of the extension even if the C header does not exist.
- -n Specify a name to use for the extension (recommended).
- -c Omit the constant() function and specialised AUTOLOAD from the XS file.
- -p Specify a prefix which should be removed from the Perl function names.
- -s Create subroutines for specified macros.
-A Omit all autoloading facilities (implies -c).
+ -F Additional flags for C preprocessor (used with -x).
-O Allow overwriting of a pre-existing extension directory.
-P Omit the stub POD section.
-X Omit the XS portion.
+ -c Omit the constant() function and specialised AUTOLOAD from the XS file.
+ -d Turn on debugging messages.
+ -f Force creation of the extension even if the C header does not exist.
+ -h Display this help message
+ -n Specify a name to use for the extension (recommended).
+ -p Specify a prefix which should be removed from the Perl function names.
+ -s Create subroutines for specified macros.
-v Specify a version number for this extension.
-x Autogenerate XSUBs using C::Scan.
- -F Additional flags for C preprocessor (used with -x).
- -h Display this help message
extra_libraries
are any libraries that might be needed for loading the
extension, e.g. -lm would try to link in the math library.
}
-getopts("AOPXcfhxv:n:p:s:F:") || usage;
+getopts("AF:OPXcdfhn:p:s:v:x") || usage;
usage if $opt_h;
$opt_c = 1 if $opt_A;
%const_xsub = map { $_,1 } split(/,+/, $opt_s) if $opt_s;
-$path_h = shift;
-$extralibs = "@ARGV";
+while (my $arg = shift) {
+ if ($arg =~ /^-l/i) {
+ $extralibs = "$arg @ARGV";
+ last;
+ }
+ push(@path_h, $arg);
+}
usage "Must supply header file or module name\n"
- unless ($path_h or $opt_n);
+ unless (@path_h or $opt_n);
-if( $path_h ){
- $name = $path_h;
+if( @path_h ){
+ foreach my $path_h (@path_h) {
+ $name ||= $path_h;
if( $path_h =~ s#::#/#g && $opt_n ){
warn "Nesting of headerfile ignored with -n\n";
}
die "Can't find $path_h\n" if ( ! $opt_f && ! -f $path_h );
# Scan the header file (we should deal with nested header files)
# Record the names of simple #define constants into const_names
- # Function prototypes are not (currently) processed.
+ # Function prototypes are processed below.
open(CH, "<$path_h") || die "Can't open $path_h: $!\n";
while (<CH>) {
- if (/^ #[ \t]*define\s+([\$\w]+)\b\s*[^("]/) {
- print "Matched $_ ($1)\n";
+ if (/^#[ \t]*define\s+([\$\w]+)\b\s*[^("]/) {
+ print "Matched $_ ($1)\n" if $opt_d;
$_ = $1;
next if /^_.*_h_*$/i; # special case, but for what?
if (defined $opt_p) {
}
}
close(CH);
- @const_names = sort keys %const_names;
}
+ }
+ @const_names = sort keys %const_names;
}
get_typemap();
my $c;
my $filter;
- my $filename = $path_h;
+ my @fdecls;
+ foreach my $filename (@path_h) {
my $addflags = $opt_F || '';
if ($fullpath =~ /,/) {
$filename = $`;
$c->set('includeDirs' => ["$Config::Config{archlib}/CORE"]);
$fdecls_parsed = $c->get('parsed_fdecls');
- $fdecls = $c->get('fdecls');
+ push(@fdecls, @{$c->get('fdecls')});
+ }
+ $fdecls = [ @fdecls ];
}
}
if( $opt_X || $opt_c || $opt_A ){
# we won't have our own AUTOLOAD(), so won't have $AUTOLOAD
print PM <<'END';
-use vars qw($VERSION @ISA @EXPORT);
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
END
}
else{
# will want Carp.
print PM <<'END';
use Carp;
-use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD);
END
}
# require autoloader if XS is disabled.
# if XS is enabled, require autoloader unless autoloading is disabled.
-if( $opt_X || (! $opt_A) ){
+if( ($opt_X && (! $opt_A)) || (!$opt_X) ) {
print PM <<"END";
require AutoLoader;
END
my \$constname;
(\$constname = \$AUTOLOAD) =~ s/.*:://;
+ croak "&$module::constant not defined" if \$constname eq 'constant';
my \$val = constant(\$constname, \@_ ? \$_[0] : 0);
if (\$! != 0) {
if (\$! =~ /Invalid/) {
croak "Your vendor has not defined $module macro \$constname";
}
}
- eval "sub \$AUTOLOAD { \$val }";
+ *\$AUTOLOAD = sub () { \$val };
goto &\$AUTOLOAD;
}
my $fdecl_doc = '';
if (@const_names and not $opt_P) {
$const_doc = <<EOD;
-
-=head1 Exported constants
+\n=head1 Exported constants
@{[join "\n ", @const_names]}
}
if (defined $fdecls and @$fdecls and not $opt_P) {
$fdecl_doc = <<EOD;
-
-=head1 Exported functions
+\n=head1 Exported functions
@{[join "\n ", @$fdecls]}
#endif
END
-if( $path_h ){
+if( @path_h ){
+ foreach my $path_h (@path_h) {
my($h) = $path_h;
$h =~ s#^/usr/include/##;
if ($^O eq 'VMS') { $h =~ s#.*vms\]#sys/# or $h =~ s#.*[:>\]]##; }
-print XS <<"END";
-#include <$h>
-
-END
+ print XS qq{#include <$h>\n};
+ }
+ print XS "\n";
}
if( ! $opt_c ){
unless ($@) { @files = readdir(D); closedir(D); }
}
if (!@files) { @files = map {chomp && $_} `ls`; }
-print MANI join("\n",@files);
+if ($^O eq 'VMS') {
+ foreach (@files) {
+ # Clip trailing '.' for portability -- non-VMS OSs don't expect it
+ s%\.$%%;
+ # Fix up for case-sensitive file systems
+ s/$modfname/$modfname/i && next;
+ $_ = "\U$_" if $_ eq 'manifest' or $_ eq 'changes';
+ $_ = 'Makefile.PL' if $_ eq 'makefile.pl';
+ }
+}
+print MANI join("\n",@files), "\n";
close MANI;
!NO!SUBS!