This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #80674] Fix compilation with very old versions of glibc
[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 seperate 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 const char *undef;
315 PERL_UNUSED_ARG(cv);
316
317 if (SvROK(ST(0))) {
318 sv = MUTABLE_SV(SvRV(ST(0)));
319 if (!SvOBJECT(sv))
320 Perl_croak(aTHX_ "Cannot find version of an unblessed reference");
321 pkg = SvSTASH(sv);
322 }
323 else {
324 pkg = gv_stashsv(ST(0), 0);
325 }
326
327 gvp = pkg ? (GV**)hv_fetchs(pkg, "VERSION", FALSE) : NULL;
328
329 if (gvp && isGV(gv = *gvp) && (sv = GvSV(gv)) && SvOK(sv)) {
330 SV * const nsv = sv_newmortal();
331 sv_setsv(nsv, sv);
332 sv = nsv;
333 if ( !sv_derived_from(sv, "version"))
334 upg_version(sv, FALSE);
335 undef = NULL;
336 }
337 else {
338 sv = &PL_sv_undef;
339 undef = "(undef)";
340 }
341
342 if (items > 1) {
343 SV *req = ST(1);
344
345 if (undef) {
346 if (pkg) {
347 const char * const name = HvNAME_get(pkg);
348 Perl_croak(aTHX_
349 "%s does not define $%s::VERSION--version check failed",
350 name, name);
351 } else {
352 Perl_croak(aTHX_
353 "%s defines neither package nor VERSION--version check failed",
354 SvPVx_nolen_const(ST(0)) );
355 }
356 }
357
358 if ( !sv_derived_from(req, "version")) {
359 /* req may very well be R/O, so create a new object */
360 req = sv_2mortal( new_version(req) );
361 }
362
363 if ( vcmp( req, sv ) > 0 ) {
364 if ( hv_exists(MUTABLE_HV(SvRV(req)), "qv", 2 ) ) {
365 Perl_croak(aTHX_ "%s version %"SVf" required--"
366 "this is only version %"SVf"", HvNAME_get(pkg),
367 SVfARG(sv_2mortal(vnormal(req))),
368 SVfARG(sv_2mortal(vnormal(sv))));
369 } else {
370 Perl_croak(aTHX_ "%s version %"SVf" required--"
371 "this is only version %"SVf"", HvNAME_get(pkg),
372 SVfARG(sv_2mortal(vstringify(req))),
373 SVfARG(sv_2mortal(vstringify(sv))));
374 }
375 }
376
377 }
378
379 if ( SvOK(sv) && sv_derived_from(sv, "version") ) {
380 ST(0) = sv_2mortal(vstringify(sv));
381 } else {
382 ST(0) = sv;
383 }
384
385 XSRETURN(1);
386}
387
388XS(XS_version_new)
389{
390 dVAR;
391 dXSARGS;
392 if (items > 3)
393 croak_xs_usage(cv, "class, version");
394 SP -= items;
395 {
396 SV *vs = ST(1);
397 SV *rv;
398 const char * const classname =
399 sv_isobject(ST(0)) /* get the class if called as an object method */
400 ? HvNAME(SvSTASH(SvRV(ST(0))))
401 : (char *)SvPV_nolen(ST(0));
402
403 if ( items == 1 || ! SvOK(vs) ) { /* no param or explicit undef */
404 /* create empty object */
405 vs = sv_newmortal();
406 sv_setpvs(vs, "0");
407 }
408 else if ( items == 3 ) {
409 vs = sv_newmortal();
410 Perl_sv_setpvf(aTHX_ vs,"v%s",SvPV_nolen_const(ST(2)));
411 }
412
413 rv = new_version(vs);
414 if ( strcmp(classname,"version") != 0 ) /* inherited new() */
415 sv_bless(rv, gv_stashpv(classname, GV_ADD));
416
417 mPUSHs(rv);
418 PUTBACK;
419 return;
420 }
421}
422
423XS(XS_version_stringify)
424{
425 dVAR;
426 dXSARGS;
427 if (items < 1)
428 croak_xs_usage(cv, "lobj, ...");
429 SP -= items;
430 {
431 SV * lobj = ST(0);
432
433 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
434 lobj = SvRV(lobj);
435 }
436 else
437 Perl_croak(aTHX_ "lobj is not of type version");
438
439 mPUSHs(vstringify(lobj));
440
441 PUTBACK;
442 return;
443 }
444}
445
446XS(XS_version_numify)
447{
448 dVAR;
449 dXSARGS;
450 if (items < 1)
451 croak_xs_usage(cv, "lobj, ...");
452 SP -= items;
453 {
454 SV * lobj = ST(0);
455
456 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
457 lobj = SvRV(lobj);
458 }
459 else
460 Perl_croak(aTHX_ "lobj is not of type version");
461
462 mPUSHs(vnumify(lobj));
463
464 PUTBACK;
465 return;
466 }
467}
468
469XS(XS_version_normal)
470{
471 dVAR;
472 dXSARGS;
473 if (items < 1)
474 croak_xs_usage(cv, "lobj, ...");
475 SP -= items;
476 {
477 SV * lobj = ST(0);
478
479 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
480 lobj = SvRV(lobj);
481 }
482 else
483 Perl_croak(aTHX_ "lobj is not of type version");
484
485 mPUSHs(vnormal(lobj));
486
487 PUTBACK;
488 return;
489 }
490}
491
492XS(XS_version_vcmp)
493{
494 dVAR;
495 dXSARGS;
496 if (items < 1)
497 croak_xs_usage(cv, "lobj, ...");
498 SP -= items;
499 {
500 SV * lobj = ST(0);
501
502 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
503 lobj = SvRV(lobj);
504 }
505 else
506 Perl_croak(aTHX_ "lobj is not of type version");
507
508 {
509 SV *rs;
510 SV *rvs;
511 SV * robj = ST(1);
512 const IV swap = (IV)SvIV(ST(2));
513
514 if ( ! sv_derived_from(robj, "version") )
515 {
516 robj = new_version(SvOK(robj) ? robj : newSVpvs_flags("0", SVs_TEMP));
517 sv_2mortal(robj);
518 }
519 rvs = SvRV(robj);
520
521 if ( swap )
522 {
523 rs = newSViv(vcmp(rvs,lobj));
524 }
525 else
526 {
527 rs = newSViv(vcmp(lobj,rvs));
528 }
529
530 mPUSHs(rs);
531 }
532
533 PUTBACK;
534 return;
535 }
536}
537
538XS(XS_version_boolean)
539{
540 dVAR;
541 dXSARGS;
542 if (items < 1)
543 croak_xs_usage(cv, "lobj, ...");
544 SP -= items;
545 if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
546 SV * const lobj = SvRV(ST(0));
547 SV * const rs = newSViv( vcmp(lobj,new_version(newSVpvs("0"))) );
548 mPUSHs(rs);
549 PUTBACK;
550 return;
551 }
552 else
553 Perl_croak(aTHX_ "lobj is not of type version");
554}
555
556XS(XS_version_noop)
557{
558 dVAR;
559 dXSARGS;
560 if (items < 1)
561 croak_xs_usage(cv, "lobj, ...");
562 if (sv_derived_from(ST(0), "version") && SvROK(ST(0)))
563 Perl_croak(aTHX_ "operation not supported with version object");
564 else
565 Perl_croak(aTHX_ "lobj is not of type version");
566#ifndef HASATTRIBUTE_NORETURN
567 XSRETURN_EMPTY;
568#endif
569}
570
571XS(XS_version_is_alpha)
572{
573 dVAR;
574 dXSARGS;
575 if (items != 1)
576 croak_xs_usage(cv, "lobj");
577 SP -= items;
578 if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
579 SV * const lobj = ST(0);
580 if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "alpha", 5 ) )
581 XSRETURN_YES;
582 else
583 XSRETURN_NO;
584 PUTBACK;
585 return;
586 }
587 else
588 Perl_croak(aTHX_ "lobj is not of type version");
589}
590
591XS(XS_version_qv)
592{
593 dVAR;
594 dXSARGS;
595 PERL_UNUSED_ARG(cv);
596 SP -= items;
597 {
598 SV * ver = ST(0);
599 SV * rv;
600 const char * classname = "";
601 if ( items == 2 && SvOK(ST(1)) ) {
602 /* getting called as object or class method */
603 ver = ST(1);
604 classname =
605 sv_isobject(ST(0)) /* class called as an object method */
606 ? HvNAME_get(SvSTASH(SvRV(ST(0))))
607 : (char *)SvPV_nolen(ST(0));
608 }
609 if ( !SvVOK(ver) ) { /* not already a v-string */
610 rv = sv_newmortal();
611 sv_setsv(rv,ver); /* make a duplicate */
612 upg_version(rv, TRUE);
613 } else {
614 rv = sv_2mortal(new_version(ver));
615 }
616 if ( items == 2 && strcmp(classname,"version") ) { /* inherited new() */
617 sv_bless(rv, gv_stashpv(classname, GV_ADD));
618 }
619 PUSHs(rv);
620 }
621 PUTBACK;
622 return;
623}
624
625XS(XS_version_is_qv)
626{
627 dVAR;
628 dXSARGS;
629 if (items != 1)
630 croak_xs_usage(cv, "lobj");
631 SP -= items;
632 if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
633 SV * const lobj = ST(0);
634 if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "qv", 2 ) )
635 XSRETURN_YES;
636 else
637 XSRETURN_NO;
638 PUTBACK;
639 return;
640 }
641 else
642 Perl_croak(aTHX_ "lobj is not of type version");
643}
644
645XS(XS_utf8_is_utf8)
646{
647 dVAR;
648 dXSARGS;
649 if (items != 1)
650 croak_xs_usage(cv, "sv");
651 else {
652 SV * const sv = ST(0);
653 SvGETMAGIC(sv);
654 if (SvUTF8(sv))
655 XSRETURN_YES;
656 else
657 XSRETURN_NO;
658 }
659 XSRETURN_EMPTY;
660}
661
662XS(XS_utf8_valid)
663{
664 dVAR;
665 dXSARGS;
666 if (items != 1)
667 croak_xs_usage(cv, "sv");
668 else {
669 SV * const sv = ST(0);
670 STRLEN len;
671 const char * const s = SvPV_const(sv,len);
672 if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len))
673 XSRETURN_YES;
674 else
675 XSRETURN_NO;
676 }
677 XSRETURN_EMPTY;
678}
679
680XS(XS_utf8_encode)
681{
682 dVAR;
683 dXSARGS;
684 if (items != 1)
685 croak_xs_usage(cv, "sv");
686 sv_utf8_encode(ST(0));
687 XSRETURN_EMPTY;
688}
689
690XS(XS_utf8_decode)
691{
692 dVAR;
693 dXSARGS;
694 if (items != 1)
695 croak_xs_usage(cv, "sv");
696 else {
697 SV * const sv = ST(0);
698 const bool RETVAL = sv_utf8_decode(sv);
699 ST(0) = boolSV(RETVAL);
700 sv_2mortal(ST(0));
701 }
702 XSRETURN(1);
703}
704
705XS(XS_utf8_upgrade)
706{
707 dVAR;
708 dXSARGS;
709 if (items != 1)
710 croak_xs_usage(cv, "sv");
711 else {
712 SV * const sv = ST(0);
713 STRLEN RETVAL;
714 dXSTARG;
715
716 RETVAL = sv_utf8_upgrade(sv);
717 XSprePUSH; PUSHi((IV)RETVAL);
718 }
719 XSRETURN(1);
720}
721
722XS(XS_utf8_downgrade)
723{
724 dVAR;
725 dXSARGS;
726 if (items < 1 || items > 2)
727 croak_xs_usage(cv, "sv, failok=0");
728 else {
729 SV * const sv = ST(0);
730 const bool failok = (items < 2) ? 0 : (int)SvIV(ST(1));
731 const bool RETVAL = sv_utf8_downgrade(sv, failok);
732
733 ST(0) = boolSV(RETVAL);
734 sv_2mortal(ST(0));
735 }
736 XSRETURN(1);
737}
738
739XS(XS_utf8_native_to_unicode)
740{
741 dVAR;
742 dXSARGS;
743 const UV uv = SvUV(ST(0));
744
745 if (items > 1)
746 croak_xs_usage(cv, "sv");
747
748 ST(0) = sv_2mortal(newSViv(NATIVE_TO_UNI(uv)));
749 XSRETURN(1);
750}
751
752XS(XS_utf8_unicode_to_native)
753{
754 dVAR;
755 dXSARGS;
756 const UV uv = SvUV(ST(0));
757
758 if (items > 1)
759 croak_xs_usage(cv, "sv");
760
761 ST(0) = sv_2mortal(newSViv(UNI_TO_NATIVE(uv)));
762 XSRETURN(1);
763}
764
765XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
766{
767 dVAR;
768 dXSARGS;
769 SV * const svz = ST(0);
770 SV * sv;
771 PERL_UNUSED_ARG(cv);
772
773 /* [perl #77776] - called as &foo() not foo() */
774 if (!SvROK(svz))
775 croak_xs_usage(cv, "SCALAR[, ON]");
776
777 sv = SvRV(svz);
778
779 if (items == 1) {
780 if (SvREADONLY(sv))
781 XSRETURN_YES;
782 else
783 XSRETURN_NO;
784 }
785 else if (items == 2) {
786 if (SvTRUE(ST(1))) {
787 SvREADONLY_on(sv);
788 XSRETURN_YES;
789 }
790 else {
791 /* I hope you really know what you are doing. */
792 SvREADONLY_off(sv);
793 XSRETURN_NO;
794 }
795 }
796 XSRETURN_UNDEF; /* Can't happen. */
797}
798
799XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
800{
801 dVAR;
802 dXSARGS;
803 SV * const svz = ST(0);
804 SV * sv;
805 PERL_UNUSED_ARG(cv);
806
807 /* [perl #77776] - called as &foo() not foo() */
808 if (!SvROK(svz))
809 croak_xs_usage(cv, "SCALAR[, REFCOUNT]");
810
811 sv = SvRV(svz);
812
813 if (items == 1)
814 XSRETURN_IV(SvREFCNT(sv) - 1); /* Minus the ref created for us. */
815 else if (items == 2) {
816 /* I hope you really know what you are doing. */
817 SvREFCNT(sv) = SvIV(ST(1));
818 XSRETURN_IV(SvREFCNT(sv));
819 }
820 XSRETURN_UNDEF; /* Can't happen. */
821}
822
823XS(XS_Internals_hv_clear_placehold)
824{
825 dVAR;
826 dXSARGS;
827
828 if (items != 1 || !SvROK(ST(0)))
829 croak_xs_usage(cv, "hv");
830 else {
831 HV * const hv = MUTABLE_HV(SvRV(ST(0)));
832 hv_clear_placeholders(hv);
833 XSRETURN(0);
834 }
835}
836
837XS(XS_PerlIO_get_layers)
838{
839 dVAR;
840 dXSARGS;
841 if (items < 1 || items % 2 == 0)
842 croak_xs_usage(cv, "filehandle[,args]");
843#ifdef USE_PERLIO
844 {
845 SV * sv;
846 GV * gv;
847 IO * io;
848 bool input = TRUE;
849 bool details = FALSE;
850
851 if (items > 1) {
852 SV * const *svp;
853 for (svp = MARK + 2; svp <= SP; svp += 2) {
854 SV * const * const varp = svp;
855 SV * const * const valp = svp + 1;
856 STRLEN klen;
857 const char * const key = SvPV_const(*varp, klen);
858
859 switch (*key) {
860 case 'i':
861 if (klen == 5 && memEQ(key, "input", 5)) {
862 input = SvTRUE(*valp);
863 break;
864 }
865 goto fail;
866 case 'o':
867 if (klen == 6 && memEQ(key, "output", 6)) {
868 input = !SvTRUE(*valp);
869 break;
870 }
871 goto fail;
872 case 'd':
873 if (klen == 7 && memEQ(key, "details", 7)) {
874 details = SvTRUE(*valp);
875 break;
876 }
877 goto fail;
878 default:
879 fail:
880 Perl_croak(aTHX_
881 "get_layers: unknown argument '%s'",
882 key);
883 }
884 }
885
886 SP -= (items - 1);
887 }
888
889 sv = POPs;
890 gv = MUTABLE_GV(sv);
891
892 if (!isGV(sv)) {
893 if (SvROK(sv) && isGV(SvRV(sv)))
894 gv = MUTABLE_GV(SvRV(sv));
895 else if (SvPOKp(sv))
896 gv = gv_fetchsv(sv, 0, SVt_PVIO);
897 }
898
899 if (gv && (io = GvIO(gv))) {
900 AV* const av = PerlIO_get_layers(aTHX_ input ?
901 IoIFP(io) : IoOFP(io));
902 I32 i;
903 const I32 last = av_len(av);
904 I32 nitem = 0;
905
906 for (i = last; i >= 0; i -= 3) {
907 SV * const * const namsvp = av_fetch(av, i - 2, FALSE);
908 SV * const * const argsvp = av_fetch(av, i - 1, FALSE);
909 SV * const * const flgsvp = av_fetch(av, i, FALSE);
910
911 const bool namok = namsvp && *namsvp && SvPOK(*namsvp);
912 const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
913 const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
914
915 if (details) {
916 /* Indents of 5? Yuck. */
917 /* We know that PerlIO_get_layers creates a new SV for
918 the name and flags, so we can just take a reference
919 and "steal" it when we free the AV below. */
920 XPUSHs(namok
921 ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
922 : &PL_sv_undef);
923 XPUSHs(argok
924 ? newSVpvn_flags(SvPVX_const(*argsvp),
925 SvCUR(*argsvp),
926 (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
927 | SVs_TEMP)
928 : &PL_sv_undef);
929 XPUSHs(flgok
930 ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
931 : &PL_sv_undef);
932 nitem += 3;
933 }
934 else {
935 if (namok && argok)
936 XPUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
937 SVfARG(*namsvp),
938 SVfARG(*argsvp))));
939 else if (namok)
940 XPUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
941 else
942 XPUSHs(&PL_sv_undef);
943 nitem++;
944 if (flgok) {
945 const IV flags = SvIVX(*flgsvp);
946
947 if (flags & PERLIO_F_UTF8) {
948 XPUSHs(newSVpvs_flags("utf8", SVs_TEMP));
949 nitem++;
950 }
951 }
952 }
953 }
954
955 SvREFCNT_dec(av);
956
957 XSRETURN(nitem);
958 }
959 }
960#endif
961
962 XSRETURN(0);
963}
964
965XS(XS_Internals_hash_seed)
966{
967 dVAR;
968 /* Using dXSARGS would also have dITEM and dSP,
969 * which define 2 unused local variables. */
970 dAXMARK;
971 PERL_UNUSED_ARG(cv);
972 PERL_UNUSED_VAR(mark);
973 XSRETURN_UV(PERL_HASH_SEED);
974}
975
976XS(XS_Internals_rehash_seed)
977{
978 dVAR;
979 /* Using dXSARGS would also have dITEM and dSP,
980 * which define 2 unused local variables. */
981 dAXMARK;
982 PERL_UNUSED_ARG(cv);
983 PERL_UNUSED_VAR(mark);
984 XSRETURN_UV(PL_rehash_seed);
985}
986
987XS(XS_Internals_HvREHASH) /* Subject to change */
988{
989 dVAR;
990 dXSARGS;
991 PERL_UNUSED_ARG(cv);
992 if (SvROK(ST(0))) {
993 const HV * const hv = (const HV *) SvRV(ST(0));
994 if (items == 1 && SvTYPE(hv) == SVt_PVHV) {
995 if (HvREHASH(hv))
996 XSRETURN_YES;
997 else
998 XSRETURN_NO;
999 }
1000 }
1001 Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
1002}
1003
1004XS(XS_re_is_regexp)
1005{
1006 dVAR;
1007 dXSARGS;
1008 PERL_UNUSED_VAR(cv);
1009
1010 if (items != 1)
1011 croak_xs_usage(cv, "sv");
1012
1013 if (SvRXOK(ST(0))) {
1014 XSRETURN_YES;
1015 } else {
1016 XSRETURN_NO;
1017 }
1018}
1019
1020XS(XS_re_regnames_count)
1021{
1022 REGEXP *rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1023 SV * ret;
1024 dVAR;
1025 dXSARGS;
1026
1027 if (items != 0)
1028 croak_xs_usage(cv, "");
1029
1030 SP -= items;
1031 PUTBACK;
1032
1033 if (!rx)
1034 XSRETURN_UNDEF;
1035
1036 ret = CALLREG_NAMED_BUFF_COUNT(rx);
1037
1038 SPAGAIN;
1039 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
1040 XSRETURN(1);
1041}
1042
1043XS(XS_re_regname)
1044{
1045 dVAR;
1046 dXSARGS;
1047 REGEXP * rx;
1048 U32 flags;
1049 SV * ret;
1050
1051 if (items < 1 || items > 2)
1052 croak_xs_usage(cv, "name[, all ]");
1053
1054 SP -= items;
1055 PUTBACK;
1056
1057 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1058
1059 if (!rx)
1060 XSRETURN_UNDEF;
1061
1062 if (items == 2 && SvTRUE(ST(1))) {
1063 flags = RXapif_ALL;
1064 } else {
1065 flags = RXapif_ONE;
1066 }
1067 ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(0), (flags | RXapif_REGNAME));
1068
1069 SPAGAIN;
1070 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
1071 XSRETURN(1);
1072}
1073
1074
1075XS(XS_re_regnames)
1076{
1077 dVAR;
1078 dXSARGS;
1079 REGEXP * rx;
1080 U32 flags;
1081 SV *ret;
1082 AV *av;
1083 I32 length;
1084 I32 i;
1085 SV **entry;
1086
1087 if (items > 1)
1088 croak_xs_usage(cv, "[all]");
1089
1090 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1091
1092 if (!rx)
1093 XSRETURN_UNDEF;
1094
1095 if (items == 1 && SvTRUE(ST(0))) {
1096 flags = RXapif_ALL;
1097 } else {
1098 flags = RXapif_ONE;
1099 }
1100
1101 SP -= items;
1102 PUTBACK;
1103
1104 ret = CALLREG_NAMED_BUFF_ALL(rx, (flags | RXapif_REGNAMES));
1105
1106 SPAGAIN;
1107
1108 if (!ret)
1109 XSRETURN_UNDEF;
1110
1111 av = MUTABLE_AV(SvRV(ret));
1112 length = av_len(av);
1113
1114 for (i = 0; i <= length; i++) {
1115 entry = av_fetch(av, i, FALSE);
1116
1117 if (!entry)
1118 Perl_croak(aTHX_ "NULL array element in re::regnames()");
1119
1120 mXPUSHs(SvREFCNT_inc_simple_NN(*entry));
1121 }
1122
1123 SvREFCNT_dec(ret);
1124
1125 PUTBACK;
1126 return;
1127}
1128
1129XS(XS_re_regexp_pattern)
1130{
1131 dVAR;
1132 dXSARGS;
1133 REGEXP *re;
1134
1135 if (items != 1)
1136 croak_xs_usage(cv, "sv");
1137
1138 SP -= items;
1139
1140 /*
1141 Checks if a reference is a regex or not. If the parameter is
1142 not a ref, or is not the result of a qr// then returns false
1143 in scalar context and an empty list in list context.
1144 Otherwise in list context it returns the pattern and the
1145 modifiers, in scalar context it returns the pattern just as it
1146 would if the qr// was stringified normally, regardless as
1147 to the class of the variable and any strigification overloads
1148 on the object.
1149 */
1150
1151 if ((re = SvRX(ST(0)))) /* assign deliberate */
1152 {
1153 /* Houston, we have a regex! */
1154 SV *pattern;
1155
1156 if ( GIMME_V == G_ARRAY ) {
1157 STRLEN left = 0;
1158 char reflags[sizeof(INT_PAT_MODS) + 1]; /* The +1 is for the charset
1159 modifier */
1160 const char *fptr;
1161 char ch;
1162 U16 match_flags;
1163
1164 /*
1165 we are in list context so stringify
1166 the modifiers that apply. We ignore "negative
1167 modifiers" in this scenario.
1168 */
1169
1170 if (RX_EXTFLAGS(re) & RXf_PMf_LOCALE) {
1171 reflags[left++] = LOCALE_PAT_MOD;
1172 }
1173 else if (RX_EXTFLAGS(re) & RXf_PMf_UNICODE) {
1174 reflags[left++] = UNICODE_PAT_MOD;
1175 }
1176 fptr = INT_PAT_MODS;
1177 match_flags = (U16)((RX_EXTFLAGS(re) & PMf_COMPILETIME)
1178 >> RXf_PMf_STD_PMMOD_SHIFT);
1179
1180 while((ch = *fptr++)) {
1181 if(match_flags & 1) {
1182 reflags[left++] = ch;
1183 }
1184 match_flags >>= 1;
1185 }
1186
1187 pattern = newSVpvn_flags(RX_PRECOMP(re),RX_PRELEN(re),
1188 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
1189
1190 /* return the pattern and the modifiers */
1191 XPUSHs(pattern);
1192 XPUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
1193 XSRETURN(2);
1194 } else {
1195 /* Scalar, so use the string that Perl would return */
1196 /* return the pattern in (?msix:..) format */
1197#if PERL_VERSION >= 11
1198 pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
1199#else
1200 pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
1201 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
1202#endif
1203 XPUSHs(pattern);
1204 XSRETURN(1);
1205 }
1206 } else {
1207 /* It ain't a regexp folks */
1208 if ( GIMME_V == G_ARRAY ) {
1209 /* return the empty list */
1210 XSRETURN_UNDEF;
1211 } else {
1212 /* Because of the (?:..) wrapping involved in a
1213 stringified pattern it is impossible to get a
1214 result for a real regexp that would evaluate to
1215 false. Therefore we can return PL_sv_no to signify
1216 that the object is not a regex, this means that one
1217 can say
1218
1219 if (regex($might_be_a_regex) eq '(?:foo)') { }
1220
1221 and not worry about undefined values.
1222 */
1223 XSRETURN_NO;
1224 }
1225 }
1226 /* NOT-REACHED */
1227}
1228
1229struct xsub_details {
1230 const char *name;
1231 XSUBADDR_t xsub;
1232 const char *proto;
1233};
1234
1235struct xsub_details details[] = {
1236 {"UNIVERSAL::isa", XS_UNIVERSAL_isa, NULL},
1237 {"UNIVERSAL::can", XS_UNIVERSAL_can, NULL},
1238 {"UNIVERSAL::DOES", XS_UNIVERSAL_DOES, NULL},
1239 {"UNIVERSAL::VERSION", XS_UNIVERSAL_VERSION, NULL},
1240 {"version::()", XS_version_noop, NULL},
1241 {"version::new", XS_version_new, NULL},
1242 {"version::parse", XS_version_new, NULL},
1243 {"version::(\"\"", XS_version_stringify, NULL},
1244 {"version::stringify", XS_version_stringify, NULL},
1245 {"version::(0+", XS_version_numify, NULL},
1246 {"version::numify", XS_version_numify, NULL},
1247 {"version::normal", XS_version_normal, NULL},
1248 {"version::(cmp", XS_version_vcmp, NULL},
1249 {"version::(<=>", XS_version_vcmp, NULL},
1250 {"version::vcmp", XS_version_vcmp, NULL},
1251 {"version::(bool", XS_version_boolean, NULL},
1252 {"version::boolean", XS_version_boolean, NULL},
1253 {"version::(nomethod", XS_version_noop, NULL},
1254 {"version::noop", XS_version_noop, NULL},
1255 {"version::is_alpha", XS_version_is_alpha, NULL},
1256 {"version::qv", XS_version_qv, NULL},
1257 {"version::declare", XS_version_qv, NULL},
1258 {"version::is_qv", XS_version_is_qv, NULL},
1259 {"utf8::is_utf8", XS_utf8_is_utf8, NULL},
1260 {"utf8::valid", XS_utf8_valid, NULL},
1261 {"utf8::encode", XS_utf8_encode, NULL},
1262 {"utf8::decode", XS_utf8_decode, NULL},
1263 {"utf8::upgrade", XS_utf8_upgrade, NULL},
1264 {"utf8::downgrade", XS_utf8_downgrade, NULL},
1265 {"utf8::native_to_unicode", XS_utf8_native_to_unicode, NULL},
1266 {"utf8::unicode_to_native", XS_utf8_unicode_to_native, NULL},
1267 {"Internals::SvREADONLY", XS_Internals_SvREADONLY, "\\[$%@];$"},
1268 {"Internals::SvREFCNT", XS_Internals_SvREFCNT, "\\[$%@];$"},
1269 {"Internals::hv_clear_placeholders", XS_Internals_hv_clear_placehold, "\\%"},
1270 {"PerlIO::get_layers", XS_PerlIO_get_layers, "*;@"},
1271 {"Internals::hash_seed", XS_Internals_hash_seed, ""},
1272 {"Internals::rehash_seed", XS_Internals_rehash_seed, ""},
1273 {"Internals::HvREHASH", XS_Internals_HvREHASH, "\\%"},
1274 {"re::is_regexp", XS_re_is_regexp, "$"},
1275 {"re::regname", XS_re_regname, ";$$"},
1276 {"re::regnames", XS_re_regnames, ";$"},
1277 {"re::regnames_count", XS_re_regnames_count, ""},
1278 {"re::regexp_pattern", XS_re_regexp_pattern, "$"},
1279};
1280
1281void
1282Perl_boot_core_UNIVERSAL(pTHX)
1283{
1284 dVAR;
1285 static const char file[] = __FILE__;
1286 struct xsub_details *xsub = details;
1287 const struct xsub_details *end
1288 = details + sizeof(details) / sizeof(details[0]);
1289
1290 do {
1291 newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
1292 } while (++xsub < end);
1293
1294 /* register the overloading (type 'A') magic */
1295 PL_amagic_generation++;
1296
1297 /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */
1298 CvFILE(newCONSTSUB(get_hv("Regexp::", GV_ADD), "DESTROY", NULL))
1299 = (char *)file;
1300}
1301
1302/*
1303 * Local variables:
1304 * c-indentation-style: bsd
1305 * c-basic-offset: 4
1306 * indent-tabs-mode: t
1307 * End:
1308 *
1309 * ex: set ts=8 sts=4 sw=4 noet:
1310 */