summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1998-01-18 18:09:07 -0500
committerGurusamy Sarathy <gsar@cpan.org>1998-01-19 04:10:43 +0000
commit189b2af51bf236b53a02db0b105a3de423d3fff4 (patch)
treee144975915f994ffa46db0ce8f0bc73998c7566d
parentf5cd9d9c4a18b1d2556c41570273131b83659fe4 (diff)
downloadperl-189b2af51bf236b53a02db0b105a3de423d3fff4.tar.gz
[win32] Fix autovivification problems with XSUB OUTPUT args
Message-Id: <199801190409.XAA26710@aatma.engin.umich.edu> Subject: [PATCH] XSUB OUTPUT arguments and 'set' magic p4raw-id: //depot/win32/perl@430
-rw-r--r--ext/GDBM_File/typemap4
-rw-r--r--ext/NDBM_File/typemap4
-rw-r--r--ext/ODBM_File/typemap4
-rw-r--r--ext/SDBM_File/typemap4
-rw-r--r--lib/ExtUtils/typemap48
-rw-r--r--os2/OS2/PrfDB/typemap2
-rw-r--r--pod/perlguts.pod185
-rw-r--r--pod/perlxs.pod7
-rw-r--r--pod/perlxstut.pod10
-rw-r--r--sv.c4
-rw-r--r--sv.h34
-rw-r--r--win32/win32.h18
12 files changed, 244 insertions, 80 deletions
diff --git a/ext/GDBM_File/typemap b/ext/GDBM_File/typemap
index a9b73d8b81..73ad370359 100644
--- a/ext/GDBM_File/typemap
+++ b/ext/GDBM_File/typemap
@@ -20,8 +20,8 @@ T_GDATUM
UNIMPLEMENTED
OUTPUT
T_DATUM
- sv_setpvn($arg, $var.dptr, $var.dsize);
+ SvSetMagicPVN($arg, $var.dptr, $var.dsize);
T_GDATUM
- sv_usepvn($arg, $var.dptr, $var.dsize);
+ SvUseMagicPVN($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 a9b73d8b81..73ad370359 100644
--- a/ext/NDBM_File/typemap
+++ b/ext/NDBM_File/typemap
@@ -20,8 +20,8 @@ T_GDATUM
UNIMPLEMENTED
OUTPUT
T_DATUM
- sv_setpvn($arg, $var.dptr, $var.dsize);
+ SvSetMagicPVN($arg, $var.dptr, $var.dsize);
T_GDATUM
- sv_usepvn($arg, $var.dptr, $var.dsize);
+ SvUseMagicPVN($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 a6b0e5faa8..c2c3e3e725 100644
--- a/ext/ODBM_File/typemap
+++ b/ext/ODBM_File/typemap
@@ -20,6 +20,6 @@ T_GDATUM
UNIMPLEMENTED
OUTPUT
T_DATUM
- sv_setpvn($arg, $var.dptr, $var.dsize);
+ SvSetMagicPVN($arg, $var.dptr, $var.dsize);
T_GDATUM
- sv_usepvn($arg, $var.dptr, $var.dsize);
+ SvUseMagicPVN($arg, $var.dptr, $var.dsize);
diff --git a/ext/SDBM_File/typemap b/ext/SDBM_File/typemap
index a9b73d8b81..73ad370359 100644
--- a/ext/SDBM_File/typemap
+++ b/ext/SDBM_File/typemap
@@ -20,8 +20,8 @@ T_GDATUM
UNIMPLEMENTED
OUTPUT
T_DATUM
- sv_setpvn($arg, $var.dptr, $var.dsize);
+ SvSetMagicPVN($arg, $var.dptr, $var.dsize);
T_GDATUM
- sv_usepvn($arg, $var.dptr, $var.dsize);
+ SvUseMagicPVN($arg, $var.dptr, $var.dsize);
T_PTROBJ
sv_setref_pv($arg, dbtype, (void*)$var);
diff --git a/lib/ExtUtils/typemap b/lib/ExtUtils/typemap
index 20cc96f0b5..430c28ad3d 100644
--- a/lib/ExtUtils/typemap
+++ b/lib/ExtUtils/typemap
@@ -190,44 +190,44 @@ T_HVREF
T_CVREF
$arg = newRV((SV*)$var);
T_IV
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_INT
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_SYSRET
if ($var != -1) {
if ($var == 0)
- sv_setpvn($arg, "0 but true", 10);
+ SvSetMagicPVN($arg, "0 but true", 10);
else
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
}
T_ENUM
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_BOOL
$arg = boolSV($var);
T_U_INT
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_SHORT
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_U_SHORT
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_LONG
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_U_LONG
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_CHAR
- sv_setpvn($arg, (char *)&$var, 1);
+ SvSetMagicPVN($arg, (char *)&$var, 1);
T_U_CHAR
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($arg, (IV)$var);
T_FLOAT
- sv_setnv($arg, (double)$var);
+ SvSetMagicNV($arg, (double)$var);
T_NV
- sv_setnv($arg, (double)$var);
+ SvSetMagicNV($arg, (double)$var);
T_DOUBLE
- sv_setnv($arg, (double)$var);
+ SvSetMagicNV($arg, (double)$var);
T_PV
- sv_setpv((SV*)$arg, $var);
+ SvSetMagicPV((SV*)$arg, $var);
T_PTR
- sv_setiv($arg, (IV)$var);
+ SvSetMagicIV($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
- sv_setpvn($arg, (char *)&$var, sizeof($var));
+ SvSetMagicPVN($arg, (char *)&$var, sizeof($var));
T_OPAQUEPTR
- sv_setpvn($arg, (char *)$var, sizeof(*$var)), XFree((char *)$var);
+ SvSetMagicPVN($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
- sv_setpvn($arg, $var.chp(), $var.size());
+ SvSetMagicPVN($arg, $var.chp(), $var.size());
T_CALLBACK
- sv_setpvn($arg, $var.context.value().chp(),
+ SvSetMagicPVN($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) )
- sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
+ SvSetMagicSV($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) )
- sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
+ SvSetMagicSV($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) )
- sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
+ SvSetMagicSV($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
else
$arg = &sv_undef;
}
diff --git a/os2/OS2/PrfDB/typemap b/os2/OS2/PrfDB/typemap
index 0b91f3750a..1e01470f87 100644
--- a/os2/OS2/PrfDB/typemap
+++ b/os2/OS2/PrfDB/typemap
@@ -11,4 +11,4 @@ T_PVNULL
#############################################################################
OUTPUT
T_PVNULL
- sv_setpv((SV*)$arg, $var);
+ SvSetMagicPV((SV*)$arg, $var);
diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index 20a11ac45c..1db8249d24 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -57,7 +57,9 @@ calculate the length by using C<sv_setpv> or by specifying 0 as the second
argument to C<newSVpv>. Be warned, though, that Perl will determine the
string's length by using C<strlen>, which depends on the string terminating
with a NUL character. The arguments of C<sv_setpvf> are processed like
-C<sprintf>, and the formatted output becomes the value.
+C<sprintf>, and the formatted output becomes the value. The C<sv_set*()>
+functions are not generic enough to operate on values that have "magic".
+See L<Magic Virtual Tables> later in this document.
All SVs that will contain strings should, but need not, be terminated
with a NUL character. If it is not NUL-terminated there is a risk of
@@ -130,7 +132,9 @@ using C<strlen>. In the second, you specify the length of the string
yourself. The third function processes its arguments like C<sprintf> and
appends the formatted output. The fourth function extends the string
stored in the first SV with the string stored in the second SV. It also
-forces the second SV to be interpreted as a string.
+forces the second SV to be interpreted as a string. The C<sv_cat*()>
+functions are not generic enough to operate on values that have "magic".
+See L<Magic Virtual Tables> later in this document.
If you know the name of a scalar variable, you can get a pointer to its SV
by using the following:
@@ -831,6 +835,17 @@ 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<sv_set*()> functions that modify scalars do
+B<not> invoke 'set' magic on their targets. This must be done by the user
+either by calling the C<SvSETMAGIC()> macro after calling these functions,
+or by using one of the C<SvSetMagic*()> macros. Similarly, generic C code
+must call the C<SvGETMAGIC()> macro to invoke any 'get' magic if they use
+an SV obtained from external sources in functions that don't handle magic.
+L<API LISTING> later in this document identifies such macros and functions.
+For example, calls to the C<sv_cat*()> functions typically need to be
+followed by C<SvSETMAGIC()>, but they don't need a prior C<SvGETMAGIC()>
+since their implementation handles 'get' magic.
+
=head2 Finding Magic
MAGIC* mg_find(SV*, int type); /* Finds the magic pointer of that type */
@@ -2324,28 +2339,29 @@ Opening bracket for arguments on a callback. See C<PUTBACK> and L<perlcall>.
=item PUSHi
Push an integer onto the stack. The stack must have room for this element.
-See C<XPUSHi>.
+Handles 'set' magic. See C<XPUSHi>.
PUSHi(int d)
=item PUSHn
Push a double onto the stack. The stack must have room for this element.
-See C<XPUSHn>.
+Handles 'set' magic. See C<XPUSHn>.
PUSHn(double d)
=item PUSHp
Push a string onto the stack. The stack must have room for this element.
-The C<len> indicates the length of the string. See C<XPUSHp>.
+The C<len> indicates the length of the string. Handles 'set' magic. See
+C<XPUSHp>.
PUSHp(char *c, int len )
=item PUSHs
-Push an SV onto the stack. The stack must have room for this element. See
-C<XPUSHs>.
+Push an SV onto the stack. The stack must have room for this element. Does
+not handle 'set' magic. See C<XPUSHs>.
PUSHs(sv)
@@ -2492,30 +2508,39 @@ of the SV is unaffected.
SV* sv_bless _((SV* sv, HV* stash));
+=item SvCatMagicPV
+
+=item SvCatMagicPVN
+
+=item SvCatMagicSV
+
=item sv_catpv
Concatenates the string onto the end of the string which is in the SV.
+Handles 'get' magic, but not 'set' magic. See C<SvCatMagicPV>.
void sv_catpv _((SV* sv, char* ptr));
=item sv_catpvn
Concatenates the string onto the end of the string which is in the SV. The
-C<len> indicates number of bytes to copy.
+C<len> indicates number of bytes to copy. Handles 'get' magic, but not
+'set' magic. See C<SvCatMagicPVN).
void sv_catpvn _((SV* sv, char* ptr, STRLEN len));
=item sv_catpvf
Processes its arguments like C<sprintf> and appends the formatted output
-to an SV.
+to an SV. Handles 'get' magic, but not 'set' magic. C<SvSETMAGIC()> must
+typically be called after calling this function to handle 'set' magic.
void sv_catpvf _((SV* sv, const char* pat, ...));
=item sv_catsv
Concatenates the string from SV C<ssv> onto the end of the string in SV
-C<dsv>.
+C<dsv>. Handles 'get' magic, but not 'set' magic. See C<SvCatMagicSV).
void sv_catsv _((SV* dsv, SV* ssv));
@@ -2559,6 +2584,13 @@ identical.
I32 sv_eq _((SV* sv1, SV* sv2));
+=item SvGETMAGIC
+
+Invokes C<mg_get> on an SV if it has 'get' magic. This macro evaluates
+its argument more than once.
+
+ void SvGETMAGIC( SV *sv )
+
=item SvGROW
Expands the character buffer in the SV. Calls C<sv_grow> to perform the
@@ -2776,7 +2808,7 @@ Checks the B<private> setting. Use C<SvPOK>.
Returns a pointer to the string in the SV, or a stringified form of the SV
if the SV does not contain a string. If C<len> is C<na> then Perl will
-handle the length on its own.
+handle the length on its own. Handles 'get' magic.
char * SvPV (SV* sv, int len )
@@ -2828,6 +2860,13 @@ Dereferences an RV to return the SV.
SV* SvRV (SV* sv);
+=item SvSETMAGIC
+
+Invokes C<mg_set> on an SV if it has 'set' magic. This macro evaluates
+its argument more than once.
+
+ void SvSETMAGIC( SV *sv )
+
=item SvTAINT
Taints an SV if tainting is enabled
@@ -2857,35 +2896,102 @@ Marks an SV as tainted.
SvTAINTED_on (SV* sv);
+=item SvSetMagicIV
+
+A macro that calls C<sv_setiv>, and invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicIV (SV* sv, IV num)
+
+=item SvSetMagicNV
+
+A macro that calls C<sv_setnv>, and invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicNV (SV* sv, double num)
+
+=item SvSetMagicPV
+
+A macro that calls C<sv_setpv>, and invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicPV (SV* sv, char *ptr)
+
+=item SvSetMagicPVIV
+
+A macro that calls C<sv_setpviv>, and invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicPVIV (SV* sv, IV num)
+
+=item SvSetMagicPVN
+
+A macro that calls C<sv_setpvn>, and invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicPVN (SV* sv, char* ptr, STRLEN len)
+
+=item SvSetMagicSV
+
+Same as C<SvSetSV>, but also invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicSV (SV* dsv, SV* ssv)
+
+=item SvSetMagicSV_nosteal
+
+Same as C<SvSetSV_nosteal>, but also invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicSV_nosteal (SV* dsv, SV* ssv)
+
+=item SvSetMagicUV
+
+A macro that calls C<sv_setuv>, and invokes 'set' magic on the SV.
+May evaluate arguments more than once.
+
+ void SvSetMagicUV (SV* sv, UV num)
+
=item sv_setiv
-Copies an integer into the given SV.
+Copies an integer into the given SV. Does not handle 'set' magic.
+See C<SvSetMagicIV>.
void sv_setiv _((SV* sv, IV num));
=item sv_setnv
-Copies a double into the given SV.
+Copies a double into the given SV. Does not handle 'set' magic.
+See C<SvSetMagicNV>.
void sv_setnv _((SV* sv, double num));
=item sv_setpv
Copies a string into an SV. The string must be null-terminated.
+Does not handle 'set' magic. See C<SvSetMagicPV>.
void sv_setpv _((SV* sv, char* ptr));
+=item sv_setpviv
+
+Copies an integer into the given SV, also updating its string value.
+Does not handle 'set' magic. See C<SvSetMagicPVIV>.
+
+ void sv_setpviv _((SV* sv, IV num));
+
=item sv_setpvn
Copies a string into an SV. The C<len> parameter indicates the number of
-bytes to be copied.
+bytes to be copied. Does not handle 'set' magic. See C<SvSetMagicPVN>.
void sv_setpvn _((SV* sv, char* ptr, STRLEN len));
=item sv_setpvf
Processes its arguments like C<sprintf> and sets an SV to the formatted
-output.
+output. Does not handle 'set' magic. C<SvSETMAGIC()> must typically
+be called after calling this function to handle 'set' magic.
void sv_setpvf _((SV* sv, const char* pat, ...));
@@ -2938,13 +3044,36 @@ a reference count of 1.
Note that C<sv_setref_pv> copies the pointer while this copies the string.
+=item SvSetSV
+
+Calls C<sv_setsv> if dsv is not the same as ssv. May evaluate arguments
+more than once.
+
+ void SvSetSV (SV* dsv, SV* ssv)
+
+=item SvSetSV_nosteal
+
+Calls a non-destructive version of C<sv_setsv> if dsv is not the same as ssv.
+May evaluate arguments more than once.
+
+ void SvSetSV_nosteal (SV* dsv, SV* ssv)
+
=item sv_setsv
Copies the contents of the source SV C<ssv> into the destination SV C<dsv>.
-The source SV may be destroyed if it is mortal.
+The source SV may be destroyed if it is mortal. Does not handle 'set' magic.
+See the macro forms C<SvSetSV>, C<SvSetSV_nosteal>, C<SvSetMagicSV> and
+C<SvSetMagicSV_nosteal>.
void sv_setsv _((SV* dsv, SV* ssv));
+=item sv_setuv
+
+Copies an unsigned integer into the given SV. Does not handle 'set' magic.
+See C<SvSetMagicUV>.
+
+ void sv_setuv _((SV* sv, UV num));
+
=item SvSTASH
Returns the stash of the SV.
@@ -2982,7 +3111,7 @@ Double type flag for scalars. See C<svtype>.
=item SvTRUE
Returns a boolean indicating whether Perl would evaluate the SV as true or
-false, defined or undefined.
+false, defined or undefined. Does not handle 'get' magic.
int SvTRUE (SV* sv)
@@ -3020,6 +3149,8 @@ as a reversal of C<newSVrv>. See C<SvROK_off>.
void sv_unref _((SV* sv));
+=item SvUseMagicPVN
+
=item sv_usepvn
Tells an SV to use C<ptr> to find its string value. Normally the string is
@@ -3027,7 +3158,8 @@ stored inside the SV but sv_usepvn allows the SV to use an outside string.
The C<ptr> should point to memory that was allocated by C<malloc>. The
string length, C<len>, must be supplied. This function will realloc the
memory pointed to by C<ptr>, so that pointer should not be freed or used by
-the programmer after giving it to sv_usepvn.
+the programmer after giving it to sv_usepvn. Does not handle 'set' magic.
+See C<SvUseMagicPVN>.
void sv_usepvn _((SV* sv, char* ptr, STRLEN len));
@@ -3060,28 +3192,29 @@ function the same way you use the C C<printf> function. See C<croak()>.
=item XPUSHi
-Push an integer onto the stack, extending the stack if necessary. See
-C<PUSHi>.
+Push an integer onto the stack, extending the stack if necessary. Handles
+'set' magic. See C<PUSHi>.
XPUSHi(int d)
=item XPUSHn
-Push a double onto the stack, extending the stack if necessary. See
-C<PUSHn>.
+Push a double onto the stack, extending the stack if necessary. Handles 'set'
+magic. See C<PUSHn>.
XPUSHn(double d)
=item XPUSHp
Push a string onto the stack, extending the stack if necessary. The C<len>
-indicates the length of the string. See C<PUSHp>.
+indicates the length of the string. Handles 'set' magic. See C<PUSHp>.
XPUSHp(char *c, int len)
=item XPUSHs
-Push an SV onto the stack, extending the stack if necessary. See C<PUSHs>.
+Push an SV onto the stack, extending the stack if necessary. Does not
+handle 'set' magic. See C<PUSHs>.
XPUSHs(sv)
@@ -3204,8 +3337,8 @@ Jeff Okamoto <F<okamoto@corp.hp.com>>
With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
-Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer, and
-Stephen McCamant.
+Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
+Stephen McCamant, and Gurusamy Sarathy.
API Listing by Dean Roehrich <F<roehrich@cray.com>>.
diff --git a/pod/perlxs.pod b/pod/perlxs.pod
index 6629af2dd5..d257b196eb 100644
--- a/pod/perlxs.pod
+++ b/pod/perlxs.pod
@@ -268,14 +268,17 @@ 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.
+typemap. The following duplicates the behavior of the
+typemap:
bool_t
rpcb_gettime(host,timep)
char *host
time_t &timep
OUTPUT:
- timep sv_setnv(ST(1), (double)timep);
+ timep SvSetMagicNV(ST(1), (double)timep);
+
+See L<perlguts> for details about C<SvSetMagicNV()>.
=head2 The CODE: Keyword
diff --git a/pod/perlxstut.pod b/pod/perlxstut.pod
index 9ebfe82a97..dfc56ffbf1 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;
}
- sv_setnv(ST(0), (double)arg); /* XXXXX */
+ SvSetMagicNV(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 sv_setnv function to
-be passed back to the calling subroutine. These two functions are explained
-in L<perlguts>; 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 SvSetMagicNV() macro
+(which calls the sv_setnv() function) to be passed back to the calling
+subroutine. These macros/functions are explained in L<perlguts>; we'll talk
+more later about what that "ST(0)" means in the section on the argument stack.
=head2 WARNING
diff --git a/sv.c b/sv.c
index d6c10391e3..b0d7f973b1 100644
--- a/sv.c
+++ b/sv.c
@@ -3906,8 +3906,10 @@ newSVrv(SV *rv, char *classname)
SV*
sv_setref_pv(SV *rv, char *classname, void *pv)
{
- if (!pv)
+ if (!pv) {
sv_setsv(rv, &sv_undef);
+ SvSETMAGIC(rv);
+ }
else
sv_setiv(newSVrv(rv,classname), (IV)pv);
return rv;
diff --git a/sv.h b/sv.h
index ffcc4aa22d..66fab163cd 100644
--- a/sv.h
+++ b/sv.h
@@ -611,23 +611,28 @@ struct xpvio {
# endif
#endif /* __GNUC__ */
-/* the following macro updates any magic values this sv is associated with */
+/* the following macros updates any magic values this sv is associated with */
-#define SvSETMAGIC(x) if (SvSMAGICAL(x)) mg_set(x)
+#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
#define SvSetSV_and(dst,src,finally) \
+ STMT_START { \
if ((dst) != (src)) { \
sv_setsv(dst, src); \
finally; \
- }
+ } \
+ } STMT_END
#define SvSetSV_nosteal_and(dst,src,finally) \
+ STMT_START { \
if ((dst) != (src)) { \
U32 tMpF = SvFLAGS(src) & SVs_TEMP; \
SvTEMP_off(src); \
sv_setsv(dst, src); \
SvFLAGS(src) |= tMpF; \
finally; \
- }
+ } \
+ } STMT_END
#define SvSetSV(dst,src) \
SvSetSV_and(dst,src,/*nothing*/;)
@@ -639,6 +644,27 @@ 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)
diff --git a/win32/win32.h b/win32/win32.h
index 5a7c89bf97..8d6b04197d 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -109,15 +109,15 @@ struct tms {
#define DllMain DllEntryPoint
#endif
-#pragma warn -ccc
-#pragma warn -rch
-#pragma warn -sig
-#pragma warn -pia
-#pragma warn -par
-#pragma warn -aus
-#pragma warn -use
-#pragma warn -csu
-#pragma warn -pro
+#pragma warn -ccc /* "condition is always true/false" */
+#pragma warn -rch /* "unreachable code" */
+#pragma warn -sig /* "conversion may lose significant digits" */
+#pragma warn -pia /* "possibly incorrect assignment" */
+#pragma warn -par /* "parameter 'foo' is never used" */
+#pragma warn -aus /* "'foo' is assigned a value that is never used" */
+#pragma warn -use /* "'foo' is declared but never used" */
+#pragma warn -csu /* "comparing signed and unsigned values" */
+#pragma warn -pro /* "call to function with no prototype" */
#endif