This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update Devel-PPPort to match 3.67
[perl5.git] / dist / Devel-PPPort / parts / inc / SvPV
1 ################################################################################
2 ##
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.
6 ##
7 ##  This program is free software; you can redistribute it and/or
8 ##  modify it under the same terms as Perl itself.
9 ##
10 ################################################################################
11
12 =provides
13
14 __UNDEFINED__
15 SvPVbyte
16 sv_2pvbyte
17 sv_2pv_flags
18 sv_pvn_force_flags
19
20 =implementation
21
22 /* Hint: sv_2pv_nolen
23  * Use the SvPV_nolen() or SvPV_nolen_const() macros instead of sv_2pv_nolen().
24  */
25
26 __UNDEFINED__  sv_2pv_nolen(sv)   SvPV_nolen(sv)
27
28 #ifdef SvPVbyte
29
30 /* Hint: SvPVbyte
31  * Does not work in perl-5.6.1, ppport.h implements a version
32  * borrowed from perl-5.7.3.
33  */
34
35 #if { VERSION < 5.7.0 }
36
37 __UNDEFINED__ sv_2pvbyte(sv, lp) (sv_utf8_downgrade((sv), 0), SvPV((sv), *(lp)))
38
39 /* Hint: sv_2pvbyte
40  * Use the SvPVbyte() macro instead of sv_2pvbyte().
41  */
42
43 /* Replace sv_2pvbyte with SvPVbyte */
44
45 #undef SvPVbyte
46
47 #define SvPVbyte(sv, lp)                                                \
48         ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK)                \
49          ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp))
50
51 #endif
52
53 #else
54
55 #  define SvPVbyte          SvPV
56 #  define sv_2pvbyte        sv_2pv
57
58 #endif
59
60 __UNDEFINED__  sv_2pvbyte_nolen(sv)  sv_2pv_nolen(sv)
61
62 /* Hint: sv_pvn
63  * Always use the SvPV() macro instead of sv_pvn().
64  */
65
66 /* Replace sv_pvn with SvPV */
67
68 /* Hint: sv_pvn_force
69  * Always use the SvPV_force() macro instead of sv_pvn_force().
70  */
71
72 /* Replace sv_pvn_force with SvPV_force */
73
74 /* If these are undefined, they're not handled by the core anyway */
75 __UNDEFINED__  SV_IMMEDIATE_UNREF       0
76 __UNDEFINED__  SV_GMAGIC                0
77 __UNDEFINED__  SV_COW_DROP_PV           0
78 __UNDEFINED__  SV_UTF8_NO_ENCODING      0
79 __UNDEFINED__  SV_CONST_RETURN          0
80 __UNDEFINED__  SV_MUTABLE_RETURN        0
81 __UNDEFINED__  SV_SMAGIC                0
82 __UNDEFINED__  SV_HAS_TRAILING_NUL      0
83 __UNDEFINED__  SV_COW_SHARED_HASH_KEYS  0
84
85 #if defined(PERL_USE_GCC_BRACE_GROUPS)
86   __UNDEFINED__ sv_2pv_flags(sv, lp, flags) ({ SV *_sv = (sv); const I32 _flags = (flags); STRLEN *_lp = lp; _lp = _lp ? : &PL_na; (!(_flags & SV_GMAGIC) && SvGMAGICAL(_sv)) ? ({ char *_pv; SvGMAGICAL_off(_sv); _pv = sv_2pv(_sv, _lp); SvGMAGICAL_on(_sv); _pv; }) : sv_2pv(_sv, _lp); })
87   __UNDEFINED__ sv_pvn_force_flags(sv, lp, flags) ({ SV *_sv = (sv); const I32 _flags = (flags); STRLEN *_lp = lp; _lp = _lp ? : &PL_na; (!(_flags & SV_GMAGIC) && SvGMAGICAL(_sv)) ? ({ char *_pv; SvGMAGICAL_off(_sv); _pv = sv_pvn_force(_sv, _lp); SvGMAGICAL_on(_sv); _pv; }) : sv_pvn_force(_sv, _lp); })
88 #else
89   __UNDEFINED__ sv_2pv_flags(sv, lp, flags) ((PL_Sv = (sv)), (!((flags) & SV_GMAGIC) && SvGMAGICAL(PL_Sv)) ? (SvGMAGICAL_off(PL_Sv), (PL_Xpv = (XPV *)sv_2pv(PL_Sv, (lp) ? (lp) : &PL_na)), SvGMAGICAL_on(PL_Sv), (char *)PL_Xpv) : sv_2pv(PL_Sv, (lp) ? (lp) : &PL_na))
90   __UNDEFINED__ sv_pvn_force_flags(sv, lp, flags) ((PL_Sv = (sv)), (!((flags) & SV_GMAGIC) && SvGMAGICAL(PL_Sv)) ? (SvGMAGICAL_off(PL_Sv), (PL_Xpv = (XPV *)sv_pvn_force(PL_Sv, (lp) ? (lp) : &PL_na)), SvGMAGICAL_on(PL_Sv), (char *)PL_Xpv) : sv_pvn_force(PL_Sv, (lp) ? (lp) : &PL_na))
91 #endif
92
93 #if { VERSION < 5.8.8 } || ( { VERSION >= 5.9.0 } && { VERSION < 5.9.3 } )
94 # define D_PPP_SVPV_NOLEN_LP_ARG &PL_na
95 #else
96 # define D_PPP_SVPV_NOLEN_LP_ARG 0
97 #endif
98
99 __UNDEFINED__  SvPV_const(sv, lp)      SvPV_flags_const(sv, lp, SV_GMAGIC)
100 __UNDEFINED__  SvPV_mutable(sv, lp)    SvPV_flags_mutable(sv, lp, SV_GMAGIC)
101
102 __UNDEFINED__  SvPV_flags(sv, lp, flags) \
103                  ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
104                   ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
105
106 __UNDEFINED__  SvPV_flags_const(sv, lp, flags) \
107                  ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
108                   ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
109                   (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN))
110
111 __UNDEFINED__  SvPV_flags_const_nolen(sv, flags) \
112                  ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
113                   ? SvPVX_const(sv) : \
114                   (const char*) sv_2pv_flags(sv, D_PPP_SVPV_NOLEN_LP_ARG, flags|SV_CONST_RETURN))
115
116 __UNDEFINED__  SvPV_flags_mutable(sv, lp, flags) \
117                  ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
118                   ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
119                   sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
120
121 __UNDEFINED__  SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
122 __UNDEFINED__  SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC)
123 __UNDEFINED__  SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC)
124 __UNDEFINED__  SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
125 __UNDEFINED__  SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0)
126
127 __UNDEFINED__  SvPV_force_flags(sv, lp, flags) \
128                  ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
129                  ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags))
130
131 __UNDEFINED__  SvPV_force_flags_nolen(sv, flags) \
132                  ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
133                  ? SvPVX(sv) : sv_pvn_force_flags(sv, D_PPP_SVPV_NOLEN_LP_ARG, flags))
134
135 __UNDEFINED__  SvPV_force_flags_mutable(sv, lp, flags) \
136                  ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
137                  ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \
138                   : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
139
140 __UNDEFINED__  SvPV_nolen(sv) \
141                  ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
142                   ? SvPVX(sv) : sv_2pv_flags(sv, D_PPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC))
143
144 __UNDEFINED__  SvPV_nolen_const(sv) \
145                  ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
146                   ? SvPVX_const(sv) : sv_2pv_flags(sv, D_PPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC|SV_CONST_RETURN))
147 #  if defined(PERL_USE_GCC_BRACE_GROUPS)
148 __UNDEFINED__  SvPVx_nolen_const(sv) ({SV *sV_ = (sv); SvPV_nolen_const(sV_); })
149 #  else
150 __UNDEFINED__  SvPVx_nolen_const(sv)  (PL_Sv = sv, SvPV_nolen_const(PL_Sv))
151 #  endif
152
153 __UNDEFINED__  SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
154 __UNDEFINED__  SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0)
155 __UNDEFINED__  SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0)
156 __UNDEFINED__  SvPV_nomg_nolen(sv) ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
157                                     ? SvPVX(sv) : sv_2pv_flags(sv, D_PPP_SVPV_NOLEN_LP_ARG, 0))
158
159 __UNDEFINED__  SvPV_renew(sv,n) STMT_START { SvLEN_set(sv, n); \
160                  SvPV_set((sv), (char *) saferealloc(          \
161                        (Malloc_t)SvPVX(sv), (MEM_SIZE)((n)))); \
162                } STMT_END
163
164 __UNDEFINED__  SvPVCLEAR(sv) sv_setpvs((sv), "")
165
166 =xsubs
167
168 IV
169 SvPVbyte(sv)
170         SV *sv
171         PREINIT:
172                 char *str;
173                 STRLEN len;
174         CODE:
175                 str = SvPVbyte(sv, len);
176                 RETVAL = strEQ(str, "mhx") ? (IV) len : (IV) -1;
177         OUTPUT:
178                 RETVAL
179
180 IV
181 SvPV_nolen(sv)
182         SV *sv
183         PREINIT:
184                 char *str;
185         CODE:
186                 str = SvPV_nolen(sv);
187                 RETVAL = strEQ(str, "mhx") ? 42 : 0;
188         OUTPUT:
189                 RETVAL
190
191 IV
192 SvPV_const(sv)
193         SV *sv
194         PREINIT:
195                 const char *str;
196                 STRLEN len;
197         CODE:
198                 str = SvPV_const(sv, len);
199                 RETVAL = len + (strEQ(str, "mhx") ? 40 : 0);
200         OUTPUT:
201                 RETVAL
202
203 IV
204 SvPV_mutable(sv)
205         SV *sv
206         PREINIT:
207                 char *str;
208                 STRLEN len;
209         CODE:
210                 str = SvPV_mutable(sv, len);
211                 RETVAL = len + (strEQ(str, "mhx") ? 41 : 0);
212         OUTPUT:
213                 RETVAL
214
215 IV
216 SvPV_flags(sv)
217         SV *sv
218         PREINIT:
219                 char *str;
220                 STRLEN len;
221         CODE:
222                 str = SvPV_flags(sv, len, SV_GMAGIC);
223                 RETVAL = len + (strEQ(str, "mhx") ? 42 : 0);
224         OUTPUT:
225                 RETVAL
226
227 IV
228 SvPV_flags_const(sv)
229         SV *sv
230         PREINIT:
231                 const char *str;
232                 STRLEN len;
233         CODE:
234                 str = SvPV_flags_const(sv, len, SV_GMAGIC);
235                 RETVAL = len + (strEQ(str, "mhx") ? 43 : 0);
236         OUTPUT:
237                 RETVAL
238
239 IV
240 SvPV_flags_const_nolen(sv)
241         SV *sv
242         PREINIT:
243                 const char *str;
244         CODE:
245                 str = SvPV_flags_const_nolen(sv, SV_GMAGIC);
246                 RETVAL = strEQ(str, "mhx") ? 47 : 0;
247         OUTPUT:
248                 RETVAL
249
250 IV
251 SvPV_flags_mutable(sv)
252         SV *sv
253         PREINIT:
254                 char *str;
255                 STRLEN len;
256         CODE:
257                 str = SvPV_flags_mutable(sv, len, SV_GMAGIC);
258                 RETVAL = len + (strEQ(str, "mhx") ? 45 : 0);
259         OUTPUT:
260                 RETVAL
261
262 IV
263 SvPV_force(sv)
264         SV *sv
265         PREINIT:
266                 char *str;
267                 STRLEN len;
268         CODE:
269                 str = SvPV_force(sv, len);
270                 RETVAL = len + (strEQ(str, "mhx") ? 46 : 0);
271         OUTPUT:
272                 RETVAL
273
274 IV
275 SvPV_force_nolen(sv)
276         SV *sv
277         PREINIT:
278                 char *str;
279         CODE:
280                 str = SvPV_force_nolen(sv);
281                 RETVAL = strEQ(str, "mhx") ? 50 : 0;
282         OUTPUT:
283                 RETVAL
284
285 IV
286 SvPV_force_mutable(sv)
287         SV *sv
288         PREINIT:
289                 char *str;
290                 STRLEN len;
291         CODE:
292                 str = SvPV_force_mutable(sv, len);
293                 RETVAL = len + (strEQ(str, "mhx") ? 48 : 0);
294         OUTPUT:
295                 RETVAL
296
297 IV
298 SvPV_force_nomg(sv)
299         SV *sv
300         PREINIT:
301                 char *str;
302                 STRLEN len;
303         CODE:
304                 str = SvPV_force_nomg(sv, len);
305                 RETVAL = len + (strEQ(str, "mhx") ? 49 : 0);
306         OUTPUT:
307                 RETVAL
308
309 IV
310 SvPV_force_nomg_nolen(sv)
311         SV *sv
312         PREINIT:
313                 char *str;
314         CODE:
315                 str = SvPV_force_nomg_nolen(sv);
316                 RETVAL = strEQ(str, "mhx") ? 53 : 0;
317         OUTPUT:
318                 RETVAL
319
320 IV
321 SvPV_force_flags(sv)
322         SV *sv
323         PREINIT:
324                 char *str;
325                 STRLEN len;
326         CODE:
327                 str = SvPV_force_flags(sv, len, SV_GMAGIC);
328                 RETVAL = len + (strEQ(str, "mhx") ? 51 : 0);
329         OUTPUT:
330                 RETVAL
331
332 IV
333 SvPV_force_flags_nolen(sv)
334         SV *sv
335         PREINIT:
336                 char *str;
337         CODE:
338                 str = SvPV_force_flags_nolen(sv, SV_GMAGIC);
339                 RETVAL = strEQ(str, "mhx") ? 55 : 0;
340         OUTPUT:
341                 RETVAL
342
343 IV
344 SvPV_force_flags_mutable(sv)
345         SV *sv
346         PREINIT:
347                 char *str;
348                 STRLEN len;
349         CODE:
350                 str = SvPV_force_flags_mutable(sv, len, SV_GMAGIC);
351                 RETVAL = len + (strEQ(str, "mhx") ? 53 : 0);
352         OUTPUT:
353                 RETVAL
354
355 IV
356 SvPV_nolen_const(sv)
357         SV *sv
358         PREINIT:
359                 const char *str;
360         CODE:
361                 str = SvPV_nolen_const(sv);
362                 RETVAL = strEQ(str, "mhx") ? 57 : 0;
363         OUTPUT:
364                 RETVAL
365
366 IV
367 SvPV_nomg(sv)
368         SV *sv
369         PREINIT:
370                 char *str;
371                 STRLEN len;
372         CODE:
373                 str = SvPV_nomg(sv, len);
374                 RETVAL = len + (strEQ(str, "mhx") ? 55 : 0);
375         OUTPUT:
376                 RETVAL
377
378 IV
379 SvPV_nomg_const(sv)
380         SV *sv
381         PREINIT:
382                 const char *str;
383                 STRLEN len;
384         CODE:
385                 str = SvPV_nomg_const(sv, len);
386                 RETVAL = len + (strEQ(str, "mhx") ? 56 : 0);
387         OUTPUT:
388                 RETVAL
389
390 IV
391 SvPV_nomg_const_nolen(sv)
392         SV *sv
393         PREINIT:
394                 const char *str;
395         CODE:
396                 str = SvPV_nomg_const_nolen(sv);
397                 RETVAL = strEQ(str, "mhx") ? 60 : 0;
398         OUTPUT:
399                 RETVAL
400
401 IV
402 SvPV_nomg_nolen(sv)
403         SV *sv
404         PREINIT:
405                 char *str;
406         CODE:
407                 str = SvPV_nomg_nolen(sv);
408                 RETVAL = strEQ(str, "mhx") ? 61 : 0;
409         OUTPUT:
410                 RETVAL
411
412 void
413 SvPV_renew(sv, nlen, insv)
414         SV *sv
415         STRLEN nlen
416         SV *insv
417         PREINIT:
418                 STRLEN slen;
419                 const char *str;
420         PPCODE:
421                 str = SvPV_const(insv, slen);
422                 XPUSHs(sv);
423                 mXPUSHi(SvLEN(sv));
424                 SvPV_renew(sv, nlen);
425                 Copy(str, SvPVX(sv), slen + 1, char);
426                 SvCUR_set(sv, slen);
427                 mXPUSHi(SvLEN(sv));
428
429 void
430 SvPVCLEAR(sv)
431         SV *sv
432         CODE:
433                 SvPVCLEAR(sv);
434
435
436 =tests plan => 50
437
438 my $mhx = "mhx";
439
440 is(&Devel::PPPort::SvPVbyte($mhx), 3);
441
442 my $i = 42;
443
444 is(&Devel::PPPort::SvPV_nolen($mhx), $i++);
445 is(&Devel::PPPort::SvPV_const($mhx), $i++);
446 is(&Devel::PPPort::SvPV_mutable($mhx), $i++);
447 is(&Devel::PPPort::SvPV_flags($mhx), $i++);
448 is(&Devel::PPPort::SvPV_flags_const($mhx), $i++);
449
450 is(&Devel::PPPort::SvPV_flags_const_nolen($mhx), $i++);
451 is(&Devel::PPPort::SvPV_flags_mutable($mhx), $i++);
452 is(&Devel::PPPort::SvPV_force($mhx), $i++);
453 is(&Devel::PPPort::SvPV_force_nolen($mhx), $i++);
454 is(&Devel::PPPort::SvPV_force_mutable($mhx), $i++);
455
456 is(&Devel::PPPort::SvPV_force_nomg($mhx), $i++);
457 is(&Devel::PPPort::SvPV_force_nomg_nolen($mhx), $i++);
458 is(&Devel::PPPort::SvPV_force_flags($mhx), $i++);
459 is(&Devel::PPPort::SvPV_force_flags_nolen($mhx), $i++);
460 is(&Devel::PPPort::SvPV_force_flags_mutable($mhx), $i++);
461
462 is(&Devel::PPPort::SvPV_nolen_const($mhx), $i++);
463 is(&Devel::PPPort::SvPV_nomg($mhx), $i++);
464 is(&Devel::PPPort::SvPV_nomg_const($mhx), $i++);
465 is(&Devel::PPPort::SvPV_nomg_const_nolen($mhx), $i++);
466 is(&Devel::PPPort::SvPV_nomg_nolen($mhx), $i++);
467
468 $mhx = 42; is(&Devel::PPPort::SvPV_nolen($mhx), 0);
469 $mhx = 42; is(&Devel::PPPort::SvPV_const($mhx), 2);
470 $mhx = 42; is(&Devel::PPPort::SvPV_mutable($mhx), 2);
471 $mhx = 42; is(&Devel::PPPort::SvPV_flags($mhx), 2);
472 $mhx = 42; is(&Devel::PPPort::SvPV_flags_const($mhx), 2);
473
474 $mhx = 42; is(&Devel::PPPort::SvPV_flags_const_nolen($mhx), 0);
475 $mhx = 42; is(&Devel::PPPort::SvPV_flags_mutable($mhx), 2);
476 $mhx = 42; is(&Devel::PPPort::SvPV_force($mhx), 2);
477 $mhx = 42; is(&Devel::PPPort::SvPV_force_nolen($mhx), 0);
478 $mhx = 42; is(&Devel::PPPort::SvPV_force_mutable($mhx), 2);
479
480 $mhx = 42; is(&Devel::PPPort::SvPV_force_nomg($mhx), 2);
481 $mhx = 42; is(&Devel::PPPort::SvPV_force_nomg_nolen($mhx), 0);
482 $mhx = 42; is(&Devel::PPPort::SvPV_force_flags($mhx), 2);
483 $mhx = 42; is(&Devel::PPPort::SvPV_force_flags_nolen($mhx), 0);
484 $mhx = 42; is(&Devel::PPPort::SvPV_force_flags_mutable($mhx), 2);
485
486 $mhx = 42; is(&Devel::PPPort::SvPV_nolen_const($mhx), 0);
487 $mhx = 42; is(&Devel::PPPort::SvPV_nomg($mhx), 2);
488 $mhx = 42; is(&Devel::PPPort::SvPV_nomg_const($mhx), 2);
489 $mhx = 42; is(&Devel::PPPort::SvPV_nomg_const_nolen($mhx), 0);
490 $mhx = 42; is(&Devel::PPPort::SvPV_nomg_nolen($mhx), 0);
491
492 &Devel::PPPort::SvPVCLEAR($mhx);
493 is($mhx, "");
494
495 my $str = "";
496 &Devel::PPPort::SvPV_force($str);
497 my($s2, $before, $after) = &Devel::PPPort::SvPV_renew($str, 81, "x"x80);
498 is($str, "x"x80);
499 is($s2, "x"x80);
500 ok($before < 81);
501 is($after, 81);
502
503 $str = "x"x400;
504 &Devel::PPPort::SvPV_force($str);
505 ($s2, $before, $after) = &Devel::PPPort::SvPV_renew($str, 41, "x"x40);
506 is($str, "x"x40);
507 is($s2, "x"x40);
508 ok($before > 41);
509 is($after, 41);