Move Devel::PPPort from ext/ to cpan/
[p5sagit/p5-mst-13.2.git] / cpan / Devel-PPPort / parts / inc / magic
CommitLineData
adfe19db 1################################################################################
2##
51d6c659 3## $Revision: 17 $
adfe19db 4## $Author: mhx $
51d6c659 5## $Date: 2009/01/18 14:10:55 +0100 $
adfe19db 6##
7################################################################################
8##
51d6c659 9## Version 3.x, Copyright (C) 2004-2009, Marcus Holland-Moritz.
adfe19db 10## Version 2.x, Copyright (C) 2001, Paul Marquess.
11## Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
12##
13## This program is free software; you can redistribute it and/or
14## modify it under the same terms as Perl itself.
15##
16################################################################################
17
18=provides
19
20__UNDEFINED__
21/sv_\w+_mg/
679ad62d 22sv_magic_portable
adfe19db 23
24=implementation
25
26__UNDEFINED__ SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
27
28__UNDEFINED__ PERL_MAGIC_sv '\0'
29__UNDEFINED__ PERL_MAGIC_overload 'A'
30__UNDEFINED__ PERL_MAGIC_overload_elem 'a'
31__UNDEFINED__ PERL_MAGIC_overload_table 'c'
32__UNDEFINED__ PERL_MAGIC_bm 'B'
33__UNDEFINED__ PERL_MAGIC_regdata 'D'
34__UNDEFINED__ PERL_MAGIC_regdatum 'd'
35__UNDEFINED__ PERL_MAGIC_env 'E'
36__UNDEFINED__ PERL_MAGIC_envelem 'e'
37__UNDEFINED__ PERL_MAGIC_fm 'f'
38__UNDEFINED__ PERL_MAGIC_regex_global 'g'
39__UNDEFINED__ PERL_MAGIC_isa 'I'
40__UNDEFINED__ PERL_MAGIC_isaelem 'i'
41__UNDEFINED__ PERL_MAGIC_nkeys 'k'
42__UNDEFINED__ PERL_MAGIC_dbfile 'L'
43__UNDEFINED__ PERL_MAGIC_dbline 'l'
44__UNDEFINED__ PERL_MAGIC_mutex 'm'
45__UNDEFINED__ PERL_MAGIC_shared 'N'
46__UNDEFINED__ PERL_MAGIC_shared_scalar 'n'
47__UNDEFINED__ PERL_MAGIC_collxfrm 'o'
48__UNDEFINED__ PERL_MAGIC_tied 'P'
49__UNDEFINED__ PERL_MAGIC_tiedelem 'p'
50__UNDEFINED__ PERL_MAGIC_tiedscalar 'q'
51__UNDEFINED__ PERL_MAGIC_qr 'r'
52__UNDEFINED__ PERL_MAGIC_sig 'S'
53__UNDEFINED__ PERL_MAGIC_sigelem 's'
54__UNDEFINED__ PERL_MAGIC_taint 't'
55__UNDEFINED__ PERL_MAGIC_uvar 'U'
56__UNDEFINED__ PERL_MAGIC_uvar_elem 'u'
57__UNDEFINED__ PERL_MAGIC_vstring 'V'
58__UNDEFINED__ PERL_MAGIC_vec 'v'
59__UNDEFINED__ PERL_MAGIC_utf8 'w'
60__UNDEFINED__ PERL_MAGIC_substr 'x'
61__UNDEFINED__ PERL_MAGIC_defelem 'y'
62__UNDEFINED__ PERL_MAGIC_glob '*'
63__UNDEFINED__ PERL_MAGIC_arylen '#'
64__UNDEFINED__ PERL_MAGIC_pos '.'
65__UNDEFINED__ PERL_MAGIC_backref '<'
66__UNDEFINED__ PERL_MAGIC_ext '~'
67
68/* That's the best we can do... */
adfe19db 69__UNDEFINED__ sv_catpvn_nomg sv_catpvn
70__UNDEFINED__ sv_catsv_nomg sv_catsv
71__UNDEFINED__ sv_setsv_nomg sv_setsv
72__UNDEFINED__ sv_pvn_nomg sv_pvn
73__UNDEFINED__ SvIV_nomg SvIV
74__UNDEFINED__ SvUV_nomg SvUV
75
76#ifndef sv_catpv_mg
77# define sv_catpv_mg(sv, ptr) \
78 STMT_START { \
79 SV *TeMpSv = sv; \
80 sv_catpv(TeMpSv,ptr); \
81 SvSETMAGIC(TeMpSv); \
82 } STMT_END
83#endif
84
85#ifndef sv_catpvn_mg
86# define sv_catpvn_mg(sv, ptr, len) \
87 STMT_START { \
88 SV *TeMpSv = sv; \
89 sv_catpvn(TeMpSv,ptr,len); \
90 SvSETMAGIC(TeMpSv); \
91 } STMT_END
92#endif
93
94#ifndef sv_catsv_mg
95# define sv_catsv_mg(dsv, ssv) \
96 STMT_START { \
97 SV *TeMpSv = dsv; \
98 sv_catsv(TeMpSv,ssv); \
99 SvSETMAGIC(TeMpSv); \
100 } STMT_END
101#endif
102
103#ifndef sv_setiv_mg
104# define sv_setiv_mg(sv, i) \
105 STMT_START { \
106 SV *TeMpSv = sv; \
107 sv_setiv(TeMpSv,i); \
108 SvSETMAGIC(TeMpSv); \
109 } STMT_END
110#endif
111
112#ifndef sv_setnv_mg
113# define sv_setnv_mg(sv, num) \
114 STMT_START { \
115 SV *TeMpSv = sv; \
116 sv_setnv(TeMpSv,num); \
117 SvSETMAGIC(TeMpSv); \
118 } STMT_END
119#endif
120
121#ifndef sv_setpv_mg
122# define sv_setpv_mg(sv, ptr) \
123 STMT_START { \
124 SV *TeMpSv = sv; \
125 sv_setpv(TeMpSv,ptr); \
126 SvSETMAGIC(TeMpSv); \
127 } STMT_END
128#endif
129
130#ifndef sv_setpvn_mg
131# define sv_setpvn_mg(sv, ptr, len) \
132 STMT_START { \
133 SV *TeMpSv = sv; \
134 sv_setpvn(TeMpSv,ptr,len); \
135 SvSETMAGIC(TeMpSv); \
136 } STMT_END
137#endif
138
139#ifndef sv_setsv_mg
140# define sv_setsv_mg(dsv, ssv) \
141 STMT_START { \
142 SV *TeMpSv = dsv; \
143 sv_setsv(TeMpSv,ssv); \
144 SvSETMAGIC(TeMpSv); \
145 } STMT_END
146#endif
147
148#ifndef sv_setuv_mg
149# define sv_setuv_mg(sv, i) \
150 STMT_START { \
151 SV *TeMpSv = sv; \
152 sv_setuv(TeMpSv,i); \
153 SvSETMAGIC(TeMpSv); \
154 } STMT_END
155#endif
156
157#ifndef sv_usepvn_mg
158# define sv_usepvn_mg(sv, ptr, len) \
159 STMT_START { \
160 SV *TeMpSv = sv; \
161 sv_usepvn(TeMpSv,ptr,len); \
162 SvSETMAGIC(TeMpSv); \
163 } STMT_END
164#endif
165
f2ab5a41 166__UNDEFINED__ SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL)
167
679ad62d 168/* Hint: sv_magic_portable
169 * This is a compatibility function that is only available with
170 * Devel::PPPort. It is NOT in the perl core.
171 * Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when
172 * it is being passed a name pointer with namlen == 0. In that
173 * case, perl 5.8.0 and later store the pointer, not a copy of it.
174 * The compatibility can be provided back to perl 5.004. With
175 * earlier versions, the code will not compile.
176 */
177
178#if { VERSION < 5.004 }
179
180 /* code that uses sv_magic_portable will not compile */
181
182#elif { VERSION < 5.8.0 }
183
c83e6f19 184# define sv_magic_portable(sv, obj, how, name, namlen) \
185 STMT_START { \
186 SV *SvMp_sv = (sv); \
187 char *SvMp_name = (char *) (name); \
188 I32 SvMp_namlen = (namlen); \
189 if (SvMp_name && SvMp_namlen == 0) \
190 { \
191 MAGIC *mg; \
192 sv_magic(SvMp_sv, obj, how, 0, 0); \
193 mg = SvMAGIC(SvMp_sv); \
194 mg->mg_len = -42; /* XXX: this is the tricky part */ \
195 mg->mg_ptr = SvMp_name; \
196 } \
197 else \
198 { \
199 sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \
200 } \
679ad62d 201 } STMT_END
202
203#else
204
205# define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e)
206
207#endif
208
adfe19db 209=xsubs
210
211void
212sv_catpv_mg(sv, string)
213 SV *sv;
214 char *string;
215 CODE:
216 sv_catpv_mg(sv, string);
217
218void
219sv_catpvn_mg(sv, sv2)
220 SV *sv;
221 SV *sv2;
222 PREINIT:
223 char *str;
224 STRLEN len;
225 CODE:
226 str = SvPV(sv2, len);
227 sv_catpvn_mg(sv, str, len);
228
229void
230sv_catsv_mg(sv, sv2)
231 SV *sv;
232 SV *sv2;
233 CODE:
234 sv_catsv_mg(sv, sv2);
235
236void
237sv_setiv_mg(sv, iv)
238 SV *sv;
239 IV iv;
240 CODE:
241 sv_setiv_mg(sv, iv);
242
243void
244sv_setnv_mg(sv, nv)
245 SV *sv;
246 NV nv;
247 CODE:
248 sv_setnv_mg(sv, nv);
249
250void
251sv_setpv_mg(sv, pv)
252 SV *sv;
253 char *pv;
254 CODE:
255 sv_setpv_mg(sv, pv);
256
257void
258sv_setpvn_mg(sv, sv2)
259 SV *sv;
260 SV *sv2;
261 PREINIT:
262 char *str;
263 STRLEN len;
264 CODE:
265 str = SvPV(sv2, len);
266 sv_setpvn_mg(sv, str, len);
267
268void
269sv_setsv_mg(sv, sv2)
270 SV *sv;
271 SV *sv2;
272 CODE:
273 sv_setsv_mg(sv, sv2);
274
275void
276sv_setuv_mg(sv, uv)
277 SV *sv;
278 UV uv;
279 CODE:
280 sv_setuv_mg(sv, uv);
281
282void
283sv_usepvn_mg(sv, sv2)
284 SV *sv;
285 SV *sv2;
286 PREINIT:
287 char *str, *copy;
288 STRLEN len;
289 CODE:
290 str = SvPV(sv2, len);
291 New(42, copy, len+1, char);
292 Copy(str, copy, len+1, char);
293 sv_usepvn_mg(sv, copy, len);
294
f2ab5a41 295int
296SvVSTRING_mg(sv)
297 SV *sv;
298 CODE:
299 RETVAL = SvVSTRING_mg(sv) != NULL;
300 OUTPUT:
301 RETVAL
302
679ad62d 303int
304sv_magic_portable(sv)
305 SV *sv
306 PREINIT:
307 MAGIC *mg;
308 const char *foo = "foo";
309 CODE:
310#if { VERSION >= 5.004 }
311 sv_magic_portable(sv, 0, '~', foo, 0);
312 mg = mg_find(sv, '~');
313 RETVAL = mg->mg_ptr == foo;
314#else
aab9a3b6 315 sv_magic(sv, 0, '~', (char *) foo, strlen(foo));
679ad62d 316 mg = mg_find(sv, '~');
317 RETVAL = strEQ(mg->mg_ptr, foo);
318#endif
319 sv_unmagic(sv, '~');
320 OUTPUT:
321 RETVAL
322
323=tests plan => 15
adfe19db 324
325use Tie::Hash;
326my %h;
327tie %h, 'Tie::StdHash';
328$h{foo} = 'foo';
329$h{bar} = '';
330
331&Devel::PPPort::sv_catpv_mg($h{foo}, 'bar');
332ok($h{foo}, 'foobar');
333
334&Devel::PPPort::sv_catpvn_mg($h{bar}, 'baz');
335ok($h{bar}, 'baz');
336
337&Devel::PPPort::sv_catsv_mg($h{foo}, '42');
338ok($h{foo}, 'foobar42');
339
340&Devel::PPPort::sv_setiv_mg($h{bar}, 42);
341ok($h{bar}, 42);
342
343&Devel::PPPort::sv_setnv_mg($h{PI}, 3.14159);
344ok(abs($h{PI} - 3.14159) < 0.01);
345
346&Devel::PPPort::sv_setpv_mg($h{mhx}, 'mhx');
347ok($h{mhx}, 'mhx');
348
349&Devel::PPPort::sv_setpvn_mg($h{mhx}, 'Marcus');
350ok($h{mhx}, 'Marcus');
351
352&Devel::PPPort::sv_setsv_mg($h{sv}, 'SV');
353ok($h{sv}, 'SV');
354
355&Devel::PPPort::sv_setuv_mg($h{sv}, 4711);
356ok($h{sv}, 4711);
357
358&Devel::PPPort::sv_usepvn_mg($h{sv}, 'Perl');
359ok($h{sv}, 'Perl');
360
f2ab5a41 361my $ver = eval qq[qv("v1.2.0")];
362ok($[ < 5.009 || $@ eq '');
363ok($@ || Devel::PPPort::SvVSTRING_mg($ver));
364ok(!Devel::PPPort::SvVSTRING_mg(4711));
365
679ad62d 366my $foo = 'bar';
367ok(Devel::PPPort::sv_magic_portable($foo));
368ok($foo eq 'bar');
369