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