From: Gurusamy Sarathy Date: Mon, 9 Feb 1998 02:31:55 +0000 (-0500) Subject: [win32] enhancements to previous patch for XSUB OUTPUT args X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ef50df4b2435a16251e94335bad8aa9485e4478c;p=p5sagit%2Fp5-mst-13.2.git [win32] enhancements to previous patch for XSUB OUTPUT args Message-Id: <199802090731.CAA04438@aatma.engin.umich.edu> Subject: Re: [PATCH] XSUB OUTPUT arguments and 'set' magic p4raw-id: //depot/win32/perl@492 --- diff --git a/embed.h b/embed.h index 41a6af9..73cc786 100644 --- a/embed.h +++ b/embed.h @@ -396,6 +396,7 @@ #define newSVnv Perl_newSVnv #define newSVpv Perl_newSVpv #define newSVpvf Perl_newSVpvf +#define newSVpvn Perl_newSVpvn #define newSVrv Perl_newSVrv #define newSVsv Perl_newSVsv #define newUNOP Perl_newUNOP @@ -927,9 +928,13 @@ #define sv_backoff Perl_sv_backoff #define sv_bless Perl_sv_bless #define sv_catpv Perl_sv_catpv +#define sv_catpv_mg Perl_sv_catpv_mg #define sv_catpvf Perl_sv_catpvf +#define sv_catpvf_mg Perl_sv_catpvf_mg #define sv_catpvn Perl_sv_catpvn +#define sv_catpvn_mg Perl_sv_catpvn_mg #define sv_catsv Perl_sv_catsv +#define sv_catsv_mg Perl_sv_catsv_mg #define sv_chop Perl_sv_chop #define sv_clean_all Perl_sv_clean_all #define sv_clean_objs Perl_sv_clean_objs @@ -966,18 +971,26 @@ #define sv_report_used Perl_sv_report_used #define sv_reset Perl_sv_reset #define sv_setiv Perl_sv_setiv +#define sv_setiv_mg Perl_sv_setiv_mg #define sv_setnv Perl_sv_setnv +#define sv_setnv_mg Perl_sv_setnv_mg #define sv_setptrobj Perl_sv_setptrobj #define sv_setpv Perl_sv_setpv +#define sv_setpv_mg Perl_sv_setpv_mg #define sv_setpvf Perl_sv_setpvf +#define sv_setpvf_mg Perl_sv_setpvf_mg #define sv_setpviv Perl_sv_setpviv +#define sv_setpviv_mg Perl_sv_setpviv_mg #define sv_setpvn Perl_sv_setpvn +#define sv_setpvn_mg Perl_sv_setpvn_mg #define sv_setref_iv Perl_sv_setref_iv #define sv_setref_nv Perl_sv_setref_nv #define sv_setref_pv Perl_sv_setref_pv #define sv_setref_pvn Perl_sv_setref_pvn #define sv_setsv Perl_sv_setsv +#define sv_setsv_mg Perl_sv_setsv_mg #define sv_setuv Perl_sv_setuv +#define sv_setuv_mg Perl_sv_setuv_mg #define sv_taint Perl_sv_taint #define sv_tainted Perl_sv_tainted #define sv_true Perl_sv_true @@ -986,6 +999,7 @@ #define sv_untaint Perl_sv_untaint #define sv_upgrade Perl_sv_upgrade #define sv_usepvn Perl_sv_usepvn +#define sv_usepvn_mg Perl_sv_usepvn_mg #define sv_uv Perl_sv_uv #define sv_vcatpvfn Perl_sv_vcatpvfn #define sv_vsetpvfn Perl_sv_vsetpvfn diff --git a/ext/GDBM_File/typemap b/ext/GDBM_File/typemap index 73ad370..a9b73d8 100644 --- a/ext/GDBM_File/typemap +++ b/ext/GDBM_File/typemap @@ -20,8 +20,8 @@ T_GDATUM UNIMPLEMENTED OUTPUT T_DATUM - SvSetMagicPVN($arg, $var.dptr, $var.dsize); + sv_setpvn($arg, $var.dptr, $var.dsize); T_GDATUM - SvUseMagicPVN($arg, $var.dptr, $var.dsize); + sv_usepvn($arg, $var.dptr, $var.dsize); T_PTROBJ sv_setref_pv($arg, dbtype, (void*)$var); diff --git a/ext/NDBM_File/typemap b/ext/NDBM_File/typemap index 73ad370..a9b73d8 100644 --- a/ext/NDBM_File/typemap +++ b/ext/NDBM_File/typemap @@ -20,8 +20,8 @@ T_GDATUM UNIMPLEMENTED OUTPUT T_DATUM - SvSetMagicPVN($arg, $var.dptr, $var.dsize); + sv_setpvn($arg, $var.dptr, $var.dsize); T_GDATUM - SvUseMagicPVN($arg, $var.dptr, $var.dsize); + sv_usepvn($arg, $var.dptr, $var.dsize); T_PTROBJ sv_setref_pv($arg, dbtype, (void*)$var); diff --git a/ext/ODBM_File/typemap b/ext/ODBM_File/typemap index c2c3e3e..a6b0e5f 100644 --- a/ext/ODBM_File/typemap +++ b/ext/ODBM_File/typemap @@ -20,6 +20,6 @@ T_GDATUM UNIMPLEMENTED OUTPUT T_DATUM - SvSetMagicPVN($arg, $var.dptr, $var.dsize); + sv_setpvn($arg, $var.dptr, $var.dsize); T_GDATUM - SvUseMagicPVN($arg, $var.dptr, $var.dsize); + sv_usepvn($arg, $var.dptr, $var.dsize); diff --git a/ext/SDBM_File/typemap b/ext/SDBM_File/typemap index 73ad370..a9b73d8 100644 --- a/ext/SDBM_File/typemap +++ b/ext/SDBM_File/typemap @@ -20,8 +20,8 @@ T_GDATUM UNIMPLEMENTED OUTPUT T_DATUM - SvSetMagicPVN($arg, $var.dptr, $var.dsize); + sv_setpvn($arg, $var.dptr, $var.dsize); T_GDATUM - SvUseMagicPVN($arg, $var.dptr, $var.dsize); + sv_usepvn($arg, $var.dptr, $var.dsize); T_PTROBJ sv_setref_pv($arg, dbtype, (void*)$var); diff --git a/global.sym b/global.sym index 27fe565..afbc7c9 100644 --- a/global.sym +++ b/global.sym @@ -971,9 +971,13 @@ sv_add_arena sv_backoff sv_bless sv_catpvf +sv_catpvf_mg sv_catpv +sv_catpv_mg sv_catpvn +sv_catpvn_mg sv_catsv +sv_catsv_mg sv_chop sv_clean_all sv_clean_objs @@ -1008,18 +1012,26 @@ sv_replace sv_report_used sv_reset sv_setpvf +sv_setpvf_mg sv_setiv +sv_setiv_mg sv_setnv +sv_setnv_mg sv_setptrobj sv_setpv +sv_setpv_mg sv_setpviv +sv_setpviv_mg sv_setpvn +sv_setpvn_mg sv_setref_iv sv_setref_nv sv_setref_pv sv_setref_pvn sv_setsv +sv_setsv_mg sv_setuv +sv_setuv_mg sv_taint sv_tainted sv_unmagic @@ -1027,6 +1039,7 @@ sv_unref sv_untaint sv_upgrade sv_usepvn +sv_usepvn_mg sv_vcatpvfn sv_vsetpvfn taint_env diff --git a/lib/ExtUtils/typemap b/lib/ExtUtils/typemap index 430c28a..20cc96f 100644 --- a/lib/ExtUtils/typemap +++ b/lib/ExtUtils/typemap @@ -190,44 +190,44 @@ T_HVREF T_CVREF $arg = newRV((SV*)$var); T_IV - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_INT - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_SYSRET if ($var != -1) { if ($var == 0) - SvSetMagicPVN($arg, "0 but true", 10); + sv_setpvn($arg, "0 but true", 10); else - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); } T_ENUM - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_BOOL $arg = boolSV($var); T_U_INT - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_SHORT - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_U_SHORT - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_LONG - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_U_LONG - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_CHAR - SvSetMagicPVN($arg, (char *)&$var, 1); + sv_setpvn($arg, (char *)&$var, 1); T_U_CHAR - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_FLOAT - SvSetMagicNV($arg, (double)$var); + sv_setnv($arg, (double)$var); T_NV - SvSetMagicNV($arg, (double)$var); + sv_setnv($arg, (double)$var); T_DOUBLE - SvSetMagicNV($arg, (double)$var); + sv_setnv($arg, (double)$var); T_PV - SvSetMagicPV((SV*)$arg, $var); + sv_setpv((SV*)$arg, $var); T_PTR - SvSetMagicIV($arg, (IV)$var); + sv_setiv($arg, (IV)$var); T_PTRREF sv_setref_pv($arg, Nullch, (void*)$var); T_REF_IV_REF @@ -244,17 +244,17 @@ T_REFREF T_REFOBJ NOT IMPLEMENTED T_OPAQUE - SvSetMagicPVN($arg, (char *)&$var, sizeof($var)); + sv_setpvn($arg, (char *)&$var, sizeof($var)); T_OPAQUEPTR - SvSetMagicPVN($arg, (char *)$var, sizeof(*$var)), XFree((char *)$var); + sv_setpvn($arg, (char *)$var, sizeof(*$var)), XFree((char *)$var); T_PACKED XS_pack_$ntype($arg, $var); T_PACKEDARRAY XS_pack_$ntype($arg, $var, count_$ntype); T_DATAUNIT - SvSetMagicPVN($arg, $var.chp(), $var.size()); + sv_setpvn($arg, $var.chp(), $var.size()); T_CALLBACK - SvSetMagicPVN($arg, $var.context.value().chp(), + sv_setpvn($arg, $var.context.value().chp(), $var.context.value().size()); T_ARRAY ST_EXTEND($var.size); @@ -267,7 +267,7 @@ T_IN { GV *gv = newGVgen("$Package"); if ( do_open(gv, "<&", 2, FALSE, 0, 0, $var) ) - SvSetMagicSV($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1))); + sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1))); else $arg = &sv_undef; } @@ -275,7 +275,7 @@ T_INOUT { GV *gv = newGVgen("$Package"); if ( do_open(gv, "+<&", 3, FALSE, 0, 0, $var) ) - SvSetMagicSV($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1))); + sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1))); else $arg = &sv_undef; } @@ -283,7 +283,7 @@ T_OUT { GV *gv = newGVgen("$Package"); if ( do_open(gv, "+>&", 3, FALSE, 0, 0, $var) ) - SvSetMagicSV($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1))); + sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1))); else $arg = &sv_undef; } diff --git a/lib/ExtUtils/xsubpp b/lib/ExtUtils/xsubpp index 04de166..6fe16dc 100755 --- a/lib/ExtUtils/xsubpp +++ b/lib/ExtUtils/xsubpp @@ -87,7 +87,7 @@ sub Q ; # Global Constants -$XSUBPP_version = "1.9505"; +$XSUBPP_version = "1.9506"; my ($Is_VMS, $SymSet); if ($^O eq 'VMS') { @@ -371,6 +371,10 @@ sub INPUT_handler { sub OUTPUT_handler { for (; !/^$BLOCK_re/o; $_ = shift(@line)) { next unless /\S/; + if (/^\s*SETMAGIC\s*:\s*(ENABLE|DISABLE)\s*/) { + $DoSetMagic = ($1 eq "ENABLE" ? 1 : 0); + next; + } my ($outarg, $outcode) = /^\s*(\S+)\s*(.*?)\s*$/s ; blurt ("Error: duplicate OUTPUT argument '$outarg' ignored"), next if $outargs{$outarg} ++ ; @@ -386,9 +390,10 @@ sub OUTPUT_handler { unless defined $var_types{$outarg} ; if ($outcode) { print "\t$outcode\n"; + print "\tSvSETMAGIC(ST(" . $var_num-1 . "));\n" if $DoSetMagic; } else { $var_num = $args_match{$outarg}; - &generate_output($var_types{$outarg}, $var_num, $outarg); + &generate_output($var_types{$outarg}, $var_num, $outarg, $DoSetMagic); } } } @@ -875,6 +880,7 @@ while (fetch_para()) { } $XSStack[$XSS_work_idx]{functions}{$Full_func_name} ++ ; %XsubAliases = %XsubAliasValues = (); + $DoSetMagic = 1; @args = split(/\s*,\s*/, $orig_args); if (defined($class)) { @@ -1059,7 +1065,8 @@ EOF if ($gotRETVAL && $RETVAL_code) { print "\t$RETVAL_code\n"; } elsif ($gotRETVAL || $wantRETVAL) { - &generate_output($ret_type, 0, 'RETVAL'); + # RETVAL almost never needs SvSETMAGIC() + &generate_output($ret_type, 0, 'RETVAL', 0); } # do cleanup @@ -1283,7 +1290,7 @@ sub generate_init { } sub generate_output { - local($type, $num, $var) = @_; + local($type, $num, $var, $do_setmagic) = @_; local($arg) = "ST(" . ($num - ($num != 0)) . ")"; local($argoff) = $num - 1; local($ntype); @@ -1291,6 +1298,7 @@ sub generate_output { $type = TidyType($type) ; if ($type =~ /^array\(([^,]*),(.*)\)/) { print "\tsv_setpvn($arg, (char *)$var, $2 * sizeof($1)), XFree((char *)$var);\n"; + print "\tSvSETMAGIC($arg);\n" if $do_setmagic; } else { blurt("Error: '$type' not in typemap"), return unless defined($type_kind{$type}); @@ -1312,6 +1320,7 @@ sub generate_output { $subexpr =~ s/\n\t/\n\t\t/g; $expr =~ s/DO_ARRAY_ELEM\n/$subexpr/; eval "print qq\a$expr\a"; + print "\t\tSvSETMAGIC(ST(ix_$var));\n" if $do_setmagic; } elsif ($var eq 'RETVAL') { if ($expr =~ /^\t\$arg = new/) { @@ -1319,6 +1328,7 @@ sub generate_output { # mortalize it. eval "print qq\a$expr\a"; print "\tsv_2mortal(ST(0));\n"; + print "\tSvSETMAGIC(ST(0));\n" if $do_setmagic; } elsif ($expr =~ /^\s*\$arg\s*=/) { # We expect that $arg has refcnt >=1, so we need @@ -1329,6 +1339,7 @@ sub generate_output { # ignored by REFCNT_dec. Builtin values have REFCNT==0. eval "print qq\a$expr\a"; print "\tif (SvREFCNT(ST(0))) sv_2mortal(ST(0));\n"; + print "\tSvSETMAGIC(ST(0));\n" if $do_setmagic; } else { # Just hope that the entry would safely write it @@ -1337,10 +1348,12 @@ sub generate_output { # works too. print "\tST(0) = sv_newmortal();\n"; eval "print qq\a$expr\a"; + # new mortals don't have set magic } } elsif ($arg =~ /^ST\(\d+\)$/) { eval "print qq\a$expr\a"; + print "\tSvSETMAGIC($arg);\n" if $do_setmagic; } } } diff --git a/os2/OS2/PrfDB/typemap b/os2/OS2/PrfDB/typemap index 1e01470..0b91f37 100644 --- a/os2/OS2/PrfDB/typemap +++ b/os2/OS2/PrfDB/typemap @@ -11,4 +11,4 @@ T_PVNULL ############################################################################# OUTPUT T_PVNULL - SvSetMagicPV((SV*)$arg, $var); + sv_setpv((SV*)$arg, $var); diff --git a/pod/perlguts.pod b/pod/perlguts.pod index 7a09d0d..111baf0 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -837,13 +837,14 @@ as the extension is sufficient. For '~' magic, it may also be appropriate to add an I32 'signature' at the top of the private data area and check that. -Also note that most of the C functions that modify scalars do -B invoke 'set' magic on their targets. This must be done by the user -either by calling the C macro after calling these functions, -or by using one of the C macros. Similarly, generic C code -must call the C macro to invoke any 'get' magic if they use -an SV obtained from external sources in functions that don't handle magic. -L later in this document identifies such macros and functions. +Also note that the C and C functions described +earlier do B invoke 'set' magic on their targets. This must +be done by the user either by calling the C macro after +calling these functions, or by using one of the C or +C functions. Similarly, generic C code must call the +C macro to invoke any 'get' magic if they use an SV +obtained from external sources in functions that don't handle magic. +L later in this document identifies such functions. For example, calls to the C functions typically need to be followed by C, but they don't need a prior C since their implementation handles 'get' magic. @@ -1428,14 +1429,14 @@ Same as C. Clears an array, making it empty. Does not free the memory used by the array itself. - void av_clear _((AV* ar)); + void av_clear (AV* ar) =item av_extend Pre-extend an array. The C is the index to which the array should be extended. - void av_extend _((AV* ar, I32 key)); + void av_extend (AV* ar, I32 key) =item av_fetch @@ -1446,13 +1447,13 @@ that the return value is non-null before dereferencing it to a C. See L for more information on how to use this function on tied arrays. - SV** av_fetch _((AV* ar, I32 key, I32 lval)); + SV** av_fetch (AV* ar, I32 key, I32 lval) =item av_len Returns the highest index in the array. Returns -1 if the array is empty. - I32 av_len _((AV* ar)); + I32 av_len (AV* ar) =item av_make @@ -1460,27 +1461,27 @@ Creates a new AV and populates it with a list of SVs. The SVs are copied into the array, so they may be freed after the call to av_make. The new AV will have a reference count of 1. - AV* av_make _((I32 size, SV** svp)); + AV* av_make (I32 size, SV** svp) =item av_pop Pops an SV off the end of the array. Returns C<&sv_undef> if the array is empty. - SV* av_pop _((AV* ar)); + SV* av_pop (AV* ar) =item av_push Pushes an SV onto the end of the array. The array will grow automatically to accommodate the addition. - void av_push _((AV* ar, SV* val)); + void av_push (AV* ar, SV* val) =item av_shift Shifts an SV off the beginning of the array. - SV* av_shift _((AV* ar)); + SV* av_shift (AV* ar) =item av_store @@ -1494,13 +1495,13 @@ before the call, and decrementing it if the function returned NULL. See L for more information on how to use this function on tied arrays. - SV** av_store _((AV* ar, I32 key, SV* val)); + SV** av_store (AV* ar, I32 key, SV* val) =item av_undef Undefines the array. Frees the memory used by the array itself. - void av_undef _((AV* ar)); + void av_undef (AV* ar) =item av_unshift @@ -1508,7 +1509,7 @@ Unshift the given number of C values onto the beginning of the array. The array will grow automatically to accommodate the addition. You must then use C to assign values to these new elements. - void av_unshift _((AV* ar, I32 num)); + void av_unshift (AV* ar, I32 num) =item CLASS @@ -1522,7 +1523,7 @@ The XSUB-writer's interface to the C C function. The C is the source, C is the destination, C is the number of items, and C is the type. May fail on overlapping copies. See also C. - (void) Copy( s, d, n, t ); + (void) Copy( s, d, n, t ) =item croak @@ -1595,7 +1596,7 @@ Opening bracket on a callback. See C and L. Used to extend the argument stack for an XSUB's return values. - EXTEND( sp, int x ); + EXTEND( sp, int x ) =item FREETMPS @@ -1659,7 +1660,7 @@ which is not visible to Perl code. So when calling C, you should not use the GV directly; instead, you should use the method's CV, which can be obtained from the GV with the C macro. - GV* gv_fetchmeth _((HV* stash, char* name, STRLEN len, I32 level)); + GV* gv_fetchmeth (HV* stash, char* name, STRLEN len, I32 level) =item gv_fetchmethod @@ -1688,9 +1689,8 @@ C. C should be writable if contains C<':'> or C<'\''>. The warning against passing the GV returned by C to C apply equally to these functions. - GV* gv_fetchmethod _((HV* stash, char* name)); - GV* gv_fetchmethod_autoload _((HV* stash, char* name, - I32 autoload)); + GV* gv_fetchmethod (HV* stash, char* name) + GV* gv_fetchmethod_autoload (HV* stash, char* name, I32 autoload) =item gv_stashpv @@ -1698,13 +1698,13 @@ Returns a pointer to the stash for a specified package. If C is set then the package will be created if it does not already exist. If C is not set and the package does not exist then NULL is returned. - HV* gv_stashpv _((char* name, I32 create)); + HV* gv_stashpv (char* name, I32 create) =item gv_stashsv Returns a pointer to the stash for a specified package. See C. - HV* gv_stashsv _((SV* sv, I32 create)); + HV* gv_stashsv (SV* sv, I32 create) =item GvSV @@ -1785,7 +1785,7 @@ Returns the value slot (type C) stored in the hash entry. Clears a hash, making it empty. - void hv_clear _((HV* tb)); + void hv_clear (HV* tb) =item hv_delayfree_ent @@ -1794,7 +1794,7 @@ delays actual freeing of key and value until the end of the current statement (or thereabouts) with C. See C and C. - void hv_delayfree_ent _((HV* hv, HE* entry)); + void hv_delayfree_ent (HV* hv, HE* entry) =item hv_delete @@ -1803,7 +1803,7 @@ and returned to the caller. The C is the length of the key. The C value will normally be zero; if set to G_DISCARD then NULL will be returned. - SV* hv_delete _((HV* tb, char* key, U32 klen, I32 flags)); + SV* hv_delete (HV* tb, char* key, U32 klen, I32 flags) =item hv_delete_ent @@ -1812,21 +1812,21 @@ and returned to the caller. The C value will normally be zero; if set to G_DISCARD then NULL will be returned. C can be a valid precomputed hash value, or 0 to ask for it to be computed. - SV* hv_delete_ent _((HV* tb, SV* key, I32 flags, U32 hash)); + SV* hv_delete_ent (HV* tb, SV* key, I32 flags, U32 hash) =item hv_exists Returns a boolean indicating whether the specified hash key exists. The C is the length of the key. - bool hv_exists _((HV* tb, char* key, U32 klen)); + bool hv_exists (HV* tb, char* key, U32 klen) =item hv_exists_ent Returns a boolean indicating whether the specified hash key exists. C can be a valid precomputed hash value, or 0 to ask for it to be computed. - bool hv_exists_ent _((HV* tb, SV* key, U32 hash)); + bool hv_exists_ent (HV* tb, SV* key, U32 hash) =item hv_fetch @@ -1838,7 +1838,7 @@ dereferencing it to a C. See L for more information on how to use this function on tied hashes. - SV** hv_fetch _((HV* tb, char* key, U32 klen, I32 lval)); + SV** hv_fetch (HV* tb, char* key, U32 klen, I32 lval) =item hv_fetch_ent @@ -1853,20 +1853,20 @@ structure if you need to store it somewhere. See L for more information on how to use this function on tied hashes. - HE* hv_fetch_ent _((HV* tb, SV* key, I32 lval, U32 hash)); + HE* hv_fetch_ent (HV* tb, SV* key, I32 lval, U32 hash) =item hv_free_ent Releases a hash entry, such as while iterating though the hash. See C and C. - void hv_free_ent _((HV* hv, HE* entry)); + void hv_free_ent (HV* hv, HE* entry) =item hv_iterinit Prepares a starting point to traverse a hash table. - I32 hv_iterinit _((HV* tb)); + I32 hv_iterinit (HV* tb) Note that hv_iterinit I returns the number of I in the hash and I the number of keys (as indicated in the Advanced @@ -1878,7 +1878,7 @@ macro to find the number of keys in a hash. Returns the key from the current position of the hash iterator. See C. - char* hv_iterkey _((HE* entry, I32* retlen)); + char* hv_iterkey (HE* entry, I32* retlen) =item hv_iterkeysv @@ -1886,33 +1886,33 @@ Returns the key as an C from the current position of the hash iterator. The return value will always be a mortal copy of the key. Also see C. - SV* hv_iterkeysv _((HE* entry)); + SV* hv_iterkeysv (HE* entry) =item hv_iternext Returns entries from a hash iterator. See C. - HE* hv_iternext _((HV* tb)); + HE* hv_iternext (HV* tb) =item hv_iternextsv Performs an C, C, and C in one operation. - SV * hv_iternextsv _((HV* hv, char** key, I32* retlen)); + SV * hv_iternextsv (HV* hv, char** key, I32* retlen) =item hv_iterval Returns the value from the current position of the hash iterator. See C. - SV* hv_iterval _((HV* tb, HE* entry)); + SV* hv_iterval (HV* tb, HE* entry) =item hv_magic Adds magic to a hash. See C. - void hv_magic _((HV* hv, GV* gv, int how)); + void hv_magic (HV* hv, GV* gv, int how) =item HvNAME @@ -1934,7 +1934,7 @@ before the call, and decrementing it if the function returned NULL. See L for more information on how to use this function on tied hashes. - SV** hv_store _((HV* tb, char* key, U32 klen, SV* val, U32 hash)); + SV** hv_store (HV* tb, char* key, U32 klen, SV* val, U32 hash) =item hv_store_ent @@ -1951,13 +1951,13 @@ it if the function returned NULL. See L for more information on how to use this function on tied hashes. - HE* hv_store_ent _((HV* tb, SV* key, SV* val, U32 hash)); + HE* hv_store_ent (HV* tb, SV* key, SV* val, U32 hash) =item hv_undef Undefines the hash. - void hv_undef _((HV* tb)); + void hv_undef (HV* tb) =item isALNUM @@ -2021,49 +2021,49 @@ Stack marker variable for the XSUB. See C. Clear something magical that the SV represents. See C. - int mg_clear _((SV* sv)); + int mg_clear (SV* sv) =item mg_copy Copies the magic from one SV to another. See C. - int mg_copy _((SV *, SV *, char *, STRLEN)); + int mg_copy (SV *, SV *, char *, STRLEN) =item mg_find Finds the magic pointer for type matching the SV. See C. - MAGIC* mg_find _((SV* sv, int type)); + MAGIC* mg_find (SV* sv, int type) =item mg_free Free any magic storage used by the SV. See C. - int mg_free _((SV* sv)); + int mg_free (SV* sv) =item mg_get Do magic after a value is retrieved from the SV. See C. - int mg_get _((SV* sv)); + int mg_get (SV* sv) =item mg_len Report on the SV's length. See C. - U32 mg_len _((SV* sv)); + U32 mg_len (SV* sv) =item mg_magical Turns on the magical status of an SV. See C. - void mg_magical _((SV* sv)); + void mg_magical (SV* sv) =item mg_set Do magic after a value is assigned to the SV. See C. - int mg_set _((SV* sv)); + int mg_set (SV* sv) =item Move @@ -2071,7 +2071,7 @@ The XSUB-writer's interface to the C C function. The C is the source, C is the destination, C is the number of items, and C is the type. Can do overlapping moves. See also C. - (void) Move( s, d, n, t ); + (void) Move( s, d, n, t ) =item na @@ -2101,20 +2101,20 @@ memory is zeroed with C. Creates a new AV. The reference count is set to 1. - AV* newAV _((void)); + AV* newAV (void) =item newHV Creates a new HV. The reference count is set to 1. - HV* newHV _((void)); + HV* newHV (void) =item newRV_inc Creates an RV wrapper for an SV. The reference count for the original SV is incremented. - SV* newRV_inc _((SV* ref)); + SV* newRV_inc (SV* ref) For historical reasons, "newRV" is a synonym for "newRV_inc". @@ -2123,7 +2123,7 @@ For historical reasons, "newRV" is a synonym for "newRV_inc". Creates an RV wrapper for an SV. The reference count for the original SV is B incremented. - SV* newRV_noinc _((SV* ref)); + SV* newRV_noinc (SV* ref) =item NEWSV @@ -2132,28 +2132,28 @@ preallocated string space the SV should have. The reference count for the new SV is set to 1. C is an integer id between 0 and 1299 (used to identify leaks). - SV* NEWSV _((int id, STRLEN len)); + SV* NEWSV (int id, STRLEN len) =item newSViv Creates a new SV and copies an integer into it. The reference count for the SV is set to 1. - SV* newSViv _((IV i)); + SV* newSViv (IV i) =item newSVnv Creates a new SV and copies a double into it. The reference count for the SV is set to 1. - SV* newSVnv _((NV i)); + SV* newSVnv (NV i) =item newSVpv Creates a new SV and copies a string into it. The reference count for the SV is set to 1. If C is zero then Perl will compute the length. - SV* newSVpv _((char* s, STRLEN len)); + SV* newSVpv (char* s, STRLEN len) =item newSVpvn @@ -2161,7 +2161,7 @@ Creates a new SV and copies a string into it. The reference count for the SV is set to 1. If C is zero then Perl will create a zero length string. - SV* newSVpvn _((char* s, STRLEN len)); + SV* newSVpvn (char* s, STRLEN len) =item newSVrv @@ -2170,13 +2170,13 @@ it will be upgraded to one. If C is non-null then the new SV will be blessed in the specified package. The new SV is returned and its reference count is 1. - SV* newSVrv _((SV* rv, char* classname)); + SV* newSVrv (SV* rv, char* classname) =item newSVsv Creates a new SV which is an exact duplicate of the original SV. - SV* newSVsv _((SV* old)); + SV* newSVsv (SV* old) =item newXS @@ -2219,27 +2219,27 @@ Allocates a new Perl interpreter. See L. Performs a callback to the specified Perl sub. See L. - I32 perl_call_argv _((char* subname, I32 flags, char** argv)); + I32 perl_call_argv (char* subname, I32 flags, char** argv) =item perl_call_method Performs a callback to the specified Perl method. The blessed object must be on the stack. See L. - I32 perl_call_method _((char* methname, I32 flags)); + I32 perl_call_method (char* methname, I32 flags) =item perl_call_pv Performs a callback to the specified Perl sub. See L. - I32 perl_call_pv _((char* subname, I32 flags)); + I32 perl_call_pv (char* subname, I32 flags) =item perl_call_sv Performs a callback to the Perl sub whose name is in the SV. See L. - I32 perl_call_sv _((SV* sv, I32 flags)); + I32 perl_call_sv (SV* sv, I32 flags) =item perl_construct @@ -2253,13 +2253,13 @@ Shuts down a Perl interpreter. See L. Tells Perl to C the string in the SV. - I32 perl_eval_sv _((SV* sv, I32 flags)); + I32 perl_eval_sv (SV* sv, I32 flags) =item perl_eval_pv Tells Perl to C the given string and return an SV* result. - SV* perl_eval_pv _((char* p, I32 croak_on_error)); + SV* perl_eval_pv (char* p, I32 croak_on_error) =item perl_free @@ -2271,7 +2271,7 @@ Returns the AV of the specified Perl array. If C is set and the Perl variable does not exist then it will be created. If C is not set and the variable does not exist then NULL is returned. - AV* perl_get_av _((char* name, I32 create)); + AV* perl_get_av (char* name, I32 create) =item perl_get_cv @@ -2279,7 +2279,7 @@ Returns the CV of the specified Perl sub. If C is set and the Perl variable does not exist then it will be created. If C is not set and the variable does not exist then NULL is returned. - CV* perl_get_cv _((char* name, I32 create)); + CV* perl_get_cv (char* name, I32 create) =item perl_get_hv @@ -2287,7 +2287,7 @@ Returns the HV of the specified Perl hash. If C is set and the Perl variable does not exist then it will be created. If C is not set and the variable does not exist then NULL is returned. - HV* perl_get_hv _((char* name, I32 create)); + HV* perl_get_hv (char* name, I32 create) =item perl_get_sv @@ -2295,7 +2295,7 @@ Returns the SV of the specified Perl scalar. If C is set and the Perl variable does not exist then it will be created. If C is not set and the variable does not exist then NULL is returned. - SV* perl_get_sv _((char* name, I32 create)); + SV* perl_get_sv (char* name, I32 create) =item perl_parse @@ -2305,7 +2305,7 @@ Tells a Perl interpreter to parse a Perl script. See L. Tells Perl to C a module. - void perl_require_pv _((char* pv)); + void perl_require_pv (char* pv) =item perl_run @@ -2315,31 +2315,31 @@ Tells a Perl interpreter to run. See L. Pops an integer off the stack. - int POPi(); + int POPi() =item POPl Pops a long off the stack. - long POPl(); + long POPl() =item POPp Pops a string off the stack. - char * POPp(); + char * POPp() =item POPn Pops a double off the stack. - double POPn(); + double POPn() =item POPs Pops an SV off the stack. - SV* POPs(); + SV* POPs() =item PUSHMARK @@ -2417,14 +2417,14 @@ The XSUB-writer's interface to the C C function. Copy a string to a safe spot. This does not use an SV. - char* savepv _((char* sv)); + char* savepv (char* sv) =item savepvn Copy a string to a safe spot. The C indicates number of bytes to copy. This does not use an SV. - char* savepvn _((char* sv, I32 len)); + char* savepvn (char* sv, I32 len) =item SAVETMPS @@ -2509,7 +2509,7 @@ indicates the number of bytes to compare. Returns true or false. Marks an SV as mortal. The SV will be destroyed when the current context ends. - SV* sv_2mortal _((SV* sv)); + SV* sv_2mortal (SV* sv) =item sv_bless @@ -2517,28 +2517,34 @@ Blesses an SV into a specified package. The SV must be an RV. The package must be designated by its stash (see C). The reference count of the SV is unaffected. - SV* sv_bless _((SV* sv, HV* stash)); + SV* sv_bless (SV* sv, HV* stash) -=item SvCatMagicPV +=item sv_catpv -=item SvCatMagicPVN +Concatenates the string onto the end of the string which is in the SV. +Handles 'get' magic, but not 'set' magic. See C. -=item SvCatMagicSV + void sv_catpv (SV* sv, char* ptr) -=item sv_catpv +=item sv_catpv_mg -Concatenates the string onto the end of the string which is in the SV. -Handles 'get' magic, but not 'set' magic. See C. +Like C, but also handles 'set' magic. - void sv_catpv _((SV* sv, char* ptr)); + void sv_catpvn (SV* sv, char* ptr) =item sv_catpvn Concatenates the string onto the end of the string which is in the SV. The C indicates number of bytes to copy. Handles 'get' magic, but not -'set' magic. See C. - void sv_catpvn _((SV* sv, char* ptr, STRLEN len)); + void sv_catpvn (SV* sv, char* ptr, STRLEN len) + +=item sv_catpvn_mg + +Like C, but also handles 'set' magic. + + void sv_catpvn_mg (SV* sv, char* ptr, STRLEN len) =item sv_catpvf @@ -2546,14 +2552,26 @@ Processes its arguments like C and appends the formatted output to an SV. Handles 'get' magic, but not 'set' magic. C must typically be called after calling this function to handle 'set' magic. - void sv_catpvf _((SV* sv, const char* pat, ...)); + void sv_catpvf (SV* sv, const char* pat, ...) + +=item sv_catpvf_mg + +Like C, but also handles 'set' magic. + + void sv_catpvf_mg (SV* sv, const char* pat, ...) =item sv_catsv Concatenates the string from SV C onto the end of the string in SV -C. Handles 'get' magic, but not 'set' magic. See C. Handles 'get' magic, but not 'set' magic. See C. + + void sv_catsv (SV* dsv, SV* ssv) + +=item sv_catsv_mg - void sv_catsv _((SV* dsv, SV* ssv)); +Like C, but also handles 'set' magic. + + void sv_catsv_mg (SV* dsv, SV* ssv) =item sv_cmp @@ -2561,7 +2579,7 @@ Compares the strings in two SVs. Returns -1, 0, or 1 indicating whether the string in C is less than, equal to, or greater than the string in C. - I32 sv_cmp _((SV* sv1, SV* sv2)); + I32 sv_cmp (SV* sv1, SV* sv2) =item SvCUR @@ -2579,7 +2597,7 @@ Set the length of the string which is in the SV. See C. Auto-decrement of the value in the SV. - void sv_dec _((SV* sv)); + void sv_dec (SV* sv) =item SvEND @@ -2593,7 +2611,7 @@ See C. Access the character as Returns a boolean indicating whether the strings in the two SVs are identical. - I32 sv_eq _((SV* sv1, SV* sv2)); + I32 sv_eq (SV* sv1, SV* sv2) =item SvGETMAGIC @@ -2619,7 +2637,7 @@ Use C. Auto-increment of the value in the SV. - void sv_inc _((SV* sv)); + void sv_inc (SV* sv) =item SvIOK @@ -2658,7 +2676,7 @@ Returns a boolean indicating whether the SV is blessed into the specified class. This does not know how to check for subtype, so it doesn't work in an inheritance relationship. - int sv_isa _((SV* sv, char* name)); + int sv_isa (SV* sv, char* name) =item SvIV @@ -2672,13 +2690,13 @@ Returns a boolean indicating whether the SV is an RV pointing to a blessed object. If the SV is not an RV, or if the object is not blessed, then this will return false. - int sv_isobject _((SV* sv)); + int sv_isobject (SV* sv) =item SvIVX Returns the integer which is stored in the SV. - int SvIVX (SV* sv); + int SvIVX (SV* sv) =item SvLEN @@ -2690,20 +2708,20 @@ Returns the size of the string buffer in the SV. See C. Returns the length of the string in the SV. Use C. - STRLEN sv_len _((SV* sv)); + STRLEN sv_len (SV* sv) =item sv_magic Adds magic to an SV. - void sv_magic _((SV* sv, SV* obj, int how, char* name, I32 namlen)); + void sv_magic (SV* sv, SV* obj, int how, char* name, I32 namlen) =item sv_mortalcopy Creates a new SV which is a copy of the original SV. The new SV is marked as mortal. - SV* sv_mortalcopy _((SV* oldsv)); + SV* sv_mortalcopy (SV* oldsv) =item SvOK @@ -2715,7 +2733,7 @@ Returns a boolean indicating whether the value is an SV. Creates a new SV which is mortal. The reference count of the SV is set to 1. - SV* sv_newmortal _((void)); + SV* sv_newmortal (void) =item sv_no @@ -2776,13 +2794,13 @@ B setting. Use C. Returns the double which is stored in the SV. - double SvNV (SV* sv); + double SvNV (SV* sv) =item SvNVX Returns the double which is stored in the SV. - double SvNVX (SV* sv); + double SvNVX (SV* sv) =item SvPOK @@ -2833,7 +2851,7 @@ Returns a pointer to the string in the SV. The SV must contain a string. Returns the value of the object's reference count. - int SvREFCNT (SV* sv); + int SvREFCNT (SV* sv) =item SvREFCNT_dec @@ -2869,7 +2887,7 @@ Tells an SV that it is an RV. Dereferences an RV to return the SV. - SV* SvRV (SV* sv); + SV* SvRV (SV* sv) =item SvSETMAGIC @@ -2882,13 +2900,13 @@ its argument more than once. Taints an SV if tainting is enabled - SvTAINT (SV* sv); + SvTAINT (SV* sv) =item SvTAINTED Checks to see if an SV is tainted. Returns TRUE if it is, FALSE if not. - SvTAINTED (SV* sv); + SvTAINTED (SV* sv) =item SvTAINTED_off @@ -2899,112 +2917,91 @@ of unconditionally untainting the value. Untainting should be done in the standard perl fashion, via a carefully crafted regexp, rather than directly untainting variables. - SvTAINTED_off (SV* sv); + SvTAINTED_off (SV* sv) =item SvTAINTED_on Marks an SV as tainted. - SvTAINTED_on (SV* sv); - -=item SvSetMagicIV - -A macro that calls C, and invokes 'set' magic on the SV. -May evaluate arguments more than once. + SvTAINTED_on (SV* sv) - void SvSetMagicIV (SV* sv, IV num) - -=item SvSetMagicNV - -A macro that calls C, and invokes 'set' magic on the SV. -May evaluate arguments more than once. - - void SvSetMagicNV (SV* sv, double num) +=item sv_setiv -=item SvSetMagicPV +Copies an integer into the given SV. Does not handle 'set' magic. +See C. -A macro that calls C, and invokes 'set' magic on the SV. -May evaluate arguments more than once. + void sv_setiv (SV* sv, IV num) - void SvSetMagicPV (SV* sv, char *ptr) +=item sv_setiv_mg -=item SvSetMagicPVIV +Like C, but also handles 'set' magic. -A macro that calls C, and invokes 'set' magic on the SV. -May evaluate arguments more than once. + void sv_setiv_mg (SV* sv, IV num) - void SvSetMagicPVIV (SV* sv, IV num) +=item sv_setnv -=item SvSetMagicPVN +Copies a double into the given SV. Does not handle 'set' magic. +See C. -A macro that calls C, and invokes 'set' magic on the SV. -May evaluate arguments more than once. + void sv_setnv (SV* sv, double num) - void SvSetMagicPVN (SV* sv, char* ptr, STRLEN len) +=item sv_setnv_mg -=item SvSetMagicSV +Like C, but also handles 'set' magic. -Same as C, but also invokes 'set' magic on the SV. -May evaluate arguments more than once. + void sv_setnv_mg (SV* sv, double num) - void SvSetMagicSV (SV* dsv, SV* ssv) - -=item SvSetMagicSV_nosteal +=item sv_setpv -Same as C, but also invokes 'set' magic on the SV. -May evaluate arguments more than once. +Copies a string into an SV. The string must be null-terminated. +Does not handle 'set' magic. See C. - void SvSetMagicSV_nosteal (SV* dsv, SV* ssv) + void sv_setpv (SV* sv, char* ptr) -=item SvSetMagicUV +=item sv_setpv_mg -A macro that calls C, and invokes 'set' magic on the SV. -May evaluate arguments more than once. +Like C, but also handles 'set' magic. - void SvSetMagicUV (SV* sv, UV num) + void sv_setpv_mg (SV* sv, char* ptr) -=item sv_setiv +=item sv_setpviv -Copies an integer into the given SV. Does not handle 'set' magic. -See C. +Copies an integer into the given SV, also updating its string value. +Does not handle 'set' magic. See C. - void sv_setiv _((SV* sv, IV num)); + void sv_setpviv (SV* sv, IV num) -=item sv_setnv +=item sv_setpviv_mg -Copies a double into the given SV. Does not handle 'set' magic. -See C. +Like C, but also handles 'set' magic. - void sv_setnv _((SV* sv, double num)); + void sv_setpviv_mg (SV* sv, IV num) -=item sv_setpv +=item sv_setpvn -Copies a string into an SV. The string must be null-terminated. -Does not handle 'set' magic. See C. +Copies a string into an SV. The C parameter indicates the number of +bytes to be copied. Does not handle 'set' magic. See C. - void sv_setpv _((SV* sv, char* ptr)); + void sv_setpvn (SV* sv, char* ptr, STRLEN len) -=item sv_setpviv +=item sv_setpvn_mg -Copies an integer into the given SV, also updating its string value. -Does not handle 'set' magic. See C. +Like C, but also handles 'set' magic. - void sv_setpviv _((SV* sv, IV num)); + void sv_setpvn_mg (SV* sv, char* ptr, STRLEN len) -=item sv_setpvn +=item sv_setpvf -Copies a string into an SV. The C parameter indicates the number of -bytes to be copied. Does not handle 'set' magic. See C. +Processes its arguments like C and sets an SV to the formatted +output. Does not handle 'set' magic. See C. - void sv_setpvn _((SV* sv, char* ptr, STRLEN len)); + void sv_setpvf (SV* sv, const char* pat, ...) -=item sv_setpvf +=item sv_setpvf_mg -Processes its arguments like C and sets an SV to the formatted -output. Does not handle 'set' magic. C must typically -be called after calling this function to handle 'set' magic. +Like C, but also handles 'set' magic. - void sv_setpvf _((SV* sv, const char* pat, ...)); + void sv_setpvf_mg (SV* sv, const char* pat, ...) =item sv_setref_iv @@ -3014,7 +3011,7 @@ the new SV. The C argument indicates the package for the blessing. Set C to C to avoid the blessing. The new SV will be returned and will have a reference count of 1. - SV* sv_setref_iv _((SV *rv, char *classname, IV iv)); + SV* sv_setref_iv (SV *rv, char *classname, IV iv) =item sv_setref_nv @@ -3024,7 +3021,7 @@ the new SV. The C argument indicates the package for the blessing. Set C to C to avoid the blessing. The new SV will be returned and will have a reference count of 1. - SV* sv_setref_nv _((SV *rv, char *classname, double nv)); + SV* sv_setref_nv (SV *rv, char *classname, double nv) =item sv_setref_pv @@ -3035,7 +3032,7 @@ into the SV. The C argument indicates the package for the blessing. Set C to C to avoid the blessing. The new SV will be returned and will have a reference count of 1. - SV* sv_setref_pv _((SV *rv, char *classname, void* pv)); + SV* sv_setref_pv (SV *rv, char *classname, void* pv) Do not use with integral Perl types such as HV, AV, SV, CV, because those objects will become corrupted by the pointer copy process. @@ -3051,7 +3048,7 @@ argument indicates the package for the blessing. Set C to C to avoid the blessing. The new SV will be returned and will have a reference count of 1. - SV* sv_setref_pvn _((SV *rv, char *classname, char* pv, I32 n)); + SV* sv_setref_pvn (SV *rv, char *classname, char* pv, I32 n) Note that C copies the pointer while this copies the string. @@ -3073,17 +3070,28 @@ May evaluate arguments more than once. Copies the contents of the source SV C into the destination SV C. The source SV may be destroyed if it is mortal. Does not handle 'set' magic. -See the macro forms C, C, C and -C. +See the macro forms C, C and C. + + void sv_setsv (SV* dsv, SV* ssv) + +=item sv_setsv_mg + +Like C, but also handles 'set' magic. - void sv_setsv _((SV* dsv, SV* ssv)); + void sv_setsv_mg (SV* dsv, SV* ssv) =item sv_setuv Copies an unsigned integer into the given SV. Does not handle 'set' magic. -See C. +See C. - void sv_setuv _((SV* sv, UV num)); + void sv_setuv (SV* sv, UV num) + +=item sv_setuv_mg + +Like C, but also handles 'set' magic. + + void sv_setuv_mg (SV* sv, UV num) =item SvSTASH @@ -3142,7 +3150,7 @@ C enum. Test these flags with the C macro. Used to upgrade an SV to a more complex form. Uses C to perform the upgrade if necessary. See C. - bool SvUPGRADE _((SV* sv, svtype mt)); + bool SvUPGRADE (SV* sv, svtype mt) =item sv_upgrade @@ -3158,9 +3166,7 @@ Unsets the RV status of the SV, and decrements the reference count of whatever was being referenced by the RV. This can almost be thought of as a reversal of C. See C. - void sv_unref _((SV* sv)); - -=item SvUseMagicPVN + void sv_unref (SV* sv) =item sv_usepvn @@ -3170,9 +3176,15 @@ The C should point to memory that was allocated by C. The string length, C, must be supplied. This function will realloc the memory pointed to by C, so that pointer should not be freed or used by the programmer after giving it to sv_usepvn. Does not handle 'set' magic. -See C. +See C. + + void sv_usepvn (SV* sv, char* ptr, STRLEN len) + +=item sv_usepvn_mg + +Like C, but also handles 'set' magic. - void sv_usepvn _((SV* sv, char* ptr, STRLEN len)); + void sv_usepvn_mg (SV* sv, char* ptr, STRLEN len) =item sv_yes @@ -3239,7 +3251,7 @@ C. Return from XSUB, indicating number of items on the stack. This is usually handled by C. - XSRETURN(int x); + XSRETURN(int x) =item XSRETURN_EMPTY @@ -3251,7 +3263,7 @@ Return an empty list from an XSUB immediately. Return an integer from an XSUB immediately. Uses C. - XSRETURN_IV(IV v); + XSRETURN_IV(IV v) =item XSRETURN_NO @@ -3263,13 +3275,13 @@ Return C<&sv_no> from an XSUB immediately. Uses C. Return an double from an XSUB immediately. Uses C. - XSRETURN_NV(NV v); + XSRETURN_NV(NV v) =item XSRETURN_PV Return a copy of a string from an XSUB immediately. Uses C. - XSRETURN_PV(char *v); + XSRETURN_PV(char *v) =item XSRETURN_UNDEF @@ -3288,39 +3300,39 @@ Return C<&sv_yes> from an XSUB immediately. Uses C. Place an integer into the specified position C on the stack. The value is stored in a new mortal SV. - XST_mIV( int i, IV v ); + XST_mIV( int i, IV v ) =item XST_mNV Place a double into the specified position C on the stack. The value is stored in a new mortal SV. - XST_mNV( int i, NV v ); + XST_mNV( int i, NV v ) =item XST_mNO Place C<&sv_no> into the specified position C on the stack. - XST_mNO( int i ); + XST_mNO( int i ) =item XST_mPV Place a copy of a string into the specified position C on the stack. The value is stored in a new mortal SV. - XST_mPV( int i, char *v ); + XST_mPV( int i, char *v ) =item XST_mUNDEF Place C<&sv_undef> into the specified position C on the stack. - XST_mUNDEF( int i ); + XST_mUNDEF( int i ) =item XST_mYES Place C<&sv_yes> into the specified position C on the stack. - XST_mYES( int i ); + XST_mYES( int i ) =item XS_VERSION @@ -3338,7 +3350,7 @@ C. See L. The XSUB-writer's interface to the C C function. The C is the destination, C is the number of items, and C is the type. - (void) Zero( d, n, t ); + (void) Zero( d, n, t ) =back diff --git a/pod/perlxs.pod b/pod/perlxs.pod index d257b19..07abd10 100644 --- a/pod/perlxs.pod +++ b/pod/perlxs.pod @@ -268,17 +268,25 @@ be seen by Perl. The OUTPUT: keyword will also allow an output parameter to be mapped to a matching piece of code rather than to a -typemap. The following duplicates the behavior of the -typemap: +typemap. bool_t rpcb_gettime(host,timep) char *host time_t &timep OUTPUT: - timep SvSetMagicNV(ST(1), (double)timep); - -See L for details about C. + 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 CODE: Keyword @@ -575,6 +583,9 @@ 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 diff --git a/pod/perlxstut.pod b/pod/perlxstut.pod index dfc56ff..867d42a 100644 --- a/pod/perlxstut.pod +++ b/pod/perlxstut.pod @@ -428,7 +428,7 @@ Let's now take a look at a portion of the .c file created for our extension. } else { arg = 0.0; } - SvSetMagicNV(ST(0), (double)arg); /* XXXXX */ + sv_setnv(ST(0), (double)arg); /* XXXXX */ } XSRETURN(1); } @@ -438,10 +438,10 @@ the typemap file, you'll see that doubles are of type T_DOUBLE. In the INPUT section, 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 SvSetMagicNV() macro -(which calls the sv_setnv() function) to be passed back to the calling -subroutine. These macros/functions are explained in L; we'll talk -more later about what that "ST(0)" means in the section on the argument stack. +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 diff --git a/proto.h b/proto.h index 1b1504e..4df73df 100644 --- a/proto.h +++ b/proto.h @@ -490,9 +490,13 @@ void sv_add_arena _((char* ptr, U32 size, U32 flags)); int sv_backoff _((SV* sv)); SV* sv_bless _((SV* sv, HV* stash)); void sv_catpvf _((SV* sv, const char* pat, ...)); +void sv_catpvf_mg _((SV* sv, const char* pat, ...)); void sv_catpv _((SV* sv, char* ptr)); +void sv_catpv_mg _((SV* sv, char* ptr)); void sv_catpvn _((SV* sv, char* ptr, STRLEN len)); +void sv_catpvn_mg _((SV* sv, char* ptr, STRLEN len)); void sv_catsv _((SV* dsv, SV* ssv)); +void sv_catsv_mg _((SV* dsv, SV* ssv)); void sv_chop _((SV* sv, char* ptr)); void sv_clean_all _((void)); void sv_clean_objs _((void)); @@ -531,17 +535,25 @@ void sv_replace _((SV* sv, SV* nsv)); void sv_report_used _((void)); void sv_reset _((char* s, HV* stash)); void sv_setpvf _((SV* sv, const char* pat, ...)); +void sv_setpvf_mg _((SV* sv, const char* pat, ...)); void sv_setiv _((SV* sv, IV num)); +void sv_setiv_mg _((SV* sv, IV num)); void sv_setpviv _((SV* sv, IV num)); +void sv_setpviv_mg _((SV* sv, IV num)); void sv_setuv _((SV* sv, UV num)); +void sv_setuv_mg _((SV* sv, UV num)); void sv_setnv _((SV* sv, double num)); +void sv_setnv_mg _((SV* sv, double num)); SV* sv_setref_iv _((SV* rv, char* classname, IV iv)); SV* sv_setref_nv _((SV* rv, char* classname, double nv)); SV* sv_setref_pv _((SV* rv, char* classname, void* pv)); SV* sv_setref_pvn _((SV* rv, char* classname, char* pv, I32 n)); void sv_setpv _((SV* sv, const char* ptr)); +void sv_setpv_mg _((SV* sv, const char* ptr)); void sv_setpvn _((SV* sv, const char* ptr, STRLEN len)); +void sv_setpvn_mg _((SV* sv, const char* ptr, STRLEN len)); void sv_setsv _((SV* dsv, SV* ssv)); +void sv_setsv_mg _((SV* dsv, SV* ssv)); void sv_taint _((SV* sv)); bool sv_tainted _((SV* sv)); int sv_unmagic _((SV* sv, int type)); @@ -549,6 +561,7 @@ void sv_unref _((SV* sv)); void sv_untaint _((SV* sv)); bool sv_upgrade _((SV* sv, U32 mt)); void sv_usepvn _((SV* sv, char* ptr, STRLEN len)); +void sv_usepvn_mg _((SV* sv, char* ptr, STRLEN len)); void sv_vcatpvfn _((SV* sv, const char* pat, STRLEN patlen, va_list* args, SV** svargs, I32 svmax, bool *used_locale)); diff --git a/sv.c b/sv.c index f460e45..1ab0e31 100644 --- a/sv.c +++ b/sv.c @@ -1138,6 +1138,13 @@ sv_setiv(register SV *sv, IV i) } void +sv_setiv_mg(register SV *sv, IV i) +{ + sv_setiv(sv,i); + SvSETMAGIC(sv); +} + +void sv_setuv(register SV *sv, UV u) { if (u <= IV_MAX) @@ -1147,6 +1154,13 @@ sv_setuv(register SV *sv, UV u) } void +sv_setuv_mg(register SV *sv, UV u) +{ + sv_setuv(sv,u); + SvSETMAGIC(sv); +} + +void sv_setnv(register SV *sv, double num) { sv_check_thinkfirst(sv); @@ -1190,6 +1204,13 @@ sv_setnv(register SV *sv, double num) SvTAINT(sv); } +void +sv_setnv_mg(register SV *sv, double num) +{ + sv_setnv(sv,num); + SvSETMAGIC(sv); +} + static void not_a_number(SV *sv) { @@ -2169,6 +2190,13 @@ sv_setsv(SV *dstr, register SV *sstr) } void +sv_setsv_mg(SV *dstr, register SV *sstr) +{ + sv_setsv(dstr,sstr); + SvSETMAGIC(dstr); +} + +void sv_setpvn(register SV *sv, register const char *ptr, register STRLEN len) { assert(len >= 0); /* STRLEN is probably unsigned, so this may @@ -2193,6 +2221,13 @@ sv_setpvn(register SV *sv, register const char *ptr, register STRLEN len) } void +sv_setpvn_mg(register SV *sv, register const char *ptr, register STRLEN len) +{ + sv_setpvn(sv,ptr,len); + SvSETMAGIC(sv); +} + +void sv_setpv(register SV *sv, register const char *ptr) { register STRLEN len; @@ -2217,6 +2252,13 @@ sv_setpv(register SV *sv, register const char *ptr) } void +sv_setpv_mg(register SV *sv, register const char *ptr) +{ + sv_setpv(sv,ptr); + SvSETMAGIC(sv); +} + +void sv_usepvn(register SV *sv, register char *ptr, register STRLEN len) { sv_check_thinkfirst(sv); @@ -2237,6 +2279,13 @@ sv_usepvn(register SV *sv, register char *ptr, register STRLEN len) SvTAINT(sv); } +void +sv_usepvn_mg(register SV *sv, register char *ptr, register STRLEN len) +{ + sv_usepvn_mg(sv,ptr,len); + SvSETMAGIC(sv); +} + static void sv_check_thinkfirst(register SV *sv) { @@ -2294,6 +2343,13 @@ sv_catpvn(register SV *sv, register char *ptr, register STRLEN len) } void +sv_catpvn_mg(register SV *sv, register char *ptr, register STRLEN len) +{ + sv_catpvn(sv,ptr,len); + SvSETMAGIC(sv); +} + +void sv_catsv(SV *dstr, register SV *sstr) { char *s; @@ -2305,6 +2361,13 @@ sv_catsv(SV *dstr, register SV *sstr) } void +sv_catsv_mg(SV *dstr, register SV *sstr) +{ + sv_catsv(dstr,sstr); + SvSETMAGIC(dstr); +} + +void sv_catpv(register SV *sv, register char *ptr) { register STRLEN len; @@ -2324,6 +2387,13 @@ sv_catpv(register SV *sv, register char *ptr) SvTAINT(sv); } +void +sv_catpv_mg(register SV *sv, register char *ptr) +{ + sv_catpv_mg(sv,ptr); + SvSETMAGIC(sv); +} + SV * #ifdef LEAKTEST newSV(I32 x, STRLEN len) @@ -4089,6 +4159,14 @@ sv_setpviv(SV *sv, IV iv) SvCUR(sv) = p - SvPVX(sv); } + +void +sv_setpviv_mg(SV *sv, IV iv) +{ + sv_setpviv(sv,iv); + SvSETMAGIC(sv); +} + #ifdef I_STDARG void sv_setpvf(SV *sv, const char* pat, ...) @@ -4111,6 +4189,30 @@ sv_setpvf(sv, pat, va_alist) va_end(args); } + +#ifdef I_STDARG +void +sv_setpvf_mg(SV *sv, const char* pat, ...) +#else +/*VARARGS0*/ +void +sv_setpvf_mg(sv, pat, va_alist) + SV *sv; + const char *pat; + va_dcl +#endif +{ + va_list args; +#ifdef I_STDARG + va_start(args, pat); +#else + va_start(args); +#endif + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + va_end(args); + SvSETMAGIC(sv); +} + #ifdef I_STDARG void sv_catpvf(SV *sv, const char* pat, ...) @@ -4133,6 +4235,29 @@ sv_catpvf(sv, pat, va_alist) va_end(args); } +#ifdef I_STDARG +void +sv_catpvf_mg(SV *sv, const char* pat, ...) +#else +/*VARARGS0*/ +void +sv_catpvf_mg(sv, pat, va_alist) + SV *sv; + const char *pat; + va_dcl +#endif +{ + va_list args; +#ifdef I_STDARG + va_start(args, pat); +#else + va_start(args); +#endif + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + va_end(args); + SvSETMAGIC(sv); +} + void sv_vsetpvfn(SV *sv, const char *pat, STRLEN patlen, va_list *args, SV **svargs, I32 svmax, bool *used_locale) { diff --git a/sv.h b/sv.h index 66fab16..5993a8d 100644 --- a/sv.h +++ b/sv.h @@ -611,7 +611,7 @@ struct xpvio { # endif #endif /* __GNUC__ */ -/* the following macros updates any magic values this sv is associated with */ +/* the following macros update any magic values this sv is associated with */ #define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END #define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END @@ -644,27 +644,6 @@ struct xpvio { #define SvSetMagicSV_nosteal(dst,src) \ SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst)) -#define SvSetMagicPV(dst,s) \ - STMT_START { sv_setpv(dst,s); SvSETMAGIC(dst); } STMT_END -#define SvSetMagicPVN(dst,s,l) \ - STMT_START { sv_setpvn(dst,s,l); SvSETMAGIC(dst); } STMT_END -#define SvSetMagicIV(dst,i) \ - STMT_START { sv_setiv(dst,i); SvSETMAGIC(dst); } STMT_END -#define SvSetMagicPVIV(dst,i) \ - STMT_START { sv_setpviv(dst,i); SvSETMAGIC(dst); } STMT_END -#define SvSetMagicUV(dst,u) \ - STMT_START { sv_setuv(dst,u); SvSETMAGIC(dst); } STMT_END -#define SvSetMagicNV(dst,n) \ - STMT_START { sv_setnv(dst,n); SvSETMAGIC(dst); } STMT_END -#define SvCatMagicPV(dst,s) \ - STMT_START { sv_catpv(dst,s); SvSETMAGIC(dst); } STMT_END -#define SvCatMagicPVN(dst,s,l) \ - STMT_START { sv_catpvn(dst,s,l); SvSETMAGIC(dst); } STMT_END -#define SvCatMagicSV(dst,src) \ - STMT_START { sv_catsv(dst,src); SvSETMAGIC(dst); } STMT_END -#define SvUseMagicPVN(dst,s,l) \ - STMT_START { sv_usepvn(dst,s,l); SvSETMAGIC(dst); } STMT_END - #define SvPEEK(sv) sv_peek(sv) #define SvIMMORTAL(sv) ((sv)==&sv_undef || (sv)==&sv_yes || (sv)==&sv_no)