1 ################################################################################
3 ## Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
4 ## Version 2.x, Copyright (C) 2001, Paul Marquess.
5 ## Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
7 ## This program is free software; you can redistribute it and/or
8 ## modify it under the same terms as Perl itself.
10 ################################################################################
21 __UNDEFINED__ SV_NOSTEAL 16
23 #if ( { VERSION >= 5.7.3 } && { VERSION < 5.8.7 } ) || ( { VERSION >= 5.9.0 } && { VERSION < 5.9.2 } )
25 #if defined(PERL_USE_GCC_BRACE_GROUPS)
26 #define sv_setsv_flags(dstr, sstr, flags) \
28 if (((flags) & SV_NOSTEAL) && (sstr) && (SvFLAGS((SV *)(sstr)) & SVs_TEMP)) { \
29 SvTEMP_off((SV *)(sstr)); \
30 Perl_sv_setsv_flags(aTHX_ (dstr), (sstr), (flags) & ~SV_NOSTEAL); \
31 SvTEMP_on((SV *)(sstr)); \
33 Perl_sv_setsv_flags(aTHX_ (dstr), (sstr), (flags) & ~SV_NOSTEAL); \
38 (((flags) & SV_NOSTEAL) && (sstr) && (SvFLAGS((SV *)(sstr)) & SVs_TEMP)) ? ( \
39 SvTEMP_off((SV *)(sstr)), \
40 Perl_sv_setsv_flags(aTHX_ (dstr), (sstr), (flags) & ~SV_NOSTEAL), \
41 SvTEMP_on((SV *)(sstr)), \
44 Perl_sv_setsv_flags(aTHX_ (dstr), (sstr), (flags) & ~SV_NOSTEAL), \
51 #if defined(PERL_USE_GCC_BRACE_GROUPS)
52 __UNDEFINED__ sv_setsv_flags(dstr, sstr, flags) \
54 if (((flags) & SV_NOSTEAL) && (sstr) && (SvFLAGS((SV *)(sstr)) & SVs_TEMP)) { \
55 SvTEMP_off((SV *)(sstr)); \
56 if (!((flags) & SV_GMAGIC) && (sstr) && SvGMAGICAL((SV *)(sstr))) { \
57 SvGMAGICAL_off((SV *)(sstr)); \
58 sv_setsv((dstr), (sstr)); \
59 SvGMAGICAL_on((SV *)(sstr)); \
61 sv_setsv((dstr), (sstr)); \
63 SvTEMP_on((SV *)(sstr)); \
65 if (!((flags) & SV_GMAGIC) && (sstr) && SvGMAGICAL((SV *)(sstr))) { \
66 SvGMAGICAL_off((SV *)(sstr)); \
67 sv_setsv((dstr), (sstr)); \
68 SvGMAGICAL_on((SV *)(sstr)); \
70 sv_setsv((dstr), (sstr)); \
75 __UNDEFINED__ sv_setsv_flags(dstr, sstr, flags) \
77 (((flags) & SV_NOSTEAL) && (sstr) && (SvFLAGS((SV *)(sstr)) & SVs_TEMP)) ? ( \
78 SvTEMP_off((SV *)(sstr)), \
79 (!((flags) & SV_GMAGIC) && (sstr) && SvGMAGICAL((SV *)(sstr))) ? ( \
80 SvGMAGICAL_off((SV *)(sstr)), \
81 sv_setsv((dstr), (sstr)), \
82 SvGMAGICAL_on((SV *)(sstr)), \
85 sv_setsv((dstr), (sstr)), \
88 SvTEMP_on((SV *)(sstr)), \
91 (!((flags) & SV_GMAGIC) && (sstr) && SvGMAGICAL((SV *)(sstr))) ? ( \
92 SvGMAGICAL_off((SV *)(sstr)), \
93 sv_setsv((dstr), (sstr)), \
94 SvGMAGICAL_on((SV *)(sstr)), \
97 sv_setsv((dstr), (sstr)), \
104 #if defined(PERL_USE_GCC_BRACE_GROUPS)
105 __UNDEFINED__ newSVsv_flags(sv, flags) ({ SV *_sv = newSV(0); sv_setsv_flags(_sv, (sv), (flags)); _sv; })
107 __UNDEFINED__ newSVsv_flags(sv, flags) ((PL_Sv = newSV(0)), sv_setsv_flags(PL_Sv, (sv), (flags)), PL_Sv)
110 __UNDEFINED__ newSVsv_nomg(sv) newSVsv_flags((sv), SV_NOSTEAL)
112 #if { VERSION >= 5.17.5 }
113 __UNDEFINED__ sv_mortalcopy_flags(sv, flags) Perl_sv_mortalcopy_flags(aTHX_ (sv), (flags))
115 __UNDEFINED__ sv_mortalcopy_flags(sv, flags) sv_2mortal(newSVsv_flags((sv), (flags)))
118 __UNDEFINED__ SvMAGIC_set(sv, val) \
119 STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
120 (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END
122 #if { VERSION < 5.9.3 }
124 __UNDEFINED__ SvPVX_const(sv) ((const char*) (0 + SvPVX(sv)))
125 __UNDEFINED__ SvPVX_mutable(sv) (0 + SvPVX(sv))
127 __UNDEFINED__ SvRV_set(sv, val) \
128 STMT_START { assert(SvTYPE(sv) >= SVt_RV); \
129 (((XRV*) SvANY(sv))->xrv_rv = (val)); } STMT_END
133 __UNDEFINED__ SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv))
134 __UNDEFINED__ SvPVX_mutable(sv) ((sv)->sv_u.svu_pv)
136 __UNDEFINED__ SvRV_set(sv, val) \
137 STMT_START { assert(SvTYPE(sv) >= SVt_RV); \
138 ((sv)->sv_u.svu_rv = (val)); } STMT_END
142 __UNDEFINED__ SvSTASH_set(sv, val) \
143 STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
144 (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END
146 #if { VERSION < 5.004 }
148 __UNDEFINED__ SvUV_set(sv, val) \
149 STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
150 (((XPVIV*) SvANY(sv))->xiv_iv = (IV) (val)); } STMT_END
154 __UNDEFINED__ SvUV_set(sv, val) \
155 STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
156 (((XPVUV*) SvANY(sv))->xuv_uv = (val)); } STMT_END
163 TestSvUV_set(sv, val)
168 RETVAL = SvUVX(sv) == val ? 42 : -1;
176 RETVAL = strEQ(SvPVX_const(sv), "mhx") ? 43 : -1;
181 TestSvPVX_mutable(sv)
184 RETVAL = strEQ(SvPVX_mutable(sv), "mhx") ? 44 : -1;
189 TestSvSTASH_set(sv, name)
194 SvREFCNT_dec(SvSTASH(sv));
195 SvSTASH_set(sv, (HV*) SvREFCNT_inc(gv_stashpv(name, 0)));
198 Test_sv_setsv_SV_NOSTEAL()
202 sv1 = sv_2mortal(newSVpv("test1", 0));
203 sv2 = sv_2mortal(newSVpv("test2", 0));
204 sv_setsv_flags(sv2, sv1, SV_NOSTEAL);
205 RETVAL = (strEQ(SvPV_nolen(sv1), "test1") && strEQ(SvPV_nolen(sv2), "test1"));
213 RETVAL = newSVsv_nomg(sv);
218 sv_setsv_compile_test(sv)
222 sv_setsv_flags(sv, NULL, 0);
223 sv_setsv_flags(sv, NULL, SV_NOSTEAL);
228 is(&Devel::PPPort::TestSvUV_set($foo, 12345), 42);
229 is(&Devel::PPPort::TestSvPVX_const("mhx"), 43);
230 is(&Devel::PPPort::TestSvPVX_mutable("mhx"), 44);
235 is($bar->x(), 'foobar');
237 Devel::PPPort::TestSvSTASH_set($bar, 'bar');
238 is($bar->x(), 'hacker');
240 if (ivers($]) != ivers(5.7.2)) {
241 ok(Devel::PPPort::Test_sv_setsv_SV_NOSTEAL());
244 skip("7.2 broken for NOSTEAL", 1);
247 tie my $scalar, 'TieScalarCounter', 'string';
249 is tied($scalar)->{fetch}, 0;
250 is tied($scalar)->{store}, 0;
251 my $copy = Devel::PPPort::newSVsv_nomg($scalar);
252 is tied($scalar)->{fetch}, 0;
253 is tied($scalar)->{store}, 0;
256 is tied($scalar)->{fetch}, 1;
257 is tied($scalar)->{store}, 0;
258 my $copy2 = Devel::PPPort::newSVsv_nomg($scalar);
259 is tied($scalar)->{fetch}, 1;
260 is tied($scalar)->{store}, 0;
263 package TieScalarCounter;
266 my ($class, $value) = @_;
267 return bless { fetch => 0, store => 0, value => $value }, $class;
273 return $self->{value};
277 my ($self, $value) = @_;
279 $self->{value} = $value;