Inline-SLang
view release on metacpan or search on metacpan
sl_setup_as_slsh( )
CODE:
setup_as_slsh();
int
sl_setup_called( )
CODE:
RETVAL = _sl_setup_as_slsh_called;
OUTPUT:
RETVAL
# how are S-Lang arrays converted to Perl?
#
int
sl_array2perl( ... )
PREINIT:
int newtype;
CODE:
if ( items > 1 ) croak( "Usage: sl_array2perl( [$flag] )" );
if ( 1 == items ) {
newtype = (int) SvIV( ST(0) );
if ( newtype < 0 || newtype > 1+(I_SL_HAVE_PDL<<1) )
croak( "Error: sl_array2perl() can only be sent an integer between 0 and %d (inclusive)", 1+(I_SL_HAVE_PDL<<1) );
_slang_array_format = newtype;
}
RETVAL = _slang_array_format;
OUTPUT:
RETVAL
# return, as an associative array reference, the
# names of defined types (key) and a 2-element
# array containing the class number and a boolean flag
# indicating whether the type is a "named" struct.
# Note that Struct_Type objects will have 0, confusingly enough
#
# Now, this latter piece of information is hard to find out
# - for now I'm going to use a S-Lang library routine that
# is not in slang.h but is not marked static
# - this is not ideal since I'm making assumptions about the
# internals of S-Lang that aren't obviously "public" (ie
# things may change)
#
# Also, have shoe-horned into this routine a list of type
# "synonyms" recognised by the S-Lang interpreter. This
# information is generated at 'perl Makefile.PL' time,
# and we just include it here. In this case the hash key is the
# synonym, the first element of the array is the 'base' type,
# and the second element is set to 2 (this assumes that there aren't
# any type synonyms of structures)
#
void
_sl_defined_types( )
PREINIT:
SLang_Class_Type *_SLclass_get_class( unsigned char ); /* from slclass.c */
HV *hashref;
AV *arrayref;
char *name;
int i, sflag;
PPCODE:
/* create the hash array to store the results in */
hashref = (HV *) sv_2mortal( (SV *) newHV() );
/*
* assume that the max number of types is 256
* - this is not a great thing to do
* and the use of _SLclass_get_class() et al
* is even worse
*/
for ( i = 0; i < 256; i++ ) {
if ( SLclass_is_class_defined(i) ) {
name = SLclass_get_datatype_name( (SLtype) i );
sflag = _SLclass_get_class( (unsigned char) i )->cl_struct_def != NULL;
arrayref = newAV();
av_extend( arrayref, (I32) 2 );
av_store( arrayref, 0, newSViv(i) );
av_store( arrayref, 1, newSViv(sflag) );
Printf( ("class number %d has a name of %s and struct flag = %d\n", i, name, sflag) );
(void) hv_store( hashref, name, strlen(name),
newRV_inc( (SV *) arrayref ), 0 );
}
} /* for: i */
/* add in the type synonyms */
/*** NOTE: are we over-writing info here ??
*** [or do the synonymns not have a class]
*** {is everything in stf.h a synonyn?}
***/
#include "stf.h"
/* return the associative array reference */
PUSHs( newRV_inc( (SV *) hashref) );
#
# returns a flag to say whether the input value is
# the name of a DataType_Type and the name of it [after converting
# synonyms]. See the DataType_Type object code in SLang.pm
#
void
_sl_isa_datatype( inname )
char *inname
PREINIT:
const char *slformat = "string(%s);typeof(%s)==DataType_Type;";
char *outname;
char *slbuffer;
size_t blen;
int flag;
PPCODE:
/* not bothered anout 2 extra chars due to %s %s in format */
blen = strlen(slformat)+2*strlen(inname);
Newz( "", slbuffer, blen, char );
snprintf( slbuffer, blen, slformat, inname, inname );
Printf( ("Checking if %s is a valid DataType_Type name\n",inname) );
Printf( ("S-Lang buffer= [%s]\n", slbuffer) );
(void) SLang_load_string( slbuffer );
if ( -1 == SLang_pop_integer(&flag) )
croak("Internal error: unable to pop an integer from the S-Lang stack" );
Printf( (" flag [ie is datatype?] = [%d]\n", flag) );
PUSHs( sv_2mortal(newSVuv(flag)) );
if ( -1 == SLang_pop_slstring(&outname) )
croak("Internal error: unable to pop a string from the S-Lang stack" );
Printf( (" and 'base' type name = [%s]\n", outname) );
PUSHs( sv_2mortal(newSVpv(outname,0)) );
/* don't forget to free up memory */
SLang_free_slstring(outname);
Safefree(slbuffer);
# try and guess the datatype of a Perl variable to try and get
# around Perl's permiscuous datatypes
# - would be nice if didn't need to treat things using a switch
# statement (since it's another bit of code that needs updating
# whenever the type code changes)
#
void
_guess_sltype( item )
SV * item
PREINIT:
SLtype sltype;
int slflag;
SV * out;
PPCODE:
sltype = pltype( item, &slflag );
switch( sltype ) {
case SLANG_NULL_TYPE: out = newSVpv( "Null_Type", 0 ); break;
case SLANG_INT_TYPE: out = newSVpv( "Integer_Type", 0 ); break;
case SLANG_DOUBLE_TYPE: out = newSVpv( "Double_Type", 0 ); break;
case SLANG_STRING_TYPE: out = newSVpv( "String_Type", 0 ); break;
case SLANG_COMPLEX_TYPE: out = newSVpv( "Complex_Type", 0 ); break;
case SLANG_DATATYPE_TYPE: out = newSVpv( "DataType_Type", 0 ); break;
case SLANG_STRUCT_TYPE: out = newSVpv( "Struct_Type", 0 ); break;
case SLANG_ASSOC_TYPE: out = newSVpv( "Assoc_Type", 0 ); break;
case SLANG_ARRAY_TYPE: out = newSVpv( "Array_Type", 0 ); break;
case SLANG_UNDEFINED_TYPE:
if ( 0 == slflag ) out = newSVpv( "Undefined_Type", 0 );
else {
/* handle a type treated as an 'opaque' type */
SV *type;
/* prob leaks mem here */
fixme( "memleak?" );
CALL_METHOD_SCALAR_SV( item, "typeof", , type );
CALL_METHOD_SCALAR_SV( type, "stringify", , out );
SvREFCNT_dec( type );
}
break;
default:
croak( "Internal error: unable to understand Perl datatype" );
}
PUSHs( sv_2mortal( out ) );
# create an empty nD array
# - function is defined in util.c, here we just convert a perl array into
# a C one
# - note no error checking
#
void
_create_empty_array( SV *in )
PREINIT:
int dims[SLARRAY_MAX_DIMS];
AV *aref;
SV * out;
int i, ndim;
PPCODE:
aref = (AV *) SvRV( in );
ndim = 1 + av_len(aref);
Printf( ("Creating an empty array (%d dim) with size ", ndim) );
for( i = 0; i < ndim; i++ ) {
int dsize = SvIV( *av_fetch( aref, i, 0 ) );
dims[i] = dsize;
Printf( ("%d ", dsize) );
}
Printf( ("\n") );
out = _create_empty_array( ndim, dims );
PUSHs( sv_2mortal( out ) );
# NOTE:
# the perl routine sl_eval, which calls this, ensures that the
# string ends in a ';'. you can call this routine directly for a minor
# speed increase and avoid the check
#
# Since we installed an error handler that calls Perl's croak on
# an error, rather than printing the messages to STDERR,
# SLang_load_string() no longer returns on error
#
void
_sl_eval( str )
char * str
PPCODE:
Printf( ("----------------------------------------------------------------------\n") );
Printf( ("sl_eval: code: %s\n", str ) );
Printf( ("----------------------------------------------------------------------\n") );
/*
* since we have installed an error handler which croak's,
* we do not need to check the return value of this function
*/
(void) SLang_load_string(str);
/* stick any return values on the stack */
CONVERT_SLANG2PERL_STACK
#undef NUM_FIXED_ARGS
#define NUM_FIXED_ARGS 1
void
sl_call_function( qualname, ... )
char * qualname
PREINIT:
int i;
PPCODE:
Printf( ("sl_call_function called:\n function: %s\n", qualname ) );
/*
* We could remove this check - ie assume that if we've got this
* far then eveything 'should' be fine
*/
if ( 1 > SLang_is_defined(qualname) ) {
croak( "'%s' is not a S-Lang function", qualname );
XSRETURN_EMPTY;
}
Printf( (" and it is a S-Lang function\n" ) );
/*
* convert the perl arguments into S-Lang arguments and
* stick them onto the S-Lang stack
*/
Printf( (" converting %d arguments to S-Lang\n", items-NUM_FIXED_ARGS) );
SLang_start_arg_list ();
for ( i = NUM_FIXED_ARGS; i < items; i++ ) {
pl2sl( ST(i) );
}
SLang_end_arg_list ();
/*
* perhaps should use SLexecute_function() instead
* - also, not clear if need to check for the return value given
* the error handler
*/
if ( -1 == SLang_execute_function( qualname ) ) {
croak( "Error: unable to execute S-lang function '%s'\n", qualname );
XSRETURN_EMPTY;
}
Printf( (" and executed the function\n") );
CONVERT_SLANG2PERL_STACK
( run in 1.146 second using v1.01-cache-2.11-cpan-5511b514fd6 )