Avoid "Constant subroutine ... redefined" warning, spotted by Jerry D. Hedden.
[p5sagit/p5-mst-13.2.git] / universal.c
CommitLineData
d6376244 1/* universal.c
2 *
b5f8cc5c 3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
1129b882 4 * 2005, 2006, 2007, 2008 by Larry Wall and others
d6376244 5 *
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8 *
9 */
10
d31a8517 11/*
4ac71550 12 * '"The roots of those mountains must be roots indeed; there must be
13 * great secrets buried there which have not been discovered since the
14 * beginning."' --Gandalf, relating Gollum's history
15 *
16 * [p.54 of _The Lord of the Rings_, I/ii: "The Shadow of the Past"]
d31a8517 17 */
18
166f8a29 19/* This file contains the code that implements the functions in Perl's
20 * UNIVERSAL package, such as UNIVERSAL->can().
192b9cd1 21 *
22 * It is also used to store XS functions that need to be present in
23 * miniperl for a lack of a better place to put them. It might be
24 * clever to move them to seperate XS files which would then be pulled
25 * in by some to-be-written build process.
166f8a29 26 */
27
6d4a7be2 28#include "EXTERN.h"
864dbfa3 29#define PERL_IN_UNIVERSAL_C
6d4a7be2 30#include "perl.h"
6d4a7be2 31
39f7a870 32#ifdef USE_PERLIO
33#include "perliol.h" /* For the PERLIO_F_XXX */
34#endif
35
aea32303 36static HV *
37S_get_isa_hash(pTHX_ HV *const stash)
00bf72ff 38{
39 dVAR;
40 struct mro_meta *const meta = HvMROMETA(stash);
41
42 PERL_ARGS_ASSERT_GET_ISA_HASH;
43
44 if (!meta->isa) {
45 AV *const isa = mro_get_linear_isa(stash);
46 if (!meta->isa) {
47 HV *const isa_hash = newHV();
48 /* Linearisation didn't build it for us, so do it here. */
49 SV *const *svp = AvARRAY(isa);
50 SV *const *const svp_end = svp + AvFILLp(isa) + 1;
51 const HEK *const canon_name = HvNAME_HEK(stash);
52
53 while (svp < svp_end) {
54 (void) hv_store_ent(isa_hash, *svp++, &PL_sv_undef, 0);
55 }
56
57 (void) hv_common(isa_hash, NULL, HEK_KEY(canon_name),
58 HEK_LEN(canon_name), HEK_FLAGS(canon_name),
59 HV_FETCH_ISSTORE, &PL_sv_undef,
60 HEK_HASH(canon_name));
61 (void) hv_store(isa_hash, "UNIVERSAL", 9, &PL_sv_undef, 0);
62
63 SvREADONLY_on(isa_hash);
64
65 meta->isa = isa_hash;
66 }
67 }
68 return meta->isa;
69}
70
6d4a7be2 71/*
72 * Contributed by Graham Barr <Graham.Barr@tiuk.ti.com>
73 * The main guts of traverse_isa was actually copied from gv_fetchmeth
74 */
75
a9ec700e 76STATIC bool
515a4f72 77S_isa_lookup(pTHX_ HV *stash, const char * const name)
6d4a7be2 78{
97aff369 79 dVAR;
a49ba3fc 80 const struct mro_meta *const meta = HvMROMETA(stash);
aea32303 81 HV *const isa = meta->isa ? meta->isa : S_get_isa_hash(aTHX_ stash);
a49ba3fc 82 STRLEN len = strlen(name);
83 const HV *our_stash;
6d4a7be2 84
7918f24d 85 PERL_ARGS_ASSERT_ISA_LOOKUP;
86
a49ba3fc 87 if (hv_common(isa, NULL, name, len, 0 /* No "UTF-8" flag possible with only
88 a char * argument*/,
89 HV_FETCH_ISEXISTS, NULL, 0)) {
90 /* Direct name lookup worked. */
a9ec700e 91 return TRUE;
a49ba3fc 92 }
6d4a7be2 93
a49ba3fc 94 /* A stash/class can go by many names (ie. User == main::User), so
95 we use the name in the stash itself, which is canonical. */
96 our_stash = gv_stashpvn(name, len, 0);
97
98 if (our_stash) {
99 HEK *const canon_name = HvNAME_HEK(our_stash);
a1d407e8 100
a49ba3fc 101 if (hv_common(isa, NULL, HEK_KEY(canon_name), HEK_LEN(canon_name),
102 HEK_FLAGS(canon_name),
103 HV_FETCH_ISEXISTS, NULL, HEK_HASH(canon_name))) {
e1a479c5 104 return TRUE;
a49ba3fc 105 }
6d4a7be2 106 }
107
a9ec700e 108 return FALSE;
6d4a7be2 109}
110
954c1994 111/*
ccfc67b7 112=head1 SV Manipulation Functions
113
954c1994 114=for apidoc sv_derived_from
115
6885da0e 116Returns a boolean indicating whether the SV is derived from the specified class
117I<at the C level>. To check derivation at the Perl level, call C<isa()> as a
118normal Perl method.
954c1994 119
120=cut
121*/
122
55497cff 123bool
15f169a1 124Perl_sv_derived_from(pTHX_ SV *sv, const char *const name)
55497cff 125{
97aff369 126 dVAR;
0b6f4f5c 127 HV *stash;
46e4b22b 128
7918f24d 129 PERL_ARGS_ASSERT_SV_DERIVED_FROM;
130
5b295bef 131 SvGETMAGIC(sv);
55497cff 132
133 if (SvROK(sv)) {
0b6f4f5c 134 const char *type;
55497cff 135 sv = SvRV(sv);
136 type = sv_reftype(sv,0);
0b6f4f5c 137 if (type && strEQ(type,name))
138 return TRUE;
139 stash = SvOBJECT(sv) ? SvSTASH(sv) : NULL;
55497cff 140 }
141 else {
da51bb9b 142 stash = gv_stashsv(sv, 0);
55497cff 143 }
46e4b22b 144
4a9e32d8 145 return stash ? isa_lookup(stash, name) : FALSE;
55497cff 146}
147
cbc021f9 148/*
149=for apidoc sv_does
150
151Returns a boolean indicating whether the SV performs a specific, named role.
152The SV can be a Perl object or the name of a Perl class.
153
154=cut
155*/
156
1b026014 157#include "XSUB.h"
158
cbc021f9 159bool
15f169a1 160Perl_sv_does(pTHX_ SV *sv, const char *const name)
cbc021f9 161{
162 const char *classname;
163 bool does_it;
59e7186f 164 SV *methodname;
cbc021f9 165 dSP;
7918f24d 166
167 PERL_ARGS_ASSERT_SV_DOES;
168
cbc021f9 169 ENTER;
170 SAVETMPS;
171
172 SvGETMAGIC(sv);
173
174 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
175 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
176 return FALSE;
177
178 if (sv_isobject(sv)) {
179 classname = sv_reftype(SvRV(sv),TRUE);
180 } else {
94707740 181 classname = SvPV_nolen(sv);
cbc021f9 182 }
183
184 if (strEQ(name,classname))
185 return TRUE;
186
187 PUSHMARK(SP);
188 XPUSHs(sv);
6e449a3a 189 mXPUSHs(newSVpv(name, 0));
cbc021f9 190 PUTBACK;
191
84bafc02 192 methodname = newSVpvs_flags("isa", SVs_TEMP);
59e7186f 193 /* ugly hack: use the SvSCREAM flag so S_method_common
194 * can figure out we're calling DOES() and not isa(),
195 * and report eventual errors correctly. --rgs */
196 SvSCREAM_on(methodname);
197 call_sv(methodname, G_SCALAR | G_METHOD);
cbc021f9 198 SPAGAIN;
199
200 does_it = SvTRUE( TOPs );
201 FREETMPS;
202 LEAVE;
203
204 return does_it;
205}
206
27da23d5 207PERL_XS_EXPORT_C void XS_UNIVERSAL_isa(pTHX_ CV *cv);
208PERL_XS_EXPORT_C void XS_UNIVERSAL_can(pTHX_ CV *cv);
cbc021f9 209PERL_XS_EXPORT_C void XS_UNIVERSAL_DOES(pTHX_ CV *cv);
27da23d5 210PERL_XS_EXPORT_C void XS_UNIVERSAL_VERSION(pTHX_ CV *cv);
439cb1c4 211XS(XS_version_new);
212XS(XS_version_stringify);
213XS(XS_version_numify);
9137345a 214XS(XS_version_normal);
439cb1c4 215XS(XS_version_vcmp);
216XS(XS_version_boolean);
2dfd8427 217#ifdef HASATTRIBUTE_NORETURN
218XS(XS_version_noop) __attribute__noreturn__;
219#else
439cb1c4 220XS(XS_version_noop);
2dfd8427 221#endif
c8d69e4a 222XS(XS_version_is_alpha);
137d6fc0 223XS(XS_version_qv);
8800c35a 224XS(XS_utf8_is_utf8);
1b026014 225XS(XS_utf8_valid);
226XS(XS_utf8_encode);
227XS(XS_utf8_decode);
228XS(XS_utf8_upgrade);
229XS(XS_utf8_downgrade);
230XS(XS_utf8_unicode_to_native);
231XS(XS_utf8_native_to_unicode);
29569577 232XS(XS_Internals_SvREADONLY);
233XS(XS_Internals_SvREFCNT);
f044d0d1 234XS(XS_Internals_hv_clear_placehold);
39f7a870 235XS(XS_PerlIO_get_layers);
9a7034eb 236XS(XS_Internals_hash_seed);
008fb0c0 237XS(XS_Internals_rehash_seed);
05619474 238XS(XS_Internals_HvREHASH);
80305961 239XS(XS_re_is_regexp);
192b9cd1 240XS(XS_re_regname);
241XS(XS_re_regnames);
80305961 242XS(XS_re_regnames_count);
192c1e27 243XS(XS_re_regexp_pattern);
192b9cd1 244XS(XS_Tie_Hash_NamedCapture_FETCH);
245XS(XS_Tie_Hash_NamedCapture_STORE);
246XS(XS_Tie_Hash_NamedCapture_DELETE);
247XS(XS_Tie_Hash_NamedCapture_CLEAR);
248XS(XS_Tie_Hash_NamedCapture_EXISTS);
86aa3d53 249XS(XS_Tie_Hash_NamedCapture_FIRSTK);
250XS(XS_Tie_Hash_NamedCapture_NEXTK);
192b9cd1 251XS(XS_Tie_Hash_NamedCapture_SCALAR);
252XS(XS_Tie_Hash_NamedCapture_flags);
0cb96387 253
254void
255Perl_boot_core_UNIVERSAL(pTHX)
256{
97aff369 257 dVAR;
157e3fc8 258 static const char file[] = __FILE__;
0cb96387 259
260 newXS("UNIVERSAL::isa", XS_UNIVERSAL_isa, file);
261 newXS("UNIVERSAL::can", XS_UNIVERSAL_can, file);
cbc021f9 262 newXS("UNIVERSAL::DOES", XS_UNIVERSAL_DOES, file);
0cb96387 263 newXS("UNIVERSAL::VERSION", XS_UNIVERSAL_VERSION, file);
439cb1c4 264 {
ad63d80f 265 /* register the overloading (type 'A') magic */
266 PL_amagic_generation++;
439cb1c4 267 /* Make it findable via fetchmethod */
be2ebcad 268 newXS("version::()", XS_version_noop, file);
439cb1c4 269 newXS("version::new", XS_version_new, file);
270 newXS("version::(\"\"", XS_version_stringify, file);
271 newXS("version::stringify", XS_version_stringify, file);
272 newXS("version::(0+", XS_version_numify, file);
273 newXS("version::numify", XS_version_numify, file);
9137345a 274 newXS("version::normal", XS_version_normal, file);
439cb1c4 275 newXS("version::(cmp", XS_version_vcmp, file);
276 newXS("version::(<=>", XS_version_vcmp, file);
277 newXS("version::vcmp", XS_version_vcmp, file);
278 newXS("version::(bool", XS_version_boolean, file);
279 newXS("version::boolean", XS_version_boolean, file);
280 newXS("version::(nomethod", XS_version_noop, file);
281 newXS("version::noop", XS_version_noop, file);
c8d69e4a 282 newXS("version::is_alpha", XS_version_is_alpha, file);
137d6fc0 283 newXS("version::qv", XS_version_qv, file);
439cb1c4 284 }
8800c35a 285 newXS("utf8::is_utf8", XS_utf8_is_utf8, file);
1b026014 286 newXS("utf8::valid", XS_utf8_valid, file);
287 newXS("utf8::encode", XS_utf8_encode, file);
288 newXS("utf8::decode", XS_utf8_decode, file);
289 newXS("utf8::upgrade", XS_utf8_upgrade, file);
290 newXS("utf8::downgrade", XS_utf8_downgrade, file);
291 newXS("utf8::native_to_unicode", XS_utf8_native_to_unicode, file);
292 newXS("utf8::unicode_to_native", XS_utf8_unicode_to_native, file);
29569577 293 newXSproto("Internals::SvREADONLY",XS_Internals_SvREADONLY, file, "\\[$%@];$");
294 newXSproto("Internals::SvREFCNT",XS_Internals_SvREFCNT, file, "\\[$%@];$");
dfd4ef2f 295 newXSproto("Internals::hv_clear_placeholders",
f044d0d1 296 XS_Internals_hv_clear_placehold, file, "\\%");
9d569fce 297 newXSproto("PerlIO::get_layers",
298 XS_PerlIO_get_layers, file, "*;@");
d5cecc0e 299 CvFILE(newCONSTSUB(get_hv("Regexp::", GV_ADD), "DESTROY", NULL))
300 = (char *)file;
9a7034eb 301 newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
008fb0c0 302 newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
05619474 303 newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
80305961 304 newXSproto("re::is_regexp", XS_re_is_regexp, file, "$");
28d8d7f4 305 newXSproto("re::regname", XS_re_regname, file, ";$$");
306 newXSproto("re::regnames", XS_re_regnames, file, ";$");
28d8d7f4 307 newXSproto("re::regnames_count", XS_re_regnames_count, file, "");
192c1e27 308 newXSproto("re::regexp_pattern", XS_re_regexp_pattern, file, "$");
192b9cd1 309 newXS("Tie::Hash::NamedCapture::FETCH", XS_Tie_Hash_NamedCapture_FETCH, file);
310 newXS("Tie::Hash::NamedCapture::STORE", XS_Tie_Hash_NamedCapture_STORE, file);
311 newXS("Tie::Hash::NamedCapture::DELETE", XS_Tie_Hash_NamedCapture_DELETE, file);
312 newXS("Tie::Hash::NamedCapture::CLEAR", XS_Tie_Hash_NamedCapture_CLEAR, file);
313 newXS("Tie::Hash::NamedCapture::EXISTS", XS_Tie_Hash_NamedCapture_EXISTS, file);
86aa3d53 314 newXS("Tie::Hash::NamedCapture::FIRSTKEY", XS_Tie_Hash_NamedCapture_FIRSTK, file);
315 newXS("Tie::Hash::NamedCapture::NEXTKEY", XS_Tie_Hash_NamedCapture_NEXTK, file);
192b9cd1 316 newXS("Tie::Hash::NamedCapture::SCALAR", XS_Tie_Hash_NamedCapture_SCALAR, file);
317 newXS("Tie::Hash::NamedCapture::flags", XS_Tie_Hash_NamedCapture_flags, file);
0cb96387 318}
319
afa74d42 320/*
321=for apidoc croak_xs_usage
322
323A specialised variant of C<croak()> for emitting the usage message for xsubs
324
325 croak_xs_usage(cv, "eee_yow");
326
327works out the package name and subroutine name from C<cv>, and then calls
328C<croak()>. Hence if C<cv> is C<&ouch::awk>, it would call C<croak> as:
329
330 Perl_croak(aTHX_ "Usage %s::%s(%s)", "ouch" "awk", "eee_yow");
331
332=cut
333*/
334
335void
336Perl_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
337{
338 const GV *const gv = CvGV(cv);
339
340 PERL_ARGS_ASSERT_CROAK_XS_USAGE;
341
342 if (gv) {
343 const char *const gvname = GvNAME(gv);
344 const HV *const stash = GvSTASH(gv);
345 const char *const hvname = stash ? HvNAME_get(stash) : NULL;
346
347 if (hvname)
348 Perl_croak(aTHX_ "Usage: %s::%s(%s)", hvname, gvname, params);
349 else
350 Perl_croak(aTHX_ "Usage: %s(%s)", gvname, params);
351 } else {
352 /* Pants. I don't think that it should be possible to get here. */
93c51217 353 Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
afa74d42 354 }
355}
55497cff 356
6d4a7be2 357XS(XS_UNIVERSAL_isa)
358{
97aff369 359 dVAR;
6d4a7be2 360 dXSARGS;
6d4a7be2 361
362 if (items != 2)
afa74d42 363 croak_xs_usage(cv, "reference, kind");
c4420975 364 else {
365 SV * const sv = ST(0);
366 const char *name;
6d4a7be2 367
c4420975 368 SvGETMAGIC(sv);
d3f7f2b2 369
c4420975 370 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
371 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
372 XSRETURN_UNDEF;
f8f70380 373
c4420975 374 name = SvPV_nolen_const(ST(1));
6d4a7be2 375
c4420975 376 ST(0) = boolSV(sv_derived_from(sv, name));
377 XSRETURN(1);
378 }
6d4a7be2 379}
380
6d4a7be2 381XS(XS_UNIVERSAL_can)
382{
97aff369 383 dVAR;
6d4a7be2 384 dXSARGS;
385 SV *sv;
6867be6d 386 const char *name;
6d4a7be2 387 SV *rv;
6f08146e 388 HV *pkg = NULL;
6d4a7be2 389
390 if (items != 2)
afa74d42 391 croak_xs_usage(cv, "object-ref, method");
6d4a7be2 392
393 sv = ST(0);
f8f70380 394
5b295bef 395 SvGETMAGIC(sv);
d3f7f2b2 396
253ecd6d 397 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
398 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
f8f70380 399 XSRETURN_UNDEF;
400
0510663f 401 name = SvPV_nolen_const(ST(1));
3280af22 402 rv = &PL_sv_undef;
6d4a7be2 403
46e4b22b 404 if (SvROK(sv)) {
daba3364 405 sv = MUTABLE_SV(SvRV(sv));
46e4b22b 406 if (SvOBJECT(sv))
6f08146e 407 pkg = SvSTASH(sv);
408 }
409 else {
da51bb9b 410 pkg = gv_stashsv(sv, 0);
6f08146e 411 }
412
413 if (pkg) {
c4420975 414 GV * const gv = gv_fetchmethod_autoload(pkg, name, FALSE);
dc848c6f 415 if (gv && isGV(gv))
daba3364 416 rv = sv_2mortal(newRV(MUTABLE_SV(GvCV(gv))));
6d4a7be2 417 }
418
419 ST(0) = rv;
420 XSRETURN(1);
421}
422
cbc021f9 423XS(XS_UNIVERSAL_DOES)
424{
425 dVAR;
426 dXSARGS;
58c0efa5 427 PERL_UNUSED_ARG(cv);
cbc021f9 428
429 if (items != 2)
26be3db7 430 Perl_croak(aTHX_ "Usage: invocant->DOES(kind)");
cbc021f9 431 else {
432 SV * const sv = ST(0);
433 const char *name;
434
435 name = SvPV_nolen_const(ST(1));
436 if (sv_does( sv, name ))
437 XSRETURN_YES;
438
439 XSRETURN_NO;
440 }
441}
442
6d4a7be2 443XS(XS_UNIVERSAL_VERSION)
444{
97aff369 445 dVAR;
6d4a7be2 446 dXSARGS;
447 HV *pkg;
448 GV **gvp;
449 GV *gv;
450 SV *sv;
e1ec3a88 451 const char *undef;
58c0efa5 452 PERL_UNUSED_ARG(cv);
6d4a7be2 453
1571675a 454 if (SvROK(ST(0))) {
daba3364 455 sv = MUTABLE_SV(SvRV(ST(0)));
1571675a 456 if (!SvOBJECT(sv))
cea2e8a9 457 Perl_croak(aTHX_ "Cannot find version of an unblessed reference");
6d4a7be2 458 pkg = SvSTASH(sv);
459 }
460 else {
da51bb9b 461 pkg = gv_stashsv(ST(0), 0);
6d4a7be2 462 }
463
4608196e 464 gvp = pkg ? (GV**)hv_fetchs(pkg, "VERSION", FALSE) : NULL;
6d4a7be2 465
0008872a 466 if (gvp && isGV(gv = *gvp) && (sv = GvSV(gv)) && SvOK(sv)) {
c4420975 467 SV * const nsv = sv_newmortal();
6d4a7be2 468 sv_setsv(nsv, sv);
469 sv = nsv;
137d6fc0 470 if ( !sv_derived_from(sv, "version"))
ac0e6a2f 471 upg_version(sv, FALSE);
c445ea15 472 undef = NULL;
6d4a7be2 473 }
474 else {
daba3364 475 sv = &PL_sv_undef;
6d4a7be2 476 undef = "(undef)";
477 }
478
1571675a 479 if (items > 1) {
1571675a 480 SV *req = ST(1);
481
62658f4d 482 if (undef) {
bfcb3514 483 if (pkg) {
c4420975 484 const char * const name = HvNAME_get(pkg);
a3b680e6 485 Perl_croak(aTHX_
bfcb3514 486 "%s does not define $%s::VERSION--version check failed",
487 name, name);
488 } else {
a3b680e6 489 Perl_croak(aTHX_
490 "%s defines neither package nor VERSION--version check failed",
0510663f 491 SvPVx_nolen_const(ST(0)) );
62658f4d 492 }
493 }
ad63d80f 494
137d6fc0 495 if ( !sv_derived_from(req, "version")) {
496 /* req may very well be R/O, so create a new object */
ac0e6a2f 497 req = sv_2mortal( new_version(req) );
137d6fc0 498 }
1571675a 499
ac0e6a2f 500 if ( vcmp( req, sv ) > 0 ) {
ef8f7699 501 if ( hv_exists(MUTABLE_HV(SvRV(req)), "qv", 2 ) ) {
ac0e6a2f 502 Perl_croak(aTHX_ "%s version %"SVf" required--"
503 "this is only version %"SVf"", HvNAME_get(pkg),
be2597df 504 SVfARG(vnormal(req)),
be2597df 505 SVfARG(vnormal(sv)));
ac0e6a2f 506 } else {
507 Perl_croak(aTHX_ "%s version %"SVf" required--"
508 "this is only version %"SVf"", HvNAME_get(pkg),
8cb289bd 509 SVfARG(vstringify(req)),
510 SVfARG(vstringify(sv)));
ac0e6a2f 511 }
512 }
513
2d8e6c8d 514 }
6d4a7be2 515
2b140d5b 516 if ( SvOK(sv) && sv_derived_from(sv, "version") ) {
8cb289bd 517 ST(0) = vstringify(sv);
13f8f398 518 } else {
519 ST(0) = sv;
b38a9dc5 520 }
6d4a7be2 521
522 XSRETURN(1);
523}
524
439cb1c4 525XS(XS_version_new)
526{
97aff369 527 dVAR;
439cb1c4 528 dXSARGS;
129318bd 529 if (items > 3)
afa74d42 530 croak_xs_usage(cv, "class, version");
439cb1c4 531 SP -= items;
532 {
137d6fc0 533 SV *vs = ST(1);
534 SV *rv;
c4420975 535 const char * const classname =
536 sv_isobject(ST(0)) /* get the class if called as an object method */
537 ? HvNAME(SvSTASH(SvRV(ST(0))))
538 : (char *)SvPV_nolen(ST(0));
9137345a 539
92dcf8ce 540 if ( items == 1 || vs == &PL_sv_undef ) { /* no param or explicit undef */
541 /* create empty object */
542 vs = sv_newmortal();
76f68e9b 543 sv_setpvs(vs,"");
9137345a 544 }
545 else if ( items == 3 ) {
546 vs = sv_newmortal();
cfd0369c 547 Perl_sv_setpvf(aTHX_ vs,"v%s",SvPV_nolen_const(ST(2)));
129318bd 548 }
439cb1c4 549
137d6fc0 550 rv = new_version(vs);
0723351e 551 if ( strcmp(classname,"version") != 0 ) /* inherited new() */
da51bb9b 552 sv_bless(rv, gv_stashpv(classname, GV_ADD));
137d6fc0 553
6e449a3a 554 mPUSHs(rv);
439cb1c4 555 PUTBACK;
556 return;
557 }
558}
559
560XS(XS_version_stringify)
561{
97aff369 562 dVAR;
41be1fbd 563 dXSARGS;
564 if (items < 1)
afa74d42 565 croak_xs_usage(cv, "lobj, ...");
41be1fbd 566 SP -= items;
567 {
7452cf6a 568 SV * lobj;
41be1fbd 569
570 if (sv_derived_from(ST(0), "version")) {
9137345a 571 lobj = SvRV(ST(0));
41be1fbd 572 }
573 else
574 Perl_croak(aTHX_ "lobj is not of type version");
575
6e449a3a 576 mPUSHs(vstringify(lobj));
41be1fbd 577
578 PUTBACK;
579 return;
580 }
439cb1c4 581}
582
583XS(XS_version_numify)
584{
97aff369 585 dVAR;
41be1fbd 586 dXSARGS;
587 if (items < 1)
afa74d42 588 croak_xs_usage(cv, "lobj, ...");
41be1fbd 589 SP -= items;
590 {
7452cf6a 591 SV * lobj;
41be1fbd 592
593 if (sv_derived_from(ST(0), "version")) {
9137345a 594 lobj = SvRV(ST(0));
41be1fbd 595 }
596 else
597 Perl_croak(aTHX_ "lobj is not of type version");
598
6e449a3a 599 mPUSHs(vnumify(lobj));
41be1fbd 600
601 PUTBACK;
602 return;
603 }
439cb1c4 604}
605
9137345a 606XS(XS_version_normal)
607{
97aff369 608 dVAR;
9137345a 609 dXSARGS;
610 if (items < 1)
afa74d42 611 croak_xs_usage(cv, "lobj, ...");
9137345a 612 SP -= items;
613 {
7452cf6a 614 SV * lobj;
9137345a 615
616 if (sv_derived_from(ST(0), "version")) {
617 lobj = SvRV(ST(0));
618 }
619 else
620 Perl_croak(aTHX_ "lobj is not of type version");
621
6e449a3a 622 mPUSHs(vnormal(lobj));
9137345a 623
624 PUTBACK;
625 return;
626 }
627}
628
439cb1c4 629XS(XS_version_vcmp)
630{
97aff369 631 dVAR;
41be1fbd 632 dXSARGS;
633 if (items < 1)
afa74d42 634 croak_xs_usage(cv, "lobj, ...");
41be1fbd 635 SP -= items;
636 {
7452cf6a 637 SV * lobj;
41be1fbd 638
639 if (sv_derived_from(ST(0), "version")) {
9137345a 640 lobj = SvRV(ST(0));
41be1fbd 641 }
642 else
643 Perl_croak(aTHX_ "lobj is not of type version");
644
645 {
646 SV *rs;
647 SV *rvs;
648 SV * robj = ST(1);
7452cf6a 649 const IV swap = (IV)SvIV(ST(2));
41be1fbd 650
651 if ( ! sv_derived_from(robj, "version") )
652 {
653 robj = new_version(robj);
654 }
655 rvs = SvRV(robj);
656
657 if ( swap )
658 {
659 rs = newSViv(vcmp(rvs,lobj));
660 }
661 else
662 {
663 rs = newSViv(vcmp(lobj,rvs));
664 }
665
6e449a3a 666 mPUSHs(rs);
41be1fbd 667 }
668
669 PUTBACK;
670 return;
671 }
439cb1c4 672}
673
674XS(XS_version_boolean)
675{
97aff369 676 dVAR;
677 dXSARGS;
678 if (items < 1)
afa74d42 679 croak_xs_usage(cv, "lobj, ...");
97aff369 680 SP -= items;
c4420975 681 if (sv_derived_from(ST(0), "version")) {
682 SV * const lobj = SvRV(ST(0));
396482e1 683 SV * const rs = newSViv( vcmp(lobj,new_version(newSVpvs("0"))) );
6e449a3a 684 mPUSHs(rs);
c4420975 685 PUTBACK;
686 return;
687 }
688 else
689 Perl_croak(aTHX_ "lobj is not of type version");
439cb1c4 690}
691
692XS(XS_version_noop)
693{
97aff369 694 dVAR;
2dfd8427 695 dXSARGS;
696 if (items < 1)
afa74d42 697 croak_xs_usage(cv, "lobj, ...");
2dfd8427 698 if (sv_derived_from(ST(0), "version"))
699 Perl_croak(aTHX_ "operation not supported with version object");
700 else
701 Perl_croak(aTHX_ "lobj is not of type version");
702#ifndef HASATTRIBUTE_NORETURN
703 XSRETURN_EMPTY;
704#endif
439cb1c4 705}
706
c8d69e4a 707XS(XS_version_is_alpha)
708{
97aff369 709 dVAR;
c8d69e4a 710 dXSARGS;
711 if (items != 1)
afa74d42 712 croak_xs_usage(cv, "lobj");
c8d69e4a 713 SP -= items;
c4420975 714 if (sv_derived_from(ST(0), "version")) {
715 SV * const lobj = ST(0);
ef8f7699 716 if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "alpha", 5 ) )
c4420975 717 XSRETURN_YES;
718 else
719 XSRETURN_NO;
c8d69e4a 720 PUTBACK;
721 return;
722 }
c4420975 723 else
724 Perl_croak(aTHX_ "lobj is not of type version");
c8d69e4a 725}
726
137d6fc0 727XS(XS_version_qv)
728{
97aff369 729 dVAR;
137d6fc0 730 dXSARGS;
731 if (items != 1)
afa74d42 732 croak_xs_usage(cv, "ver");
137d6fc0 733 SP -= items;
734 {
735 SV * ver = ST(0);
c4420975 736 if ( !SvVOK(ver) ) { /* only need to do with if not already v-string */
ac0e6a2f 737 SV * const rv = sv_newmortal();
738 sv_setsv(rv,ver); /* make a duplicate */
739 upg_version(rv, TRUE);
740 PUSHs(rv);
137d6fc0 741 }
742 else
743 {
6e449a3a 744 mPUSHs(new_version(ver));
137d6fc0 745 }
746
747 PUTBACK;
748 return;
749 }
750}
751
8800c35a 752XS(XS_utf8_is_utf8)
753{
97aff369 754 dVAR;
41be1fbd 755 dXSARGS;
756 if (items != 1)
afa74d42 757 croak_xs_usage(cv, "sv");
c4420975 758 else {
759 const SV * const sv = ST(0);
760 if (SvUTF8(sv))
761 XSRETURN_YES;
762 else
763 XSRETURN_NO;
41be1fbd 764 }
765 XSRETURN_EMPTY;
8800c35a 766}
767
1b026014 768XS(XS_utf8_valid)
769{
97aff369 770 dVAR;
41be1fbd 771 dXSARGS;
772 if (items != 1)
afa74d42 773 croak_xs_usage(cv, "sv");
c4420975 774 else {
775 SV * const sv = ST(0);
776 STRLEN len;
777 const char * const s = SvPV_const(sv,len);
778 if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len))
779 XSRETURN_YES;
780 else
781 XSRETURN_NO;
782 }
41be1fbd 783 XSRETURN_EMPTY;
1b026014 784}
785
786XS(XS_utf8_encode)
787{
97aff369 788 dVAR;
1b026014 789 dXSARGS;
790 if (items != 1)
afa74d42 791 croak_xs_usage(cv, "sv");
c4420975 792 sv_utf8_encode(ST(0));
1b026014 793 XSRETURN_EMPTY;
794}
795
796XS(XS_utf8_decode)
797{
97aff369 798 dVAR;
1b026014 799 dXSARGS;
800 if (items != 1)
afa74d42 801 croak_xs_usage(cv, "sv");
c4420975 802 else {
803 SV * const sv = ST(0);
6867be6d 804 const bool RETVAL = sv_utf8_decode(sv);
1b026014 805 ST(0) = boolSV(RETVAL);
806 sv_2mortal(ST(0));
807 }
808 XSRETURN(1);
809}
810
811XS(XS_utf8_upgrade)
812{
97aff369 813 dVAR;
1b026014 814 dXSARGS;
815 if (items != 1)
afa74d42 816 croak_xs_usage(cv, "sv");
c4420975 817 else {
818 SV * const sv = ST(0);
1b026014 819 STRLEN RETVAL;
820 dXSTARG;
821
822 RETVAL = sv_utf8_upgrade(sv);
823 XSprePUSH; PUSHi((IV)RETVAL);
824 }
825 XSRETURN(1);
826}
827
828XS(XS_utf8_downgrade)
829{
97aff369 830 dVAR;
1b026014 831 dXSARGS;
832 if (items < 1 || items > 2)
afa74d42 833 croak_xs_usage(cv, "sv, failok=0");
c4420975 834 else {
835 SV * const sv = ST(0);
6867be6d 836 const bool failok = (items < 2) ? 0 : (int)SvIV(ST(1));
837 const bool RETVAL = sv_utf8_downgrade(sv, failok);
1b026014 838
1b026014 839 ST(0) = boolSV(RETVAL);
840 sv_2mortal(ST(0));
841 }
842 XSRETURN(1);
843}
844
845XS(XS_utf8_native_to_unicode)
846{
97aff369 847 dVAR;
1b026014 848 dXSARGS;
6867be6d 849 const UV uv = SvUV(ST(0));
b7953727 850
851 if (items > 1)
afa74d42 852 croak_xs_usage(cv, "sv");
b7953727 853
1b026014 854 ST(0) = sv_2mortal(newSViv(NATIVE_TO_UNI(uv)));
855 XSRETURN(1);
856}
857
858XS(XS_utf8_unicode_to_native)
859{
97aff369 860 dVAR;
1b026014 861 dXSARGS;
6867be6d 862 const UV uv = SvUV(ST(0));
b7953727 863
864 if (items > 1)
afa74d42 865 croak_xs_usage(cv, "sv");
b7953727 866
1b026014 867 ST(0) = sv_2mortal(newSViv(UNI_TO_NATIVE(uv)));
868 XSRETURN(1);
869}
870
14a976d6 871XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
29569577 872{
97aff369 873 dVAR;
29569577 874 dXSARGS;
c4420975 875 SV * const sv = SvRV(ST(0));
58c0efa5 876 PERL_UNUSED_ARG(cv);
6867be6d 877
29569577 878 if (items == 1) {
879 if (SvREADONLY(sv))
880 XSRETURN_YES;
881 else
882 XSRETURN_NO;
883 }
884 else if (items == 2) {
885 if (SvTRUE(ST(1))) {
886 SvREADONLY_on(sv);
887 XSRETURN_YES;
888 }
889 else {
14a976d6 890 /* I hope you really know what you are doing. */
29569577 891 SvREADONLY_off(sv);
892 XSRETURN_NO;
893 }
894 }
14a976d6 895 XSRETURN_UNDEF; /* Can't happen. */
29569577 896}
897
14a976d6 898XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
29569577 899{
97aff369 900 dVAR;
29569577 901 dXSARGS;
c4420975 902 SV * const sv = SvRV(ST(0));
58c0efa5 903 PERL_UNUSED_ARG(cv);
6867be6d 904
29569577 905 if (items == 1)
14a976d6 906 XSRETURN_IV(SvREFCNT(sv) - 1); /* Minus the ref created for us. */
29569577 907 else if (items == 2) {
14a976d6 908 /* I hope you really know what you are doing. */
29569577 909 SvREFCNT(sv) = SvIV(ST(1));
910 XSRETURN_IV(SvREFCNT(sv));
911 }
14a976d6 912 XSRETURN_UNDEF; /* Can't happen. */
29569577 913}
914
f044d0d1 915XS(XS_Internals_hv_clear_placehold)
dfd4ef2f 916{
97aff369 917 dVAR;
dfd4ef2f 918 dXSARGS;
6867be6d 919
3540d4ce 920 if (items != 1)
afa74d42 921 croak_xs_usage(cv, "hv");
c4420975 922 else {
ef8f7699 923 HV * const hv = MUTABLE_HV(SvRV(ST(0)));
c4420975 924 hv_clear_placeholders(hv);
925 XSRETURN(0);
926 }
dfd4ef2f 927}
39f7a870 928
929XS(XS_PerlIO_get_layers)
930{
97aff369 931 dVAR;
39f7a870 932 dXSARGS;
933 if (items < 1 || items % 2 == 0)
afa74d42 934 croak_xs_usage(cv, "filehandle[,args]");
5fef3b4a 935#ifdef USE_PERLIO
39f7a870 936 {
937 SV * sv;
938 GV * gv;
939 IO * io;
940 bool input = TRUE;
941 bool details = FALSE;
942
943 if (items > 1) {
c4420975 944 SV * const *svp;
39f7a870 945 for (svp = MARK + 2; svp <= SP; svp += 2) {
c4420975 946 SV * const * const varp = svp;
947 SV * const * const valp = svp + 1;
39f7a870 948 STRLEN klen;
c4420975 949 const char * const key = SvPV_const(*varp, klen);
39f7a870 950
951 switch (*key) {
952 case 'i':
953 if (klen == 5 && memEQ(key, "input", 5)) {
954 input = SvTRUE(*valp);
955 break;
956 }
957 goto fail;
958 case 'o':
959 if (klen == 6 && memEQ(key, "output", 6)) {
960 input = !SvTRUE(*valp);
961 break;
962 }
963 goto fail;
964 case 'd':
965 if (klen == 7 && memEQ(key, "details", 7)) {
966 details = SvTRUE(*valp);
967 break;
968 }
969 goto fail;
970 default:
971 fail:
972 Perl_croak(aTHX_
973 "get_layers: unknown argument '%s'",
974 key);
975 }
976 }
977
978 SP -= (items - 1);
979 }
980
981 sv = POPs;
159b6efe 982 gv = MUTABLE_GV(sv);
39f7a870 983
984 if (!isGV(sv)) {
985 if (SvROK(sv) && isGV(SvRV(sv)))
159b6efe 986 gv = MUTABLE_GV(SvRV(sv));
671d49be 987 else if (SvPOKp(sv))
f776e3cd 988 gv = gv_fetchsv(sv, 0, SVt_PVIO);
39f7a870 989 }
990
991 if (gv && (io = GvIO(gv))) {
c4420975 992 AV* const av = PerlIO_get_layers(aTHX_ input ?
39f7a870 993 IoIFP(io) : IoOFP(io));
994 I32 i;
c4420975 995 const I32 last = av_len(av);
39f7a870 996 I32 nitem = 0;
997
998 for (i = last; i >= 0; i -= 3) {
c4420975 999 SV * const * const namsvp = av_fetch(av, i - 2, FALSE);
1000 SV * const * const argsvp = av_fetch(av, i - 1, FALSE);
1001 SV * const * const flgsvp = av_fetch(av, i, FALSE);
39f7a870 1002
c4420975 1003 const bool namok = namsvp && *namsvp && SvPOK(*namsvp);
1004 const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
1005 const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
39f7a870 1006
1007 if (details) {
92e45a3e 1008 /* Indents of 5? Yuck. */
1009 /* We know that PerlIO_get_layers creates a new SV for
1010 the name and flags, so we can just take a reference
1011 and "steal" it when we free the AV below. */
ec3bab8e 1012 XPUSHs(namok
92e45a3e 1013 ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
ec3bab8e 1014 : &PL_sv_undef);
1015 XPUSHs(argok
92e45a3e 1016 ? newSVpvn_flags(SvPVX_const(*argsvp),
1017 SvCUR(*argsvp),
1018 (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
1019 | SVs_TEMP)
1020 : &PL_sv_undef);
96ccaf53 1021 XPUSHs(flgok
92e45a3e 1022 ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
ec3bab8e 1023 : &PL_sv_undef);
39f7a870 1024 nitem += 3;
1025 }
1026 else {
1027 if (namok && argok)
1eb9e81d 1028 XPUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
be2597df 1029 SVfARG(*namsvp),
1eb9e81d 1030 SVfARG(*argsvp))));
39f7a870 1031 else if (namok)
92e45a3e 1032 XPUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
39f7a870 1033 else
1034 XPUSHs(&PL_sv_undef);
1035 nitem++;
1036 if (flgok) {
c4420975 1037 const IV flags = SvIVX(*flgsvp);
39f7a870 1038
1039 if (flags & PERLIO_F_UTF8) {
84bafc02 1040 XPUSHs(newSVpvs_flags("utf8", SVs_TEMP));
39f7a870 1041 nitem++;
1042 }
1043 }
1044 }
1045 }
1046
1047 SvREFCNT_dec(av);
1048
1049 XSRETURN(nitem);
1050 }
1051 }
5fef3b4a 1052#endif
39f7a870 1053
1054 XSRETURN(0);
1055}
1056
9a7034eb 1057XS(XS_Internals_hash_seed)
c910b28a 1058{
97aff369 1059 dVAR;
c85d3f85 1060 /* Using dXSARGS would also have dITEM and dSP,
1061 * which define 2 unused local variables. */
557b887a 1062 dAXMARK;
53c1dcc0 1063 PERL_UNUSED_ARG(cv);
ad73156c 1064 PERL_UNUSED_VAR(mark);
81eaca17 1065 XSRETURN_UV(PERL_HASH_SEED);
c910b28a 1066}
1067
008fb0c0 1068XS(XS_Internals_rehash_seed)
8e90d776 1069{
97aff369 1070 dVAR;
8e90d776 1071 /* Using dXSARGS would also have dITEM and dSP,
1072 * which define 2 unused local variables. */
557b887a 1073 dAXMARK;
53c1dcc0 1074 PERL_UNUSED_ARG(cv);
ad73156c 1075 PERL_UNUSED_VAR(mark);
008fb0c0 1076 XSRETURN_UV(PL_rehash_seed);
8e90d776 1077}
1078
05619474 1079XS(XS_Internals_HvREHASH) /* Subject to change */
1080{
97aff369 1081 dVAR;
05619474 1082 dXSARGS;
93c51217 1083 PERL_UNUSED_ARG(cv);
05619474 1084 if (SvROK(ST(0))) {
ef8f7699 1085 const HV * const hv = (const HV *) SvRV(ST(0));
05619474 1086 if (items == 1 && SvTYPE(hv) == SVt_PVHV) {
1087 if (HvREHASH(hv))
1088 XSRETURN_YES;
1089 else
1090 XSRETURN_NO;
1091 }
1092 }
1093 Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
1094}
241d1a3b 1095
80305961 1096XS(XS_re_is_regexp)
1097{
1098 dVAR;
1099 dXSARGS;
f7e71195 1100 PERL_UNUSED_VAR(cv);
1101
80305961 1102 if (items != 1)
afa74d42 1103 croak_xs_usage(cv, "sv");
f7e71195 1104
80305961 1105 SP -= items;
f7e71195 1106
1107 if (SvRXOK(ST(0))) {
1108 XSRETURN_YES;
1109 } else {
1110 XSRETURN_NO;
80305961 1111 }
1112}
1113
192b9cd1 1114XS(XS_re_regnames_count)
80305961 1115{
192b9cd1 1116 REGEXP *rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1117 SV * ret;
80305961 1118 dVAR;
1119 dXSARGS;
192b9cd1 1120
1121 if (items != 0)
afa74d42 1122 croak_xs_usage(cv, "");
192b9cd1 1123
1124 SP -= items;
1125
1126 if (!rx)
1127 XSRETURN_UNDEF;
1128
1129 ret = CALLREG_NAMED_BUFF_COUNT(rx);
1130
1131 SPAGAIN;
1132
1133 if (ret) {
ec83ea38 1134 mXPUSHs(ret);
192b9cd1 1135 PUTBACK;
1136 return;
1137 } else {
1138 XSRETURN_UNDEF;
1139 }
1140}
1141
1142XS(XS_re_regname)
1143{
1144 dVAR;
1145 dXSARGS;
1146 REGEXP * rx;
1147 U32 flags;
1148 SV * ret;
1149
28d8d7f4 1150 if (items < 1 || items > 2)
afa74d42 1151 croak_xs_usage(cv, "name[, all ]");
192b9cd1 1152
80305961 1153 SP -= items;
80305961 1154
192b9cd1 1155 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1156
1157 if (!rx)
1158 XSRETURN_UNDEF;
1159
1160 if (items == 2 && SvTRUE(ST(1))) {
f1b875a0 1161 flags = RXapif_ALL;
192b9cd1 1162 } else {
f1b875a0 1163 flags = RXapif_ONE;
80305961 1164 }
f1b875a0 1165 ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(0), (flags | RXapif_REGNAME));
192b9cd1 1166
1167 if (ret) {
ec83ea38 1168 mXPUSHs(ret);
192b9cd1 1169 XSRETURN(1);
1170 }
1171 XSRETURN_UNDEF;
80305961 1172}
1173
192b9cd1 1174
80305961 1175XS(XS_re_regnames)
1176{
192b9cd1 1177 dVAR;
80305961 1178 dXSARGS;
192b9cd1 1179 REGEXP * rx;
1180 U32 flags;
1181 SV *ret;
1182 AV *av;
1183 I32 length;
1184 I32 i;
1185 SV **entry;
1186
1187 if (items > 1)
afa74d42 1188 croak_xs_usage(cv, "[all]");
192b9cd1 1189
1190 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1191
1192 if (!rx)
1193 XSRETURN_UNDEF;
1194
1195 if (items == 1 && SvTRUE(ST(0))) {
f1b875a0 1196 flags = RXapif_ALL;
192b9cd1 1197 } else {
f1b875a0 1198 flags = RXapif_ONE;
192b9cd1 1199 }
1200
80305961 1201 SP -= items;
80305961 1202
f1b875a0 1203 ret = CALLREG_NAMED_BUFF_ALL(rx, (flags | RXapif_REGNAMES));
192b9cd1 1204
1205 SPAGAIN;
1206
1207 SP -= items;
1208
1209 if (!ret)
1210 XSRETURN_UNDEF;
1211
502c6561 1212 av = MUTABLE_AV(SvRV(ret));
192b9cd1 1213 length = av_len(av);
1214
1215 for (i = 0; i <= length; i++) {
1216 entry = av_fetch(av, i, FALSE);
1217
1218 if (!entry)
1219 Perl_croak(aTHX_ "NULL array element in re::regnames()");
1220
ec83ea38 1221 mXPUSHs(SvREFCNT_inc_simple_NN(*entry));
80305961 1222 }
ec83ea38 1223
1224 SvREFCNT_dec(ret);
1225
192b9cd1 1226 PUTBACK;
1227 return;
80305961 1228}
1229
192c1e27 1230XS(XS_re_regexp_pattern)
1231{
1232 dVAR;
1233 dXSARGS;
1234 REGEXP *re;
192c1e27 1235
1236 if (items != 1)
afa74d42 1237 croak_xs_usage(cv, "sv");
192c1e27 1238
1239 SP -= items;
1240
1241 /*
1242 Checks if a reference is a regex or not. If the parameter is
1243 not a ref, or is not the result of a qr// then returns false
1244 in scalar context and an empty list in list context.
1245 Otherwise in list context it returns the pattern and the
1246 modifiers, in scalar context it returns the pattern just as it
1247 would if the qr// was stringified normally, regardless as
1248 to the class of the variable and any strigification overloads
1249 on the object.
1250 */
1251
1252 if ((re = SvRX(ST(0)))) /* assign deliberate */
1253 {
1254 /* Housten, we have a regex! */
1255 SV *pattern;
1256 STRLEN left = 0;
1257 char reflags[6];
1258
1259 if ( GIMME_V == G_ARRAY ) {
1260 /*
1261 we are in list context so stringify
1262 the modifiers that apply. We ignore "negative
1263 modifiers" in this scenario.
1264 */
1265
1266 const char *fptr = INT_PAT_MODS;
1267 char ch;
1268 U16 match_flags = (U16)((RX_EXTFLAGS(re) & PMf_COMPILETIME)
1269 >> RXf_PMf_STD_PMMOD_SHIFT);
1270
1271 while((ch = *fptr++)) {
1272 if(match_flags & 1) {
1273 reflags[left++] = ch;
1274 }
1275 match_flags >>= 1;
1276 }
1277
fb632ce3 1278 pattern = newSVpvn_flags(RX_PRECOMP(re),RX_PRELEN(re),
1279 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
192c1e27 1280
1281 /* return the pattern and the modifiers */
1282 XPUSHs(pattern);
fb632ce3 1283 XPUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
192c1e27 1284 XSRETURN(2);
1285 } else {
1286 /* Scalar, so use the string that Perl would return */
1287 /* return the pattern in (?msix:..) format */
1288#if PERL_VERSION >= 11
daba3364 1289 pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
192c1e27 1290#else
fb632ce3 1291 pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
1292 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
192c1e27 1293#endif
1294 XPUSHs(pattern);
1295 XSRETURN(1);
1296 }
1297 } else {
1298 /* It ain't a regexp folks */
1299 if ( GIMME_V == G_ARRAY ) {
1300 /* return the empty list */
1301 XSRETURN_UNDEF;
1302 } else {
1303 /* Because of the (?:..) wrapping involved in a
1304 stringified pattern it is impossible to get a
1305 result for a real regexp that would evaluate to
1306 false. Therefore we can return PL_sv_no to signify
1307 that the object is not a regex, this means that one
1308 can say
1309
1310 if (regex($might_be_a_regex) eq '(?:foo)') { }
1311
1312 and not worry about undefined values.
1313 */
1314 XSRETURN_NO;
1315 }
1316 }
1317 /* NOT-REACHED */
1318}
1319
192b9cd1 1320XS(XS_Tie_Hash_NamedCapture_FETCH)
80305961 1321{
192b9cd1 1322 dVAR;
80305961 1323 dXSARGS;
192b9cd1 1324 REGEXP * rx;
1325 U32 flags;
1326 SV * ret;
1327
1328 if (items != 2)
afa74d42 1329 croak_xs_usage(cv, "$key, $flags");
192b9cd1 1330
1331 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1332
1333 if (!rx)
1334 XSRETURN_UNDEF;
1335
80305961 1336 SP -= items;
192b9cd1 1337
daba3364 1338 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1339 ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(1), flags);
1340
1341 SPAGAIN;
1342
1343 if (ret) {
ec83ea38 1344 mXPUSHs(ret);
192b9cd1 1345 PUTBACK;
1346 return;
1347 }
1348 XSRETURN_UNDEF;
1349}
1350
1351XS(XS_Tie_Hash_NamedCapture_STORE)
1352{
1353 dVAR;
1354 dXSARGS;
1355 REGEXP * rx;
1356 U32 flags;
1357
1358 if (items != 3)
afa74d42 1359 croak_xs_usage(cv, "$key, $value, $flags");
192b9cd1 1360
1361 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1362
1363 if (!rx) {
1364 if (!PL_localizing)
f1f66076 1365 Perl_croak(aTHX_ "%s", PL_no_modify);
192b9cd1 1366 else
28d8d7f4 1367 XSRETURN_UNDEF;
80305961 1368 }
192b9cd1 1369
1370 SP -= items;
1371
daba3364 1372 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1373 CALLREG_NAMED_BUFF_STORE(rx,ST(1), ST(2), flags);
80305961 1374}
1375
192b9cd1 1376XS(XS_Tie_Hash_NamedCapture_DELETE)
1377{
1378 dVAR;
1379 dXSARGS;
1380 REGEXP * rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1381 U32 flags;
80305961 1382
192b9cd1 1383 if (items != 2)
afa74d42 1384 croak_xs_usage(cv, "$key, $flags");
192b9cd1 1385
1386 if (!rx)
f1f66076 1387 Perl_croak(aTHX_ "%s", PL_no_modify);
192b9cd1 1388
1389 SP -= items;
1390
daba3364 1391 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1392 CALLREG_NAMED_BUFF_DELETE(rx, ST(1), flags);
1393}
1394
1395XS(XS_Tie_Hash_NamedCapture_CLEAR)
80305961 1396{
192b9cd1 1397 dVAR;
80305961 1398 dXSARGS;
192b9cd1 1399 REGEXP * rx;
1400 U32 flags;
1401
1402 if (items != 1)
afa74d42 1403 croak_xs_usage(cv, "$flags");
192b9cd1 1404
1405 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1406
1407 if (!rx)
f1f66076 1408 Perl_croak(aTHX_ "%s", PL_no_modify);
192b9cd1 1409
80305961 1410 SP -= items;
80305961 1411
daba3364 1412 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1413 CALLREG_NAMED_BUFF_CLEAR(rx, flags);
1414}
1415
1416XS(XS_Tie_Hash_NamedCapture_EXISTS)
1417{
1418 dVAR;
1419 dXSARGS;
1420 REGEXP * rx;
1421 U32 flags;
1422 SV * ret;
1423
1424 if (items != 2)
afa74d42 1425 croak_xs_usage(cv, "$key, $flags");
192b9cd1 1426
1427 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1428
1429 if (!rx)
28d8d7f4 1430 XSRETURN_UNDEF;
192b9cd1 1431
1432 SP -= items;
1433
daba3364 1434 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1435 ret = CALLREG_NAMED_BUFF_EXISTS(rx, ST(1), flags);
1436
1437 SPAGAIN;
1438
1439 XPUSHs(ret);
80305961 1440 PUTBACK;
1441 return;
80305961 1442}
1443
86aa3d53 1444XS(XS_Tie_Hash_NamedCapture_FIRSTK)
192b9cd1 1445{
1446 dVAR;
1447 dXSARGS;
1448 REGEXP * rx;
1449 U32 flags;
1450 SV * ret;
80305961 1451
192b9cd1 1452 if (items != 1)
afa74d42 1453 croak_xs_usage(cv, "");
192b9cd1 1454
1455 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1456
1457 if (!rx)
1458 XSRETURN_UNDEF;
1459
1460 SP -= items;
1461
daba3364 1462 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1463 ret = CALLREG_NAMED_BUFF_FIRSTKEY(rx, flags);
1464
1465 SPAGAIN;
1466
1467 if (ret) {
ec83ea38 1468 mXPUSHs(ret);
192b9cd1 1469 PUTBACK;
1470 } else {
1471 XSRETURN_UNDEF;
1472 }
1473
1474}
1475
86aa3d53 1476XS(XS_Tie_Hash_NamedCapture_NEXTK)
80305961 1477{
192b9cd1 1478 dVAR;
80305961 1479 dXSARGS;
192b9cd1 1480 REGEXP * rx;
1481 U32 flags;
1482 SV * ret;
1483
1484 if (items != 2)
afa74d42 1485 croak_xs_usage(cv, "$lastkey");
192b9cd1 1486
1487 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1488
1489 if (!rx)
1490 XSRETURN_UNDEF;
80305961 1491
80305961 1492 SP -= items;
192b9cd1 1493
daba3364 1494 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1495 ret = CALLREG_NAMED_BUFF_NEXTKEY(rx, ST(1), flags);
1496
1497 SPAGAIN;
1498
1499 if (ret) {
ec83ea38 1500 mXPUSHs(ret);
80305961 1501 } else {
1502 XSRETURN_UNDEF;
1503 }
1504 PUTBACK;
192b9cd1 1505}
1506
1507XS(XS_Tie_Hash_NamedCapture_SCALAR)
1508{
1509 dVAR;
1510 dXSARGS;
1511 REGEXP * rx;
1512 U32 flags;
1513 SV * ret;
1514
1515 if (items != 1)
afa74d42 1516 croak_xs_usage(cv, "");
192b9cd1 1517
1518 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1519
1520 if (!rx)
1521 XSRETURN_UNDEF;
1522
1523 SP -= items;
1524
daba3364 1525 flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
192b9cd1 1526 ret = CALLREG_NAMED_BUFF_SCALAR(rx, flags);
1527
1528 SPAGAIN;
1529
1530 if (ret) {
ec83ea38 1531 mXPUSHs(ret);
192b9cd1 1532 PUTBACK;
1533 return;
1534 } else {
1535 XSRETURN_UNDEF;
1536 }
1537}
1538
1539XS(XS_Tie_Hash_NamedCapture_flags)
1540{
1541 dVAR;
1542 dXSARGS;
1543
1544 if (items != 0)
afa74d42 1545 croak_xs_usage(cv, "");
192b9cd1 1546
6e449a3a 1547 mXPUSHu(RXapif_ONE);
1548 mXPUSHu(RXapif_ALL);
192b9cd1 1549 PUTBACK;
1550 return;
80305961 1551}
1552
1553
241d1a3b 1554/*
1555 * Local variables:
1556 * c-indentation-style: bsd
1557 * c-basic-offset: 4
1558 * indent-tabs-mode: t
1559 * End:
1560 *
37442d52 1561 * ex: set ts=8 sts=4 sw=4 noet:
1562 */