perlcall.pod SAVETMPS/FREETMPS bracket
[p5sagit/p5-mst-13.2.git] / utils / h2xs.PL
index 78f9647..52f590b 100644 (file)
@@ -2,6 +2,7 @@
 
 use Config;
 use File::Basename qw(&basename &dirname);
+use Cwd;
 
 # List explicitly here the variables you want Configure to
 # generate.  Metaconfig only looks for shell variables, so you
@@ -12,10 +13,10 @@ use File::Basename qw(&basename &dirname);
 
 # 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"
+$origdir = cwd;
+chdir dirname($0);
+$file = basename($0, '.PL');
+$file .= '.com' if $^O eq 'VMS';
 
 open OUT,">$file" or die "Can't create $file: $!";
 
@@ -25,9 +26,9 @@ print "Extracting $file (with variable substitutions)\n";
 # 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.
@@ -40,19 +41,19 @@ h2xs - convert .h C header files to Perl extensions
 
 =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
@@ -72,6 +73,11 @@ in the extra-libraries argument.
 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.
@@ -80,11 +86,20 @@ 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
@@ -114,29 +129,19 @@ These macros are assumed to have a return type of B<char *>, e.g., S<-s sec_rgy_
 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
@@ -206,28 +211,29 @@ The usual warnings if it cannot read or write the files involved.
 
 =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.
@@ -235,7 +241,7 @@ extra_libraries
 }
 
 
-getopts("AOPXcfhxv:n:p:s:F:") || usage;
+getopts("AF:OPXcdfhn:p:s:v:x") || usage;
 
 usage if $opt_h;
 
@@ -245,15 +251,21 @@ if( $opt_v ){
 $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";
     }
@@ -284,11 +296,11 @@ if( $path_h ){
       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) {
@@ -303,8 +315,9 @@ if( $path_h ){
          }
       }
       close(CH);
-      @const_names = sort keys %const_names;
     }
+    }
+    @const_names = sort keys %const_names;
 }
 
 
@@ -361,7 +374,8 @@ if( ! $opt_X ){  # use XS, unless it was disabled
     get_typemap();
     my $c;
     my $filter;
-    my $filename = $path_h;
+        my @fdecls;
+        foreach my $filename (@path_h) {
     my $addflags = $opt_F || '';
     if ($fullpath =~ /,/) {
       $filename = $`;
@@ -373,7 +387,9 @@ if( ! $opt_X ){  # use XS, unless it was disabled
     $c->set('includeDirs' => ["$Config::Config{archlib}/CORE"]);
     
     $fdecls_parsed = $c->get('parsed_fdecls');
-    $fdecls = $c->get('fdecls');
+            push(@fdecls, @{$c->get('fdecls')});
+        }
+        $fdecls = [ @fdecls ];
   }
 }
 
@@ -391,7 +407,7 @@ END
 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{
@@ -399,7 +415,7 @@ 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
 }
 
@@ -414,7 +430,7 @@ 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
@@ -472,6 +488,7 @@ sub AUTOLOAD {
 
     my \$constname;
     (\$constname = \$AUTOLOAD) =~ s/.*:://;
+    croak "&$module::constant not defined" if \$constname eq 'constant';
     my \$val = constant(\$constname, \@_ ? \$_[0] : 0);
     if (\$! != 0) {
        if (\$! =~ /Invalid/) {
@@ -482,7 +499,7 @@ sub AUTOLOAD {
                croak "Your vendor has not defined $module macro \$constname";
        }
     }
-    eval "sub \$AUTOLOAD { \$val }";
+    *\$AUTOLOAD = sub () { \$val };
     goto &\$AUTOLOAD;
 }
 
@@ -518,8 +535,7 @@ my $const_doc = '';
 my $fdecl_doc = '';
 if (@const_names and not $opt_P) {
   $const_doc = <<EOD;
-
-=head1 Exported constants
+\n=head1 Exported constants
 
   @{[join "\n  ", @const_names]}
 
@@ -527,8 +543,7 @@ EOD
 }
 if (defined $fdecls and @$fdecls and not $opt_P) {
   $fdecl_doc = <<EOD;
-
-=head1 Exported functions
+\n=head1 Exported functions
 
   @{[join "\n  ", @$fdecls]}
 
@@ -587,14 +602,14 @@ extern "C" {
 #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 ){
@@ -870,10 +885,21 @@ if (!@files) {
   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!
 
 close OUT or die "Can't close $file: $!";
 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
+chdir $origdir;