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