summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Beattie <mbeattie@sable.ox.ac.uk>1998-02-11 13:04:50 +0000
committerMalcolm Beattie <mbeattie@sable.ox.ac.uk>1998-02-11 13:04:50 +0000
commitbf0f82cfd49ab93b8023104206fc86377822b057 (patch)
tree6bb596c6c97713d7d62c00de8ffd88d9efe07463
parent4c2eb2563685e652246970f0aedca9ee496d53d5 (diff)
parentc6c1a8fdade112d307195fa6eff91d3af5c3ee70 (diff)
downloadperl-bf0f82cfd49ab93b8023104206fc86377822b057.tar.gz
Integrate win32 into mainline.
p4raw-id: //depot/perl@496
-rw-r--r--embed.h14
-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--global.sym13
-rw-r--r--gv.c17
-rw-r--r--lib/ExtUtils/typemap48
-rwxr-xr-xlib/ExtUtils/xsubpp21
-rw-r--r--op.c30
-rw-r--r--os2/OS2/PrfDB/typemap2
-rw-r--r--pod/perlguts.pod422
-rw-r--r--pod/perlobj.pod26
-rw-r--r--pod/perlxs.pod21
-rw-r--r--pod/perlxstut.pod10
-rw-r--r--proto.h13
-rw-r--r--sv.c186
-rw-r--r--sv.h23
-rwxr-xr-xt/op/ref.t46
-rw-r--r--win32/makedef.pl1
-rw-r--r--win32/win32.c96
-rw-r--r--win32/win32iop.h9
22 files changed, 670 insertions, 344 deletions
diff --git a/embed.h b/embed.h
index 41a6af9e99..73cc786924 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 73ad370359..a9b73d8b81 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 73ad370359..a9b73d8b81 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 c2c3e3e725..a6b0e5faa8 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 73ad370359..a9b73d8b81 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 27fe565d11..afbc7c9620 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/gv.c b/gv.c
index 3633e7bf62..11dc761e14 100644
--- a/gv.c
+++ b/gv.c
@@ -426,18 +426,17 @@ gv_fetchpv(char *nambeg, I32 add, I32 sv_type)
tmpbuf[len++] = ':';
tmpbuf[len] = '\0';
gvp = (GV**)hv_fetch(stash,tmpbuf,len,add);
+ gv = gvp ? *gvp : Nullgv;
+ if (gv && gv != (GV*)&sv_undef) {
+ if (SvTYPE(gv) != SVt_PVGV)
+ gv_init(gv, stash, tmpbuf, len, (add & 2));
+ else
+ GvMULTI_on(gv);
+ }
if (tmpbuf != autobuf)
Safefree(tmpbuf);
- if (!gvp || *gvp == (GV*)&sv_undef)
+ if (!gv || gv == (GV*)&sv_undef)
return Nullgv;
- gv = *gvp;
-
- if (SvTYPE(gv) == SVt_PVGV)
- GvMULTI_on(gv);
- else if (!add)
- return Nullgv;
- else
- gv_init(gv, stash, nambeg, namend - nambeg, (add & 2));
if (!(stash = GvHV(gv)))
stash = GvHV(gv) = newHV();
diff --git a/lib/ExtUtils/typemap b/lib/ExtUtils/typemap
index 430c28ad3d..20cc96f0b5 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 04de166ad6..6fe16dc371 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/op.c b/op.c
index 5e2f5c2d17..593667d538 100644
--- a/op.c
+++ b/op.c
@@ -393,7 +393,8 @@ pad_alloc(I32 optype, U32 tmptype)
(unsigned long) thr, (unsigned long) curpad,
(long) retval, op_name[optype]));
#else
- DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad alloc %ld for %s\n",
+ DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%lx alloc %ld for %s\n",
+ (unsigned long) curpad,
(long) retval, op_name[optype]));
#endif /* USE_THREADS */
return (PADOFFSET)retval;
@@ -414,7 +415,8 @@ pad_sv(PADOFFSET po)
#else
if (!po)
croak("panic: pad_sv po");
- DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad sv %d\n", po));
+ DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%lx sv %d\n",
+ (unsigned long) curpad, po));
#endif /* USE_THREADS */
return curpad[po]; /* eventually we'll turn this into a macro */
}
@@ -438,7 +440,8 @@ pad_free(PADOFFSET po)
DEBUG_X(PerlIO_printf(Perl_debug_log, "0x%lx Pad 0x%lx free %d\n",
(unsigned long) thr, (unsigned long) curpad, po));
#else
- DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad free %d\n", po));
+ DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%lx free %d\n",
+ (unsigned long) curpad, po));
#endif /* USE_THREADS */
if (curpad[po] && curpad[po] != &sv_undef)
SvPADTMP_off(curpad[po]);
@@ -463,7 +466,8 @@ pad_swipe(PADOFFSET po)
DEBUG_X(PerlIO_printf(Perl_debug_log, "0x%lx Pad 0x%lx swipe %d\n",
(unsigned long) thr, (unsigned long) curpad, po));
#else
- DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad swipe %d\n", po));
+ DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%lx swipe %d\n",
+ (unsigned long) curpad, po));
#endif /* USE_THREADS */
SvPADTMP_off(curpad[po]);
curpad[po] = NEWSV(1107,0);
@@ -472,9 +476,16 @@ pad_swipe(PADOFFSET po)
padix = po - 1;
}
+/* XXX pad_reset() is currently disabled because it results in serious bugs.
+ * It causes pad temp TARGs to be shared between OPs. Since TARGs are pushed
+ * on the stack by OPs that use them, there are several ways to get an alias
+ * to a shared TARG. Such an alias will change randomly and unpredictably.
+ * We avoid doing this until we can think of a Better Way.
+ * GSAR 97-10-29 */
void
pad_reset(void)
{
+#ifdef USE_BROKEN_PAD_RESET
dTHR;
register I32 po;
@@ -484,7 +495,8 @@ pad_reset(void)
DEBUG_X(PerlIO_printf(Perl_debug_log, "0x%lx Pad 0x%lx reset\n",
(unsigned long) thr, (unsigned long) curpad));
#else
- DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad reset\n"));
+ DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%lx reset\n",
+ (unsigned long) curpad));
#endif /* USE_THREADS */
if (!tainting) { /* Can't mix tainted and non-tainted temporaries. */
for (po = AvMAX(comppad); po > padix_floor; po--) {
@@ -493,6 +505,7 @@ pad_reset(void)
}
padix = padix_floor;
}
+#endif
pad_reset_pending = FALSE;
}
@@ -4612,7 +4625,7 @@ ck_subr(OP *o)
kid->op_sibling = 0;
o2 = newUNOP(OP_RV2GV, 0, kid);
o2->op_sibling = sib;
- prev->op_sibling = o;
+ prev->op_sibling = o2;
}
goto wrapref;
case '\\':
@@ -4641,9 +4654,10 @@ ck_subr(OP *o)
wrapref:
{
OP* kid = o2;
- o2 = newUNOP(OP_REFGEN, 0, kid);
- o2->op_sibling = kid->op_sibling;
+ OP* sib = kid->op_sibling;
kid->op_sibling = 0;
+ o2 = newUNOP(OP_REFGEN, 0, kid);
+ o2->op_sibling = sib;
prev->op_sibling = o2;
}
break;
diff --git a/os2/OS2/PrfDB/typemap b/os2/OS2/PrfDB/typemap
index 1e01470f87..0b91f3750a 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 7a09d0d33c..111baf0899 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<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.
+Also note that the C<sv_set*()> and C<sv_cat*()> functions described
+earlier 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<sv_set*_mg()> or
+C<sv_cat*_mg()> functions. 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 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.
@@ -1428,14 +1429,14 @@ Same as C<av_len>.
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<key> 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<SV*>.
See L<Understanding the Magic of Tied Hashes and Arrays> 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<Understanding the Magic of Tied Hashes and Arrays> 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<undef> values onto the beginning of the
array. The array will grow automatically to accommodate the addition.
You must then use C<av_store> 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<memcpy> function. The C<s> is the
source, C<d> is the destination, C<n> is the number of items, and C<t> is
the type. May fail on overlapping copies. See also C<Move>.
- (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<LEAVE> and L<perlcall>.
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<perl_call_sv>,
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<GvCV> 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<level==0>. C<name> should be writable if contains C<':'> or C<'\''>.
The warning against passing the GV returned by C<gv_fetchmeth> to
C<perl_call_sv> 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<create> is set
then the package will be created if it does not already exist. If C<create>
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<gv_stashpv>.
- 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<SV*>) 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<sv_2mortal>. See C<hv_iternext>
and C<hv_free_ent>.
- 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<klen> is the length of the key. The
C<flags> 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<flags> value will normally be zero; if set
to G_DISCARD then NULL will be returned. C<hash> 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<klen> 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<hash>
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<SV*>.
See L<Understanding the Magic of Tied Hashes and Arrays> 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<Understanding the Magic of Tied Hashes and Arrays> 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<hv_iternext> and C<hv_delayfree_ent>.
- 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<currently> returns the number of I<buckets> in
the hash and I<not> 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<hv_iterinit>.
- 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<SV*> from the current position of the hash
iterator. The return value will always be a mortal copy of the
key. Also see C<hv_iterinit>.
- SV* hv_iterkeysv _((HE* entry));
+ SV* hv_iterkeysv (HE* entry)
=item hv_iternext
Returns entries from a hash iterator. See C<hv_iterinit>.
- HE* hv_iternext _((HV* tb));
+ HE* hv_iternext (HV* tb)
=item hv_iternextsv
Performs an C<hv_iternext>, C<hv_iterkey>, and C<hv_iterval> 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<hv_iterkey>.
- SV* hv_iterval _((HV* tb, HE* entry));
+ SV* hv_iterval (HV* tb, HE* entry)
=item hv_magic
Adds magic to a hash. See C<sv_magic>.
- 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<Understanding the Magic of Tied Hashes and Arrays> 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<Understanding the Magic of Tied Hashes and Arrays> 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<dMARK>.
Clear something magical that the SV represents. See C<sv_magic>.
- int mg_clear _((SV* sv));
+ int mg_clear (SV* sv)
=item mg_copy
Copies the magic from one SV to another. See C<sv_magic>.
- 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<sv_magic>.
- 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<sv_magic>.
- 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<sv_magic>.
- int mg_get _((SV* sv));
+ int mg_get (SV* sv)
=item mg_len
Report on the SV's length. See C<sv_magic>.
- U32 mg_len _((SV* sv));
+ U32 mg_len (SV* sv)
=item mg_magical
Turns on the magical status of an SV. See C<sv_magic>.
- 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<sv_magic>.
- 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<memmove> function. The C<s> is the
source, C<d> is the destination, C<n> is the number of items, and C<t> is
the type. Can do overlapping moves. See also C<Copy>.
- (void) Move( s, d, n, t );
+ (void) Move( s, d, n, t )
=item na
@@ -2101,20 +2101,20 @@ memory is zeroed with C<memzero>.
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<not> 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<id> 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<len> 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<len> 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<classname> 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<perlembed>.
Performs a callback to the specified Perl sub. See L<perlcall>.
- 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<perlcall>.
- 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<perlcall>.
- 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<perlcall>.
- 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<perlembed>.
Tells Perl to C<eval> 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<eval> 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<create> is set and the
Perl variable does not exist then it will be created. If C<create> 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<create> is set and the Perl
variable does not exist then it will be created. If C<create> 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<create> is set and the Perl
variable does not exist then it will be created. If C<create> 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<create> is set and the
Perl variable does not exist then it will be created. If C<create> 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<perlembed>.
Tells Perl to C<require> 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<perlembed>.
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<realloc> 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<len> 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<gv_stashpv()>). 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<sv_catpv_mg>.
-=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<SvCatMagicPV>.
+Like C<sv_catpv>, 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<len> indicates number of bytes to copy. Handles 'get' magic, but not
-'set' magic. See C<SvCatMagicPVN).
+'set' magic. See C<sv_catpvn_mg>.
- void sv_catpvn _((SV* sv, char* ptr, STRLEN len));
+ void sv_catpvn (SV* sv, char* ptr, STRLEN len)
+
+=item sv_catpvn_mg
+
+Like C<sv_catpvn>, 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<sprintf> and appends the formatted output
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, ...));
+ void sv_catpvf (SV* sv, const char* pat, ...)
+
+=item sv_catpvf_mg
+
+Like C<sv_catpvf>, but also handles 'set' magic.
+
+ void sv_catpvf_mg (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>. Handles 'get' magic, but not 'set' magic. See C<SvCatMagicSV).
+C<dsv>. Handles 'get' magic, but not 'set' magic. See C<sv_catsv_mg>.
+
+ void sv_catsv (SV* dsv, SV* ssv)
+
+=item sv_catsv_mg
- void sv_catsv _((SV* dsv, SV* ssv));
+Like C<sv_catsv>, 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<sv1> is less than, equal to, or greater than the string in
C<sv2>.
- 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<SvCUR>.
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<SvCUR>. 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<SvGROW>.
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<SvCUR>.
Returns the length of the string in the SV. Use C<SvCUR>.
- 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<private> setting. Use C<SvNOK>.
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<sv_setiv>, 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<sv_setnv>, 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<sv_setiv_mg>.
-A macro that calls C<sv_setpv>, 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<sv_setiv>, but also handles 'set' magic.
-A macro that calls C<sv_setpviv>, 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<sv_setnv_mg>.
-A macro that calls C<sv_setpvn>, 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<sv_setnv>, but also handles 'set' magic.
-Same as C<SvSetSV>, 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<SvSetSV_nosteal>, 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<sv_setpv_mg>.
- 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<sv_setuv>, and invokes 'set' magic on the SV.
-May evaluate arguments more than once.
+Like C<sv_setpv>, 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<SvSetMagicIV>.
+Copies an integer into the given SV, also updating its string value.
+Does not handle 'set' magic. See C<sv_setpviv_mg>.
- 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<SvSetMagicNV>.
+Like C<sv_setpviv>, 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<SvSetMagicPV>.
+Copies a string into an SV. The C<len> parameter indicates the number of
+bytes to be copied. Does not handle 'set' magic. See C<sv_setpvn_mg>.
- 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<SvSetMagicPVIV>.
+Like C<sv_setpvn>, 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<len> parameter indicates the number of
-bytes to be copied. Does not handle 'set' magic. See C<SvSetMagicPVN>.
+Processes its arguments like C<sprintf> and sets an SV to the formatted
+output. Does not handle 'set' magic. See C<sv_setpvf_mg>.
- 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<sprintf> and sets an SV to the formatted
-output. Does not handle 'set' magic. C<SvSETMAGIC()> must typically
-be called after calling this function to handle 'set' magic.
+Like C<sv_setpvf>, 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<classname> argument indicates the package for the
blessing. Set C<classname> to C<Nullch> 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<classname> argument indicates the package for the
blessing. Set C<classname> to C<Nullch> 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<classname> argument indicates the package for the
blessing. Set C<classname> to C<Nullch> 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<classname> to
C<Nullch> 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<sv_setref_pv> 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<ssv> into the destination SV C<dsv>.
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>.
+See the macro forms C<SvSetSV>, C<SvSetSV_nosteal> and C<sv_setsv_mg>.
+
+ void sv_setsv (SV* dsv, SV* ssv)
+
+=item sv_setsv_mg
+
+Like C<sv_setsv>, 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<SvSetMagicUV>.
+See C<sv_setuv_mg>.
- void sv_setuv _((SV* sv, UV num));
+ void sv_setuv (SV* sv, UV num)
+
+=item sv_setuv_mg
+
+Like C<sv_setuv>, but also handles 'set' magic.
+
+ void sv_setuv_mg (SV* sv, UV num)
=item SvSTASH
@@ -3142,7 +3150,7 @@ C<svtype> enum. Test these flags with the C<SvTYPE> macro.
Used to upgrade an SV to a more complex form. Uses C<sv_upgrade> to perform
the upgrade if necessary. See C<svtype>.
- 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<newSVrv>. See C<SvROK_off>.
- void sv_unref _((SV* sv));
-
-=item SvUseMagicPVN
+ void sv_unref (SV* sv)
=item sv_usepvn
@@ -3170,9 +3176,15 @@ 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. Does not handle 'set' magic.
-See C<SvUseMagicPVN>.
+See C<sv_usepvn_mg>.
+
+ void sv_usepvn (SV* sv, char* ptr, STRLEN len)
+
+=item sv_usepvn_mg
+
+Like C<sv_usepvn>, 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<xsubpp>.
Return from XSUB, indicating number of items on the stack. This is usually
handled by C<xsubpp>.
- 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<XST_mIV>.
- 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<XST_mNO>.
Return an double from an XSUB immediately. Uses C<XST_mNV>.
- XSRETURN_NV(NV v);
+ XSRETURN_NV(NV v)
=item XSRETURN_PV
Return a copy of a string from an XSUB immediately. Uses C<XST_mPV>.
- 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<XST_mYES>.
Place an integer into the specified position C<i> 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<i> 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<i> 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<i> 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<i> on the stack.
- XST_mUNDEF( int i );
+ XST_mUNDEF( int i )
=item XST_mYES
Place C<&sv_yes> into the specified position C<i> on the stack.
- XST_mYES( int i );
+ XST_mYES( int i )
=item XS_VERSION
@@ -3338,7 +3350,7 @@ C<xsubpp>. See L<perlxs/"The VERSIONCHECK: Keyword">.
The XSUB-writer's interface to the C C<memzero> function. The C<d> is the
destination, C<n> is the number of items, and C<t> is the type.
- (void) Zero( d, n, t );
+ (void) Zero( d, n, t )
=back
diff --git a/pod/perlobj.pod b/pod/perlobj.pod
index 7428334ee2..3d7bee8647 100644
--- a/pod/perlobj.pod
+++ b/pod/perlobj.pod
@@ -331,14 +331,24 @@ automatically destroyed. (This may even be after you exit, if you've
stored references in global variables.) If you want to capture control
just before the object is freed, you may define a DESTROY method in
your class. It will automatically be called at the appropriate moment,
-and you can do any extra cleanup you need to do.
-
-Perl doesn't do nested destruction for you. If your constructor
-re-blessed a reference from one of your base classes, your DESTROY may
-need to call DESTROY for any base classes that need it. But this applies
-to only re-blessed objects--an object reference that is merely
-I<CONTAINED> in the current object will be freed and destroyed
-automatically when the current object is freed.
+and you can do any extra cleanup you need to do. Perl passes a reference
+to the object under destruction as the first (and only) argument. Beware
+that the reference is a read-only value, and cannot be modified by
+manipulating C<$_[0]> within the destructor. The object itself (i.e.
+the thingy the reference points to, namely C<${$_[0]}>, C<@{$_[0]}>,
+C<%{$_[0]}> etc.) is not similarly constrained.
+
+If you arrange to re-bless the reference before the destructor returns,
+perl will again call the DESTROY method for the re-blessed object after
+the current one returns. This can be used for clean delegation of
+object destruction, or for ensuring that destructors in the base classes
+of your choosing get called. Explicitly calling DESTROY is also possible,
+but is usually never needed.
+
+Do not confuse the foregoing with how objects I<CONTAINED> in the current
+one are destroyed. Such objects will be freed and destroyed automatically
+when the current object is freed, provided no other references to them exist
+elsewhere.
=head2 WARNING
diff --git a/pod/perlxs.pod b/pod/perlxs.pod
index d257b196eb..07abd10564 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<perlguts> for details about C<SvSetMagicNV()>.
+ timep sv_setnv(ST(1), (double)timep);
+
+B<xsubpp> emits an automatic C<SvSETMAGIC()> 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<SETMAGIC: DISABLE> line
+to disable it for the remainder of the parameters in the OUTPUT section.
+Likewise, C<SETMAGIC: ENABLE> can be used to reenable it for the
+remainder of the OUTPUT section. See L<perlguts> 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<perlguts> 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 dfc56ffbf1..867d42a8c2 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<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 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.
=head2 WARNING
diff --git a/proto.h b/proto.h
index 1b1504e336..4df73df835 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 b0d81f3ef5..1ab0e315e7 100644
--- a/sv.c
+++ b/sv.c
@@ -59,6 +59,10 @@ static void sv_mortalgrow _((void));
static void sv_unglob _((SV* sv));
static void sv_check_thinkfirst _((SV *sv));
+#ifndef PURIFY
+static void *my_safemalloc(MEM_SIZE size);
+#endif
+
typedef void (*SVFUNC) _((SV*));
#ifdef PURIFY
@@ -576,8 +580,7 @@ more_xpv(void)
# define my_safefree(s) free(s)
#else
static void*
-my_safemalloc(size)
- MEM_SIZE size;
+my_safemalloc(MEM_SIZE size)
{
char *p;
New(717, p, size, char);
@@ -1135,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)
@@ -1144,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);
@@ -1187,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)
{
@@ -2166,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
@@ -2190,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;
@@ -2214,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);
@@ -2234,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)
{
@@ -2291,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;
@@ -2302,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;
@@ -2321,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)
@@ -2643,37 +2716,37 @@ sv_clear(register SV *sv)
if (defstash) { /* Still have a symbol table? */
djSP;
GV* destructor;
+ HV* stash;
+ SV ref;
- ENTER;
- SAVEFREESV(SvSTASH(sv));
-
- destructor = gv_fetchmethod(SvSTASH(sv), "DESTROY");
- if (destructor) {
- SV ref;
-
- Zero(&ref, 1, SV);
- sv_upgrade(&ref, SVt_RV);
- SvRV(&ref) = SvREFCNT_inc(sv);
- SvROK_on(&ref);
- SvREFCNT(&ref) = 1; /* Fake, but otherwise
- creating+destructing a ref
- leads to disaster. */
-
- EXTEND(SP, 2);
- PUSHMARK(SP);
- PUSHs(&ref);
- PUTBACK;
- perl_call_sv((SV*)GvCV(destructor),
- G_DISCARD|G_EVAL|G_KEEPERR);
- del_XRV(SvANY(&ref));
- SvREFCNT(sv)--;
- }
+ Zero(&ref, 1, SV);
+ sv_upgrade(&ref, SVt_RV);
+ SvROK_on(&ref);
+ SvREADONLY_on(&ref); /* DESTROY() could be naughty */
+ SvREFCNT(&ref) = 1;
- LEAVE;
+ do {
+ stash = SvSTASH(sv);
+ destructor = gv_fetchmethod(SvSTASH(sv), "DESTROY");
+ if (destructor) {
+ ENTER;
+ SvRV(&ref) = SvREFCNT_inc(sv);
+ EXTEND(SP, 2);
+ PUSHMARK(SP);
+ PUSHs(&ref);
+ PUTBACK;
+ perl_call_sv((SV*)GvCV(destructor),
+ G_DISCARD|G_EVAL|G_KEEPERR);
+ SvREFCNT(sv)--;
+ LEAVE;
+ }
+ } while (SvOBJECT(sv) && SvSTASH(sv) != stash);
+
+ del_XRV(SvANY(&ref));
}
- else
- SvREFCNT_dec(SvSTASH(sv));
+
if (SvOBJECT(sv)) {
+ SvREFCNT_dec(SvSTASH(sv)); /* possibly of changed persuasion */
SvOBJECT_off(sv); /* Curse the object. */
if (SvTYPE(sv) != SVt_PVIO)
--sv_objcount; /* XXX Might want something more general */
@@ -4086,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, ...)
@@ -4108,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, ...)
@@ -4130,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 66fab163cd..5993a8de9b 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)
diff --git a/t/op/ref.t b/t/op/ref.t
index 56925177d1..1d70f9fd4c 100755
--- a/t/op/ref.t
+++ b/t/op/ref.t
@@ -1,6 +1,6 @@
#!./perl
-print "1..52\n";
+print "1..55\n";
# Test glob operations.
@@ -235,12 +235,50 @@ $var = "ok 49";
$_ = \$var;
print $$_,"\n";
+# test if reblessing during destruction results in more destruction
+
+{
+ package A;
+ sub new { bless {}, shift }
+ DESTROY { print "# destroying 'A'\nok 51\n" }
+ package B;
+ sub new { bless {}, shift }
+ DESTROY { print "# destroying 'B'\nok 50\n"; bless shift, 'A' }
+ package main;
+ my $b = B->new;
+}
+
+# test if $_[0] is properly protected in DESTROY()
+
+{
+ my $i = 0;
+ local $SIG{'__DIE__'} = sub {
+ my $m = shift;
+ if ($i++ > 4) {
+ print "# infinite recursion, bailing\nnot ok 52\n";
+ exit 1;
+ }
+ print "# $m";
+ if ($m =~ /^Modification of a read-only/) { print "ok 52\n" }
+ };
+ package C;
+ sub new { bless {}, shift }
+ DESTROY { $_[0] = 'foo' }
+ {
+ print "# should generate an error...\n";
+ my $c = C->new;
+ }
+ print "# good, didn't recurse\n";
+}
+
+# test global destruction
+
package FINALE;
{
- $ref3 = bless ["ok 52\n"]; # package destruction
- my $ref2 = bless ["ok 51\n"]; # lexical destruction
- local $ref1 = bless ["ok 50\n"]; # dynamic destruction
+ $ref3 = bless ["ok 55\n"]; # package destruction
+ my $ref2 = bless ["ok 54\n"]; # lexical destruction
+ local $ref1 = bless ["ok 53\n"]; # dynamic destruction
1; # flush any temp values on stack
}
diff --git a/win32/makedef.pl b/win32/makedef.pl
index e0312e2494..46e4374838 100644
--- a/win32/makedef.pl
+++ b/win32/makedef.pl
@@ -509,6 +509,7 @@ win32_alarm
win32_open_osfhandle
win32_get_osfhandle
win32_ioctl
+win32_utime
win32_wait
win32_str_os_error
Perl_win32_init
diff --git a/win32/win32.c b/win32/win32.c
index 9ae2a7d70f..3eeaa6a988 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -35,6 +35,12 @@
#include <string.h>
#include <stdarg.h>
#include <float.h>
+#include <time.h>
+#ifdef _MSC_VER
+#include <sys/utime.h>
+#else
+#include <utime.h>
+#endif
#ifdef __GNUC__
/* Mingw32 defaults to globing command line
@@ -53,6 +59,7 @@ static long tokenize(char *str, char **dest, char ***destv);
static int do_spawn2(char *cmd, int exectype);
static BOOL has_redirection(char *ptr);
static long filetime_to_clock(PFILETIME ft);
+static BOOL filetime_from_time(PFILETIME ft, time_t t);
char * w32_perlshell_tokens = Nullch;
char ** w32_perlshell_vec;
@@ -469,7 +476,10 @@ opendir(char *filename)
/* check to see if filename is a directory */
if (win32_stat(filename, &sbuf) < 0 || (sbuf.st_mode & S_IFDIR) == 0) {
- return NULL;
+ /* CRT is buggy on sharenames, so make sure it really isn't */
+ DWORD r = GetFileAttributes(filename);
+ if (r == 0xffffffff || !(r & FILE_ATTRIBUTE_DIRECTORY))
+ return NULL;
}
/* get the file system characteristics */
@@ -800,6 +810,68 @@ win32_times(struct tms *timebuf)
return 0;
}
+/* fix utime() so it works on directories in NT
+ * thanks to Jan Dubois <jan.dubois@ibm.net>
+ */
+static BOOL
+filetime_from_time(PFILETIME pFileTime, time_t Time)
+{
+ struct tm *pTM = gmtime(&Time);
+ SYSTEMTIME SystemTime;
+
+ if (pTM == NULL)
+ return FALSE;
+
+ SystemTime.wYear = pTM->tm_year + 1900;
+ SystemTime.wMonth = pTM->tm_mon + 1;
+ SystemTime.wDay = pTM->tm_mday;
+ SystemTime.wHour = pTM->tm_hour;
+ SystemTime.wMinute = pTM->tm_min;
+ SystemTime.wSecond = pTM->tm_sec;
+ SystemTime.wMilliseconds = 0;
+
+ return SystemTimeToFileTime(&SystemTime, pFileTime);
+}
+
+DllExport int
+win32_utime(const char *filename, struct utimbuf *times)
+{
+ HANDLE handle;
+ FILETIME ftCreate;
+ FILETIME ftAccess;
+ FILETIME ftWrite;
+ struct utimbuf TimeBuffer;
+
+ int rc = utime(filename,times);
+ /* EACCES: path specifies directory or readonly file */
+ if (rc == 0 || errno != EACCES /* || !IsWinNT() */)
+ return rc;
+
+ if (times == NULL) {
+ times = &TimeBuffer;
+ time(&times->actime);
+ times->modtime = times->actime;
+ }
+
+ /* This will (and should) still fail on readonly files */
+ handle = CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (handle == INVALID_HANDLE_VALUE)
+ return rc;
+
+ if (GetFileTime(handle, &ftCreate, &ftAccess, &ftWrite) &&
+ filetime_from_time(&ftAccess, times->actime) &&
+ filetime_from_time(&ftWrite, times->modtime) &&
+ SetFileTime(handle, &ftCreate, &ftAccess, &ftWrite))
+ {
+ rc = 0;
+ }
+
+ CloseHandle(handle);
+ return rc;
+}
+
DllExport int
win32_wait(int *status)
{
@@ -1885,15 +1957,22 @@ XS(w32_GetShortPathName)
XSRETURN(1);
}
+static
+XS(w32_Sleep)
+{
+ dXSARGS;
+ if (items != 1)
+ croak("usage: Win32::Sleep($milliseconds)");
+ Sleep(SvIV(ST(0)));
+ XSRETURN_YES;
+}
+
void
Perl_init_os_extras()
{
char *file = __FILE__;
dXSUB_SYS;
- /* XXX should be removed after checking with Nick */
- newXS("Win32::GetCurrentDirectory", w32_GetCwd, file);
-
/* these names are Activeware compatible */
newXS("Win32::GetCwd", w32_GetCwd, file);
newXS("Win32::SetCwd", w32_SetCwd, file);
@@ -1910,6 +1989,7 @@ Perl_init_os_extras()
newXS("Win32::Spawn", w32_Spawn, file);
newXS("Win32::GetTickCount", w32_GetTickCount, file);
newXS("Win32::GetShortPathName", w32_GetShortPathName, file);
+ newXS("Win32::Sleep", w32_Sleep, file);
/* XXX Bloat Alert! The following Activeware preloads really
* ought to be part of Win32::Sys::*, so they're not included
@@ -1962,11 +2042,3 @@ win32_strip_return(SV *sv)
}
#endif
-
-
-
-
-
-
-
-
diff --git a/win32/win32iop.h b/win32/win32iop.h
index e71bf3865e..d77f542500 100644
--- a/win32/win32iop.h
+++ b/win32/win32iop.h
@@ -13,6 +13,12 @@
#endif
#endif
+#ifdef _MSC_VER
+# include <sys/utime.h>
+#else
+# include <utime.h>
+#endif
+
/*
* defines for flock emulation
*/
@@ -114,6 +120,7 @@ DllExport int win32_times(struct tms *timebuf);
DllExport unsigned win32_alarm(unsigned int sec);
DllExport int win32_stat(const char *path, struct stat *buf);
DllExport int win32_ioctl(int i, unsigned int u, char *data);
+DllExport int win32_utime(const char *f, struct utimbuf *t);
DllExport int win32_wait(int *status);
#ifdef HAVE_DES_FCRYPT
@@ -140,6 +147,7 @@ END_EXTERN_C
#undef times
#undef alarm
#undef ioctl
+#undef utime
#undef wait
#ifdef __BORLANDC__
@@ -240,6 +248,7 @@ END_EXTERN_C
#define times win32_times
#define alarm win32_alarm
#define ioctl win32_ioctl
+#define utime win32_utime
#define wait win32_wait
#ifdef HAVE_DES_FCRYPT