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