--AD October 16, 1995
*/
-#include "constants.c"
+#include "const-c.inc"
MODULE = Fcntl PACKAGE = Fcntl
-INCLUDE: constants.xs
\ No newline at end of file
+INCLUDE: const-xs.inc
use ExtUtils::MakeMaker;
-use ExtUtils::Constant 0.07 'WriteConstants';
+use ExtUtils::Constant 0.11 'WriteConstants';
WriteMakefile(
NAME => 'Fcntl',
MAN3PODS => {}, # Pods will be built by installman.
XSPROTOARG => '-noprototypes', # XXX remove later?
VERSION_FROM => 'Fcntl.pm',
- realclean => {FILES=> 'constants.c constants.xs'},
);
my @names = (qw(FAPPEND FASYNC FCREAT FDEFER FDSYNC FD_CLOEXEC FEXCL FLARGEFILE
#define GLOB_ERROR (MY_CXT.x_GLOB_ERROR)
-#include "constants.c"
+#include "const-c.inc"
#ifdef WIN32
#define errfunc NULL
bsd_globfree(&pglob);
}
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
use ExtUtils::MakeMaker;
-use ExtUtils::Constant 0.08 'WriteConstants';
+use ExtUtils::Constant 0.11 'WriteConstants';
WriteMakefile(
NAME => 'File::Glob',
VERSION_FROM => 'Glob.pm',
MAN3PODS => {}, # Pods will be built by installman.
OBJECT => 'bsd_glob$(OBJ_EXT) Glob$(OBJ_EXT)',
- realclean => {FILES=> 'constants.c constants.xs'},
## uncomment for glob debugging (will cause make test to fail)
# DEFINE => '-DGLOB_DEBUG',
#define gdbm_setopt(db,optflag,optval,optlen) not_here("gdbm_setopt")
#endif
-#include "constants.c"
+#include "const-c.inc"
MODULE = GDBM_File PACKAGE = GDBM_File PREFIX = gdbm_
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
GDBM_File
gdbm_TIEHASH(dbtype, name, read_write, mode, fatal_func = (FATALFUNC)croak)
use ExtUtils::MakeMaker;
-use ExtUtils::Constant 0.07 'WriteConstants';
+use ExtUtils::Constant 0.11 'WriteConstants';
WriteMakefile(
NAME => 'GDBM_File',
LIBS => ["-L/usr/local/lib -lgdbm", "-ldbm"],
MAN3PODS => {}, # Pods will be built by installman.
XSPROTOARG => '-noprototypes', # XXX remove later?
VERSION_FROM => 'GDBM_File.pm',
- realclean => {FILES=> 'constants.c constants.xs'},
);
WriteConstants(
NAME => 'GDBM_File',
# include <langinfo.h>
#endif
-#include "constants.c"
+#include "const-c.inc"
MODULE = I18N::Langinfo PACKAGE = I18N::Langinfo
PROTOTYPES: ENABLE
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
SV*
langinfo(code)
# Insert -I. if you add *.h files later:
'INC' => '', # e.g., '-I/usr/include/other'
'MAN3PODS' => {}, # Pods will be built by installman
- # Without this the constants xs files are spotted, and cause rules to be
- # added to delete the similarly named C files, which isn't what we want.
- XS => {'Langinfo.xs' => 'Langinfo.c'},
- realclean => {FILES=> 'constants.c constants.xs'},
# Un-comment this if you add C files to link with later:
# 'OBJECT' => '$(O_FILES)', # link all the C files too
);
);
} else {
use File::Copy;
- copy ('fallback.c', 'constants.c')
- or die "Can't copy fallback.c to constants.c: $!";
- copy ('fallback.xs', 'constants.xs')
- or die "Can't copy fallback.xs to constants.xs: $!";
+ use File::Spec;
+ foreach my $file ('const-c.inc', 'const-xs.inc') {
+ my $fallback = File::Spec->catfile('fallback', $file);
+ copy ($fallback, $file) or die "Can't copy $fallback to $file: $!";
+ }
}
use ExtUtils::MakeMaker;
-use ExtUtils::Constant 0.07 'WriteConstants';
+use ExtUtils::Constant 0.11 'WriteConstants';
use Config;
my @libs;
if ($^O ne 'MSWin32') {
MAN3PODS => {}, # Pods will be built by installman.
XSPROTOARG => '-noprototypes', # XXX remove later?
VERSION_FROM => 'POSIX.pm',
- realclean => {FILES=> 'constants.c constants.xs'},
);
my @names =
return -1;
}
-#include "constants.c"
+#include "const-c.inc"
/* These were implemented in the old "constant" subroutine. They are actually
macros that take an integer argument and return an integer result. */
MODULE = POSIX PACKAGE = POSIX
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
void
int_macro_int(sv, iv)
use ExtUtils::MakeMaker;
-use ExtUtils::Constant 0.07 'WriteConstants';
+use ExtUtils::Constant 0.11 'WriteConstants';
use Config;
WriteMakefile(
NAME => 'Socket',
($Config{libs} =~ /(-lsocks\S*)/ ? (LIBS => [ "$1" ] ) : ()),
MAN3PODS => {}, # Pods will be built by installman.
XSPROTOARG => '-noprototypes', # XXX remove later?
- realclean => {FILES=> 'constants.c constants.xs'},
);
my @names = (qw(AF_802 AF_AAL AF_APPLETALK AF_CCITT AF_CHAOS AF_CTF
AF_DATAKIT AF_DECnet AF_DLI AF_ECMA AF_GOSIP AF_HYLINK
*
* --jhi */
-#include "constants.c"
+#include "const-c.inc"
MODULE = Socket PACKAGE = Socket
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
void
inet_aton(host)
use ExtUtils::MakeMaker;
-use ExtUtils::Constant 0.07 'WriteConstants';
+use ExtUtils::Constant 0.11 'WriteConstants';
WriteMakefile(
NAME => 'Sys::Syslog',
VERSION_FROM => 'Syslog.pm',
MAN3PODS => {}, # Pods will be built by installman.
XSPROTOARG => '-noprototypes',
- realclean => {FILES=> 'constants.c constants.xs'},
);
# We hope syslogd understands /dev/log.
#include <syslog.h>
#endif
-#include "constants.c"
+#include "const-c.inc"
MODULE = Sys::Syslog PACKAGE = Sys::Syslog
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
int
LOG_FAC(p)
package ExtUtils::Constant;
use vars qw (@ISA $VERSION %XS_Constant %XS_TypeSet @EXPORT_OK %EXPORT_TAGS);
-$VERSION = '0.10';
+$VERSION = '0.11';
=head1 NAME
WriteConstants(
NAME => 'Foo',
NAMES => [qw(FOO BAR BAZ)],
- C_FILE => 'constants.c',
- XS_FILE => 'constants.xs',
);
# Generates wrapper code to make the values of the constants FOO BAR BAZ
# available to perl
Generally one only needs to call the C<WriteConstants> function, and then
- #include "constants.c"
+ #include "const-c.inc"
in the C section of C<Foo.xs>
- INCLUDE constants.xs
+ INCLUDE const-xs.inc
in the XS section of C<Foo.xs>.
=item C_FILE
The name of the file to write containing the C code. The default is
-C<constants.c>.
+C<const-c.inc>. The C<-> in the name ensures that the file can't be
+mistaken for anything related to a legitimate perl package name, and
+not naming the file C<.c> avoids having to override Makefile.PL's
+C<.xs> to C<.c> rules.
=item XS_FILE
The name of the file to write containing the XS code. The default is
-C<constants.xs>.
+C<const-xs.inc>.
=item SUBNAME
sub WriteConstants {
my %ARGS =
( # defaults
- C_FILE => 'constants.c',
- XS_FILE => 'constants.xs',
+ C_FILE => 'const-c.inc',
+ XS_FILE => 'const-xs.inc',
SUBNAME => 'constant',
DEFAULT_TYPE => 'IV',
@_);
# use strict; # we are not really testing this
use File::Path; # for cleaning up with rmtree()
-use Test;
+use Test::More;
use File::Spec;
+use File::Find;
+use ExtUtils::Manifest;
+# Don't want its diagnostics getting in the way of ours.
+$ExtUtils::Manifest::Quiet=1;
+my $up = File::Spec->updir();
my $extracted_program = '../utils/h2xs'; # unix, nt, ...
if ($^O eq 'VMS') { $extracted_program = '[-.utils]h2xs.com'; }
Writing $name/ppport.h
Writing $name/$name.pm
Writing $name/$name.xs
-Writing $name/fallback.c
-Writing $name/fallback.xs
+Writing $name/fallback/const-c.inc
+Writing $name/fallback/const-xs.inc
Writing $name/Makefile.PL
Writing $name/README
Writing $name/t/1.t
Writing $name/ppport.h
Writing $name/$name.pm
Writing $name/$name.xs
-Writing $name/fallback.c
-Writing $name/fallback.xs
+Writing $name/fallback/const-c.inc
+Writing $name/fallback/const-xs.inc
Writing $name/Makefile.PL
Writing $name/README
Writing $name/t/1.t
Writing $name/ppport.h
Writing $name/$name.pm
Writing $name/$name.xs
-Writing $name/fallback.c
-Writing $name/fallback.xs
+Writing $name/fallback/const-c.inc
+Writing $name/fallback/const-xs.inc
Writing $name/Makefile.PL
Writing $name/README
Writing $name/t/1.t
Writing $name/ppport.h
Writing $name/$name.pm
Writing $name/$name.xs
-Writing $name/fallback.c
-Writing $name/fallback.xs
+Writing $name/fallback/const-c.inc
+Writing $name/fallback/const-xs.inc
Writing $name/Makefile.PL
Writing $name/README
Writing $name/t/1.t
Writing $name/ppport.h
Writing $name/$name.pm
Writing $name/$name.xs
-Writing $name/fallback.c
-Writing $name/fallback.xs
+Writing $name/fallback/const-c.inc
+Writing $name/fallback/const-xs.inc
Writing $name/Makefile.PL
Writing $name/README
Writing $name/t/1.t
for (my $i = $#tests; $i > 0; $i-=3) {
# 1 test for running it, 1 test for the expected result, and 1 for each file
# plus 1 to open and 1 to check for the use in $name.pm and Makefile.PL
+ # And 1 more for our check for "bonus" files, 2 more for ExtUtil::Manifest.
# use the () to force list context and hence count the number of matches.
- $total_tests += 6 + (() = $tests[$i] =~ /(Writing)/sg);
+ $total_tests += 9 + (() = $tests[$i] =~ /(Writing)/sg);
}
plan tests => $total_tests;
-ok (open (HEADER, ">$header"));
+ok (open (HEADER, ">$header"), "open '$header'");
print HEADER <<HEADER or die $!;
#define Camel 2
#define Dromedary 1
HEADER
-ok (close (HEADER));
+ok (close (HEADER), "close '$header'");
while (my ($args, $version, $expectation) = splice @tests, 0, 3) {
# h2xs warns about what it is writing hence the (possibly unportable)
# does it run?
my $prog = "$^X $lib $extracted_program $args $dupe";
@result = `$prog`;
- ok ($?, 0, "running $prog ");
+ cmp_ok ($?, "==", 0, "running $prog ");
$result = join("",@result);
# accomodate MPW # comment character prependage
#print "# expectation is >$expectation<\n";
#print "# result is >$result<\n";
# Was the output the list of files that were expected?
- ok ($result, $expectation, "running $prog");
+ is ($result, $expectation, "running $prog");
+
+ my (%got);
+ find (sub {$got{$File::Find::name}++ unless -d $_}, $name);
foreach ($expectation =~ /Writing\s+(\S+)/gm) {
if ($^O eq 'MacOS') {
$_ = ':' . join(':',split(/\//,$_));
$_ =~ s/$name:t:1.t/$name:t\/1.t/; # is this an h2xs bug?
}
- ok (-e $_, 1, "$_ missing");
+ ok (-e $_, "check for $_") and delete $got{$_};
+ }
+ my @extra = keys %got;
+ unless (ok (!@extra, "Are any extra files present?")) {
+ print "# These files are unexpectedly present:\n";
+ print "# $_\n" foreach sort @extra;
}
+ chdir ($name) or die "chdir $name failed: $!";
+ # Aargh. Something wants to load a bit of regexp. And we have to chdir
+ # for ExtUtils::Manifest. Caught between a rock and a hard place, so this
+ # seems the least evil thing to do:
+ push @INC, "../../lib";
+ my ($missing, $extra) = ExtUtils::Manifest::fullcheck();
+ is_deeply ($missing, [], "No files in the MANIFEST should be missing");
+ is_deeply ($extra, [], "and all files present should be in the MANIFEST");
+ pop @INC;
+ chdir ($up) or die "chdir $up failed: $!";
+
foreach my $leaf ("$name.pm", 'Makefile.PL') {
my $file = File::Spec->catfile($name, $leaf);
- if (ok (open (FILE, $file), 1, "open $file")) {
+ if (ok (open (FILE, $file), "open $file")) {
my $match = qr/use $version;/;
my $found;
while (<FILE>) {
last if $found = /$match/;
}
- ok ($found, 1, "looking for /$match/ in $file");
+ ok ($found, "looking for /$match/ in $file");
close FILE or die "close $file: $!";
}
}
rmtree($name);
}
-ok (unlink ($header), 1, $!);
+cmp_ok (unlink ($header), "==", 1, "unlink '$header'") or die "\$! is $!";
# Save current directory so that C::Scan can use it
my $cwd = File::Spec->rel2abs( File::Spec->curdir );
-my ($ext, $nested, @modparts, $modfname, $modpname, $constsfname);
+my ($ext, $nested, @modparts, $modfname, $modpname);
+# As Ilya suggested, use a name that contains - and then it can't clash with
+# the names of any packages. A directory 'fallback' will clash with any
+# new pragmata down the fallback:: tree, but that seems unlikely.
+my $constscfname = 'const-c.inc';
+my $constsxsfname = 'const-xs.inc';
+my $fallbackdirname = 'fallback';
$ext = chdir 'ext' ? 'ext/' : '';
@modparts = ();
$modfname = $modpname = $module;
}
-# Don't trip up if someone calls their module 'constants'
-$constsfname = $modfname eq 'constants' ? 'constdefs' : 'constants';
if ($opt_O) {
# ExtUtils::Constant.
# h2xs will later check that these are the same as those generated by the
# code embedded into Makefile.PL
- warn "Writing $ext$modpname/fallback.c\n";
- warn "Writing $ext$modpname/fallback.xs\n";
- WriteConstants ( C_FILE => "fallback.c",
- XS_FILE => "fallback.xs",
+ unless (-d $fallbackdirname) {
+ mkdir "$fallbackdirname" or die "Cannot mkdir $fallbackdirname: $!\n";
+ }
+ warn "Writing $ext$modpname/$fallbackdirname/$constscfname\n";
+ warn "Writing $ext$modpname/$fallbackdirname/$constsxsfname\n";
+ my $cfallback = File::Spec->catfile($fallbackdirname, $constscfname);
+ my $xsfallback = File::Spec->catfile($fallbackdirname, $constsxsfname);
+ WriteConstants ( C_FILE => $cfallback,
+ XS_FILE => $xsfallback,
DEFAULT_TYPE => $opt_t,
NAME => $module,
NAMES => \@const_names,
);
- print XS "#include \"$constsfname.c\"\n";
+ print XS "#include \"$constscfname\"\n";
}
# If a constant() function was #included then output a corresponding
# XS declaration:
-print XS "INCLUDE: $constsfname.xs\n" unless $opt_c;
+print XS "INCLUDE: $constsxsfname\n" unless $opt_c;
print XS <<"END" if $opt_g;
$Icomment 'INC' => '$I', # e.g., '${Ihelp}-I/usr/include/other'
END
- if (!$opt_c) {
- print PL <<"END";
- # Without this the constants xs files are spotted, and cause rules to be
- # added to delete the similarly names C files, which isn't what we want.
- 'XS' => {'$modfname.xs' => '$modfname.c'},
- realclean => {FILES => '$constsfname.c $constsfname.xs'},
-END
- }
-
- my $C = grep {$_ ne "$modfname.c" && $_ ne "fallback.c"}
+ my $C = grep {$_ ne "$modfname.c"}
(glob '*.c'), (glob '*.cc'), (glob '*.C');
my $Cpre = ($C ? '' : '# ');
my $Ccomment = ($C ? '' : <<EOC);
print PL ");\n";
if (!$opt_c) {
my $generate_code =
- WriteMakefileSnippet ( C_FILE => "$constsfname.c",
- XS_FILE => "$constsfname.xs",
+ WriteMakefileSnippet ( C_FILE => $constscfname,
+ XS_FILE => $constsxsfname,
DEFAULT_TYPE => $opt_t,
NAME => $module,
NAMES => \@const_names,
print PL <<"END";
if (eval {require ExtUtils::Constant; 1}) {
# If you edit these definitions to change the constants used by this module,
- # you will need to use the generated $constsfname.c and $constsfname.xs
+ # you will need to use the generated $constscfname and $constsxsfname
# files to replace their "fallback" counterparts before distributing your
# changes.
$generate_code
}
else {
use File::Copy;
- copy ('fallback.c', '$constsfname.c')
- or die "Can't copy fallback.c to $constsfname.c: \$!";
- copy ('fallback.xs', '$constsfname.xs')
- or die "Can't copy fallback.xs to $constsfname.xs: \$!";
+ use File::Spec;
+ foreach my \$file ('$constscfname', '$constsxsfname') {
+ my \$fallback = File::Spec->catfile('$fallbackdirname', \$file);
+ copy (\$fallback, \$file) or die "Can't copy \$fallback to \$file: \$!";
+ }
}
END
} else {
my $fail;
- foreach ('c', 'xs') {
- if (compare("fallback.$_", "$constsfname.$_")) {
+ foreach my $file ($constscfname, $constsxsfname) {
+ my $fallback = File::Spec->catfile($fallbackdirname, $file);
+ if (compare($file, $fallback)) {
warn << "EOM";
-Files "$ext$modpname/fallback.$_" and "$ext$modpname/$constsfname.$_" differ.
+Files "$ext$modpname/$fallbackdirname/$file" and "$ext$modpname/$file" differ.
EOM
$fail++;
}
if ($fail) {
warn fill ('','', <<"EOM") . "\n";
It appears that the code in $ext$modpname/Makefile.PL does not autogenerate
-the files $ext$modpname/$constsfname.c and $ext$modpname/$constsfname.xs
+the files $ext$modpname/$constscfname and $ext$modpname/$constsxsfname
correctly.
-
+
Please report the circumstances of this bug in h2xs version $H2XS_VERSION
using the perlbug script.
EOM
} else {
- unlink "$constsfname.c", "$constsfname.xs";
+ unlink $constscfname, $constsxsfname;
}
}
}
warn "Writing $ext$modpname/MANIFEST\n";
open(MANI,'>MANIFEST') or die "Can't create MANIFEST: $!";
-my @files = grep { -f } (<*>, <t/*>);
+my @files = grep { -f } (<*>, <t/*>, <$fallbackdirname/*>);
if (!@files) {
eval {opendir(D,'.');};
unless ($@) { @files = readdir(D); closedir(D); }
$_ = 'Makefile.PL' if $_ eq 'makefile.pl';
}
}
-if (!$opt_c) {
- @files = grep {$_ ne "$constsfname.c" and $_ ne "$constsfname.xs"} @files;
-}
print MANI join("\n",@files), "\n";
close MANI;
!NO!SUBS!