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