From 092e483d7bc058cf15aeb470e590d62ce60424d6 Mon Sep 17 00:00:00 2001 From: openeuler-basic Date: Sun, 12 Jan 2020 19:33:04 +0800 Subject: [PATCH] remove unnecessary files --- ExtUtils-ParseXS-3.35-Upgrade-to-3.39.patch | 4743 ------------------- perl-ExtUtils-ParseXS.spec | 13 +- 2 files changed, 9 insertions(+), 4747 deletions(-) delete mode 100644 ExtUtils-ParseXS-3.35-Upgrade-to-3.39.patch diff --git a/ExtUtils-ParseXS-3.35-Upgrade-to-3.39.patch b/ExtUtils-ParseXS-3.35-Upgrade-to-3.39.patch deleted file mode 100644 index a18bfae..0000000 --- a/ExtUtils-ParseXS-3.35-Upgrade-to-3.39.patch +++ /dev/null @@ -1,4743 +0,0 @@ -From c85261a4cef59150c379ff88a21d0f9ca6374dc2 Mon Sep 17 00:00:00 2001 -From: Jitka Plesnikova -Date: Thu, 24 May 2018 09:57:37 +0200 -Subject: [PATCH] Upgrade to 3.39 - ---- - Changes | 6 + - lib/ExtUtils/ParseXS.pm | 14 +- - lib/ExtUtils/ParseXS/Constants.pm | 2 +- - lib/ExtUtils/ParseXS/CountLines.pm | 2 +- - lib/ExtUtils/ParseXS/Eval.pm | 6 +- - lib/ExtUtils/ParseXS/Utilities.pm | 2 +- - lib/ExtUtils/Typemaps.pm | 6 +- - lib/ExtUtils/Typemaps/Cmd.pm | 2 +- - lib/ExtUtils/Typemaps/InputMap.pm | 2 +- - lib/ExtUtils/Typemaps/OutputMap.pm | 2 +- - lib/ExtUtils/Typemaps/Type.pm | 2 +- - lib/perlxs.pod | 2354 ++++++++++++++++++++++++++++++++++++ - lib/perlxstut.pod | 1401 +++++++++++++++++++++ - lib/perlxstypemap.pod | 711 +++++++++++ - t/XSTest.xs | 1 + - t/XSUsage.xs | 2 + - 16 files changed, 4497 insertions(+), 18 deletions(-) - create mode 100644 lib/perlxs.pod - create mode 100644 lib/perlxstut.pod - create mode 100644 lib/perlxstypemap.pod - -diff --git a/Changes b/Changes -index 0181371..f9fb36e 100644 ---- a/Changes -+++ b/Changes -@@ -1,5 +1,11 @@ - Revision history for Perl extension ExtUtils::ParseXS. - -+3.36 -+ - Make generated code avoid warnings about the "items" variable -+ being unused -+ - Avoid some unused-variable warnings generated by XS code in the -+ test suite -+ - 3.35 - Mon Jul 31 17:50:00 CET 2017 - - Fix ExtUtils-ParseXS/t/*.t that needed '.' in @INC (David Mitchell) - - Remove impediment to compiling under C++11 (Karl Williamson) -diff --git a/lib/ExtUtils/ParseXS.pm b/lib/ExtUtils/ParseXS.pm -index d629cf6..e1f0940 100644 ---- a/lib/ExtUtils/ParseXS.pm -+++ b/lib/ExtUtils/ParseXS.pm -@@ -11,12 +11,12 @@ use Symbol; - - our $VERSION; - BEGIN { -- $VERSION = '3.35'; -+ $VERSION = '3.39'; -+ require ExtUtils::ParseXS::Constants; ExtUtils::ParseXS::Constants->VERSION($VERSION); -+ require ExtUtils::ParseXS::CountLines; ExtUtils::ParseXS::CountLines->VERSION($VERSION); -+ require ExtUtils::ParseXS::Utilities; ExtUtils::ParseXS::Utilities->VERSION($VERSION); -+ require ExtUtils::ParseXS::Eval; ExtUtils::ParseXS::Eval->VERSION($VERSION); - } --use ExtUtils::ParseXS::Constants $VERSION; --use ExtUtils::ParseXS::CountLines $VERSION; --use ExtUtils::ParseXS::Utilities $VERSION; --use ExtUtils::ParseXS::Eval $VERSION; - $VERSION = eval $VERSION if $VERSION =~ /_/; - - use ExtUtils::ParseXS::Utilities qw( -@@ -519,9 +519,10 @@ EOF - EOF - } - else { -- # cv likely to be unused -+ # cv and items likely to be unused - print Q(<<"EOF"); - # PERL_UNUSED_VAR(cv); /* -W */ -+# PERL_UNUSED_VAR(items); /* -W */ - EOF - } - -@@ -871,6 +872,7 @@ EOF - #XS_EUPXS(XS_$self->{Packid}_nil) - #{ - # dXSARGS; -+# PERL_UNUSED_VAR(items); - # XSRETURN_EMPTY; - #} - # -diff --git a/lib/ExtUtils/ParseXS/Constants.pm b/lib/ExtUtils/ParseXS/Constants.pm -index 2150fb8..45b5674 100644 ---- a/lib/ExtUtils/ParseXS/Constants.pm -+++ b/lib/ExtUtils/ParseXS/Constants.pm -@@ -3,7 +3,7 @@ use strict; - use warnings; - use Symbol; - --our $VERSION = '3.35'; -+our $VERSION = '3.39'; - - =head1 NAME - -diff --git a/lib/ExtUtils/ParseXS/CountLines.pm b/lib/ExtUtils/ParseXS/CountLines.pm -index ad86b57..5b48449 100644 ---- a/lib/ExtUtils/ParseXS/CountLines.pm -+++ b/lib/ExtUtils/ParseXS/CountLines.pm -@@ -1,7 +1,7 @@ - package ExtUtils::ParseXS::CountLines; - use strict; - --our $VERSION = '3.35'; -+our $VERSION = '3.39'; - - our $SECTION_END_MARKER; - -diff --git a/lib/ExtUtils/ParseXS/Eval.pm b/lib/ExtUtils/ParseXS/Eval.pm -index 6b06bf5..9eba5e5 100644 ---- a/lib/ExtUtils/ParseXS/Eval.pm -+++ b/lib/ExtUtils/ParseXS/Eval.pm -@@ -2,7 +2,7 @@ package ExtUtils::ParseXS::Eval; - use strict; - use warnings; - --our $VERSION = '3.35'; -+our $VERSION = '3.39'; - - =head1 NAME - -@@ -29,7 +29,7 @@ Warns the contents of C<$@> if any. - Not all these variables are necessarily considered "public" wrt. use in - typemaps, so beware. Variables set up from the ExtUtils::ParseXS object: - -- $Package $Alias $func_name $Full_func_name $pname -+ $Package $ALIAS $func_name $Full_func_name $pname - - Variables set up from C<$other_hashref>: - -@@ -63,7 +63,7 @@ Warns the contents of C<$@> if any. - Not all these variables are necessarily considered "public" wrt. use in - typemaps, so beware. Variables set up from the ExtUtils::ParseXS object: - -- $Package $Alias $func_name $Full_func_name $pname -+ $Package $ALIAS $func_name $Full_func_name $pname - - Variables set up from C<$other_hashref>: - -diff --git a/lib/ExtUtils/ParseXS/Utilities.pm b/lib/ExtUtils/ParseXS/Utilities.pm -index bc1e098..ae25b33 100644 ---- a/lib/ExtUtils/ParseXS/Utilities.pm -+++ b/lib/ExtUtils/ParseXS/Utilities.pm -@@ -5,7 +5,7 @@ use Exporter; - use File::Spec; - use ExtUtils::ParseXS::Constants (); - --our $VERSION = '3.35'; -+our $VERSION = '3.39'; - - our (@ISA, @EXPORT_OK); - @ISA = qw(Exporter); -diff --git a/lib/ExtUtils/Typemaps.pm b/lib/ExtUtils/Typemaps.pm -index 992d15b..a762322 100644 ---- a/lib/ExtUtils/Typemaps.pm -+++ b/lib/ExtUtils/Typemaps.pm -@@ -2,7 +2,7 @@ package ExtUtils::Typemaps; - use 5.006001; - use strict; - use warnings; --our $VERSION = '3.35'; -+our $VERSION = '3.38'; - - require ExtUtils::ParseXS; - require ExtUtils::ParseXS::Constants; -@@ -781,7 +781,9 @@ corresponding OUTPUT code: - $var.context.value().size()); - ', - 'T_OUT' => ' { -- GV *gv = newGVgen("$Package"); -+ GV *gv = (GV *)sv_newmortal(); -+ gv_init_pvn(gv, gv_stashpvs("$Package",1), -+ "__ANONIO__",10,0); - if ( do_open(gv, "+>&", 3, FALSE, 0, 0, $var) ) - sv_setsv( - $arg, -diff --git a/lib/ExtUtils/Typemaps/Cmd.pm b/lib/ExtUtils/Typemaps/Cmd.pm -index 7ff0780..3c33f54 100644 ---- a/lib/ExtUtils/Typemaps/Cmd.pm -+++ b/lib/ExtUtils/Typemaps/Cmd.pm -@@ -2,7 +2,7 @@ package ExtUtils::Typemaps::Cmd; - use 5.006001; - use strict; - use warnings; --our $VERSION = '3.35'; -+our $VERSION = '3.38'; - - use ExtUtils::Typemaps; - -diff --git a/lib/ExtUtils/Typemaps/InputMap.pm b/lib/ExtUtils/Typemaps/InputMap.pm -index b626973..bf19df1 100644 ---- a/lib/ExtUtils/Typemaps/InputMap.pm -+++ b/lib/ExtUtils/Typemaps/InputMap.pm -@@ -2,7 +2,7 @@ package ExtUtils::Typemaps::InputMap; - use 5.006001; - use strict; - use warnings; --our $VERSION = '3.35'; -+our $VERSION = '3.38'; - - =head1 NAME - -diff --git a/lib/ExtUtils/Typemaps/OutputMap.pm b/lib/ExtUtils/Typemaps/OutputMap.pm -index 8c72e5b..90adb48 100644 ---- a/lib/ExtUtils/Typemaps/OutputMap.pm -+++ b/lib/ExtUtils/Typemaps/OutputMap.pm -@@ -2,7 +2,7 @@ package ExtUtils::Typemaps::OutputMap; - use 5.006001; - use strict; - use warnings; --our $VERSION = '3.35'; -+our $VERSION = '3.38'; - - =head1 NAME - -diff --git a/lib/ExtUtils/Typemaps/Type.pm b/lib/ExtUtils/Typemaps/Type.pm -index 7909bbe..01bd51d 100644 ---- a/lib/ExtUtils/Typemaps/Type.pm -+++ b/lib/ExtUtils/Typemaps/Type.pm -@@ -4,7 +4,7 @@ use strict; - use warnings; - require ExtUtils::Typemaps; - --our $VERSION = '3.35'; -+our $VERSION = '3.38'; - - =head1 NAME - -diff --git a/lib/perlxs.pod b/lib/perlxs.pod -new file mode 100644 -index 0000000..1419ee0 ---- /dev/null -+++ b/lib/perlxs.pod -@@ -0,0 +1,2354 @@ -+=head1 NAME -+ -+perlxs - XS language reference manual -+ -+=head1 DESCRIPTION -+ -+=head2 Introduction -+ -+XS is an interface description file format used to create an extension -+interface between Perl and C code (or a C library) which one wishes -+to use with Perl. The XS interface is combined with the library to -+create a new library which can then be either dynamically loaded -+or statically linked into perl. The XS interface description is -+written in the XS language and is the core component of the Perl -+extension interface. -+ -+Before writing XS, read the L section below. -+ -+An B forms the basic unit of the XS interface. After compilation -+by the B compiler, each XSUB amounts to a C function definition -+which will provide the glue between Perl calling conventions and C -+calling conventions. -+ -+The glue code pulls the arguments from the Perl stack, converts these -+Perl values to the formats expected by a C function, call this C function, -+transfers the return values of the C function back to Perl. -+Return values here may be a conventional C return value or any C -+function arguments that may serve as output parameters. These return -+values may be passed back to Perl either by putting them on the -+Perl stack, or by modifying the arguments supplied from the Perl side. -+ -+The above is a somewhat simplified view of what really happens. Since -+Perl allows more flexible calling conventions than C, XSUBs may do much -+more in practice, such as checking input parameters for validity, -+throwing exceptions (or returning undef/empty list) if the return value -+from the C function indicates failure, calling different C functions -+based on numbers and types of the arguments, providing an object-oriented -+interface, etc. -+ -+Of course, one could write such glue code directly in C. However, this -+would be a tedious task, especially if one needs to write glue for -+multiple C functions, and/or one is not familiar enough with the Perl -+stack discipline and other such arcana. XS comes to the rescue here: -+instead of writing this glue C code in long-hand, one can write -+a more concise short-hand I of what should be done by -+the glue, and let the XS compiler B handle the rest. -+ -+The XS language allows one to describe the mapping between how the C -+routine is used, and how the corresponding Perl routine is used. It -+also allows creation of Perl routines which are directly translated to -+C code and which are not related to a pre-existing C function. In cases -+when the C interface coincides with the Perl interface, the XSUB -+declaration is almost identical to a declaration of a C function (in K&R -+style). In such circumstances, there is another tool called C -+that is able to translate an entire C header file into a corresponding -+XS file that will provide glue to the functions/macros described in -+the header file. -+ -+The XS compiler is called B. This compiler creates -+the constructs necessary to let an XSUB manipulate Perl values, and -+creates the glue necessary to let Perl call the XSUB. The compiler -+uses B to determine how to map C function parameters -+and output values to Perl values and back. The default typemap -+(which comes with Perl) handles many common C types. A supplementary -+typemap may also be needed to handle any special structures and types -+for the library being linked. For more information on typemaps, -+see L. -+ -+A file in XS format starts with a C language section which goes until the -+first C> directive. Other XS directives and XSUB definitions -+may follow this line. The "language" used in this part of the file -+is usually referred to as the XS language. B recognizes and -+skips POD (see L) in both the C and XS language sections, which -+allows the XS file to contain embedded documentation. -+ -+See L for a tutorial on the whole extension creation process. -+ -+Note: For some extensions, Dave Beazley's SWIG system may provide a -+significantly more convenient mechanism for creating the extension -+glue code. See L for more information. -+ -+=head2 On The Road -+ -+Many of the examples which follow will concentrate on creating an interface -+between Perl and the ONC+ RPC bind library functions. The rpcb_gettime() -+function is used to demonstrate many features of the XS language. This -+function has two parameters; the first is an input parameter and the second -+is an output parameter. The function also returns a status value. -+ -+ bool_t rpcb_gettime(const char *host, time_t *timep); -+ -+From C this function will be called with the following -+statements. -+ -+ #include -+ bool_t status; -+ time_t timep; -+ status = rpcb_gettime( "localhost", &timep ); -+ -+If an XSUB is created to offer a direct translation between this function -+and Perl, then this XSUB will be used from Perl with the following code. -+The $status and $timep variables will contain the output of the function. -+ -+ use RPC; -+ $status = rpcb_gettime( "localhost", $timep ); -+ -+The following XS file shows an XS subroutine, or XSUB, which -+demonstrates one possible interface to the rpcb_gettime() -+function. This XSUB represents a direct translation between -+C and Perl and so preserves the interface even from Perl. -+This XSUB will be invoked from Perl with the usage shown -+above. Note that the first three #include statements, for -+C, C, and C, will always be present at the -+beginning of an XS file. This approach and others will be -+expanded later in this document. A #define for C -+should be present to fetch the interpreter context more efficiently, -+see L for details. -+ -+ #define PERL_NO_GET_CONTEXT -+ #include "EXTERN.h" -+ #include "perl.h" -+ #include "XSUB.h" -+ #include -+ -+ MODULE = RPC PACKAGE = RPC -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep -+ OUTPUT: -+ timep -+ -+Any extension to Perl, including those containing XSUBs, -+should have a Perl module to serve as the bootstrap which -+pulls the extension into Perl. This module will export the -+extension's functions and variables to the Perl program and -+will cause the extension's XSUBs to be linked into Perl. -+The following module will be used for most of the examples -+in this document and should be used from Perl with the C -+command as shown earlier. Perl modules are explained in -+more detail later in this document. -+ -+ package RPC; -+ -+ require Exporter; -+ require DynaLoader; -+ @ISA = qw(Exporter DynaLoader); -+ @EXPORT = qw( rpcb_gettime ); -+ -+ bootstrap RPC; -+ 1; -+ -+Throughout this document a variety of interfaces to the rpcb_gettime() -+XSUB will be explored. The XSUBs will take their parameters in different -+orders or will take different numbers of parameters. In each case the -+XSUB is an abstraction between Perl and the real C rpcb_gettime() -+function, and the XSUB must always ensure that the real rpcb_gettime() -+function is called with the correct parameters. This abstraction will -+allow the programmer to create a more Perl-like interface to the C -+function. -+ -+=head2 The Anatomy of an XSUB -+ -+The simplest XSUBs consist of 3 parts: a description of the return -+value, the name of the XSUB routine and the names of its arguments, -+and a description of types or formats of the arguments. -+ -+The following XSUB allows a Perl program to access a C library function -+called sin(). The XSUB will imitate the C function which takes a single -+argument and returns a single value. -+ -+ double -+ sin(x) -+ double x -+ -+Optionally, one can merge the description of types and the list of -+argument names, rewriting this as -+ -+ double -+ sin(double x) -+ -+This makes this XSUB look similar to an ANSI C declaration. An optional -+semicolon is allowed after the argument list, as in -+ -+ double -+ sin(double x); -+ -+Parameters with C pointer types can have different semantic: C functions -+with similar declarations -+ -+ bool string_looks_as_a_number(char *s); -+ bool make_char_uppercase(char *c); -+ -+are used in absolutely incompatible manner. Parameters to these functions -+could be described B like this: -+ -+ char * s -+ char &c -+ -+Both these XS declarations correspond to the C C type, but they have -+different semantics, see L<"The & Unary Operator">. -+ -+It is convenient to think that the indirection operator -+C<*> should be considered as a part of the type and the address operator C<&> -+should be considered part of the variable. See L -+for more info about handling qualifiers and unary operators in C types. -+ -+The function name and the return type must be placed on -+separate lines and should be flush left-adjusted. -+ -+ INCORRECT CORRECT -+ -+ double sin(x) double -+ double x sin(x) -+ double x -+ -+The rest of the function description may be indented or left-adjusted. The -+following example shows a function with its body left-adjusted. Most -+examples in this document will indent the body for better readability. -+ -+ CORRECT -+ -+ double -+ sin(x) -+ double x -+ -+More complicated XSUBs may contain many other sections. Each section of -+an XSUB starts with the corresponding keyword, such as INIT: or CLEANUP:. -+However, the first two lines of an XSUB always contain the same data: -+descriptions of the return type and the names of the function and its -+parameters. Whatever immediately follows these is considered to be -+an INPUT: section unless explicitly marked with another keyword. -+(See L.) -+ -+An XSUB section continues until another section-start keyword is found. -+ -+=head2 The Argument Stack -+ -+The Perl argument stack is used to store the values which are -+sent as parameters to the XSUB and to store the XSUB's -+return value(s). In reality all Perl functions (including non-XSUB -+ones) keep their values on this stack all the same time, each limited -+to its own range of positions on the stack. In this document the -+first position on that stack which belongs to the active -+function will be referred to as position 0 for that function. -+ -+XSUBs refer to their stack arguments with the macro B, where I -+refers to a position in this XSUB's part of the stack. Position 0 for that -+function would be known to the XSUB as ST(0). The XSUB's incoming -+parameters and outgoing return values always begin at ST(0). For many -+simple cases the B compiler will generate the code necessary to -+handle the argument stack by embedding code fragments found in the -+typemaps. In more complex cases the programmer must supply the code. -+ -+=head2 The RETVAL Variable -+ -+The RETVAL variable is a special C variable that is declared automatically -+for you. The C type of RETVAL matches the return type of the C library -+function. The B compiler will declare this variable in each XSUB -+with non-C return type. By default the generated C function -+will use RETVAL to hold the return value of the C library function being -+called. In simple cases the value of RETVAL will be placed in ST(0) of -+the argument stack where it can be received by Perl as the return value -+of the XSUB. -+ -+If the XSUB has a return type of C then the compiler will -+not declare a RETVAL variable for that function. When using -+a PPCODE: section no manipulation of the RETVAL variable is required, the -+section may use direct stack manipulation to place output values on the stack. -+ -+If PPCODE: directive is not used, C return value should be used -+only for subroutines which do not return a value, I CODE: -+directive is used which sets ST(0) explicitly. -+ -+Older versions of this document recommended to use C return -+value in such cases. It was discovered that this could lead to -+segfaults in cases when XSUB was I C. This practice is -+now deprecated, and may be not supported at some future version. Use -+the return value C in such cases. (Currently C contains -+some heuristic code which tries to disambiguate between "truly-void" -+and "old-practice-declared-as-void" functions. Hence your code is at -+mercy of this heuristics unless you use C as return value.) -+ -+=head2 Returning SVs, AVs and HVs through RETVAL -+ -+When you're using RETVAL to return an C, there's some magic -+going on behind the scenes that should be mentioned. When you're -+manipulating the argument stack using the ST(x) macro, for example, -+you usually have to pay special attention to reference counts. (For -+more about reference counts, see L.) To make your life -+easier, the typemap file automatically makes C mortal when -+you're returning an C. Thus, the following two XSUBs are more -+or less equivalent: -+ -+ void -+ alpha() -+ PPCODE: -+ ST(0) = newSVpv("Hello World",0); -+ sv_2mortal(ST(0)); -+ XSRETURN(1); -+ -+ SV * -+ beta() -+ CODE: -+ RETVAL = newSVpv("Hello World",0); -+ OUTPUT: -+ RETVAL -+ -+This is quite useful as it usually improves readability. While -+this works fine for an C, it's unfortunately not as easy -+to have C or C as a return value. You I be -+able to write: -+ -+ AV * -+ array() -+ CODE: -+ RETVAL = newAV(); -+ /* do something with RETVAL */ -+ OUTPUT: -+ RETVAL -+ -+But due to an unfixable bug (fixing it would break lots of existing -+CPAN modules) in the typemap file, the reference count of the C -+is not properly decremented. Thus, the above XSUB would leak memory -+whenever it is being called. The same problem exists for C, -+C, and C (which indicates a scalar reference, not -+a general C). -+In XS code on perls starting with perl 5.16, you can override the -+typemaps for any of these types with a version that has proper -+handling of refcounts. In your C section, do -+ -+ AV* T_AVREF_REFCOUNT_FIXED -+ -+to get the repaired variant. For backward compatibility with older -+versions of perl, you can instead decrement the reference count -+manually when you're returning one of the aforementioned -+types using C: -+ -+ AV * -+ array() -+ CODE: -+ RETVAL = newAV(); -+ sv_2mortal((SV*)RETVAL); -+ /* do something with RETVAL */ -+ OUTPUT: -+ RETVAL -+ -+Remember that you don't have to do this for an C. The reference -+documentation for all core typemaps can be found in L. -+ -+=head2 The MODULE Keyword -+ -+The MODULE keyword is used to start the XS code and to specify the package -+of the functions which are being defined. All text preceding the first -+MODULE keyword is considered C code and is passed through to the output with -+POD stripped, but otherwise untouched. Every XS module will have a -+bootstrap function which is used to hook the XSUBs into Perl. The package -+name of this bootstrap function will match the value of the last MODULE -+statement in the XS source files. The value of MODULE should always remain -+constant within the same XS file, though this is not required. -+ -+The following example will start the XS code and will place -+all functions in a package named RPC. -+ -+ MODULE = RPC -+ -+=head2 The PACKAGE Keyword -+ -+When functions within an XS source file must be separated into packages -+the PACKAGE keyword should be used. This keyword is used with the MODULE -+keyword and must follow immediately after it when used. -+ -+ MODULE = RPC PACKAGE = RPC -+ -+ [ XS code in package RPC ] -+ -+ MODULE = RPC PACKAGE = RPCB -+ -+ [ XS code in package RPCB ] -+ -+ MODULE = RPC PACKAGE = RPC -+ -+ [ XS code in package RPC ] -+ -+The same package name can be used more than once, allowing for -+non-contiguous code. This is useful if you have a stronger ordering -+principle than package names. -+ -+Although this keyword is optional and in some cases provides redundant -+information it should always be used. This keyword will ensure that the -+XSUBs appear in the desired package. -+ -+=head2 The PREFIX Keyword -+ -+The PREFIX keyword designates prefixes which should be -+removed from the Perl function names. If the C function is -+C and the PREFIX value is C then Perl will -+see this function as C. -+ -+This keyword should follow the PACKAGE keyword when used. -+If PACKAGE is not used then PREFIX should follow the MODULE -+keyword. -+ -+ MODULE = RPC PREFIX = rpc_ -+ -+ MODULE = RPC PACKAGE = RPCB PREFIX = rpcb_ -+ -+=head2 The OUTPUT: Keyword -+ -+The OUTPUT: keyword indicates that certain function parameters should be -+updated (new values made visible to Perl) when the XSUB terminates or that -+certain values should be returned to the calling Perl function. For -+simple functions which have no CODE: or PPCODE: section, -+such as the sin() function above, the RETVAL variable is -+automatically designated as an output value. For more complex functions -+the B compiler will need help to determine which variables are output -+variables. -+ -+This keyword will normally be used to complement the CODE: keyword. -+The RETVAL variable is not recognized as an output variable when the -+CODE: keyword is present. The OUTPUT: keyword is used in this -+situation to tell the compiler that RETVAL really is an output -+variable. -+ -+The OUTPUT: keyword can also be used to indicate that function parameters -+are output variables. This may be necessary when a parameter has been -+modified within the function and the programmer would like the update to -+be seen by Perl. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep -+ OUTPUT: -+ timep -+ -+The OUTPUT: keyword will also allow an output parameter to -+be mapped to a matching piece of code rather than to a -+typemap. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep -+ OUTPUT: -+ timep sv_setnv(ST(1), (double)timep); -+ -+B emits an automatic C for all parameters in the -+OUTPUT section of the XSUB, except RETVAL. This is the usually desired -+behavior, as it takes care of properly invoking 'set' magic on output -+parameters (needed for hash or array element parameters that must be -+created if they didn't exist). If for some reason, this behavior is -+not desired, the OUTPUT section may contain a C line -+to disable it for the remainder of the parameters in the OUTPUT section. -+Likewise, C can be used to reenable it for the -+remainder of the OUTPUT section. See L for more details -+about 'set' magic. -+ -+=head2 The NO_OUTPUT Keyword -+ -+The NO_OUTPUT can be placed as the first token of the XSUB. This keyword -+indicates that while the C subroutine we provide an interface to has -+a non-C return type, the return value of this C subroutine should not -+be returned from the generated Perl subroutine. -+ -+With this keyword present L is created, and in the -+generated call to the subroutine this variable is assigned to, but the value -+of this variable is not going to be used in the auto-generated code. -+ -+This keyword makes sense only if C is going to be accessed by the -+user-supplied code. It is especially useful to make a function interface -+more Perl-like, especially when the C return value is just an error condition -+indicator. For example, -+ -+ NO_OUTPUT int -+ delete_file(char *name) -+ POSTCALL: -+ if (RETVAL != 0) -+ croak("Error %d while deleting file '%s'", RETVAL, name); -+ -+Here the generated XS function returns nothing on success, and will die() -+with a meaningful error message on error. -+ -+=head2 The CODE: Keyword -+ -+This keyword is used in more complicated XSUBs which require -+special handling for the C function. The RETVAL variable is -+still declared, but it will not be returned unless it is specified -+in the OUTPUT: section. -+ -+The following XSUB is for a C function which requires special handling of -+its parameters. The Perl usage is given first. -+ -+ $status = rpcb_gettime( "localhost", $timep ); -+ -+The XSUB follows. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t timep -+ CODE: -+ RETVAL = rpcb_gettime( host, &timep ); -+ OUTPUT: -+ timep -+ RETVAL -+ -+=head2 The INIT: Keyword -+ -+The INIT: keyword allows initialization to be inserted into the XSUB before -+the compiler generates the call to the C function. Unlike the CODE: keyword -+above, this keyword does not affect the way the compiler handles RETVAL. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep -+ INIT: -+ printf("# Host is %s\n", host ); -+ OUTPUT: -+ timep -+ -+Another use for the INIT: section is to check for preconditions before -+making a call to the C function: -+ -+ long long -+ lldiv(a,b) -+ long long a -+ long long b -+ INIT: -+ if (a == 0 && b == 0) -+ XSRETURN_UNDEF; -+ if (b == 0) -+ croak("lldiv: cannot divide by 0"); -+ -+=head2 The NO_INIT Keyword -+ -+The NO_INIT keyword is used to indicate that a function -+parameter is being used only as an output value. The B -+compiler will normally generate code to read the values of -+all function parameters from the argument stack and assign -+them to C variables upon entry to the function. NO_INIT -+will tell the compiler that some parameters will be used for -+output rather than for input and that they will be handled -+before the function terminates. -+ -+The following example shows a variation of the rpcb_gettime() function. -+This function uses the timep variable only as an output variable and does -+not care about its initial contents. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep = NO_INIT -+ OUTPUT: -+ timep -+ -+=head2 The TYPEMAP: Keyword -+ -+Starting with Perl 5.16, you can embed typemaps into your XS code -+instead of or in addition to typemaps in a separate file. Multiple -+such embedded typemaps will be processed in order of appearance in -+the XS code and like local typemap files take precedence over the -+default typemap, the embedded typemaps may overwrite previous -+definitions of TYPEMAP, INPUT, and OUTPUT stanzas. The syntax for -+embedded typemaps is -+ -+ TYPEMAP: < keyword must appear in the first column of a -+new line. -+ -+Refer to L for details on writing typemaps. -+ -+=head2 Initializing Function Parameters -+ -+C function parameters are normally initialized with their values from -+the argument stack (which in turn contains the parameters that were -+passed to the XSUB from Perl). The typemaps contain the -+code segments which are used to translate the Perl values to -+the C parameters. The programmer, however, is allowed to -+override the typemaps and supply alternate (or additional) -+initialization code. Initialization code starts with the first -+C<=>, C<;> or C<+> on a line in the INPUT: section. The only -+exception happens if this C<;> terminates the line, then this C<;> -+is quietly ignored. -+ -+The following code demonstrates how to supply initialization code for -+function parameters. The initialization code is eval'ed within double -+quotes by the compiler before it is added to the output so anything -+which should be interpreted literally [mainly C<$>, C<@>, or C<\\>] -+must be protected with backslashes. The variables C<$var>, C<$arg>, -+and C<$type> can be used as in typemaps. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host = (char *)SvPV_nolen($arg); -+ time_t &timep = 0; -+ OUTPUT: -+ timep -+ -+This should not be used to supply default values for parameters. One -+would normally use this when a function parameter must be processed by -+another library function before it can be used. Default parameters are -+covered in the next section. -+ -+If the initialization begins with C<=>, then it is output in -+the declaration for the input variable, replacing the initialization -+supplied by the typemap. If the initialization -+begins with C<;> or C<+>, then it is performed after -+all of the input variables have been declared. In the C<;> -+case the initialization normally supplied by the typemap is not performed. -+For the C<+> case, the declaration for the variable will include the -+initialization from the typemap. A global -+variable, C<%v>, is available for the truly rare case where -+information from one initialization is needed in another -+initialization. -+ -+Here's a truly obscure example: -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ time_t &timep; /* \$v{timep}=@{[$v{timep}=$arg]} */ -+ char *host + SvOK($v{timep}) ? SvPV_nolen($arg) : NULL; -+ OUTPUT: -+ timep -+ -+The construct C<\$v{timep}=@{[$v{timep}=$arg]}> used in the above -+example has a two-fold purpose: first, when this line is processed by -+B, the Perl snippet C<$v{timep}=$arg> is evaluated. Second, -+the text of the evaluated snippet is output into the generated C file -+(inside a C comment)! During the processing of C line, -+C<$arg> will evaluate to C, and C<$v{timep}> will evaluate to -+C. -+ -+=head2 Default Parameter Values -+ -+Default values for XSUB arguments can be specified by placing an -+assignment statement in the parameter list. The default value may -+be a number, a string or the special string C. Defaults should -+always be used on the right-most parameters only. -+ -+To allow the XSUB for rpcb_gettime() to have a default host -+value the parameters to the XSUB could be rearranged. The -+XSUB will then call the real rpcb_gettime() function with -+the parameters in the correct order. This XSUB can be called -+from Perl with either of the following statements: -+ -+ $status = rpcb_gettime( $timep, $host ); -+ -+ $status = rpcb_gettime( $timep ); -+ -+The XSUB will look like the code which follows. A CODE: -+block is used to call the real rpcb_gettime() function with -+the parameters in the correct order for that function. -+ -+ bool_t -+ rpcb_gettime(timep,host="localhost") -+ char *host -+ time_t timep = NO_INIT -+ CODE: -+ RETVAL = rpcb_gettime( host, &timep ); -+ OUTPUT: -+ timep -+ RETVAL -+ -+=head2 The PREINIT: Keyword -+ -+The PREINIT: keyword allows extra variables to be declared immediately -+before or after the declarations of the parameters from the INPUT: section -+are emitted. -+ -+If a variable is declared inside a CODE: section it will follow any typemap -+code that is emitted for the input parameters. This may result in the -+declaration ending up after C code, which is C syntax error. Similar -+errors may happen with an explicit C<;>-type or C<+>-type initialization of -+parameters is used (see L<"Initializing Function Parameters">). Declaring -+these variables in an INIT: section will not help. -+ -+In such cases, to force an additional variable to be declared together -+with declarations of other variables, place the declaration into a -+PREINIT: section. The PREINIT: keyword may be used one or more times -+within an XSUB. -+ -+The following examples are equivalent, but if the code is using complex -+typemaps then the first example is safer. -+ -+ bool_t -+ rpcb_gettime(timep) -+ time_t timep = NO_INIT -+ PREINIT: -+ char *host = "localhost"; -+ CODE: -+ RETVAL = rpcb_gettime( host, &timep ); -+ OUTPUT: -+ timep -+ RETVAL -+ -+For this particular case an INIT: keyword would generate the -+same C code as the PREINIT: keyword. Another correct, but error-prone example: -+ -+ bool_t -+ rpcb_gettime(timep) -+ time_t timep = NO_INIT -+ CODE: -+ char *host = "localhost"; -+ RETVAL = rpcb_gettime( host, &timep ); -+ OUTPUT: -+ timep -+ RETVAL -+ -+Another way to declare C is to use a C block in the CODE: section: -+ -+ bool_t -+ rpcb_gettime(timep) -+ time_t timep = NO_INIT -+ CODE: -+ { -+ char *host = "localhost"; -+ RETVAL = rpcb_gettime( host, &timep ); -+ } -+ OUTPUT: -+ timep -+ RETVAL -+ -+The ability to put additional declarations before the typemap entries are -+processed is very handy in the cases when typemap conversions manipulate -+some global state: -+ -+ MyObject -+ mutate(o) -+ PREINIT: -+ MyState st = global_state; -+ INPUT: -+ MyObject o; -+ CLEANUP: -+ reset_to(global_state, st); -+ -+Here we suppose that conversion to C in the INPUT: section and from -+MyObject when processing RETVAL will modify a global variable C. -+After these conversions are performed, we restore the old value of -+C (to avoid memory leaks, for example). -+ -+There is another way to trade clarity for compactness: INPUT sections allow -+declaration of C variables which do not appear in the parameter list of -+a subroutine. Thus the above code for mutate() can be rewritten as -+ -+ MyObject -+ mutate(o) -+ MyState st = global_state; -+ MyObject o; -+ CLEANUP: -+ reset_to(global_state, st); -+ -+and the code for rpcb_gettime() can be rewritten as -+ -+ bool_t -+ rpcb_gettime(timep) -+ time_t timep = NO_INIT -+ char *host = "localhost"; -+ C_ARGS: -+ host, &timep -+ OUTPUT: -+ timep -+ RETVAL -+ -+=head2 The SCOPE: Keyword -+ -+The SCOPE: keyword allows scoping to be enabled for a particular XSUB. If -+enabled, the XSUB will invoke ENTER and LEAVE automatically. -+ -+To support potentially complex type mappings, if a typemap entry used -+by an XSUB contains a comment like C then scoping will -+be automatically enabled for that XSUB. -+ -+To enable scoping: -+ -+ SCOPE: ENABLE -+ -+To disable scoping: -+ -+ SCOPE: DISABLE -+ -+=head2 The INPUT: Keyword -+ -+The XSUB's parameters are usually evaluated immediately after entering the -+XSUB. The INPUT: keyword can be used to force those parameters to be -+evaluated a little later. The INPUT: keyword can be used multiple times -+within an XSUB and can be used to list one or more input variables. This -+keyword is used with the PREINIT: keyword. -+ -+The following example shows how the input parameter C can be -+evaluated late, after a PREINIT. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ PREINIT: -+ time_t tt; -+ INPUT: -+ time_t timep -+ CODE: -+ RETVAL = rpcb_gettime( host, &tt ); -+ timep = tt; -+ OUTPUT: -+ timep -+ RETVAL -+ -+The next example shows each input parameter evaluated late. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ PREINIT: -+ time_t tt; -+ INPUT: -+ char *host -+ PREINIT: -+ char *h; -+ INPUT: -+ time_t timep -+ CODE: -+ h = host; -+ RETVAL = rpcb_gettime( h, &tt ); -+ timep = tt; -+ OUTPUT: -+ timep -+ RETVAL -+ -+Since INPUT sections allow declaration of C variables which do not appear -+in the parameter list of a subroutine, this may be shortened to: -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ time_t tt; -+ char *host; -+ char *h = host; -+ time_t timep; -+ CODE: -+ RETVAL = rpcb_gettime( h, &tt ); -+ timep = tt; -+ OUTPUT: -+ timep -+ RETVAL -+ -+(We used our knowledge that input conversion for C is a "simple" one, -+thus C is initialized on the declaration line, and our assignment -+C is not performed too early. Otherwise one would need to have the -+assignment C in a CODE: or INIT: section.) -+ -+=head2 The IN/OUTLIST/IN_OUTLIST/OUT/IN_OUT Keywords -+ -+In the list of parameters for an XSUB, one can precede parameter names -+by the C/C/C/C/C keywords. -+C keyword is the default, the other keywords indicate how the Perl -+interface should differ from the C interface. -+ -+Parameters preceded by C/C/C/C -+keywords are considered to be used by the C subroutine I. C/C keywords indicate that the C subroutine -+does not inspect the memory pointed by this parameter, but will write -+through this pointer to provide additional return values. -+ -+Parameters preceded by C keyword do not appear in the usage -+signature of the generated Perl function. -+ -+Parameters preceded by C/C/C I appear as -+parameters to the Perl function. With the exception of -+C-parameters, these parameters are converted to the corresponding -+C type, then pointers to these data are given as arguments to the C -+function. It is expected that the C function will write through these -+pointers. -+ -+The return list of the generated Perl function consists of the C return value -+from the function (unless the XSUB is of C return type or -+C was used) followed by all the C -+and C parameters (in the order of appearance). On the -+return from the XSUB the C/C Perl parameter will be -+modified to have the values written by the C function. -+ -+For example, an XSUB -+ -+ void -+ day_month(OUTLIST day, IN unix_time, OUTLIST month) -+ int day -+ int unix_time -+ int month -+ -+should be used from Perl as -+ -+ my ($day, $month) = day_month(time); -+ -+The C signature of the corresponding function should be -+ -+ void day_month(int *day, int unix_time, int *month); -+ -+The C/C/C/C/C keywords can be -+mixed with ANSI-style declarations, as in -+ -+ void -+ day_month(OUTLIST int day, int unix_time, OUTLIST int month) -+ -+(here the optional C keyword is omitted). -+ -+The C parameters are identical with parameters introduced with -+L and put into the C section (see -+L). The C parameters are very similar, -+the only difference being that the value C function writes through the -+pointer would not modify the Perl parameter, but is put in the output -+list. -+ -+The C/C parameter differ from C/C -+parameters only by the initial value of the Perl parameter not -+being read (and not being given to the C function - which gets some -+garbage instead). For example, the same C function as above can be -+interfaced with as -+ -+ void day_month(OUT int day, int unix_time, OUT int month); -+ -+or -+ -+ void -+ day_month(day, unix_time, month) -+ int &day = NO_INIT -+ int unix_time -+ int &month = NO_INIT -+ OUTPUT: -+ day -+ month -+ -+However, the generated Perl function is called in very C-ish style: -+ -+ my ($day, $month); -+ day_month($day, time, $month); -+ -+=head2 The C Keyword -+ -+If one of the input arguments to the C function is the length of a string -+argument C, one can substitute the name of the length-argument by -+C in the XSUB declaration. This argument must be omitted when -+the generated Perl function is called. E.g., -+ -+ void -+ dump_chars(char *s, short l) -+ { -+ short n = 0; -+ while (n < l) { -+ printf("s[%d] = \"\\%#03o\"\n", n, (int)s[n]); -+ n++; -+ } -+ } -+ -+ MODULE = x PACKAGE = x -+ -+ void dump_chars(char *s, short length(s)) -+ -+should be called as C. -+ -+This directive is supported with ANSI-type function declarations only. -+ -+=head2 Variable-length Parameter Lists -+ -+XSUBs can have variable-length parameter lists by specifying an ellipsis -+C<(...)> in the parameter list. This use of the ellipsis is similar to that -+found in ANSI C. The programmer is able to determine the number of -+arguments passed to the XSUB by examining the C variable which the -+B compiler supplies for all XSUBs. By using this mechanism one can -+create an XSUB which accepts a list of parameters of unknown length. -+ -+The I parameter for the rpcb_gettime() XSUB can be -+optional so the ellipsis can be used to indicate that the -+XSUB will take a variable number of parameters. Perl should -+be able to call this XSUB with either of the following statements. -+ -+ $status = rpcb_gettime( $timep, $host ); -+ -+ $status = rpcb_gettime( $timep ); -+ -+The XS code, with ellipsis, follows. -+ -+ bool_t -+ rpcb_gettime(timep, ...) -+ time_t timep = NO_INIT -+ PREINIT: -+ char *host = "localhost"; -+ CODE: -+ if( items > 1 ) -+ host = (char *)SvPV_nolen(ST(1)); -+ RETVAL = rpcb_gettime( host, &timep ); -+ OUTPUT: -+ timep -+ RETVAL -+ -+=head2 The C_ARGS: Keyword -+ -+The C_ARGS: keyword allows creating of XSUBS which have different -+calling sequence from Perl than from C, without a need to write -+CODE: or PPCODE: section. The contents of the C_ARGS: paragraph is -+put as the argument to the called C function without any change. -+ -+For example, suppose that a C function is declared as -+ -+ symbolic nth_derivative(int n, symbolic function, int flags); -+ -+and that the default flags are kept in a global C variable -+C. Suppose that you want to create an interface which -+is called as -+ -+ $second_deriv = $function->nth_derivative(2); -+ -+To do this, declare the XSUB as -+ -+ symbolic -+ nth_derivative(function, n) -+ symbolic function -+ int n -+ C_ARGS: -+ n, function, default_flags -+ -+=head2 The PPCODE: Keyword -+ -+The PPCODE: keyword is an alternate form of the CODE: keyword and is used -+to tell the B compiler that the programmer is supplying the code to -+control the argument stack for the XSUBs return values. Occasionally one -+will want an XSUB to return a list of values rather than a single value. -+In these cases one must use PPCODE: and then explicitly push the list of -+values on the stack. The PPCODE: and CODE: keywords should not be used -+together within the same XSUB. -+ -+The actual difference between PPCODE: and CODE: sections is in the -+initialization of C macro (which stands for the I Perl -+stack pointer), and in the handling of data on the stack when returning -+from an XSUB. In CODE: sections SP preserves the value which was on -+entry to the XSUB: SP is on the function pointer (which follows the -+last parameter). In PPCODE: sections SP is moved backward to the -+beginning of the parameter list, which allows C macros -+to place output values in the place Perl expects them to be when -+the XSUB returns back to Perl. -+ -+The generated trailer for a CODE: section ensures that the number of return -+values Perl will see is either 0 or 1 (depending on the Cness of the -+return value of the C function, and heuristics mentioned in -+L<"The RETVAL Variable">). The trailer generated for a PPCODE: section -+is based on the number of return values and on the number of times -+C was updated by C<[X]PUSH*()> macros. -+ -+Note that macros C, C and C work equally -+well in CODE: sections and PPCODE: sections. -+ -+The following XSUB will call the C rpcb_gettime() function -+and will return its two output values, timep and status, to -+Perl as a single list. -+ -+ void -+ rpcb_gettime(host) -+ char *host -+ PREINIT: -+ time_t timep; -+ bool_t status; -+ PPCODE: -+ status = rpcb_gettime( host, &timep ); -+ EXTEND(SP, 2); -+ PUSHs(sv_2mortal(newSViv(status))); -+ PUSHs(sv_2mortal(newSViv(timep))); -+ -+Notice that the programmer must supply the C code necessary -+to have the real rpcb_gettime() function called and to have -+the return values properly placed on the argument stack. -+ -+The C return type for this function tells the B compiler that -+the RETVAL variable is not needed or used and that it should not be created. -+In most scenarios the void return type should be used with the PPCODE: -+directive. -+ -+The EXTEND() macro is used to make room on the argument -+stack for 2 return values. The PPCODE: directive causes the -+B compiler to create a stack pointer available as C, and it -+is this pointer which is being used in the EXTEND() macro. -+The values are then pushed onto the stack with the PUSHs() -+macro. -+ -+Now the rpcb_gettime() function can be used from Perl with -+the following statement. -+ -+ ($status, $timep) = rpcb_gettime("localhost"); -+ -+When handling output parameters with a PPCODE section, be sure to handle -+'set' magic properly. See L for details about 'set' magic. -+ -+=head2 Returning Undef And Empty Lists -+ -+Occasionally the programmer will want to return simply -+C or an empty list if a function fails rather than a -+separate status value. The rpcb_gettime() function offers -+just this situation. If the function succeeds we would like -+to have it return the time and if it fails we would like to -+have undef returned. In the following Perl code the value -+of $timep will either be undef or it will be a valid time. -+ -+ $timep = rpcb_gettime( "localhost" ); -+ -+The following XSUB uses the C return type as a mnemonic only, -+and uses a CODE: block to indicate to the compiler -+that the programmer has supplied all the necessary code. The -+sv_newmortal() call will initialize the return value to undef, making that -+the default return value. -+ -+ SV * -+ rpcb_gettime(host) -+ char * host -+ PREINIT: -+ time_t timep; -+ bool_t x; -+ CODE: -+ ST(0) = sv_newmortal(); -+ if( rpcb_gettime( host, &timep ) ) -+ sv_setnv( ST(0), (double)timep); -+ -+The next example demonstrates how one would place an explicit undef in the -+return value, should the need arise. -+ -+ SV * -+ rpcb_gettime(host) -+ char * host -+ PREINIT: -+ time_t timep; -+ bool_t x; -+ CODE: -+ if( rpcb_gettime( host, &timep ) ){ -+ ST(0) = sv_newmortal(); -+ sv_setnv( ST(0), (double)timep); -+ } -+ else{ -+ ST(0) = &PL_sv_undef; -+ } -+ -+To return an empty list one must use a PPCODE: block and -+then not push return values on the stack. -+ -+ void -+ rpcb_gettime(host) -+ char *host -+ PREINIT: -+ time_t timep; -+ PPCODE: -+ if( rpcb_gettime( host, &timep ) ) -+ PUSHs(sv_2mortal(newSViv(timep))); -+ else{ -+ /* Nothing pushed on stack, so an empty -+ * list is implicitly returned. */ -+ } -+ -+Some people may be inclined to include an explicit C in the above -+XSUB, rather than letting control fall through to the end. In those -+situations C should be used, instead. This will ensure that -+the XSUB stack is properly adjusted. Consult L for other -+C macros. -+ -+Since C macros can be used with CODE blocks as well, one can -+rewrite this example as: -+ -+ int -+ rpcb_gettime(host) -+ char *host -+ PREINIT: -+ time_t timep; -+ CODE: -+ RETVAL = rpcb_gettime( host, &timep ); -+ if (RETVAL == 0) -+ XSRETURN_UNDEF; -+ OUTPUT: -+ RETVAL -+ -+In fact, one can put this check into a POSTCALL: section as well. Together -+with PREINIT: simplifications, this leads to: -+ -+ int -+ rpcb_gettime(host) -+ char *host -+ time_t timep; -+ POSTCALL: -+ if (RETVAL == 0) -+ XSRETURN_UNDEF; -+ -+=head2 The REQUIRE: Keyword -+ -+The REQUIRE: keyword is used to indicate the minimum version of the -+B compiler needed to compile the XS module. An XS module which -+contains the following statement will compile with only B version -+1.922 or greater: -+ -+ REQUIRE: 1.922 -+ -+=head2 The CLEANUP: Keyword -+ -+This keyword can be used when an XSUB requires special cleanup procedures -+before it terminates. When the CLEANUP: keyword is used it must follow -+any CODE:, or OUTPUT: blocks which are present in the XSUB. The code -+specified for the cleanup block will be added as the last statements in -+the XSUB. -+ -+=head2 The POSTCALL: Keyword -+ -+This keyword can be used when an XSUB requires special procedures -+executed after the C subroutine call is performed. When the POSTCALL: -+keyword is used it must precede OUTPUT: and CLEANUP: blocks which are -+present in the XSUB. -+ -+See examples in L<"The NO_OUTPUT Keyword"> and L<"Returning Undef And Empty Lists">. -+ -+The POSTCALL: block does not make a lot of sense when the C subroutine -+call is supplied by user by providing either CODE: or PPCODE: section. -+ -+=head2 The BOOT: Keyword -+ -+The BOOT: keyword is used to add code to the extension's bootstrap -+function. The bootstrap function is generated by the B compiler and -+normally holds the statements necessary to register any XSUBs with Perl. -+With the BOOT: keyword the programmer can tell the compiler to add extra -+statements to the bootstrap function. -+ -+This keyword may be used any time after the first MODULE keyword and should -+appear on a line by itself. The first blank line after the keyword will -+terminate the code block. -+ -+ BOOT: -+ # The following message will be printed when the -+ # bootstrap function executes. -+ printf("Hello from the bootstrap!\n"); -+ -+=head2 The VERSIONCHECK: Keyword -+ -+The VERSIONCHECK: keyword corresponds to B's C<-versioncheck> and -+C<-noversioncheck> options. This keyword overrides the command line -+options. Version checking is enabled by default. When version checking is -+enabled the XS module will attempt to verify that its version matches the -+version of the PM module. -+ -+To enable version checking: -+ -+ VERSIONCHECK: ENABLE -+ -+To disable version checking: -+ -+ VERSIONCHECK: DISABLE -+ -+Note that if the version of the PM module is an NV (a floating point -+number), it will be stringified with a possible loss of precision -+(currently chopping to nine decimal places) so that it may not match -+the version of the XS module anymore. Quoting the $VERSION declaration -+to make it a string is recommended if long version numbers are used. -+ -+=head2 The PROTOTYPES: Keyword -+ -+The PROTOTYPES: keyword corresponds to B's C<-prototypes> and -+C<-noprototypes> options. This keyword overrides the command line options. -+Prototypes are disabled by default. When prototypes are enabled, XSUBs will -+be given Perl prototypes. This keyword may be used multiple times in an XS -+module to enable and disable prototypes for different parts of the module. -+Note that B will nag you if you don't explicitly enable or disable -+prototypes, with: -+ -+ Please specify prototyping behavior for Foo.xs (see perlxs manual) -+ -+To enable prototypes: -+ -+ PROTOTYPES: ENABLE -+ -+To disable prototypes: -+ -+ PROTOTYPES: DISABLE -+ -+=head2 The PROTOTYPE: Keyword -+ -+This keyword is similar to the PROTOTYPES: keyword above but can be used to -+force B to use a specific prototype for the XSUB. This keyword -+overrides all other prototype options and keywords but affects only the -+current XSUB. Consult L for information about Perl -+prototypes. -+ -+ bool_t -+ rpcb_gettime(timep, ...) -+ time_t timep = NO_INIT -+ PROTOTYPE: $;$ -+ PREINIT: -+ char *host = "localhost"; -+ CODE: -+ if( items > 1 ) -+ host = (char *)SvPV_nolen(ST(1)); -+ RETVAL = rpcb_gettime( host, &timep ); -+ OUTPUT: -+ timep -+ RETVAL -+ -+If the prototypes are enabled, you can disable it locally for a given -+XSUB as in the following example: -+ -+ void -+ rpcb_gettime_noproto() -+ PROTOTYPE: DISABLE -+ ... -+ -+=head2 The ALIAS: Keyword -+ -+The ALIAS: keyword allows an XSUB to have two or more unique Perl names -+and to know which of those names was used when it was invoked. The Perl -+names may be fully-qualified with package names. Each alias is given an -+index. The compiler will setup a variable called C which contain the -+index of the alias which was used. When the XSUB is called with its -+declared name C will be 0. -+ -+The following example will create aliases C and -+C for this function. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep -+ ALIAS: -+ FOO::gettime = 1 -+ BAR::getit = 2 -+ INIT: -+ printf("# ix = %d\n", ix ); -+ OUTPUT: -+ timep -+ -+=head2 The OVERLOAD: Keyword -+ -+Instead of writing an overloaded interface using pure Perl, you -+can also use the OVERLOAD keyword to define additional Perl names -+for your functions (like the ALIAS: keyword above). However, the -+overloaded functions must be defined in such a way as to accept the number -+of parameters supplied by perl's overload system. For most overload -+methods, it will be three parameters; for the C function it will -+be four. However, the bitwise operators C<&>, C<|>, C<^>, and C<~> may be -+called with three I five arguments (see L). -+ -+If any -+function has the OVERLOAD: keyword, several additional lines -+will be defined in the c file generated by xsubpp in order to -+register with the overload magic. -+ -+Since blessed objects are actually stored as RV's, it is useful -+to use the typemap features to preprocess parameters and extract -+the actual SV stored within the blessed RV. See the sample for -+T_PTROBJ_SPECIAL below. -+ -+To use the OVERLOAD: keyword, create an XS function which takes -+three input parameters (or use the C-style '...' definition) like -+this: -+ -+ SV * -+ cmp (lobj, robj, swap) -+ My_Module_obj lobj -+ My_Module_obj robj -+ IV swap -+ OVERLOAD: cmp <=> -+ { /* function defined here */} -+ -+In this case, the function will overload both of the three way -+comparison operators. For all overload operations using non-alpha -+characters, you must type the parameter without quoting, separating -+multiple overloads with whitespace. Note that "" (the stringify -+overload) should be entered as \"\" (i.e. escaped). -+ -+Since, as mentioned above, bitwise operators may take extra arguments, you -+may want to use something like C<(lobj, robj, swap, ...)> (with -+literal C<...>) as your parameter list. -+ -+=head2 The FALLBACK: Keyword -+ -+In addition to the OVERLOAD keyword, if you need to control how -+Perl autogenerates missing overloaded operators, you can set the -+FALLBACK keyword in the module header section, like this: -+ -+ MODULE = RPC PACKAGE = RPC -+ -+ FALLBACK: TRUE -+ ... -+ -+where FALLBACK can take any of the three values TRUE, FALSE, or -+UNDEF. If you do not set any FALLBACK value when using OVERLOAD, -+it defaults to UNDEF. FALLBACK is not used except when one or -+more functions using OVERLOAD have been defined. Please see -+L for more details. -+ -+=head2 The INTERFACE: Keyword -+ -+This keyword declares the current XSUB as a keeper of the given -+calling signature. If some text follows this keyword, it is -+considered as a list of functions which have this signature, and -+should be attached to the current XSUB. -+ -+For example, if you have 4 C functions multiply(), divide(), add(), -+subtract() all having the signature: -+ -+ symbolic f(symbolic, symbolic); -+ -+you can make them all to use the same XSUB using this: -+ -+ symbolic -+ interface_s_ss(arg1, arg2) -+ symbolic arg1 -+ symbolic arg2 -+ INTERFACE: -+ multiply divide -+ add subtract -+ -+(This is the complete XSUB code for 4 Perl functions!) Four generated -+Perl function share names with corresponding C functions. -+ -+The advantage of this approach comparing to ALIAS: keyword is that there -+is no need to code a switch statement, each Perl function (which shares -+the same XSUB) knows which C function it should call. Additionally, one -+can attach an extra function remainder() at runtime by using -+ -+ CV *mycv = newXSproto("Symbolic::remainder", -+ XS_Symbolic_interface_s_ss, __FILE__, "$$"); -+ XSINTERFACE_FUNC_SET(mycv, remainder); -+ -+say, from another XSUB. (This example supposes that there was no -+INTERFACE_MACRO: section, otherwise one needs to use something else instead of -+C, see the next section.) -+ -+=head2 The INTERFACE_MACRO: Keyword -+ -+This keyword allows one to define an INTERFACE using a different way -+to extract a function pointer from an XSUB. The text which follows -+this keyword should give the name of macros which would extract/set a -+function pointer. The extractor macro is given return type, C, -+and C for this C. The setter macro is given cv, -+and the function pointer. -+ -+The default value is C and C. -+An INTERFACE keyword with an empty list of functions can be omitted if -+INTERFACE_MACRO keyword is used. -+ -+Suppose that in the previous example functions pointers for -+multiply(), divide(), add(), subtract() are kept in a global C array -+C with offsets being C, C, C, -+C. Then one can use -+ -+ #define XSINTERFACE_FUNC_BYOFFSET(ret,cv,f) \ -+ ((XSINTERFACE_CVT_ANON(ret))fp[CvXSUBANY(cv).any_i32]) -+ #define XSINTERFACE_FUNC_BYOFFSET_set(cv,f) \ -+ CvXSUBANY(cv).any_i32 = CAT2( f, _off ) -+ -+in C section, -+ -+ symbolic -+ interface_s_ss(arg1, arg2) -+ symbolic arg1 -+ symbolic arg2 -+ INTERFACE_MACRO: -+ XSINTERFACE_FUNC_BYOFFSET -+ XSINTERFACE_FUNC_BYOFFSET_set -+ INTERFACE: -+ multiply divide -+ add subtract -+ -+in XSUB section. -+ -+=head2 The INCLUDE: Keyword -+ -+This keyword can be used to pull other files into the XS module. The other -+files may have XS code. INCLUDE: can also be used to run a command to -+generate the XS code to be pulled into the module. -+ -+The file F contains our C function: -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep -+ OUTPUT: -+ timep -+ -+The XS module can use INCLUDE: to pull that file into it. -+ -+ INCLUDE: Rpcb1.xsh -+ -+If the parameters to the INCLUDE: keyword are followed by a pipe (C<|>) then -+the compiler will interpret the parameters as a command. This feature is -+mildly deprecated in favour of the C directive, as documented -+below. -+ -+ INCLUDE: cat Rpcb1.xsh | -+ -+Do not use this to run perl: C will run the perl that -+happens to be the first in your path and not necessarily the same perl that is -+used to run C. See L<"The INCLUDE_COMMAND: Keyword">. -+ -+=head2 The INCLUDE_COMMAND: Keyword -+ -+Runs the supplied command and includes its output into the current XS -+document. C assigns special meaning to the C<$^X> token -+in that it runs the same perl interpreter that is running C: -+ -+ INCLUDE_COMMAND: cat Rpcb1.xsh -+ -+ INCLUDE_COMMAND: $^X -e ... -+ -+=head2 The CASE: Keyword -+ -+The CASE: keyword allows an XSUB to have multiple distinct parts with each -+part acting as a virtual XSUB. CASE: is greedy and if it is used then all -+other XS keywords must be contained within a CASE:. This means nothing may -+precede the first CASE: in the XSUB and anything following the last CASE: is -+included in that case. -+ -+A CASE: might switch via a parameter of the XSUB, via the C ALIAS: -+variable (see L<"The ALIAS: Keyword">), or maybe via the C variable -+(see L<"Variable-length Parameter Lists">). The last CASE: becomes the -+B case if it is not associated with a conditional. The following -+example shows CASE switched via C with a function C -+having an alias C. When the function is called as -+C its parameters are the usual C<(char *host, time_t *timep)>, -+but when the function is called as C its parameters are -+reversed, C<(time_t *timep, char *host)>. -+ -+ long -+ rpcb_gettime(a,b) -+ CASE: ix == 1 -+ ALIAS: -+ x_gettime = 1 -+ INPUT: -+ # 'a' is timep, 'b' is host -+ char *b -+ time_t a = NO_INIT -+ CODE: -+ RETVAL = rpcb_gettime( b, &a ); -+ OUTPUT: -+ a -+ RETVAL -+ CASE: -+ # 'a' is host, 'b' is timep -+ char *a -+ time_t &b = NO_INIT -+ OUTPUT: -+ b -+ RETVAL -+ -+That function can be called with either of the following statements. Note -+the different argument lists. -+ -+ $status = rpcb_gettime( $host, $timep ); -+ -+ $status = x_gettime( $timep, $host ); -+ -+=head2 The EXPORT_XSUB_SYMBOLS: Keyword -+ -+The EXPORT_XSUB_SYMBOLS: keyword is likely something you will never need. -+In perl versions earlier than 5.16.0, this keyword does nothing. Starting -+with 5.16, XSUB symbols are no longer exported by default. That is, they -+are C functions. If you include -+ -+ EXPORT_XSUB_SYMBOLS: ENABLE -+ -+in your XS code, the XSUBs following this line will not be declared C. -+You can later disable this with -+ -+ EXPORT_XSUB_SYMBOLS: DISABLE -+ -+which, again, is the default that you should probably never change. -+You cannot use this keyword on versions of perl before 5.16 to make -+XSUBs C. -+ -+=head2 The & Unary Operator -+ -+The C<&> unary operator in the INPUT: section is used to tell B -+that it should convert a Perl value to/from C using the C type to the left -+of C<&>, but provide a pointer to this value when the C function is called. -+ -+This is useful to avoid a CODE: block for a C function which takes a parameter -+by reference. Typically, the parameter should be not a pointer type (an -+C or C but not an C or C). -+ -+The following XSUB will generate incorrect C code. The B compiler will -+turn this into code which calls C with parameters C<(char -+*host, time_t timep)>, but the real C wants the C -+parameter to be of type C rather than C. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t timep -+ OUTPUT: -+ timep -+ -+That problem is corrected by using the C<&> operator. The B compiler -+will now turn this into code which calls C correctly with -+parameters C<(char *host, time_t *timep)>. It does this by carrying the -+C<&> through, so the function call looks like C. -+ -+ bool_t -+ rpcb_gettime(host,timep) -+ char *host -+ time_t &timep -+ OUTPUT: -+ timep -+ -+=head2 Inserting POD, Comments and C Preprocessor Directives -+ -+C preprocessor directives are allowed within BOOT:, PREINIT: INIT:, CODE:, -+PPCODE:, POSTCALL:, and CLEANUP: blocks, as well as outside the functions. -+Comments are allowed anywhere after the MODULE keyword. The compiler will -+pass the preprocessor directives through untouched and will remove the -+commented lines. POD documentation is allowed at any point, both in the -+C and XS language sections. POD must be terminated with a C<=cut> command; -+C will exit with an error if it does not. It is very unlikely that -+human generated C code will be mistaken for POD, as most indenting styles -+result in whitespace in front of any line starting with C<=>. Machine -+generated XS files may fall into this trap unless care is taken to -+ensure that a space breaks the sequence "\n=". -+ -+Comments can be added to XSUBs by placing a C<#> as the first -+non-whitespace of a line. Care should be taken to avoid making the -+comment look like a C preprocessor directive, lest it be interpreted as -+such. The simplest way to prevent this is to put whitespace in front of -+the C<#>. -+ -+If you use preprocessor directives to choose one of two -+versions of a function, use -+ -+ #if ... version1 -+ #else /* ... version2 */ -+ #endif -+ -+and not -+ -+ #if ... version1 -+ #endif -+ #if ... version2 -+ #endif -+ -+because otherwise B will believe that you made a duplicate -+definition of the function. Also, put a blank line before the -+#else/#endif so it will not be seen as part of the function body. -+ -+=head2 Using XS With C++ -+ -+If an XSUB name contains C<::>, it is considered to be a C++ method. -+The generated Perl function will assume that -+its first argument is an object pointer. The object pointer -+will be stored in a variable called THIS. The object should -+have been created by C++ with the new() function and should -+be blessed by Perl with the sv_setref_pv() macro. The -+blessing of the object by Perl can be handled by a typemap. An example -+typemap is shown at the end of this section. -+ -+If the return type of the XSUB includes C, the method is considered -+to be a static method. It will call the C++ -+function using the class::method() syntax. If the method is not static -+the function will be called using the THIS-Emethod() syntax. -+ -+The next examples will use the following C++ class. -+ -+ class color { -+ public: -+ color(); -+ ~color(); -+ int blue(); -+ void set_blue( int ); -+ -+ private: -+ int c_blue; -+ }; -+ -+The XSUBs for the blue() and set_blue() methods are defined with the class -+name but the parameter for the object (THIS, or "self") is implicit and is -+not listed. -+ -+ int -+ color::blue() -+ -+ void -+ color::set_blue( val ) -+ int val -+ -+Both Perl functions will expect an object as the first parameter. In the -+generated C++ code the object is called C, and the method call will -+be performed on this object. So in the C++ code the blue() and set_blue() -+methods will be called as this: -+ -+ RETVAL = THIS->blue(); -+ -+ THIS->set_blue( val ); -+ -+You could also write a single get/set method using an optional argument: -+ -+ int -+ color::blue( val = NO_INIT ) -+ int val -+ PROTOTYPE $;$ -+ CODE: -+ if (items > 1) -+ THIS->set_blue( val ); -+ RETVAL = THIS->blue(); -+ OUTPUT: -+ RETVAL -+ -+If the function's name is B then the C++ C function will be -+called and C will be given as its parameter. The generated C++ code for -+ -+ void -+ color::DESTROY() -+ -+will look like this: -+ -+ color *THIS = ...; // Initialized as in typemap -+ -+ delete THIS; -+ -+If the function's name is B then the C++ C function will be called -+to create a dynamic C++ object. The XSUB will expect the class name, which -+will be kept in a variable called C, to be given as the first -+argument. -+ -+ color * -+ color::new() -+ -+The generated C++ code will call C. -+ -+ RETVAL = new color(); -+ -+The following is an example of a typemap that could be used for this C++ -+example. -+ -+ TYPEMAP -+ color * O_OBJECT -+ -+ OUTPUT -+ # The Perl object is blessed into 'CLASS', which should be a -+ # char* having the name of the package for the blessing. -+ O_OBJECT -+ sv_setref_pv( $arg, CLASS, (void*)$var ); -+ -+ INPUT -+ O_OBJECT -+ if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) -+ $var = ($type)SvIV((SV*)SvRV( $arg )); -+ else{ -+ warn("${Package}::$func_name() -- " . -+ "$var is not a blessed SV reference"); -+ XSRETURN_UNDEF; -+ } -+ -+=head2 Interface Strategy -+ -+When designing an interface between Perl and a C library a straight -+translation from C to XS (such as created by C) is often sufficient. -+However, sometimes the interface will look -+very C-like and occasionally nonintuitive, especially when the C function -+modifies one of its parameters, or returns failure inband (as in "negative -+return values mean failure"). In cases where the programmer wishes to -+create a more Perl-like interface the following strategy may help to -+identify the more critical parts of the interface. -+ -+Identify the C functions with input/output or output parameters. The XSUBs for -+these functions may be able to return lists to Perl. -+ -+Identify the C functions which use some inband info as an indication -+of failure. They may be -+candidates to return undef or an empty list in case of failure. If the -+failure may be detected without a call to the C function, you may want to use -+an INIT: section to report the failure. For failures detectable after the C -+function returns one may want to use a POSTCALL: section to process the -+failure. In more complicated cases use CODE: or PPCODE: sections. -+ -+If many functions use the same failure indication based on the return value, -+you may want to create a special typedef to handle this situation. Put -+ -+ typedef int negative_is_failure; -+ -+near the beginning of XS file, and create an OUTPUT typemap entry -+for C which converts negative values to C, or -+maybe croak()s. After this the return value of type C -+will create more Perl-like interface. -+ -+Identify which values are used by only the C and XSUB functions -+themselves, say, when a parameter to a function should be a contents of a -+global variable. If Perl does not need to access the contents of the value -+then it may not be necessary to provide a translation for that value -+from C to Perl. -+ -+Identify the pointers in the C function parameter lists and return -+values. Some pointers may be used to implement input/output or -+output parameters, they can be handled in XS with the C<&> unary operator, -+and, possibly, using the NO_INIT keyword. -+Some others will require handling of types like C, and one needs -+to decide what a useful Perl translation will do in such a case. When -+the semantic is clear, it is advisable to put the translation into a typemap -+file. -+ -+Identify the structures used by the C functions. In many -+cases it may be helpful to use the T_PTROBJ typemap for -+these structures so they can be manipulated by Perl as -+blessed objects. (This is handled automatically by C.) -+ -+If the same C type is used in several different contexts which require -+different translations, C several new types mapped to this C type, -+and create separate F entries for these new types. Use these -+types in declarations of return type and parameters to XSUBs. -+ -+=head2 Perl Objects And C Structures -+ -+When dealing with C structures one should select either -+B or B for the XS type. Both types are -+designed to handle pointers to complex objects. The -+T_PTRREF type will allow the Perl object to be unblessed -+while the T_PTROBJ type requires that the object be blessed. -+By using T_PTROBJ one can achieve a form of type-checking -+because the XSUB will attempt to verify that the Perl object -+is of the expected type. -+ -+The following XS code shows the getnetconfigent() function which is used -+with ONC+ TIRPC. The getnetconfigent() function will return a pointer to a -+C structure and has the C prototype shown below. The example will -+demonstrate how the C pointer will become a Perl reference. Perl will -+consider this reference to be a pointer to a blessed object and will -+attempt to call a destructor for the object. A destructor will be -+provided in the XS source to free the memory used by getnetconfigent(). -+Destructors in XS can be created by specifying an XSUB function whose name -+ends with the word B. XS destructors can be used to free memory -+which may have been malloc'd by another XSUB. -+ -+ struct netconfig *getnetconfigent(const char *netid); -+ -+A C will be created for C. The Perl -+object will be blessed in a class matching the name of the C -+type, with the tag C appended, and the name should not -+have embedded spaces if it will be a Perl package name. The -+destructor will be placed in a class corresponding to the -+class of the object and the PREFIX keyword will be used to -+trim the name to the word DESTROY as Perl will expect. -+ -+ typedef struct netconfig Netconfig; -+ -+ MODULE = RPC PACKAGE = RPC -+ -+ Netconfig * -+ getnetconfigent(netid) -+ char *netid -+ -+ MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_ -+ -+ void -+ rpcb_DESTROY(netconf) -+ Netconfig *netconf -+ CODE: -+ printf("Now in NetconfigPtr::DESTROY\n"); -+ free( netconf ); -+ -+This example requires the following typemap entry. Consult -+L for more information about adding new typemaps -+for an extension. -+ -+ TYPEMAP -+ Netconfig * T_PTROBJ -+ -+This example will be used with the following Perl statements. -+ -+ use RPC; -+ $netconf = getnetconfigent("udp"); -+ -+When Perl destroys the object referenced by $netconf it will send the -+object to the supplied XSUB DESTROY function. Perl cannot determine, and -+does not care, that this object is a C struct and not a Perl object. In -+this sense, there is no difference between the object created by the -+getnetconfigent() XSUB and an object created by a normal Perl subroutine. -+ -+=head2 Safely Storing Static Data in XS -+ -+Starting with Perl 5.8, a macro framework has been defined to allow -+static data to be safely stored in XS modules that will be accessed from -+a multi-threaded Perl. -+ -+Although primarily designed for use with multi-threaded Perl, the macros -+have been designed so that they will work with non-threaded Perl as well. -+ -+It is therefore strongly recommended that these macros be used by all -+XS modules that make use of static data. -+ -+The easiest way to get a template set of macros to use is by specifying -+the C<-g> (C<--global>) option with h2xs (see L). -+ -+Below is an example module that makes use of the macros. -+ -+ #define PERL_NO_GET_CONTEXT -+ #include "EXTERN.h" -+ #include "perl.h" -+ #include "XSUB.h" -+ -+ /* Global Data */ -+ -+ #define MY_CXT_KEY "BlindMice::_guts" XS_VERSION -+ -+ typedef struct { -+ int count; -+ char name[3][100]; -+ } my_cxt_t; -+ -+ START_MY_CXT -+ -+ MODULE = BlindMice PACKAGE = BlindMice -+ -+ BOOT: -+ { -+ MY_CXT_INIT; -+ MY_CXT.count = 0; -+ strcpy(MY_CXT.name[0], "None"); -+ strcpy(MY_CXT.name[1], "None"); -+ strcpy(MY_CXT.name[2], "None"); -+ } -+ -+ int -+ newMouse(char * name) -+ PREINIT: -+ dMY_CXT; -+ CODE: -+ if (MY_CXT.count >= 3) { -+ warn("Already have 3 blind mice"); -+ RETVAL = 0; -+ } -+ else { -+ RETVAL = ++ MY_CXT.count; -+ strcpy(MY_CXT.name[MY_CXT.count - 1], name); -+ } -+ OUTPUT: -+ RETVAL -+ -+ char * -+ get_mouse_name(index) -+ int index -+ PREINIT: -+ dMY_CXT; -+ CODE: -+ if (index > MY_CXT.count) -+ croak("There are only 3 blind mice."); -+ else -+ RETVAL = MY_CXT.name[index - 1]; -+ OUTPUT: -+ RETVAL -+ -+ void -+ CLONE(...) -+ CODE: -+ MY_CXT_CLONE; -+ -+=head3 MY_CXT REFERENCE -+ -+=over 5 -+ -+=item MY_CXT_KEY -+ -+This macro is used to define a unique key to refer to the static data -+for an XS module. The suggested naming scheme, as used by h2xs, is to -+use a string that consists of the module name, the string "::_guts" -+and the module version number. -+ -+ #define MY_CXT_KEY "MyModule::_guts" XS_VERSION -+ -+=item typedef my_cxt_t -+ -+This struct typedef I always be called C. The other -+C macros assume the existence of the C typedef name. -+ -+Declare a typedef named C that is a structure that contains -+all the data that needs to be interpreter-local. -+ -+ typedef struct { -+ int some_value; -+ } my_cxt_t; -+ -+=item START_MY_CXT -+ -+Always place the START_MY_CXT macro directly after the declaration -+of C. -+ -+=item MY_CXT_INIT -+ -+The MY_CXT_INIT macro initializes storage for the C struct. -+ -+It I be called exactly once, typically in a BOOT: section. If you -+are maintaining multiple interpreters, it should be called once in each -+interpreter instance, except for interpreters cloned from existing ones. -+(But see L below.) -+ -+=item dMY_CXT -+ -+Use the dMY_CXT macro (a declaration) in all the functions that access -+MY_CXT. -+ -+=item MY_CXT -+ -+Use the MY_CXT macro to access members of the C struct. For -+example, if C is -+ -+ typedef struct { -+ int index; -+ } my_cxt_t; -+ -+then use this to access the C member -+ -+ dMY_CXT; -+ MY_CXT.index = 2; -+ -+=item aMY_CXT/pMY_CXT -+ -+C may be quite expensive to calculate, and to avoid the overhead -+of invoking it in each function it is possible to pass the declaration -+onto other functions using the C/C macros, eg -+ -+ void sub1() { -+ dMY_CXT; -+ MY_CXT.index = 1; -+ sub2(aMY_CXT); -+ } -+ -+ void sub2(pMY_CXT) { -+ MY_CXT.index = 2; -+ } -+ -+Analogously to C, there are equivalent forms for when the macro is the -+first or last in multiple arguments, where an underscore represents a -+comma, i.e. C<_aMY_CXT>, C, C<_pMY_CXT> and C. -+ -+=item MY_CXT_CLONE -+ -+By default, when a new interpreter is created as a copy of an existing one -+(eg via C<< threads->create() >>), both interpreters share the same physical -+my_cxt_t structure. Calling C (typically via the package's -+C function), causes a byte-for-byte copy of the structure to be -+taken, and any future dMY_CXT will cause the copy to be accessed instead. -+ -+=item MY_CXT_INIT_INTERP(my_perl) -+ -+=item dMY_CXT_INTERP(my_perl) -+ -+These are versions of the macros which take an explicit interpreter as an -+argument. -+ -+=back -+ -+Note that these macros will only work together within the I source -+file; that is, a dMY_CTX in one source file will access a different structure -+than a dMY_CTX in another source file. -+ -+=head2 Thread-aware system interfaces -+ -+Starting from Perl 5.8, in C/C++ level Perl knows how to wrap -+system/library interfaces that have thread-aware versions -+(e.g. getpwent_r()) into frontend macros (e.g. getpwent()) that -+correctly handle the multithreaded interaction with the Perl -+interpreter. This will happen transparently, the only thing -+you need to do is to instantiate a Perl interpreter. -+ -+This wrapping happens always when compiling Perl core source -+(PERL_CORE is defined) or the Perl core extensions (PERL_EXT is -+defined). When compiling XS code outside of the Perl core, the wrapping -+does not take place before Perl 5.28. Starting in that release you can -+ -+ #define PERL_REENTRANT -+ -+in your code to enable the wrapping. It is advisable to do so if you -+are using such functions, as intermixing the C<_r>-forms (as Perl compiled -+for multithreaded operation will do) and the C<_r>-less forms is neither -+well-defined (inconsistent results, data corruption, or even crashes -+become more likely), nor is it very portable. Unfortunately, not all -+systems have all the C<_r> forms, but using this C<#define> gives you -+whatever protection that Perl is aware is available on each system. -+ -+=head1 EXAMPLES -+ -+File C: Interface to some ONC+ RPC bind library functions. -+ -+ #define PERL_NO_GET_CONTEXT -+ #include "EXTERN.h" -+ #include "perl.h" -+ #include "XSUB.h" -+ -+ #include -+ -+ typedef struct netconfig Netconfig; -+ -+ MODULE = RPC PACKAGE = RPC -+ -+ SV * -+ rpcb_gettime(host="localhost") -+ char *host -+ PREINIT: -+ time_t timep; -+ CODE: -+ ST(0) = sv_newmortal(); -+ if( rpcb_gettime( host, &timep ) ) -+ sv_setnv( ST(0), (double)timep ); -+ -+ Netconfig * -+ getnetconfigent(netid="udp") -+ char *netid -+ -+ MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_ -+ -+ void -+ rpcb_DESTROY(netconf) -+ Netconfig *netconf -+ CODE: -+ printf("NetconfigPtr::DESTROY\n"); -+ free( netconf ); -+ -+File C: Custom typemap for RPC.xs. (cf. L) -+ -+ TYPEMAP -+ Netconfig * T_PTROBJ -+ -+File C: Perl module for the RPC extension. -+ -+ package RPC; -+ -+ require Exporter; -+ require DynaLoader; -+ @ISA = qw(Exporter DynaLoader); -+ @EXPORT = qw(rpcb_gettime getnetconfigent); -+ -+ bootstrap RPC; -+ 1; -+ -+File C: Perl test program for the RPC extension. -+ -+ use RPC; -+ -+ $netconf = getnetconfigent(); -+ $a = rpcb_gettime(); -+ print "time = $a\n"; -+ print "netconf = $netconf\n"; -+ -+ $netconf = getnetconfigent("tcp"); -+ $a = rpcb_gettime("poplar"); -+ print "time = $a\n"; -+ print "netconf = $netconf\n"; -+ -+=head1 CAVEATS -+ -+XS code has full access to system calls including C library functions. -+It thus has the capability of interfering with things that the Perl core -+or other modules have set up, such as signal handlers or file handles. -+It could mess with the memory, or any number of harmful things. Don't. -+ -+Some modules have an event loop, waiting for user-input. It is highly -+unlikely that two such modules would work adequately together in a -+single Perl application. -+ -+In general, the perl interpreter views itself as the center of the -+universe as far as the Perl program goes. XS code is viewed as a -+help-mate, to accomplish things that perl doesn't do, or doesn't do fast -+enough, but always subservient to perl. The closer XS code adheres to -+this model, the less likely conflicts will occur. -+ -+One area where there has been conflict is in regards to C locales. (See -+L.) perl, with one exception and unless told otherwise, -+sets up the underlying locale the program is running in to the locale -+passed -+into it from the environment. This is an important difference from a -+generic C language program, where the underlying locale is the "C" -+locale unless the program changes it. As of v5.20, this underlying -+locale is completely hidden from pure Perl code outside the lexical -+scope of C> except for a couple of function calls in the -+POSIX module which of necessity use it. But the underlying locale, with -+that -+one exception is exposed to XS code, affecting all C library routines -+whose behavior is locale-dependent. Your XS code better not assume that -+the underlying locale is "C". The exception is the -+L|perllocale/Category LC_NUMERIC: Numeric Formatting> -+locale category, and the reason it is an exception is that experience -+has shown that it can be problematic for XS code, whereas we have not -+had reports of problems with the -+L. And the reason -+for this one category being problematic is that the character used as a -+decimal point can vary. Many European languages use a comma, whereas -+English, and hence Perl are expecting a dot (U+002E: FULL STOP). Many -+modules can handle only the radix character being a dot, and so perl -+attempts to make it so. Up through Perl v5.20, the attempt was merely -+to set C upon startup to the C<"C"> locale. Any -+L otherwise would change -+it; this caused some failures. Therefore, starting in v5.22, perl tries -+to keep C always set to C<"C"> for XS code. -+ -+To summarize, here's what to expect and how to handle locales in XS code: -+ -+=over -+ -+=item Non-locale-aware XS code -+ -+Keep in mind that even if you think your code is not locale-aware, it -+may call a library function that is. Hopefully the man page for such -+a function will indicate that dependency, but the documentation is -+imperfect. -+ -+The current locale is exposed to XS code except possibly C -+(explained in the next paragraph). -+There have not been reports of problems with the other categories. -+Perl initializes things on start-up so that the current locale is the -+one which is indicated by the user's environment in effect at that time. -+See L. -+ -+However, up through v5.20, Perl initialized things on start-up so that -+C was set to the "C" locale. But if any code anywhere -+changed it, it would stay changed. This means that your module can't -+count on C being something in particular, and you can't -+expect floating point numbers (including version strings) to have dots -+in them. If you don't allow for a non-dot, your code could break if -+anyone anywhere changed the locale. For this reason, v5.22 changed -+the behavior so that Perl tries to keep C in the "C" locale -+except around the operations internally where it should be something -+else. Misbehaving XS code will always be able to change the locale -+anyway, but the most common instance of this is checked for and -+handled. -+ -+=item Locale-aware XS code -+ -+If the locale from the user's environment is desired, there should be no -+need for XS code to set the locale except for C, as perl has -+already set the others up. XS code should avoid changing the locale, as -+it can adversely affect other, unrelated, code and may not be -+thread-safe. To minimize problems, the macros -+L, -+L, and -+L should be used to affect any needed -+change. -+ -+But, starting with Perl v5.28, locales are thread-safe on platforms that -+support this functionality. Windows has this starting with Visual -+Studio 2005. Many other modern platforms support the thread-safe POSIX -+2008 functions. The C C<#define> C will be -+defined iff this build is using these. From Perl-space, the read-only -+variable C<${SAFE_LOCALES}> is 1 if either the build is not threaded, or -+if C is defined; otherwise it is 0. -+ -+The way this works under-the-hood is that every thread has a choice of -+using a locale specific to it (this is the Windows and POSIX 2008 -+functionality), or the global locale that is accessible to all threads -+(this is the functionality that has always been there). The -+implementations for Windows and POSIX are completely different. On -+Windows, the runtime can be set up so that the standard -+L> function either only knows about the global locale or -+the locale for this thread. On POSIX, C always deals with -+the global locale, and other functions have been created to handle -+per-thread locales. Perl makes this transparent to perl-space code. It -+continues to use C, and the interpreter translates -+that into the per-thread functions. -+ -+All other locale-senstive functions automatically use the per-thread -+locale, if that is turned on, and failing that, the global locale. Thus -+calls to C are ineffective on POSIX systems for the current -+thread if that thread is using a per-thread locale. If perl is compiled -+for single-thread operation, it does not use the per-thread functions, -+so C does work as expected. -+ -+If you have loaded the L> module you can use the methods given -+in L to call L|POSIX/setlocale> to safely -+change or query the locale (on systems where it is safe to do so), or -+you can use the new 5.28 function L instead, -+which is a drop-in replacement for the system L>, and -+handles single-threaded and multi-threaded applications transparently. -+ -+There are some locale-related library calls that still aren't -+thread-safe because they return data in a buffer global to all threads. -+In the past, these didn't matter as locales weren't thread-safe at all. -+But now you have to be aware of them in case your module is called in a -+multi-threaded application. The known ones are -+ -+ asctime() -+ ctime() -+ gcvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)] -+ getdate() -+ wcrtomb() if its final argument is NULL -+ wcsrtombs() if its final argument is NULL -+ wcstombs() -+ wctomb() -+ -+Some of these shouldn't really be called in a Perl application, and for -+others there are thread-safe versions of these already implemented: -+ -+ asctime_r() -+ ctime_r() -+ Perl_langinfo() -+ -+The C<_r> forms are automatically used, starting in Perl 5.28, if you -+compile your code, with -+ -+ #define PERL_REENTRANT -+ -+See also L. -+You can use the methods given in L, to get the best available -+locale-safe versions of these -+ -+ POSIX::localeconv() -+ POSIX::wcstombs() -+ POSIX::wctomb() -+ -+And note, that some items returned by C are available -+through L. -+ -+The others shouldn't be used in a threaded application. -+ -+Some modules may call a non-perl library that is locale-aware. This is -+fine as long as it doesn't try to query or change the locale using the -+system C. But if these do call the system C, -+those calls may be ineffective. Instead, -+L|perlapi/Perl_setlocale> works in all circumstances. -+Plain setlocale is ineffective on multi-threaded POSIX 2008 systems. It -+operates only on the global locale, whereas each thread has its own -+locale, paying no attention to the global one. Since converting -+these non-Perl libraries to C is out of the question, -+there is a new function in v5.28 -+L|perlapi/switch_to_global_locale> that will -+switch the thread it is called from so that any system C -+calls will have their desired effect. The function -+L|perlapi/sync_locale> must be called before returning to -+perl. -+ -+This thread can change the locale all it wants and it won't affect any -+other thread, except any that also have been switched to the global -+locale. This means that a multi-threaded application can have a single -+thread using an alien library without a problem; but no more than a -+single thread can be so-occupied. Bad results likely will happen. -+ -+In perls without multi-thread locale support, some alien libraries, -+such as C change locales. This can cause problems for the Perl -+core and other modules. For these, before control is returned to -+perl, starting in v5.20.1, calling the function -+L from XS should be sufficient to -+avoid most of these problems. Prior to this, you need a pure Perl -+statement that does this: -+ -+ POSIX::setlocale(LC_ALL, POSIX::setlocale(LC_ALL)); -+ -+or use the methods given in L. -+ -+=back -+ -+=head1 XS VERSION -+ -+This document covers features supported by C -+(also known as C) 3.13_01. -+ -+=head1 AUTHOR -+ -+Originally written by Dean Roehrich >. -+ -+Maintained since 1996 by The Perl Porters >. -diff --git a/lib/perlxstut.pod b/lib/perlxstut.pod -new file mode 100644 -index 0000000..ef154ad ---- /dev/null -+++ b/lib/perlxstut.pod -@@ -0,0 +1,1401 @@ -+=head1 NAME -+ -+perlxstut - Tutorial for writing XSUBs -+ -+=head1 DESCRIPTION -+ -+This tutorial will educate the reader on the steps involved in creating -+a Perl extension. The reader is assumed to have access to L, -+L and L. -+ -+This tutorial starts with very simple examples and becomes more complex, -+with each new example adding new features. Certain concepts may not be -+completely explained until later in the tutorial in order to slowly ease -+the reader into building extensions. -+ -+This tutorial was written from a Unix point of view. Where I know them -+to be otherwise different for other platforms (e.g. Win32), I will list -+them. If you find something that was missed, please let me know. -+ -+=head1 SPECIAL NOTES -+ -+=head2 make -+ -+This tutorial assumes that the make program that Perl is configured to -+use is called C. Instead of running "make" in the examples that -+follow, you may have to substitute whatever make program Perl has been -+configured to use. Running B should tell you what it is. -+ -+=head2 Version caveat -+ -+When writing a Perl extension for general consumption, one should expect that -+the extension will be used with versions of Perl different from the -+version available on your machine. Since you are reading this document, -+the version of Perl on your machine is probably 5.005 or later, but the users -+of your extension may have more ancient versions. -+ -+To understand what kinds of incompatibilities one may expect, and in the rare -+case that the version of Perl on your machine is older than this document, -+see the section on "Troubleshooting these Examples" for more information. -+ -+If your extension uses some features of Perl which are not available on older -+releases of Perl, your users would appreciate an early meaningful warning. -+You would probably put this information into the F file, but nowadays -+installation of extensions may be performed automatically, guided by F -+module or other tools. -+ -+In MakeMaker-based installations, F provides the earliest -+opportunity to perform version checks. One can put something like this -+in F for this purpose: -+ -+ eval { require 5.007 } -+ or die < build them, but you must link the XSUBs subroutines with the -+rest of Perl, creating a new executable. This situation is similar to -+Perl 4. -+ -+This tutorial can still be used on such a system. The XSUB build mechanism -+will check the system and build a dynamically-loadable library if possible, -+or else a static library and then, optionally, a new statically-linked -+executable with that static library linked in. -+ -+Should you wish to build a statically-linked executable on a system which -+can dynamically load libraries, you may, in all the following examples, -+where the command "C" with no arguments is executed, run the command -+"C" instead. -+ -+If you have generated such a statically-linked executable by choice, then -+instead of saying "C", you should say "C". -+On systems that cannot build dynamically-loadable libraries at all, simply -+saying "C" is sufficient. -+ -+=head2 Threads and PERL_NO_GET_CONTEXT -+ -+For threaded builds, perl requires the context pointer for the current -+thread, without C, perl will call a function to -+retrieve the context. -+ -+For improved performance, include: -+ -+ #define PERL_NO_GET_CONTEXT -+ -+as shown below. -+ -+For more details, see L. -+ -+=head1 TUTORIAL -+ -+Now let's go on with the show! -+ -+=head2 EXAMPLE 1 -+ -+Our first extension will be very simple. When we call the routine in the -+extension, it will print out a well-known message and return. -+ -+Run "C". This creates a directory named Mytest, -+possibly under ext/ if that directory exists in the current working -+directory. Several files will be created under the Mytest dir, including -+MANIFEST, Makefile.PL, lib/Mytest.pm, Mytest.xs, t/Mytest.t, and Changes. -+ -+The MANIFEST file contains the names of all the files just created in the -+Mytest directory. -+ -+The file Makefile.PL should look something like this: -+ -+ use ExtUtils::MakeMaker; -+ # See lib/ExtUtils/MakeMaker.pm for details of how to influence -+ # the contents of the Makefile that is written. -+ WriteMakefile( -+ NAME => 'Mytest', -+ VERSION_FROM => 'Mytest.pm', # finds $VERSION -+ LIBS => [''], # e.g., '-lm' -+ DEFINE => '', # e.g., '-DHAVE_SOMETHING' -+ INC => '', # e.g., '-I/usr/include/other' -+ ); -+ -+The file Mytest.pm should start with something like this: -+ -+ package Mytest; -+ -+ use 5.008008; -+ use strict; -+ use warnings; -+ -+ require Exporter; -+ -+ our @ISA = qw(Exporter); -+ our %EXPORT_TAGS = ( 'all' => [ qw( -+ -+ ) ] ); -+ -+ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); -+ -+ our @EXPORT = qw( -+ -+ ); -+ -+ our $VERSION = '0.01'; -+ -+ require XSLoader; -+ XSLoader::load('Mytest', $VERSION); -+ -+ # Preloaded methods go here. -+ -+ 1; -+ __END__ -+ # Below is the stub of documentation for your module. You better -+ # edit it! -+ -+The rest of the .pm file contains sample code for providing documentation for -+the extension. -+ -+Finally, the Mytest.xs file should look something like this: -+ -+ #define PERL_NO_GET_CONTEXT -+ #include "EXTERN.h" -+ #include "perl.h" -+ #include "XSUB.h" -+ -+ #include "ppport.h" -+ -+ MODULE = Mytest PACKAGE = Mytest -+ -+Let's edit the .xs file by adding this to the end of the file: -+ -+ void -+ hello() -+ CODE: -+ printf("Hello, world!\n"); -+ -+It is okay for the lines starting at the "CODE:" line to not be indented. -+However, for readability purposes, it is suggested that you indent CODE: -+one level and the lines following one more level. -+ -+Now we'll run "C". This will create a real Makefile, -+which make needs. Its output looks something like: -+ -+ % perl Makefile.PL -+ Checking if your kit is complete... -+ Looks good -+ Writing Makefile for Mytest -+ % -+ -+Now, running make will produce output that looks something like this (some -+long lines have been shortened for clarity and some extraneous lines have -+been deleted): -+ -+ % make -+ cp lib/Mytest.pm blib/lib/Mytest.pm -+ perl xsubpp -typemap typemap Mytest.xs > Mytest.xsc && \ -+ mv Mytest.xsc Mytest.c -+ Please specify prototyping behavior for Mytest.xs (see perlxs manual) -+ cc -c Mytest.c -+ Running Mkbootstrap for Mytest () -+ chmod 644 Mytest.bs -+ rm -f blib/arch/auto/Mytest/Mytest.so -+ cc -shared -L/usr/local/lib Mytest.o -o blib/arch/auto/Mytest/Mytest.so -+ -+ chmod 755 blib/arch/auto/Mytest/Mytest.so -+ cp Mytest.bs blib/arch/auto/Mytest/Mytest.bs -+ chmod 644 blib/arch/auto/Mytest/Mytest.bs -+ Manifying blib/man3/Mytest.3pm -+ % -+ -+You can safely ignore the line about "prototyping behavior" - it is -+explained in L. -+ -+Perl has its own special way of easily writing test scripts, but for this -+example only, we'll create our own test script. Create a file called hello -+that looks like this: -+ -+ #! /opt/perl5/bin/perl -+ -+ use ExtUtils::testlib; -+ -+ use Mytest; -+ -+ Mytest::hello(); -+ -+Now we make the script executable (C), run the script -+and we should see the following output: -+ -+ % ./hello -+ Hello, world! -+ % -+ -+=head2 EXAMPLE 2 -+ -+Now let's add to our extension a subroutine that will take a single numeric -+argument as input and return 1 if the number is even or 0 if the number -+is odd. -+ -+Add the following to the end of Mytest.xs: -+ -+ int -+ is_even(input) -+ int input -+ CODE: -+ RETVAL = (input % 2 == 0); -+ OUTPUT: -+ RETVAL -+ -+There does not need to be whitespace at the start of the "C" -+line, but it is useful for improving readability. Placing a semi-colon at -+the end of that line is also optional. Any amount and kind of whitespace -+may be placed between the "C" and "C". -+ -+Now re-run make to rebuild our new shared library. -+ -+Now perform the same steps as before, generating a Makefile from the -+Makefile.PL file, and running make. -+ -+In order to test that our extension works, we now need to look at the -+file Mytest.t. This file is set up to imitate the same kind of testing -+structure that Perl itself has. Within the test script, you perform a -+number of tests to confirm the behavior of the extension, printing "ok" -+when the test is correct, "not ok" when it is not. -+ -+ use Test::More tests => 4; -+ BEGIN { use_ok('Mytest') }; -+ -+ ######################### -+ -+ # Insert your test code below, the Test::More module is use()ed here -+ # so read its man page ( perldoc Test::More ) for help writing this -+ # test script. -+ -+ is(&Mytest::is_even(0), 1); -+ is(&Mytest::is_even(1), 0); -+ is(&Mytest::is_even(2), 1); -+ -+We will be calling the test script through the command "C". You -+should see output that looks something like this: -+ -+ %make test -+ PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" -+ "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t -+ t/Mytest....ok -+ All tests successful. -+ Files=1, Tests=4, 0 wallclock secs ( 0.03 cusr + 0.00 csys = 0.03 CPU) -+ % -+ -+=head2 What has gone on? -+ -+The program h2xs is the starting point for creating extensions. In later -+examples we'll see how we can use h2xs to read header files and generate -+templates to connect to C routines. -+ -+h2xs creates a number of files in the extension directory. The file -+Makefile.PL is a perl script which will generate a true Makefile to build -+the extension. We'll take a closer look at it later. -+ -+The .pm and .xs files contain the meat of the extension. The .xs file holds -+the C routines that make up the extension. The .pm file contains routines -+that tell Perl how to load your extension. -+ -+Generating the Makefile and running C created a directory called blib -+(which stands for "build library") in the current working directory. This -+directory will contain the shared library that we will build. Once we have -+tested it, we can install it into its final location. -+ -+Invoking the test script via "C" did something very important. -+It invoked perl with all those C<-I> arguments so that it could find the -+various files that are part of the extension. It is I important that -+while you are still testing extensions that you use "C". If you -+try to run the test script all by itself, you will get a fatal error. -+Another reason it is important to use "C" to run your test -+script is that if you are testing an upgrade to an already-existing version, -+using "C" ensures that you will test your new extension, not the -+already-existing version. -+ -+When Perl sees a C, it searches for a file with the same name -+as the C'd extension that has a .pm suffix. If that file cannot be found, -+Perl dies with a fatal error. The default search path is contained in the -+C<@INC> array. -+ -+In our case, Mytest.pm tells perl that it will need the Exporter and Dynamic -+Loader extensions. It then sets the C<@ISA> and C<@EXPORT> arrays and the -+C<$VERSION> scalar; finally it tells perl to bootstrap the module. Perl -+will call its dynamic loader routine (if there is one) and load the shared -+library. -+ -+The two arrays C<@ISA> and C<@EXPORT> are very important. The C<@ISA> -+array contains a list of other packages in which to search for methods (or -+subroutines) that do not exist in the current package. This is usually -+only important for object-oriented extensions (which we will talk about -+much later), and so usually doesn't need to be modified. -+ -+The C<@EXPORT> array tells Perl which of the extension's variables and -+subroutines should be placed into the calling package's namespace. Because -+you don't know if the user has already used your variable and subroutine -+names, it's vitally important to carefully select what to export. Do I -+export method or variable names I without a good reason. -+ -+As a general rule, if the module is trying to be object-oriented then don't -+export anything. If it's just a collection of functions and variables, then -+you can export them via another array, called C<@EXPORT_OK>. This array -+does not automatically place its subroutine and variable names into the -+namespace unless the user specifically requests that this be done. -+ -+See L for more information. -+ -+The C<$VERSION> variable is used to ensure that the .pm file and the shared -+library are "in sync" with each other. Any time you make changes to -+the .pm or .xs files, you should increment the value of this variable. -+ -+=head2 Writing good test scripts -+ -+The importance of writing good test scripts cannot be over-emphasized. You -+should closely follow the "ok/not ok" style that Perl itself uses, so that -+it is very easy and unambiguous to determine the outcome of each test case. -+When you find and fix a bug, make sure you add a test case for it. -+ -+By running "C", you ensure that your Mytest.t script runs and uses -+the correct version of your extension. If you have many test cases, -+save your test files in the "t" directory and use the suffix ".t". -+When you run "C", all of these test files will be executed. -+ -+=head2 EXAMPLE 3 -+ -+Our third extension will take one argument as its input, round off that -+value, and set the I to the rounded value. -+ -+Add the following to the end of Mytest.xs: -+ -+ void -+ round(arg) -+ double arg -+ CODE: -+ if (arg > 0.0) { -+ arg = floor(arg + 0.5); -+ } else if (arg < 0.0) { -+ arg = ceil(arg - 0.5); -+ } else { -+ arg = 0.0; -+ } -+ OUTPUT: -+ arg -+ -+Edit the Makefile.PL file so that the corresponding line looks like this: -+ -+ 'LIBS' => ['-lm'], # e.g., '-lm' -+ -+Generate the Makefile and run make. Change the test number in Mytest.t to -+"9" and add the following tests: -+ -+ $i = -1.5; &Mytest::round($i); is( $i, -2.0 ); -+ $i = -1.1; &Mytest::round($i); is( $i, -1.0 ); -+ $i = 0.0; &Mytest::round($i); is( $i, 0.0 ); -+ $i = 0.5; &Mytest::round($i); is( $i, 1.0 ); -+ $i = 1.2; &Mytest::round($i); is( $i, 1.0 ); -+ -+Running "C" should now print out that all nine tests are okay. -+ -+Notice that in these new test cases, the argument passed to round was a -+scalar variable. You might be wondering if you can round a constant or -+literal. To see what happens, temporarily add the following line to Mytest.t: -+ -+ &Mytest::round(3); -+ -+Run "C" and notice that Perl dies with a fatal error. Perl won't -+let you change the value of constants! -+ -+=head2 What's new here? -+ -+=over 4 -+ -+=item * -+ -+We've made some changes to Makefile.PL. In this case, we've specified an -+extra library to be linked into the extension's shared library, the math -+library libm in this case. We'll talk later about how to write XSUBs that -+can call every routine in a library. -+ -+=item * -+ -+The value of the function is not being passed back as the function's return -+value, but by changing the value of the variable that was passed into the -+function. You might have guessed that when you saw that the return value -+of round is of type "void". -+ -+=back -+ -+=head2 Input and Output Parameters -+ -+You specify the parameters that will be passed into the XSUB on the line(s) -+after you declare the function's return value and name. Each input parameter -+line starts with optional whitespace, and may have an optional terminating -+semicolon. -+ -+The list of output parameters occurs at the very end of the function, just -+after the OUTPUT: directive. The use of RETVAL tells Perl that you -+wish to send this value back as the return value of the XSUB function. In -+Example 3, we wanted the "return value" placed in the original variable -+which we passed in, so we listed it (and not RETVAL) in the OUTPUT: section. -+ -+=head2 The XSUBPP Program -+ -+The B program takes the XS code in the .xs file and translates it into -+C code, placing it in a file whose suffix is .c. The C code created makes -+heavy use of the C functions within Perl. -+ -+=head2 The TYPEMAP file -+ -+The B program uses rules to convert from Perl's data types (scalar, -+array, etc.) to C's data types (int, char, etc.). These rules are stored -+in the typemap file ($PERLLIB/ExtUtils/typemap). There's a brief discussion -+below, but all the nitty-gritty details can be found in L. -+If you have a new-enough version of perl (5.16 and up) or an upgraded -+XS compiler (C 3.13_01 or better), then you can inline -+typemaps in your XS instead of writing separate files. -+Either way, this typemap thing is split into three parts: -+ -+The first section maps various C data types to a name, which corresponds -+somewhat with the various Perl types. The second section contains C code -+which B uses to handle input parameters. The third section contains -+C code which B uses to handle output parameters. -+ -+Let's take a look at a portion of the .c file created for our extension. -+The file name is Mytest.c: -+ -+ XS(XS_Mytest_round) -+ { -+ dXSARGS; -+ if (items != 1) -+ Perl_croak(aTHX_ "Usage: Mytest::round(arg)"); -+ PERL_UNUSED_VAR(cv); /* -W */ -+ { -+ double arg = (double)SvNV(ST(0)); /* XXXXX */ -+ if (arg > 0.0) { -+ arg = floor(arg + 0.5); -+ } else if (arg < 0.0) { -+ arg = ceil(arg - 0.5); -+ } else { -+ arg = 0.0; -+ } -+ sv_setnv(ST(0), (double)arg); /* XXXXX */ -+ SvSETMAGIC(ST(0)); -+ } -+ XSRETURN_EMPTY; -+ } -+ -+Notice the two lines commented with "XXXXX". If you check the first part -+of the typemap file (or section), you'll see that doubles are of type -+T_DOUBLE. In the INPUT part of the typemap, an argument that is T_DOUBLE -+is assigned to the variable arg by calling the routine SvNV on something, -+then casting it to double, then assigned to the variable arg. Similarly, -+in the OUTPUT section, once arg has its final value, it is passed to the -+sv_setnv function to be passed back to the calling subroutine. These two -+functions are explained in L; we'll talk more later about what -+that "ST(0)" means in the section on the argument stack. -+ -+=head2 Warning about Output Arguments -+ -+In general, it's not a good idea to write extensions that modify their input -+parameters, as in Example 3. Instead, you should probably return multiple -+values in an array and let the caller handle them (we'll do this in a later -+example). However, in order to better accommodate calling pre-existing C -+routines, which often do modify their input parameters, this behavior is -+tolerated. -+ -+=head2 EXAMPLE 4 -+ -+In this example, we'll now begin to write XSUBs that will interact with -+pre-defined C libraries. To begin with, we will build a small library of -+our own, then let h2xs write our .pm and .xs files for us. -+ -+Create a new directory called Mytest2 at the same level as the directory -+Mytest. In the Mytest2 directory, create another directory called mylib, -+and cd into that directory. -+ -+Here we'll create some files that will generate a test library. These will -+include a C source file and a header file. We'll also create a Makefile.PL -+in this directory. Then we'll make sure that running make at the Mytest2 -+level will automatically run this Makefile.PL file and the resulting Makefile. -+ -+In the mylib directory, create a file mylib.h that looks like this: -+ -+ #define TESTVAL 4 -+ -+ extern double foo(int, long, const char*); -+ -+Also create a file mylib.c that looks like this: -+ -+ #include -+ #include "./mylib.h" -+ -+ double -+ foo(int a, long b, const char *c) -+ { -+ return (a + b + atof(c) + TESTVAL); -+ } -+ -+And finally create a file Makefile.PL that looks like this: -+ -+ use ExtUtils::MakeMaker; -+ $Verbose = 1; -+ WriteMakefile( -+ NAME => 'Mytest2::mylib', -+ SKIP => [qw(all static static_lib dynamic dynamic_lib)], -+ clean => {'FILES' => 'libmylib$(LIB_EXT)'}, -+ ); -+ -+ -+ sub MY::top_targets { -+ ' -+ all :: static -+ -+ pure_all :: static -+ -+ static :: libmylib$(LIB_EXT) -+ -+ libmylib$(LIB_EXT): $(O_FILES) -+ $(AR) cr libmylib$(LIB_EXT) $(O_FILES) -+ $(RANLIB) libmylib$(LIB_EXT) -+ -+ '; -+ } -+ -+Make sure you use a tab and not spaces on the lines beginning with "$(AR)" -+and "$(RANLIB)". Make will not function properly if you use spaces. -+It has also been reported that the "cr" argument to $(AR) is unnecessary -+on Win32 systems. -+ -+We will now create the main top-level Mytest2 files. Change to the directory -+above Mytest2 and run the following command: -+ -+ % h2xs -O -n Mytest2 ./Mytest2/mylib/mylib.h -+ -+This will print out a warning about overwriting Mytest2, but that's okay. -+Our files are stored in Mytest2/mylib, and will be untouched. -+ -+The normal Makefile.PL that h2xs generates doesn't know about the mylib -+directory. We need to tell it that there is a subdirectory and that we -+will be generating a library in it. Let's add the argument MYEXTLIB to -+the WriteMakefile call so that it looks like this: -+ -+ WriteMakefile( -+ 'NAME' => 'Mytest2', -+ 'VERSION_FROM' => 'Mytest2.pm', # finds $VERSION -+ 'LIBS' => [''], # e.g., '-lm' -+ 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' -+ 'INC' => '', # e.g., '-I/usr/include/other' -+ 'MYEXTLIB' => 'mylib/libmylib$(LIB_EXT)', -+ ); -+ -+and then at the end add a subroutine (which will override the pre-existing -+subroutine). Remember to use a tab character to indent the line beginning -+with "cd"! -+ -+ sub MY::postamble { -+ ' -+ $(MYEXTLIB): mylib/Makefile -+ cd mylib && $(MAKE) $(PASSTHRU) -+ '; -+ } -+ -+Let's also fix the MANIFEST file so that it accurately reflects the contents -+of our extension. The single line that says "mylib" should be replaced by -+the following three lines: -+ -+ mylib/Makefile.PL -+ mylib/mylib.c -+ mylib/mylib.h -+ -+To keep our namespace nice and unpolluted, edit the .pm file and change -+the variable C<@EXPORT> to C<@EXPORT_OK>. Finally, in the -+.xs file, edit the #include line to read: -+ -+ #include "mylib/mylib.h" -+ -+And also add the following function definition to the end of the .xs file: -+ -+ double -+ foo(a,b,c) -+ int a -+ long b -+ const char * c -+ OUTPUT: -+ RETVAL -+ -+Now we also need to create a typemap because the default Perl doesn't -+currently support the C type. Include a new TYPEMAP -+section in your XS code before the above function: -+ -+ TYPEMAP: <" and all should be well. There are some warnings on missing -+tests for the Mytest2::mylib extension, but you can ignore them. -+ -+=head2 What has happened here? -+ -+Unlike previous examples, we've now run h2xs on a real include file. This -+has caused some extra goodies to appear in both the .pm and .xs files. -+ -+=over 4 -+ -+=item * -+ -+In the .xs file, there's now a #include directive with the absolute path to -+the mylib.h header file. We changed this to a relative path so that we -+could move the extension directory if we wanted to. -+ -+=item * -+ -+There's now some new C code that's been added to the .xs file. The purpose -+of the C routine is to make the values that are #define'd in the -+header file accessible by the Perl script (by calling either C or -+C<&Mytest2::TESTVAL>). There's also some XS code to allow calls to the -+C routine. -+ -+=item * -+ -+The .pm file originally exported the name C in the C<@EXPORT> array. -+This could lead to name clashes. A good rule of thumb is that if the #define -+is only going to be used by the C routines themselves, and not by the user, -+they should be removed from the C<@EXPORT> array. Alternately, if you don't -+mind using the "fully qualified name" of a variable, you could move most -+or all of the items from the C<@EXPORT> array into the C<@EXPORT_OK> array. -+ -+=item * -+ -+If our include file had contained #include directives, these would not have -+been processed by h2xs. There is no good solution to this right now. -+ -+=item * -+ -+We've also told Perl about the library that we built in the mylib -+subdirectory. That required only the addition of the C variable -+to the WriteMakefile call and the replacement of the postamble subroutine -+to cd into the subdirectory and run make. The Makefile.PL for the -+library is a bit more complicated, but not excessively so. Again we -+replaced the postamble subroutine to insert our own code. This code -+simply specified that the library to be created here was a static archive -+library (as opposed to a dynamically loadable library) and provided the -+commands to build it. -+ -+=back -+ -+=head2 Anatomy of .xs file -+ -+The .xs file of L<"EXAMPLE 4"> contained some new elements. To understand -+the meaning of these elements, pay attention to the line which reads -+ -+ MODULE = Mytest2 PACKAGE = Mytest2 -+ -+Anything before this line is plain C code which describes which headers -+to include, and defines some convenience functions. No translations are -+performed on this part, apart from having embedded POD documentation -+skipped over (see L) it goes into the generated output C file as is. -+ -+Anything after this line is the description of XSUB functions. -+These descriptions are translated by B into C code which -+implements these functions using Perl calling conventions, and which -+makes these functions visible from Perl interpreter. -+ -+Pay a special attention to the function C. This name appears -+twice in the generated .xs file: once in the first part, as a static C -+function, then another time in the second part, when an XSUB interface to -+this static C function is defined. -+ -+This is quite typical for .xs files: usually the .xs file provides -+an interface to an existing C function. Then this C function is defined -+somewhere (either in an external library, or in the first part of .xs file), -+and a Perl interface to this function (i.e. "Perl glue") is described in the -+second part of .xs file. The situation in L<"EXAMPLE 1">, L<"EXAMPLE 2">, -+and L<"EXAMPLE 3">, when all the work is done inside the "Perl glue", is -+somewhat of an exception rather than the rule. -+ -+=head2 Getting the fat out of XSUBs -+ -+In L<"EXAMPLE 4"> the second part of .xs file contained the following -+description of an XSUB: -+ -+ double -+ foo(a,b,c) -+ int a -+ long b -+ const char * c -+ OUTPUT: -+ RETVAL -+ -+Note that in contrast with L<"EXAMPLE 1">, L<"EXAMPLE 2"> and L<"EXAMPLE 3">, -+this description does not contain the actual I for what is done -+during a call to Perl function foo(). To understand what is going -+on here, one can add a CODE section to this XSUB: -+ -+ double -+ foo(a,b,c) -+ int a -+ long b -+ const char * c -+ CODE: -+ RETVAL = foo(a,b,c); -+ OUTPUT: -+ RETVAL -+ -+However, these two XSUBs provide almost identical generated C code: B -+compiler is smart enough to figure out the C section from the first -+two lines of the description of XSUB. What about C section? In -+fact, that is absolutely the same! The C section can be removed -+as well, I section or C section> is not -+specified: B can see that it needs to generate a function call -+section, and will autogenerate the OUTPUT section too. Thus one can -+shortcut the XSUB to become: -+ -+ double -+ foo(a,b,c) -+ int a -+ long b -+ const char * c -+ -+Can we do the same with an XSUB -+ -+ int -+ is_even(input) -+ int input -+ CODE: -+ RETVAL = (input % 2 == 0); -+ OUTPUT: -+ RETVAL -+ -+of L<"EXAMPLE 2">? To do this, one needs to define a C function C. As we saw in L, a proper place -+for this definition is in the first part of .xs file. In fact a C function -+ -+ int -+ is_even(int arg) -+ { -+ return (arg % 2 == 0); -+ } -+ -+is probably overkill for this. Something as simple as a C<#define> will -+do too: -+ -+ #define is_even(arg) ((arg) % 2 == 0) -+ -+After having this in the first part of .xs file, the "Perl glue" part becomes -+as simple as -+ -+ int -+ is_even(input) -+ int input -+ -+This technique of separation of the glue part from the workhorse part has -+obvious tradeoffs: if you want to change a Perl interface, you need to -+change two places in your code. However, it removes a lot of clutter, -+and makes the workhorse part independent from idiosyncrasies of Perl calling -+convention. (In fact, there is nothing Perl-specific in the above description, -+a different version of B might have translated this to TCL glue or -+Python glue as well.) -+ -+=head2 More about XSUB arguments -+ -+With the completion of Example 4, we now have an easy way to simulate some -+real-life libraries whose interfaces may not be the cleanest in the world. -+We shall now continue with a discussion of the arguments passed to the -+B compiler. -+ -+When you specify arguments to routines in the .xs file, you are really -+passing three pieces of information for each argument listed. The first -+piece is the order of that argument relative to the others (first, second, -+etc). The second is the type of argument, and consists of the type -+declaration of the argument (e.g., int, char*, etc). The third piece is -+the calling convention for the argument in the call to the library function. -+ -+While Perl passes arguments to functions by reference, -+C passes arguments by value; to implement a C function which modifies data -+of one of the "arguments", the actual argument of this C function would be -+a pointer to the data. Thus two C functions with declarations -+ -+ int string_length(char *s); -+ int upper_case_char(char *cp); -+ -+may have completely different semantics: the first one may inspect an array -+of chars pointed by s, and the second one may immediately dereference C -+and manipulate C<*cp> only (using the return value as, say, a success -+indicator). From Perl one would use these functions in -+a completely different manner. -+ -+One conveys this info to B by replacing C<*> before the -+argument by C<&>. C<&> means that the argument should be passed to a library -+function by its address. The above two function may be XSUB-ified as -+ -+ int -+ string_length(s) -+ char * s -+ -+ int -+ upper_case_char(cp) -+ char &cp -+ -+For example, consider: -+ -+ int -+ foo(a,b) -+ char &a -+ char * b -+ -+The first Perl argument to this function would be treated as a char and -+assigned to the variable a, and its address would be passed into the function -+foo. The second Perl argument would be treated as a string pointer and assigned -+to the variable b. The I of b would be passed into the function foo. -+The actual call to the function foo that B generates would look like -+this: -+ -+ foo(&a, b); -+ -+B will parse the following function argument lists identically: -+ -+ char &a -+ char&a -+ char & a -+ -+However, to help ease understanding, it is suggested that you place a "&" -+next to the variable name and away from the variable type), and place a -+"*" near the variable type, but away from the variable name (as in the -+call to foo above). By doing so, it is easy to understand exactly what -+will be passed to the C function; it will be whatever is in the "last -+column". -+ -+You should take great pains to try to pass the function the type of variable -+it wants, when possible. It will save you a lot of trouble in the long run. -+ -+=head2 The Argument Stack -+ -+If we look at any of the C code generated by any of the examples except -+example 1, you will notice a number of references to ST(n), where n is -+usually 0. "ST" is actually a macro that points to the n'th argument -+on the argument stack. ST(0) is thus the first argument on the stack and -+therefore the first argument passed to the XSUB, ST(1) is the second -+argument, and so on. -+ -+When you list the arguments to the XSUB in the .xs file, that tells B -+which argument corresponds to which of the argument stack (i.e., the first -+one listed is the first argument, and so on). You invite disaster if you -+do not list them in the same order as the function expects them. -+ -+The actual values on the argument stack are pointers to the values passed -+in. When an argument is listed as being an OUTPUT value, its corresponding -+value on the stack (i.e., ST(0) if it was the first argument) is changed. -+You can verify this by looking at the C code generated for Example 3. -+The code for the round() XSUB routine contains lines that look like this: -+ -+ double arg = (double)SvNV(ST(0)); -+ /* Round the contents of the variable arg */ -+ sv_setnv(ST(0), (double)arg); -+ -+The arg variable is initially set by taking the value from ST(0), then is -+stored back into ST(0) at the end of the routine. -+ -+XSUBs are also allowed to return lists, not just scalars. This must be -+done by manipulating stack values ST(0), ST(1), etc, in a subtly -+different way. See L for details. -+ -+XSUBs are also allowed to avoid automatic conversion of Perl function arguments -+to C function arguments. See L for details. Some people prefer -+manual conversion by inspecting C even in the cases when automatic -+conversion will do, arguing that this makes the logic of an XSUB call clearer. -+Compare with L<"Getting the fat out of XSUBs"> for a similar tradeoff of -+a complete separation of "Perl glue" and "workhorse" parts of an XSUB. -+ -+While experts may argue about these idioms, a novice to Perl guts may -+prefer a way which is as little Perl-guts-specific as possible, meaning -+automatic conversion and automatic call generation, as in -+L<"Getting the fat out of XSUBs">. This approach has the additional -+benefit of protecting the XSUB writer from future changes to the Perl API. -+ -+=head2 Extending your Extension -+ -+Sometimes you might want to provide some extra methods or subroutines -+to assist in making the interface between Perl and your extension simpler -+or easier to understand. These routines should live in the .pm file. -+Whether they are automatically loaded when the extension itself is loaded -+or only loaded when called depends on where in the .pm file the subroutine -+definition is placed. You can also consult L for an alternate -+way to store and load your extra subroutines. -+ -+=head2 Documenting your Extension -+ -+There is absolutely no excuse for not documenting your extension. -+Documentation belongs in the .pm file. This file will be fed to pod2man, -+and the embedded documentation will be converted to the manpage format, -+then placed in the blib directory. It will be copied to Perl's -+manpage directory when the extension is installed. -+ -+You may intersperse documentation and Perl code within the .pm file. -+In fact, if you want to use method autoloading, you must do this, -+as the comment inside the .pm file explains. -+ -+See L for more information about the pod format. -+ -+=head2 Installing your Extension -+ -+Once your extension is complete and passes all its tests, installing it -+is quite simple: you simply run "make install". You will either need -+to have write permission into the directories where Perl is installed, -+or ask your system administrator to run the make for you. -+ -+Alternately, you can specify the exact directory to place the extension's -+files by placing a "PREFIX=/destination/directory" after the make install -+(or in between the make and install if you have a brain-dead version of make). -+This can be very useful if you are building an extension that will eventually -+be distributed to multiple systems. You can then just archive the files in -+the destination directory and distribute them to your destination systems. -+ -+=head2 EXAMPLE 5 -+ -+In this example, we'll do some more work with the argument stack. The -+previous examples have all returned only a single value. We'll now -+create an extension that returns an array. -+ -+This extension is very Unix-oriented (struct statfs and the statfs system -+call). If you are not running on a Unix system, you can substitute for -+statfs any other function that returns multiple values, you can hard-code -+values to be returned to the caller (although this will be a bit harder -+to test the error case), or you can simply not do this example. If you -+change the XSUB, be sure to fix the test cases to match the changes. -+ -+Return to the Mytest directory and add the following code to the end of -+Mytest.xs: -+ -+ void -+ statfs(path) -+ char * path -+ INIT: -+ int i; -+ struct statfs buf; -+ -+ PPCODE: -+ i = statfs(path, &buf); -+ if (i == 0) { -+ XPUSHs(sv_2mortal(newSVnv(buf.f_bavail))); -+ XPUSHs(sv_2mortal(newSVnv(buf.f_bfree))); -+ XPUSHs(sv_2mortal(newSVnv(buf.f_blocks))); -+ XPUSHs(sv_2mortal(newSVnv(buf.f_bsize))); -+ XPUSHs(sv_2mortal(newSVnv(buf.f_ffree))); -+ XPUSHs(sv_2mortal(newSVnv(buf.f_files))); -+ XPUSHs(sv_2mortal(newSVnv(buf.f_type))); -+ } else { -+ XPUSHs(sv_2mortal(newSVnv(errno))); -+ } -+ -+You'll also need to add the following code to the top of the .xs file, just -+after the include of "XSUB.h": -+ -+ #include -+ -+Also add the following code segment to Mytest.t while incrementing the "9" -+tests to "11": -+ -+ @a = &Mytest::statfs("/blech"); -+ ok( scalar(@a) == 1 && $a[0] == 2 ); -+ @a = &Mytest::statfs("/"); -+ is( scalar(@a), 7 ); -+ -+=head2 New Things in this Example -+ -+This example added quite a few new concepts. We'll take them one at a time. -+ -+=over 4 -+ -+=item * -+ -+The INIT: directive contains code that will be placed immediately after -+the argument stack is decoded. C does not allow variable declarations at -+arbitrary locations inside a function, -+so this is usually the best way to declare local variables needed by the XSUB. -+(Alternatively, one could put the whole C section into braces, and -+put these declarations on top.) -+ -+=item * -+ -+This routine also returns a different number of arguments depending on the -+success or failure of the call to statfs. If there is an error, the error -+number is returned as a single-element array. If the call is successful, -+then a 7-element array is returned. Since only one argument is passed into -+this function, we need room on the stack to hold the 7 values which may be -+returned. -+ -+We do this by using the PPCODE: directive, rather than the CODE: directive. -+This tells B that we will be managing the return values that will be -+put on the argument stack by ourselves. -+ -+=item * -+ -+When we want to place values to be returned to the caller onto the stack, -+we use the series of macros that begin with "XPUSH". There are five -+different versions, for placing integers, unsigned integers, doubles, -+strings, and Perl scalars on the stack. In our example, we placed a -+Perl scalar onto the stack. (In fact this is the only macro which -+can be used to return multiple values.) -+ -+The XPUSH* macros will automatically extend the return stack to prevent -+it from being overrun. You push values onto the stack in the order you -+want them seen by the calling program. -+ -+=item * -+ -+The values pushed onto the return stack of the XSUB are actually mortal SV's. -+They are made mortal so that once the values are copied by the calling -+program, the SV's that held the returned values can be deallocated. -+If they were not mortal, then they would continue to exist after the XSUB -+routine returned, but would not be accessible. This is a memory leak. -+ -+=item * -+ -+If we were interested in performance, not in code compactness, in the success -+branch we would not use C macros, but C macros, and would -+pre-extend the stack before pushing the return values: -+ -+ EXTEND(SP, 7); -+ -+The tradeoff is that one needs to calculate the number of return values -+in advance (though overextending the stack will not typically hurt -+anything but memory consumption). -+ -+Similarly, in the failure branch we could use C I extending -+the stack: the Perl function reference comes to an XSUB on the stack, thus -+the stack is I large enough to take one return value. -+ -+=back -+ -+=head2 EXAMPLE 6 -+ -+In this example, we will accept a reference to an array as an input -+parameter, and return a reference to an array of hashes. This will -+demonstrate manipulation of complex Perl data types from an XSUB. -+ -+This extension is somewhat contrived. It is based on the code in -+the previous example. It calls the statfs function multiple times, -+accepting a reference to an array of filenames as input, and returning -+a reference to an array of hashes containing the data for each of the -+filesystems. -+ -+Return to the Mytest directory and add the following code to the end of -+Mytest.xs: -+ -+ SV * -+ multi_statfs(paths) -+ SV * paths -+ INIT: -+ AV * results; -+ SSize_t numpaths = 0, n; -+ int i; -+ struct statfs buf; -+ -+ SvGETMAGIC(paths); -+ if ((!SvROK(paths)) -+ || (SvTYPE(SvRV(paths)) != SVt_PVAV) -+ || ((numpaths = av_top_index((AV *)SvRV(paths))) < 0)) -+ { -+ XSRETURN_UNDEF; -+ } -+ results = (AV *)sv_2mortal((SV *)newAV()); -+ CODE: -+ for (n = 0; n <= numpaths; n++) { -+ HV * rh; -+ STRLEN l; -+ char * fn = SvPV(*av_fetch((AV *)SvRV(paths), n, 0), l); -+ -+ i = statfs(fn, &buf); -+ if (i != 0) { -+ av_push(results, newSVnv(errno)); -+ continue; -+ } -+ -+ rh = (HV *)sv_2mortal((SV *)newHV()); -+ -+ hv_store(rh, "f_bavail", 8, newSVnv(buf.f_bavail), 0); -+ hv_store(rh, "f_bfree", 7, newSVnv(buf.f_bfree), 0); -+ hv_store(rh, "f_blocks", 8, newSVnv(buf.f_blocks), 0); -+ hv_store(rh, "f_bsize", 7, newSVnv(buf.f_bsize), 0); -+ hv_store(rh, "f_ffree", 7, newSVnv(buf.f_ffree), 0); -+ hv_store(rh, "f_files", 7, newSVnv(buf.f_files), 0); -+ hv_store(rh, "f_type", 6, newSVnv(buf.f_type), 0); -+ -+ av_push(results, newRV_inc((SV *)rh)); -+ } -+ RETVAL = newRV_inc((SV *)results); -+ OUTPUT: -+ RETVAL -+ -+And add the following code to Mytest.t, while incrementing the "11" -+tests to "13": -+ -+ $results = Mytest::multi_statfs([ '/', '/blech' ]); -+ ok( ref $results->[0] ); -+ ok( ! ref $results->[1] ); -+ -+=head2 New Things in this Example -+ -+There are a number of new concepts introduced here, described below: -+ -+=over 4 -+ -+=item * -+ -+This function does not use a typemap. Instead, we declare it as accepting -+one SV* (scalar) parameter, and returning an SV* value, and we take care of -+populating these scalars within the code. Because we are only returning -+one value, we don't need a C directive - instead, we use C -+and C directives. -+ -+=item * -+ -+When dealing with references, it is important to handle them with caution. -+The C block first calls SvGETMAGIC(paths), in case -+paths is a tied variable. Then it checks that C returns -+true, which indicates that paths is a valid reference. (Simply -+checking C won't trigger FETCH on a tied variable.) It -+then verifies that the object referenced by paths is an array, using C -+to dereference paths, and C to discover its type. As an added test, -+it checks that the array referenced by paths is non-empty, using the -+C function (which returns -1 if the array is empty). The -+XSRETURN_UNDEF macro is used to abort the XSUB and return the undefined value -+whenever all three of these conditions are not met. -+ -+=item * -+ -+We manipulate several arrays in this XSUB. Note that an array is represented -+internally by an AV* pointer. The functions and macros for manipulating -+arrays are similar to the functions in Perl: C returns the -+highest index in an AV*, much like $#array; C fetches a single scalar -+value from an array, given its index; C pushes a scalar value onto the -+end of the array, automatically extending the array as necessary. -+ -+Specifically, we read pathnames one at a time from the input array, and -+store the results in an output array (results) in the same order. If -+statfs fails, the element pushed onto the return array is the value of -+errno after the failure. If statfs succeeds, though, the value pushed -+onto the return array is a reference to a hash containing some of the -+information in the statfs structure. -+ -+As with the return stack, it would be possible (and a small performance win) -+to pre-extend the return array before pushing data into it, since we know -+how many elements we will return: -+ -+ av_extend(results, numpaths); -+ -+=item * -+ -+We are performing only one hash operation in this function, which is storing -+a new scalar under a key using C. A hash is represented by an HV* -+pointer. Like arrays, the functions for manipulating hashes from an XSUB -+mirror the functionality available from Perl. See L and L -+for details. -+ -+=item * -+ -+To create a reference, we use the C function. Note that you can -+cast an AV* or an HV* to type SV* in this case (and many others). This -+allows you to take references to arrays, hashes and scalars with the same -+function. Conversely, the C function always returns an SV*, which may -+need to be cast to the appropriate type if it is something other than a -+scalar (check with C). -+ -+=item * -+ -+At this point, xsubpp is doing very little work - the differences between -+Mytest.xs and Mytest.c are minimal. -+ -+=back -+ -+=head2 EXAMPLE 7 (Coming Soon) -+ -+XPUSH args AND set RETVAL AND assign return value to array -+ -+=head2 EXAMPLE 8 (Coming Soon) -+ -+Setting $! -+ -+=head2 EXAMPLE 9 Passing open files to XSes -+ -+You would think passing files to an XS is difficult, with all the -+typeglobs and stuff. Well, it isn't. -+ -+Suppose that for some strange reason we need a wrapper around the -+standard C library function C. This is all we need: -+ -+ #define PERLIO_NOT_STDIO 0 -+ #define PERL_NO_GET_CONTEXT -+ #include "EXTERN.h" -+ #include "perl.h" -+ #include "XSUB.h" -+ -+ #include -+ -+ int -+ fputs(s, stream) -+ char * s -+ FILE * stream -+ -+The real work is done in the standard typemap. -+ -+B you lose all the fine stuff done by the perlio layers. This -+calls the stdio function C, which knows nothing about them. -+ -+The standard typemap offers three variants of PerlIO *: -+C (T_IN), C (T_INOUT) and C -+(T_OUT). A bare C is considered a T_INOUT. If it matters -+in your code (see below for why it might) #define or typedef -+one of the specific names and use that as the argument or result -+type in your XS file. -+ -+The standard typemap does not contain PerlIO * before perl 5.7, -+but it has the three stream variants. Using a PerlIO * directly -+is not backwards compatible unless you provide your own typemap. -+ -+For streams coming I perl the main difference is that -+C will get the output PerlIO * - which may make -+a difference on a socket. Like in our example... -+ -+For streams being handed I perl a new file handle is created -+(i.e. a reference to a new glob) and associated with the PerlIO * -+provided. If the read/write state of the PerlIO * is not correct then you -+may get errors or warnings from when the file handle is used. -+So if you opened the PerlIO * as "w" it should really be an -+C if open as "r" it should be an C. -+ -+Now, suppose you want to use perlio layers in your XS. We'll use the -+perlio C function as an example. -+ -+In the C part of the XS file (above the first MODULE line) you -+have -+ -+ #define OutputStream PerlIO * -+ or -+ typedef PerlIO * OutputStream; -+ -+ -+And this is the XS code: -+ -+ int -+ perlioputs(s, stream) -+ char * s -+ OutputStream stream -+ CODE: -+ RETVAL = PerlIO_puts(stream, s); -+ OUTPUT: -+ RETVAL -+ -+We have to use a C section because C has the arguments -+reversed compared to C, and we want to keep the arguments the same. -+ -+Wanting to explore this thoroughly, we want to use the stdio C -+on a PerlIO *. This means we have to ask the perlio system for a stdio -+C: -+ -+ int -+ perliofputs(s, stream) -+ char * s -+ OutputStream stream -+ PREINIT: -+ FILE *fp = PerlIO_findFILE(stream); -+ CODE: -+ if (fp != (FILE*) 0) { -+ RETVAL = fputs(s, fp); -+ } else { -+ RETVAL = -1; -+ } -+ OUTPUT: -+ RETVAL -+ -+Note: C will search the layers for a stdio -+layer. If it can't find one, it will call C to -+generate a new stdio C. Please only call C if -+you want a I C. It will generate one on each call and push a -+new stdio layer. So don't call it repeatedly on the same -+file. C will retrieve the stdio layer once it has been -+generated by C. -+ -+This applies to the perlio system only. For versions before 5.7, -+C is equivalent to C. -+ -+=head2 Troubleshooting these Examples -+ -+As mentioned at the top of this document, if you are having problems with -+these example extensions, you might see if any of these help you. -+ -+=over 4 -+ -+=item * -+ -+In versions of 5.002 prior to the gamma version, the test script in Example -+1 will not function properly. You need to change the "use lib" line to -+read: -+ -+ use lib './blib'; -+ -+=item * -+ -+In versions of 5.002 prior to version 5.002b1h, the test.pl file was not -+automatically created by h2xs. This means that you cannot say "make test" -+to run the test script. You will need to add the following line before the -+"use extension" statement: -+ -+ use lib './blib'; -+ -+=item * -+ -+In versions 5.000 and 5.001, instead of using the above line, you will need -+to use the following line: -+ -+ BEGIN { unshift(@INC, "./blib") } -+ -+=item * -+ -+This document assumes that the executable named "perl" is Perl version 5. -+Some systems may have installed Perl version 5 as "perl5". -+ -+=back -+ -+=head1 See also -+ -+For more information, consult L, L, L, L, -+and L. -+ -+=head1 Author -+ -+Jeff Okamoto > -+ -+Reviewed and assisted by Dean Roehrich, Ilya Zakharevich, Andreas Koenig, -+and Tim Bunce. -+ -+PerlIO material contributed by Lupe Christoph, with some clarification -+by Nick Ing-Simmons. -+ -+Changes for h2xs as of Perl 5.8.x by Renee Baecker -+ -+=head2 Last Changed -+ -+2012-01-20 -diff --git a/lib/perlxstypemap.pod b/lib/perlxstypemap.pod -new file mode 100644 -index 0000000..7d1f73c ---- /dev/null -+++ b/lib/perlxstypemap.pod -@@ -0,0 +1,711 @@ -+=head1 NAME -+ -+perlxstypemap - Perl XS C/Perl type mapping -+ -+=head1 DESCRIPTION -+ -+The more you think about interfacing between two languages, the more -+you'll realize that the majority of programmer effort has to go into -+converting between the data structures that are native to either of -+the languages involved. This trumps other matter such as differing -+calling conventions because the problem space is so much greater. -+There are simply more ways to shove data into memory than there are -+ways to implement a function call. -+ -+Perl XS' attempt at a solution to this is the concept of typemaps. -+At an abstract level, a Perl XS typemap is nothing but a recipe for -+converting from a certain Perl data structure to a certain C -+data structure and vice versa. Since there can be C types that -+are sufficiently similar to one another to warrant converting with -+the same logic, XS typemaps are represented by a unique identifier, -+henceforth called an B in this document. You can then tell -+the XS compiler that multiple C types are to be mapped with the same -+XS typemap. -+ -+In your XS code, when you define an argument with a C type or when -+you are using a C and an C section together with a -+C return type of your XSUB, it'll be the typemapping mechanism that -+makes this easy. -+ -+=head2 Anatomy of a typemap -+ -+In more practical terms, the typemap is a collection of code -+fragments which are used by the B compiler to map C function -+parameters and values to Perl values. The typemap file may consist -+of three sections labelled C, C, and C. -+An unlabelled initial section is assumed to be a C section. -+The INPUT section tells the compiler how to translate Perl values -+into variables of certain C types. The OUTPUT section tells the -+compiler how to translate the values from certain C types into values -+Perl can understand. The TYPEMAP section tells the compiler which -+of the INPUT and OUTPUT code fragments should be used to map a given -+C type to a Perl value. The section labels C, C, or -+C must begin in the first column on a line by themselves, -+and must be in uppercase. -+ -+Each type of section can appear an arbitrary number of times -+and does not have to appear at all. For example, a typemap may -+commonly lack C and C sections if all it needs to -+do is associate additional C types with core XS types like T_PTROBJ. -+Lines that start with a hash C<#> are considered comments and ignored -+in the C section, but are considered significant in C -+and C. Blank lines are generally ignored. -+ -+Traditionally, typemaps needed to be written to a separate file, -+conventionally called C in a CPAN distribution. With -+ExtUtils::ParseXS (the XS compiler) version 3.12 or better which -+comes with perl 5.16, typemaps can also be embedded directly into -+XS code using a HERE-doc like syntax: -+ -+ TYPEMAP: < can be replaced by other identifiers like with normal -+Perl HERE-docs. All details below about the typemap textual format -+remain valid. -+ -+The C section should contain one pair of C type and -+XS type per line as follows. An example from the core typemap file: -+ -+ TYPEMAP -+ # all variants of char* is handled by the T_PV typemap -+ char * T_PV -+ const char * T_PV -+ unsigned char * T_PV -+ ... -+ -+The C and C sections have identical formats, that is, -+each unindented line starts a new in- or output map respectively. -+A new in- or output map must start with the name of the XS type to -+map on a line by itself, followed by the code that implements it -+indented on the following lines. Example: -+ -+ INPUT -+ T_PV -+ $var = ($type)SvPV_nolen($arg) -+ T_PTR -+ $var = INT2PTR($type,SvIV($arg)) -+ -+We'll get to the meaning of those Perlish-looking variables in a -+little bit. -+ -+Finally, here's an example of the full typemap file for mapping C -+strings of the C type to Perl scalars/strings: -+ -+ TYPEMAP -+ char * T_PV -+ -+ INPUT -+ T_PV -+ $var = ($type)SvPV_nolen($arg) -+ -+ OUTPUT -+ T_PV -+ sv_setpv((SV*)$arg, $var); -+ -+Here's a more complicated example: suppose that you wanted -+C to be blessed into the class C. -+One way to do this is to use underscores (_) to separate package -+names, as follows: -+ -+ typedef struct netconfig * Net_Config; -+ -+And then provide a typemap entry C that maps -+underscores to double-colons (::), and declare C to be of -+that type: -+ -+ TYPEMAP -+ Net_Config T_PTROBJ_SPECIAL -+ -+ INPUT -+ T_PTROBJ_SPECIAL -+ if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")){ -+ IV tmp = SvIV((SV*)SvRV($arg)); -+ $var = INT2PTR($type, tmp); -+ } -+ else -+ croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\") -+ -+ OUTPUT -+ T_PTROBJ_SPECIAL -+ sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\", -+ (void*)$var); -+ -+The INPUT and OUTPUT sections substitute underscores for double-colons -+on the fly, giving the desired effect. This example demonstrates some -+of the power and versatility of the typemap facility. -+ -+The C macro (defined in perl.h) casts an integer to a pointer -+of a given type, taking care of the possible different size of integers -+and pointers. There are also C, C, C macros, -+to map the other way, which may be useful in OUTPUT sections. -+ -+=head2 The Role of the typemap File in Your Distribution -+ -+The default typemap in the F directory of the Perl source -+contains many useful types which can be used by Perl extensions. Some -+extensions define additional typemaps which they keep in their own directory. -+These additional typemaps may reference INPUT and OUTPUT maps in the main -+typemap. The B compiler will allow the extension's own typemap to -+override any mappings which are in the default typemap. Instead of using -+an additional F file, typemaps may be embedded verbatim in XS -+with a heredoc-like syntax. See the documentation on the C XS -+keyword. -+ -+For CPAN distributions, you can assume that the XS types defined by -+the perl core are already available. Additionally, the core typemap -+has default XS types for a large number of C types. For example, if -+you simply return a C from your XSUB, the core typemap will -+have this C type associated with the T_PV XS type. That means your -+C string will be copied into the PV (pointer value) slot of a new scalar -+that will be returned from your XSUB to Perl. -+ -+If you're developing a CPAN distribution using XS, you may add your own -+file called F to the distribution. That file may contain -+typemaps that either map types that are specific to your code or that -+override the core typemap file's mappings for common C types. -+ -+=head2 Sharing typemaps Between CPAN Distributions -+ -+Starting with ExtUtils::ParseXS version 3.13_01 (comes with perl 5.16 -+and better), it is rather easy to share typemap code between multiple -+CPAN distributions. The general idea is to share it as a module that -+offers a certain API and have the dependent modules declare that as a -+built-time requirement and import the typemap into the XS. An example -+of such a typemap-sharing module on CPAN is -+C. Two steps to getting that module's -+typemaps available in your code: -+ -+=over 4 -+ -+=item * -+ -+Declare C as a build-time dependency -+in C (use C), or in your C -+(use C). -+ -+=item * -+ -+Include the following line in the XS section of your XS file: -+(don't break the line) -+ -+ INCLUDE_COMMAND: $^X -MExtUtils::Typemaps::Cmd -+ -e "print embeddable_typemap(q{Basic})" -+ -+=back -+ -+=head2 Writing typemap Entries -+ -+Each INPUT or OUTPUT typemap entry is a double-quoted Perl string that -+will be evaluated in the presence of certain variables to get the -+final C code for mapping a certain C type. -+ -+This means that you can embed Perl code in your typemap (C) code using -+constructs such as -+C<${ perl code that evaluates to scalar reference here }>. A common -+use case is to generate error messages that refer to the true function -+name even when using the ALIAS XS feature: -+ -+ ${ $ALIAS ? \q[GvNAME(CvGV(cv))] : \qq[\"$pname\"] } -+ -+For many typemap examples, refer to the core typemap file that can be -+found in the perl source tree at F. -+ -+The Perl variables that are available for interpolation into typemaps -+are the following: -+ -+=over 4 -+ -+=item * -+ -+I<$var> - the name of the input or output variable, eg. RETVAL for -+return values. -+ -+=item * -+ -+I<$type> - the raw C type of the parameter, any C<:> replaced with -+C<_>. -+e.g. for a type of C, I<$type> is C -+ -+=item * -+ -+I<$ntype> - the supplied type with C<*> replaced with C. -+e.g. for a type of C, I<$ntype> is C -+ -+=item * -+ -+I<$arg> - the stack entry, that the parameter is input from or output -+to, e.g. C -+ -+=item * -+ -+I<$argoff> - the argument stack offset of the argument. ie. 0 for the -+first argument, etc. -+ -+=item * -+ -+I<$pname> - the full name of the XSUB, with including the C -+name, with any C stripped. This is the non-ALIAS name. -+ -+=item * -+ -+I<$Package> - the package specified by the most recent C -+keyword. -+ -+=item * -+ -+I<$ALIAS> - non-zero if the current XSUB has any aliases declared with -+C. -+ -+=back -+ -+=head2 Full Listing of Core Typemaps -+ -+Each C type is represented by an entry in the typemap file that -+is responsible for converting perl variables (SV, AV, HV, CV, etc.) -+to and from that type. The following sections list all XS types -+that come with perl by default. -+ -+=over 4 -+ -+=item T_SV -+ -+This simply passes the C representation of the Perl variable (an SV*) -+in and out of the XS layer. This can be used if the C code wants -+to deal directly with the Perl variable. -+ -+=item T_SVREF -+ -+Used to pass in and return a reference to an SV. -+ -+Note that this typemap does not decrement the reference count -+when returning the reference to an SV*. -+See also: T_SVREF_REFCOUNT_FIXED -+ -+=item T_SVREF_FIXED -+ -+Used to pass in and return a reference to an SV. -+This is a fixed -+variant of T_SVREF that decrements the refcount appropriately -+when returning a reference to an SV*. Introduced in perl 5.15.4. -+ -+=item T_AVREF -+ -+From the perl level this is a reference to a perl array. -+From the C level this is a pointer to an AV. -+ -+Note that this typemap does not decrement the reference count -+when returning an AV*. See also: T_AVREF_REFCOUNT_FIXED -+ -+=item T_AVREF_REFCOUNT_FIXED -+ -+From the perl level this is a reference to a perl array. -+From the C level this is a pointer to an AV. This is a fixed -+variant of T_AVREF that decrements the refcount appropriately -+when returning an AV*. Introduced in perl 5.15.4. -+ -+=item T_HVREF -+ -+From the perl level this is a reference to a perl hash. -+From the C level this is a pointer to an HV. -+ -+Note that this typemap does not decrement the reference count -+when returning an HV*. See also: T_HVREF_REFCOUNT_FIXED -+ -+=item T_HVREF_REFCOUNT_FIXED -+ -+From the perl level this is a reference to a perl hash. -+From the C level this is a pointer to an HV. This is a fixed -+variant of T_HVREF that decrements the refcount appropriately -+when returning an HV*. Introduced in perl 5.15.4. -+ -+=item T_CVREF -+ -+From the perl level this is a reference to a perl subroutine -+(e.g. $sub = sub { 1 };). From the C level this is a pointer -+to a CV. -+ -+Note that this typemap does not decrement the reference count -+when returning an HV*. See also: T_HVREF_REFCOUNT_FIXED -+ -+=item T_CVREF_REFCOUNT_FIXED -+ -+From the perl level this is a reference to a perl subroutine -+(e.g. $sub = sub { 1 };). From the C level this is a pointer -+to a CV. -+ -+This is a fixed -+variant of T_HVREF that decrements the refcount appropriately -+when returning an HV*. Introduced in perl 5.15.4. -+ -+=item T_SYSRET -+ -+The T_SYSRET typemap is used to process return values from system calls. -+It is only meaningful when passing values from C to perl (there is -+no concept of passing a system return value from Perl to C). -+ -+System calls return -1 on error (setting ERRNO with the reason) -+and (usually) 0 on success. If the return value is -1 this typemap -+returns C. If the return value is not -1, this typemap -+translates a 0 (perl false) to "0 but true" (which -+is perl true) or returns the value itself, to indicate that the -+command succeeded. -+ -+The L module makes extensive use of this type. -+ -+=item T_UV -+ -+An unsigned integer. -+ -+=item T_IV -+ -+A signed integer. This is cast to the required integer type when -+passed to C and converted to an IV when passed back to Perl. -+ -+=item T_INT -+ -+A signed integer. This typemap converts the Perl value to a native -+integer type (the C type on the current platform). When returning -+the value to perl it is processed in the same way as for T_IV. -+ -+Its behaviour is identical to using an C type in XS with T_IV. -+ -+=item T_ENUM -+ -+An enum value. Used to transfer an enum component -+from C. There is no reason to pass an enum value to C since -+it is stored as an IV inside perl. -+ -+=item T_BOOL -+ -+A boolean type. This can be used to pass true and false values to and -+from C. -+ -+=item T_U_INT -+ -+This is for unsigned integers. It is equivalent to using T_UV -+but explicitly casts the variable to type C. -+The default type for C is T_UV. -+ -+=item T_SHORT -+ -+Short integers. This is equivalent to T_IV but explicitly casts -+the return to type C. The default typemap for C -+is T_IV. -+ -+=item T_U_SHORT -+ -+Unsigned short integers. This is equivalent to T_UV but explicitly -+casts the return to type C. The default typemap for -+C is T_UV. -+ -+T_U_SHORT is used for type C in the standard typemap. -+ -+=item T_LONG -+ -+Long integers. This is equivalent to T_IV but explicitly casts -+the return to type C. The default typemap for C -+is T_IV. -+ -+=item T_U_LONG -+ -+Unsigned long integers. This is equivalent to T_UV but explicitly -+casts the return to type C. The default typemap for -+C is T_UV. -+ -+T_U_LONG is used for type C in the standard typemap. -+ -+=item T_CHAR -+ -+Single 8-bit characters. -+ -+=item T_U_CHAR -+ -+An unsigned byte. -+ -+=item T_FLOAT -+ -+A floating point number. This typemap guarantees to return a variable -+cast to a C. -+ -+=item T_NV -+ -+A Perl floating point number. Similar to T_IV and T_UV in that the -+return type is cast to the requested numeric type rather than -+to a specific type. -+ -+=item T_DOUBLE -+ -+A double precision floating point number. This typemap guarantees to -+return a variable cast to a C. -+ -+=item T_PV -+ -+A string (char *). -+ -+=item T_PTR -+ -+A memory address (pointer). Typically associated with a C -+type. -+ -+=item T_PTRREF -+ -+Similar to T_PTR except that the pointer is stored in a scalar and the -+reference to that scalar is returned to the caller. This can be used -+to hide the actual pointer value from the programmer since it is usually -+not required directly from within perl. -+ -+The typemap checks that a scalar reference is passed from perl to XS. -+ -+=item T_PTROBJ -+ -+Similar to T_PTRREF except that the reference is blessed into a class. -+This allows the pointer to be used as an object. Most commonly used to -+deal with C structs. The typemap checks that the perl object passed -+into the XS routine is of the correct class (or part of a subclass). -+ -+The pointer is blessed into a class that is derived from the name -+of type of the pointer but with all '*' in the name replaced with -+'Ptr'. -+ -+For C XSUBs only, a T_PTROBJ is optimized to a T_PTRREF. This means -+the class check is skipped. -+ -+=item T_REF_IV_REF -+ -+NOT YET -+ -+=item T_REF_IV_PTR -+ -+Similar to T_PTROBJ in that the pointer is blessed into a scalar object. -+The difference is that when the object is passed back into XS it must be -+of the correct type (inheritance is not supported) while T_PTROBJ supports -+inheritance. -+ -+The pointer is blessed into a class that is derived from the name -+of type of the pointer but with all '*' in the name replaced with -+'Ptr'. -+ -+For C XSUBs only, a T_REF_IV_PTR is optimized to a T_PTRREF. This -+means the class check is skipped. -+ -+=item T_PTRDESC -+ -+NOT YET -+ -+=item T_REFREF -+ -+Similar to T_PTRREF, except the pointer stored in the referenced scalar -+is dereferenced and copied to the output variable. This means that -+T_REFREF is to T_PTRREF as T_OPAQUE is to T_OPAQUEPTR. All clear? -+ -+Only the INPUT part of this is implemented (Perl to XSUB) and there -+are no known users in core or on CPAN. -+ -+=item T_REFOBJ -+ -+Like T_REFREF, except it does strict type checking (inheritance is not -+supported). -+ -+For C XSUBs only, a T_REFOBJ is optimized to a T_REFREF. This means -+the class check is skipped. -+ -+=item T_OPAQUEPTR -+ -+This can be used to store bytes in the string component of the -+SV. Here the representation of the data is irrelevant to perl and the -+bytes themselves are just stored in the SV. It is assumed that the C -+variable is a pointer (the bytes are copied from that memory -+location). If the pointer is pointing to something that is -+represented by 8 bytes then those 8 bytes are stored in the SV (and -+length() will report a value of 8). This entry is similar to T_OPAQUE. -+ -+In principle the unpack() command can be used to convert the bytes -+back to a number (if the underlying type is known to be a number). -+ -+This entry can be used to store a C structure (the number -+of bytes to be copied is calculated using the C C function) -+and can be used as an alternative to T_PTRREF without having to worry -+about a memory leak (since Perl will clean up the SV). -+ -+=item T_OPAQUE -+ -+This can be used to store data from non-pointer types in the string -+part of an SV. It is similar to T_OPAQUEPTR except that the -+typemap retrieves the pointer directly rather than assuming it -+is being supplied. For example, if an integer is imported into -+Perl using T_OPAQUE rather than T_IV the underlying bytes representing -+the integer will be stored in the SV but the actual integer value will -+not be available. i.e. The data is opaque to perl. -+ -+The data may be retrieved using the C function if the -+underlying type of the byte stream is known. -+ -+T_OPAQUE supports input and output of simple types. -+T_OPAQUEPTR can be used to pass these bytes back into C if a pointer -+is acceptable. -+ -+=item Implicit array -+ -+xsubpp supports a special syntax for returning -+packed C arrays to perl. If the XS return type is given as -+ -+ array(type, nelem) -+ -+xsubpp will copy the contents of C bytes from -+RETVAL to an SV and push it onto the stack. This is only really useful -+if the number of items to be returned is known at compile time and you -+don't mind having a string of bytes in your SV. Use T_ARRAY to push a -+variable number of arguments onto the return stack (they won't be -+packed as a single string though). -+ -+This is similar to using T_OPAQUEPTR but can be used to process more -+than one element. -+ -+=item T_PACKED -+ -+Calls user-supplied functions for conversion. For C -+(XSUB to Perl), a function named C is called -+with the output Perl scalar and the C variable to convert from. -+C<$ntype> is the normalized C type that is to be mapped to -+Perl. Normalized means that all C<*> are replaced by the -+string C. The return value of the function is ignored. -+ -+Conversely for C (Perl to XSUB) mapping, the -+function named C is called with the input Perl -+scalar as argument and the return value is cast to the mapped -+C type and assigned to the output C variable. -+ -+An example conversion function for a typemapped struct -+C might be: -+ -+ static void -+ XS_pack_foo_tPtr(SV *out, foo_t *in) -+ { -+ dTHX; /* alas, signature does not include pTHX_ */ -+ HV* hash = newHV(); -+ hv_stores(hash, "int_member", newSViv(in->int_member)); -+ hv_stores(hash, "float_member", newSVnv(in->float_member)); -+ /* ... */ -+ -+ /* mortalize as thy stack is not refcounted */ -+ sv_setsv(out, sv_2mortal(newRV_noinc((SV*)hash))); -+ } -+ -+The conversion from Perl to C is left as an exercise to the reader, -+but the prototype would be: -+ -+ static foo_t * -+ XS_unpack_foo_tPtr(SV *in); -+ -+Instead of an actual C function that has to fetch the thread context -+using C, you can define macros of the same name and avoid the -+overhead. Also, keep in mind to possibly free the memory allocated by -+C. -+ -+=item T_PACKEDARRAY -+ -+T_PACKEDARRAY is similar to T_PACKED. In fact, the C (Perl -+to XSUB) typemap is identical, but the C typemap passes -+an additional argument to the C function. This -+third parameter indicates the number of elements in the output -+so that the function can handle C arrays sanely. The variable -+needs to be declared by the user and must have the name -+C where C<$ntype> is the normalized C type name -+as explained above. The signature of the function would be for -+the example above and C: -+ -+ static void -+ XS_pack_foo_tPtrPtr(SV *out, foo_t *in, UV count_foo_tPtrPtr); -+ -+The type of the third parameter is arbitrary as far as the typemap -+is concerned. It just has to be in line with the declared variable. -+ -+Of course, unless you know the number of elements in the -+C C array, within your XSUB, the return value from -+C will be hard to decipher. -+Since the details are all up to the XS author (the typemap user), -+there are several solutions, none of which particularly elegant. -+The most commonly seen solution has been to allocate memory for -+N+1 pointers and assign C to the (N+1)th to facilitate -+iteration. -+ -+Alternatively, using a customized typemap for your purposes in -+the first place is probably preferable. -+ -+=item T_DATAUNIT -+ -+NOT YET -+ -+=item T_CALLBACK -+ -+NOT YET -+ -+=item T_ARRAY -+ -+This is used to convert the perl argument list to a C array -+and for pushing the contents of a C array onto the perl -+argument stack. -+ -+The usual calling signature is -+ -+ @out = array_func( @in ); -+ -+Any number of arguments can occur in the list before the array but -+the input and output arrays must be the last elements in the list. -+ -+When used to pass a perl list to C the XS writer must provide a -+function (named after the array type but with 'Ptr' substituted for -+'*') to allocate the memory required to hold the list. A pointer -+should be returned. It is up to the XS writer to free the memory on -+exit from the function. The variable C is set to the number -+of elements in the new array. -+ -+When returning a C array to Perl the XS writer must provide an integer -+variable called C containing the number of elements in the -+array. This is used to determine how many elements should be pushed -+onto the return argument stack. This is not required on input since -+Perl knows how many arguments are on the stack when the routine is -+called. Ordinarily this variable would be called C. -+ -+Additionally, the type of each element is determined from the type of -+the array. If the array uses type C xsubpp will -+automatically work out that it contains variables of type C and -+use that typemap entry to perform the copy of each element. All -+pointer '*' and 'Array' tags are removed from the name to determine -+the subtype. -+ -+=item T_STDIO -+ -+This is used for passing perl filehandles to and from C using -+C structures. -+ -+=item T_INOUT -+ -+This is used for passing perl filehandles to and from C using -+C structures. The file handle can used for reading and -+writing. This corresponds to the C<+E> mode, see also T_IN -+and T_OUT. -+ -+See L for more information on the Perl IO abstraction -+layer. Perl must have been built with C<-Duseperlio>. -+ -+There is no check to assert that the filehandle passed from Perl -+to C was created with the right C mode. -+ -+Hint: The L tutorial covers the T_INOUT, T_IN, and T_OUT -+XS types nicely. -+ -+=item T_IN -+ -+Same as T_INOUT, but the filehandle that is returned from C to Perl -+can only be used for reading (mode C>). -+ -+=item T_OUT -+ -+Same as T_INOUT, but the filehandle that is returned from C to Perl -+is set to use the open mode C<+E>. -+ -+=back -+ -diff --git a/t/XSTest.xs b/t/XSTest.xs -index 89df22f..452d3db 100644 ---- a/t/XSTest.xs -+++ b/t/XSTest.xs -@@ -76,6 +76,7 @@ bool - T_BOOL_2(in) - bool in - CODE: -+ PERL_UNUSED_VAR(RETVAL); - OUTPUT: in - - void -diff --git a/t/XSUsage.xs b/t/XSUsage.xs -index 9a8d93d..ed3c8f8 100644 ---- a/t/XSUsage.xs -+++ b/t/XSUsage.xs -@@ -35,6 +35,8 @@ xsusage_two() - ALIAS: - two_x = 1 - FOO::two = 2 -+ INIT: -+ PERL_UNUSED_VAR(ix); - - int - interface_v_i() --- -2.14.3 - diff --git a/perl-ExtUtils-ParseXS.spec b/perl-ExtUtils-ParseXS.spec index f525419..6c2e48f 100644 --- a/perl-ExtUtils-ParseXS.spec +++ b/perl-ExtUtils-ParseXS.spec @@ -1,13 +1,12 @@ Name: perl-ExtUtils-ParseXS -Epoch: 1 -Version: 3.39 -Release: 419 +Epoch: 2 +Version: 3.35 +Release: 1 Summary: Convert Perl XS code into C code License: GPL+ or Artistic URL: https://metacpan.org/pod/ExtUtils::ParseXS Source0: https://cpan.metacpan.org/authors/id/S/SM/SMUELLER/ExtUtils-ParseXS-3.35.tar.gz -Patch0: ExtUtils-ParseXS-3.35-Upgrade-to-3.39.patch BuildArch: noarch BuildRequires: gcc git coreutils make perl-devel perl-generators perl-interpreter perl(Config) BuildRequires: perl(ExtUtils::MakeMaker) >= 6.76 perl(File::Spec) perl(strict) perl(warnings) @@ -51,6 +50,12 @@ make test %{_mandir}/man3/* %changelog +* Sat Jan 11 2020 openEuler Buildteam - 2:3.35-1 +- Type: enhancement +- ID: NA +- SUG: NA +- DESC: remove unnecessary files + * Sun Sep 29 2019 openEuler Buildteam - 1:3.39-419 - Type:enhancement - ID:NA -- Gitee