Hide Show 16 lines of Pod
@ISA
=
qw( Exporter )
;
@EXPORT
=
qw( isbigendian genpp %PDL_DATATYPES
PDL_INCLUDE PDL_TYPEMAP
PDL_AUTO_INCLUDE PDL_BOOT
PDL_INST_INCLUDE PDL_INST_TYPEMAP
pdlpp_postamble_int pdlpp_stdargs_int
pdlpp_postamble pdlpp_stdargs write_dummy_make
unsupported getcyglib trylink
pdlpp_mkgen
)
;
sub
PDL_INCLUDE {
'"-I'
.whereami_any().
'/Core"'
};
sub
PDL_TYPEMAP { whereami_any().
'/Core/typemap.pdl'
};
sub
PDL_INST_INCLUDE {
&PDL_INCLUDE
}
sub
PDL_INST_TYPEMAP {
&PDL_TYPEMAP
}
sub
PDL_AUTO_INCLUDE {
my
(
$symname
) =
@_
;
$symname
||=
'PDL'
;
return
<<
"EOR"
;
static Core*
$symname
; /* Structure holds core C functions */
static SV* CoreSV; /* Gets pointer to perl var holding core structure */
EOR
}
sub
PDL_BOOT {
my
(
$symname
,
$module
) =
@_
;
$symname
||=
'PDL'
;
$module
||=
'The code'
;
return
<<
"EOR"
;
perl_require_pv (
"PDL/Core.pm"
); /* make sure PDL::Core is loaded */
if
(SvTRUE (ERRSV)) Perl_croak(aTHX_
"%s"
,SvPV_nolen (ERRSV));
CoreSV = perl_get_sv(
"PDL::SHARE"
,FALSE); /* SV* value */
if
(CoreSV==NULL)
Perl_croak(aTHX_
"We require the PDL::Core module, which was not found"
);
$symname
= INT2PTR(Core*,SvIV( CoreSV )); /* Core* value */
if
(
$symname
->Version != PDL_CORE_VERSION)
Perl_croak(aTHX_
"[$symname->Version: \%d PDL_CORE_VERSION: \%d XS_VERSION: \%s] $module needs to be recompiled against the newly installed PDL"
,
$symname
->Version, PDL_CORE_VERSION, XS_VERSION);
EOR
}
sub
whereami_any {
my
$dir
= (
&whereami
(1) or
&whereami_inst
(1) or
die
"Unable to determine ANY directory path to PDL::Core::Dev module\n"
);
return
abs_path(
$dir
);
}
sub
whereami {
for
$dir
(
@INC
,
qw|. .. ../.. ../../.. ../../../..|
) {
return
(
$_
[0] ?
$dir
.
'/Basic'
:
$dir
)
if
-e
"$dir/Basic/Core/Dev.pm"
;
}
die
"Unable to determine UNINSTALLED directory path to PDL::Core::Dev module\n"
if
!
$_
[0];
return
undef
;
}
sub
whereami_inst {
for
$dir
(
@INC
,
map
{
$_
.
"/blib"
}
qw|. .. ../.. ../../.. ../../../..|
) {
return
(
$_
[0] ?
$dir
.
'/PDL'
:
$dir
)
if
-e
"$dir/PDL/Core/Dev.pm"
;
}
die
"Unable to determine INSTALLED directory path to PDL::Core::Dev module\n"
if
!
$_
[0];
return
undef
;
}
unless
(
%PDL::Config
) {
my
$dir
;
$dir
= whereami(1);
if
(
defined
$dir
) {
$dir
= abs_path(
$dir
.
"/Core"
);
}
else
{
$dir
= whereami_inst;
$dir
= abs_path(
$dir
.
"/PDL"
);
}
my
$dir2
=
$dir
;
$dir2
=~ s/\}/\\\}/g;
eval
sprintf
(
'require q{%s/Config.pm};'
,
$dir2
);
die
"Unable to find PDL's configuration info\n [$@]"
if
$@;
}
{
my
$loaded_types
=
grep
(m%(PDL|Core)/Types[.]pm$%,
keys
%INC
);
$@ =
''
;
eval
(
'require "'
.whereami_any().
'/Core/Types.pm"'
)
unless
$loaded_types
;
if
($@) {
my
$foo
= $@;
$@=
""
;
eval
(
'require PDL::Types'
);
if
($@) {
die
"can't find PDL::Types: $foo and $@"
unless
$@ eq
""
;
}
}
}
PDL::Types->
import
();
my
$inc
=
defined
$PDL::Config
{MALLOCDBG}->{include} ?
"$PDL::Config{MALLOCDBG}->{include}"
:
''
;
my
$libs
=
defined
$PDL::Config
{MALLOCDBG}->{libs} ?
"$PDL::Config{MALLOCDBG}->{libs}"
:
''
;
%PDL_DATATYPES
= ();
foreach
$key
(
keys
%PDL::Types::typehash
) {
$PDL_DATATYPES
{
$PDL::Types::typehash
{
$key
}->{
'sym'
}} =
$PDL::Types::typehash
{
$key
}->{
'ctype'
};
}
$O_NONBLOCK
=
defined
$Config
{
'o_nonblock'
} ?
$Config
{
'o_nonblock'
}
:
'O_NONBLOCK'
;
Hide Show 20 lines of Pod
sub
isbigendian {
my
$byteorder
=
$Config
{byteorder} ||
die
"ERROR: Unable to find 'byteorder' in perl's Config\n"
;
return
1
if
$byteorder
eq
"4321"
;
return
1
if
$byteorder
eq
"87654321"
;
return
0
if
$byteorder
eq
"1234"
;
return
0
if
$byteorder
eq
"12345678"
;
die
"ERROR: PDL does not understand your machine's byteorder ($byteorder)\n"
;
}
sub
genpp {
$gotstart
= 0;
@gencode
= ();
while
(<>) {
s/O_NONBLOCK/
$O_NONBLOCK
/go;
if
( m/ (\s*)? \b GENERICLOOP \s* \( ( [^\)]* ) \) ( \s*; )? /x ){
die
"Found GENERICLOOP while searching for ENDGENERICLOOP\n"
if
$gotstart
;
$loopvar
= $2;
$indent
= $1;
print
$PREMATCH
;
@gencode
= ();
push
@gencode
,
$POSTMATCH
;
$gotstart
= 1;
next
;
}
if
( m/ \b ENDGENERICLOOP ( \s*; )? /x ) {
die
"Found ENDGENERICLOOP while searching for GENERICLOOP\n"
unless
$gotstart
;
push
@gencode
,
$PREMATCH
;
flushgeneric();
print
$POSTMATCH
;
$gotstart
= 0;
next
;
}
if
(
$gotstart
) {
push
@gencode
,
$_
;
}
else
{
print
;
}
}
}
sub
flushgeneric {
print
$indent
,
"switch ($loopvar) {\n\n"
;
for
$case
(
keys
%PDL_DATATYPES
) {
$type
=
$PDL_DATATYPES
{
$case
};
my
$ppsym
=
$PDL::Types::typehash
{
$case
}->{ppsym};
print
$indent
,
"case $case:\n"
;
print
$indent
,
" {"
;
for
(
@gencode
) {
$line
=
$_
;
$line
=~ s/\bgeneric\b/
$type
/g;
$line
=~ s/\bgeneric_ppsym\b/
$ppsym
/g;
print
" "
,
$line
;
}
print
"}break;\n\n"
;
}
print
$indent
,
"default:\n"
;
print
$indent
,
' croak ("Not a known data type code=%d",'
.
$loopvar
.
");\n"
;
print
$indent
,
"}"
;
}
sub
genpp_cmdline {
my
(
$in
,
$out
) =
@_
;
my
$MM
=
bless
{
NAME
=>
'Fake'
},
'MM'
;
my
$devpm
= whereami_any().
"/Core/Dev.pm"
;
sprintf
(
$MM
->oneliner(
<<'EOF'), $devpm) . qq{ "$in" > "$out"};
require "%s"; PDL::Core::Dev->import(); genpp();
EOF
}
sub
postamble {
my
(
$self
) =
@_
;
sprintf
<<'EOF', genpp_cmdline(qw($< $@));
# Rules for the generic preprocessor
.SUFFIXES: .g
.g.c :
%s
EOF
}
sub
pdlpp_postamble_int {
join
''
,
map
{
my
(
$src
,
$pref
,
$mod
,
$deps
) =
@$_
;
die
"If give dependencies, must be array-ref"
if
$deps
and !
ref
$deps
;
my
$w
= whereami_any();
$w
=~ s%/((PDL)|(Basic))$%%;
my
$top
= File::Spec->abs2rel(
$w
);
my
$basic
= File::Spec->catdir(
$top
,
'Basic'
);
my
$core
= File::Spec->catdir(
$basic
,
'Core'
);
my
$gen
= File::Spec->catdir(
$basic
,
'Gen'
);
my
$depbuild
=
''
;
for
my
$dep
(@{
$deps
|| []}) {
my
$target
=
''
;
if
(
$dep
eq
'core'
) {
$dep
=
$top
;
$target
=
' core'
;
}
$dep
=~ s
$depbuild
.= MM->oneliner(
"exit(!(chdir q($dep) && !system(q(\$(MAKE)$target))))"
);
$depbuild
.=
"\n\t"
;
}
qq|
$pref.pm: $src $core/Types.pm
$depbuild\$(PERLRUNINST) \"-MPDL::PP qw/$mod $mod $pref/\" $src
$pref.xs: $pref.pm
\$(TOUCH) \$@
$pref.c: $pref.xs
$pref\$(OBJ_EXT): $pref.c
|
} (
@_
)
}
sub
pdlpp_postamble {
join
''
,
map
{
my
(
$src
,
$pref
,
$mod
) =
@$_
;
my
$w
= whereami_any();
$w
=~ s%/((PDL)|(Basic))$%%;
qq|
$pref.pm: $src
\$(PERL) "-I$w" \"-MPDL::PP qw/$mod $mod $pref/\" $src
$pref.xs: $pref.pm
\$(TOUCH) \$@
$pref.c: $pref.xs
$pref\$(OBJ_EXT): $pref.c
|
} (
@_
)
}
sub
pdlpp_stdargs_int {
my
(
$rec
) =
@_
;
my
(
$src
,
$pref
,
$mod
) =
@$rec
;
my
$w
= whereami();
my
$malloclib
=
exists
$PDL::Config
{MALLOCDBG}->{libs} ?
$PDL::Config
{MALLOCDBG}->{libs} :
''
;
my
$mallocinc
=
exists
$PDL::Config
{MALLOCDBG}->{include} ?
$PDL::Config
{MALLOCDBG}->{include} :
''
;
my
$libsarg
=
$libs
||
$malloclib
?
"$libs $malloclib "
:
''
;
return
(
%::PDL_OPTIONS,
'NAME'
=>
$mod
,
'VERSION_FROM'
=>
"$w/Basic/Core/Version.pm"
,
'TYPEMAPS'
=> [
&PDL_TYPEMAP
()],
'OBJECT'
=>
"$pref\$(OBJ_EXT)"
,
PM
=> {
"$pref.pm"
=>
"\$(INST_LIBDIR)/$pref.pm"
},
MAN3PODS
=> {
"$pref.pm"
=>
"\$(INST_MAN3DIR)/$mod.\$(MAN3EXT)"
},
'INC'
=>
&PDL_INCLUDE
().
" $inc $mallocinc"
,
'LIBS'
=>
$libsarg
? [
$libsarg
] : [],
'clean'
=> {
'FILES'
=>
"$pref.xs $pref.pm $pref\$(OBJ_EXT) $pref.c"
},
(
eval
(
$ExtUtils::MakeMaker::VERSION
) >= 6.57_02 ? (
'NO_MYMETA'
=> 1) : ()),
);
}
sub
pdlpp_stdargs {
my
(
$rec
) =
@_
;
my
(
$src
,
$pref
,
$mod
) =
@$rec
;
return
(
%::PDL_OPTIONS,
'NAME'
=>
$mod
,
'TYPEMAPS'
=> [
&PDL_INST_TYPEMAP
()],
'OBJECT'
=>
"$pref\$(OBJ_EXT)"
,
PM
=> {
"$pref.pm"
=>
"\$(INST_LIBDIR)/$pref.pm"
},
MAN3PODS
=> {
"$pref.pm"
=>
"\$(INST_MAN3DIR)/$mod.\$(MAN3EXT)"
},
'INC'
=>
&PDL_INST_INCLUDE
().
" $inc"
,
'LIBS'
=>
$libs
? [
"$libs "
] : [],
'clean'
=> {
'FILES'
=>
"$pref.xs $pref.pm $pref\$(OBJ_EXT) $pref.c"
},
'dist'
=> {
'PREOP'
=>
'$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" -MPDL::Core::Dev -e pdlpp_mkgen $(DISTVNAME)'
},
(
eval
(
$ExtUtils::MakeMaker::VERSION
) >= 6.57_02 ? (
'NO_MYMETA'
=> 1) : ()),
);
}
sub
pdlpp_mkgen {
my
$dir
=
@_
> 0 ?
$_
[0] :
$ARGV
[0];
die
"pdlpp_mkgen: unspecified directory"
unless
defined
$dir
&& -d
$dir
;
my
$file
=
"$dir/MANIFEST"
;
die
"pdlpp_mkgen: non-existing '$dir/MANIFEST'"
unless
-f
$file
;
my
@pairs
= ();
my
$manifest
= ExtUtils::Manifest::maniread(
$file
);
for
(
keys
%$manifest
) {
next
if
$_
!~ m/\.pd$/;
next
if
$_
=~ m/^(t|xt)\//;
next
unless
-f
$_
;
my
$content
=
do
{
local
$/;
open
my
$in
,
'<'
,
$_
; <
$in
> };
if
(
$content
=~ /=head1\s+NAME\s+(\S+)\s+/sg) {
push
@pairs
, [
$_
, $1];
}
else
{
warn
"pdlpp_mkgen: unknown module name for '$_' (use proper '=head1 NAME' section)\n"
;
}
}
my
%added
= ();
for
(
@pairs
) {
my
(
$pd
,
$mod
) =
@$_
;
(
my
$prefix
=
$mod
) =~ s|::|/|g;
my
$manifestpm
=
"GENERATED/$prefix.pm"
;
$prefix
=
"$dir/GENERATED/$prefix"
;
File::Path::mkpath(dirname(
$prefix
));
my
@in
=
map
{
"-I$_"
}
@INC
,
'inc'
;
my
$rv
=
system
($^X,
@in
,
"-MPDL::PP qw[$mod $mod $prefix]"
,
$pd
);
if
(
$rv
== 0 && -f
"$prefix.pm"
) {
$added
{
$manifestpm
} =
"mod=$mod pd=$pd (added by pdlpp_mkgen)"
;
unlink
"$prefix.xs"
;
}
else
{
warn
"pdlpp_mkgen: cannot convert '$pd'\n"
;
}
}
if
(
scalar
(
keys
%added
) > 0) {
local
$ExtUtils::Manifest::MANIFEST
=
$file
;
ExtUtils::Manifest::maniadd(\
%added
);
}
}
sub
unsupported {
my
(
$package
,
$os
) =
@_
;
"No support for $package on $os platform yet. Will skip build process"
;
}
sub
write_dummy_make {
my
(
$msg
) =
@_
;
$msg
=~ s
$msg
=~ s
print
$msg
;
ExtUtils::MakeMaker::WriteEmptyMakefile(
NAME
=>
'Dummy'
,
DIR
=> []);
}
sub
getcyglib {
my
(
$lib
) =
@_
;
my
$lp
= `gcc -
print
-file-name=lib
$lib
.a`;
$lp
=~ s|/[^/]+$||;
$lp
=~ s|^([a-z,A-Z]):|//$1|g;
return
"-L$lp -l$lib"
;
}
Hide Show 83 lines of Pod
sub
trylink {
my
$opt
=
ref
$_
[
$#_
] eq
'HASH'
?
pop
: {};
my
(
$txt
,
$inc
,
$body
,
$libs
,
$cflags
) =
@_
;
$cflags
||=
''
;
my
$cdir
=
sub
{
return
File::Spec->catdir(
@_
)};
my
$cfile
=
sub
{
return
File::Spec->catfile(
@_
)};
for
my
$key
(
keys
%$opt
) {
$opt
->{
lc
$key
} =
$opt
->{
$key
}}
my
$mmprocess
=
exists
$opt
->{makemaker} &&
$opt
->{makemaker};
my
$hide
=
exists
$opt
->{hide} ?
$opt
->{hide} :
exists
$PDL::Config
{HIDE_TRYLINK} ?
$PDL::Config
{HIDE_TRYLINK} : 1;
my
$clean
=
exists
$opt
->{clean} ?
$opt
->{clean} : 1;
if
(
$mmprocess
) {
my
$self
= new ExtUtils::MakeMaker {
DIR
=> [],
'NAME'
=>
'NONE'
};
my
@libs
=
$self
->ext(
$libs
, 0);
print
"processed LIBS: $libs[0]\n"
unless
$hide
;
$libs
=
$libs
[0];
}
print
" Trying $txt...\n "
unless
$txt
=~ /^\s*$/;
my
$HIDE
= !
$hide
?
''
:
'>/dev/null 2>&1'
;
if
($^O =~ /mswin32/i) {
$HIDE
=
'>NUL 2>&1'
}
my
$tempd
;
$tempd
= File::Temp::tempdir(
CLEANUP
=>1) ||
die
"trylink: could not make TEMPDIR"
;
my
(
$tc
,
$te
) =
map
{
&$cfile
(
$tempd
,
"testfile$_"
)} (
'.c'
,
''
);
open
FILE,
">$tc"
or
die
"trylink: couldn't open testfile `$tc' for writing, $!"
;
my
$prog
=
<<"EOF";
$inc
int main(void) {
$body
return 0;
}
EOF
print
FILE
$prog
;
close
FILE;
open
(T,
">$te"
) or
die
(
"unable to write to test executable `$te'"
);
close
T;
print
"$Config{cc} $cflags -o $te $tc $libs $HIDE ...\n"
unless
$hide
;
my
$success
= (
system
(
"$Config{cc} $cflags -o $te $tc $libs $HIDE"
) == 0) &&
-e
$te
? 1 : 0;
unlink
"$te"
,
"$tc"
if
$clean
;
print
$success
?
"\t\tYES\n"
:
"\t\tNO\n"
unless
$txt
=~ /^\s*$/;
print
$success
?
"\t\tSUCCESS\n"
:
"\t\tFAILED\n"
if
$txt
=~ /^\s*$/ && !
$hide
;
return
$success
;
}
Hide Show 8 lines of Pod
sub
datatypes_switch {
my
$ntypes
=
$#PDL::Types::names
;
my
@m
;
foreach
my
$i
( 0 ..
$ntypes
) {
my
$type
= PDL::Type->new(
$i
);
my
$typesym
=
$type
->symbol;
my
$typeppsym
=
$type
->ppsym;
my
$cname
=
$type
->ctype;
$cname
=~ s/^PDL_//;
push
@m
,
"\tcase $typesym: retval.type = $typesym; retval.value.$typeppsym = PDL.bvals.$cname; break;"
;
}
print
map
"$_\n"
,
@m
;
}
Hide Show 8 lines of Pod
my
%flags
= (
hdrcpy
=> {
set
=> 1 },
fflows
=> {
FLAG
=>
"DATAFLOW_F"
},
bflows
=> {
FLAG
=>
"DATAFLOW_B"
},
is_inplace
=> {
FLAG
=>
"INPLACE"
,
postset
=> 1 },
donttouch
=> {
FLAG
=>
"DONTTOUCHDATA"
},
allocated
=> { },
vaffine
=> {
FLAG
=>
"OPT_VAFFTRANSOK"
},
anychgd
=> {
FLAG
=>
"ANYCHANGED"
},
dimschgd
=> {
FLAG
=>
"PARENTDIMSCHANGED"
},
tracedebug
=> {
FLAG
=>
"TRACEDEBUG"
,
set
=> 1},
);
sub
generate_core_flags {
foreach
my
$name
(
keys
%flags
) {
my
$flag
=
"PDL_"
. (
$flags
{
$name
}{FLAG} ||
uc
(
$name
));
if
(
$flags
{
$name
}{set} ) {
print
<<"!WITH!SUBS!";
int
$name(x,mode=0)
pdl *x
int mode
CODE:
if (items>1)
{ setflag(x->state,$flag,mode); }
RETVAL = ((x->state & $flag) > 0);
OUTPUT:
RETVAL
!WITH!SUBS!
}
elsif
(
$flags
{
$name
}{postset}) {
print
<<"!WITH!SUBS!";
int
$name(x,mode=0)
pdl *x
int mode
CODE:
RETVAL = ((x->state & $flag) > 0);
if (items>1)
{ setflag(x->state,$flag,mode); }
OUTPUT:
RETVAL
!WITH!SUBS!
}
else
{
print
<<"!WITH!SUBS!";
int
$name(self)
pdl *self
CODE:
RETVAL = ((self->state & $flag) > 0);
OUTPUT:
RETVAL
!WITH!SUBS!
}
}
}
Hide Show 8 lines of Pod
sub
generate_badval_init {
for
my
$type
(PDL::Types::types()) {
my
$typename
=
$type
->ctype;
$typename
=~ s/^PDL_//;
my
$bval
=
$type
->defbval;
if
(
$PDL::Config
{BADVAL_USENAN} &&
$type
->usenan) {
print
"\tPDL.bvals.$typename = PDL.NaN_$type;\n"
;
}
else
{
print
"\tPDL.bvals.$typename = PDL.bvals.default_$typename = $bval;\n"
;
}
}
}
1;