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