This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
APItest/t/utf8_warn_base.pl: Add some tests
[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#if defined(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 const struct mro_meta *const meta = HvMROMETA(stash);
45 HV *isa = meta->isa;
46 const HV *our_stash;
47
48 PERL_ARGS_ASSERT_ISA_LOOKUP;
49
50 if (!isa) {
51 (void)mro_get_linear_isa(stash);
52 isa = meta->isa;
53 }
54
55 if (hv_common(isa, NULL, name, len, ( flags & SVf_UTF8 ? HVhek_UTF8 : 0),
56 HV_FETCH_ISEXISTS, NULL, 0)) {
57 /* Direct name lookup worked. */
58 return TRUE;
59 }
60
61 /* A stash/class can go by many names (ie. User == main::User), so
62 we use the HvENAME in the stash itself, which is canonical, falling
63 back to HvNAME if necessary. */
64 our_stash = gv_stashpvn(name, len, flags);
65
66 if (our_stash) {
67 HEK *canon_name = HvENAME_HEK(our_stash);
68 if (!canon_name) canon_name = HvNAME_HEK(our_stash);
69 assert(canon_name);
70 if (hv_common(isa, NULL, HEK_KEY(canon_name), HEK_LEN(canon_name),
71 HEK_FLAGS(canon_name),
72 HV_FETCH_ISEXISTS, NULL, HEK_HASH(canon_name))) {
73 return TRUE;
74 }
75 }
76
77 return FALSE;
78}
79
80/*
81=head1 SV Manipulation Functions
82
83=for apidoc sv_derived_from_pvn
84
85Returns a boolean indicating whether the SV is derived from the specified class
86I<at the C level>. To check derivation at the Perl level, call C<isa()> as a
87normal Perl method.
88
89Currently, the only significant value for C<flags> is SVf_UTF8.
90
91=cut
92
93=for apidoc sv_derived_from_sv
94
95Exactly like L</sv_derived_from_pvn>, but takes the name string in the form
96of an SV instead of a string/length pair.
97
98=cut
99
100*/
101
102bool
103Perl_sv_derived_from_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
104{
105 char *namepv;
106 STRLEN namelen;
107 PERL_ARGS_ASSERT_SV_DERIVED_FROM_SV;
108 namepv = SvPV(namesv, namelen);
109 if (SvUTF8(namesv))
110 flags |= SVf_UTF8;
111 return sv_derived_from_pvn(sv, namepv, namelen, flags);
112}
113
114/*
115=for apidoc sv_derived_from
116
117Exactly like L</sv_derived_from_pv>, but doesn't take a C<flags> parameter.
118
119=cut
120*/
121
122bool
123Perl_sv_derived_from(pTHX_ SV *sv, const char *const name)
124{
125 PERL_ARGS_ASSERT_SV_DERIVED_FROM;
126 return sv_derived_from_pvn(sv, name, strlen(name), 0);
127}
128
129/*
130=for apidoc sv_derived_from_pv
131
132Exactly like L</sv_derived_from_pvn>, but takes a nul-terminated string
133instead of a string/length pair.
134
135=cut
136*/
137
138
139bool
140Perl_sv_derived_from_pv(pTHX_ SV *sv, const char *const name, U32 flags)
141{
142 PERL_ARGS_ASSERT_SV_DERIVED_FROM_PV;
143 return sv_derived_from_pvn(sv, name, strlen(name), flags);
144}
145
146bool
147Perl_sv_derived_from_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len, U32 flags)
148{
149 HV *stash;
150
151 PERL_ARGS_ASSERT_SV_DERIVED_FROM_PVN;
152
153 SvGETMAGIC(sv);
154
155 if (SvROK(sv)) {
156 const char *type;
157 sv = SvRV(sv);
158 type = sv_reftype(sv,0);
159 if (type && strEQ(type,name))
160 return TRUE;
161 if (!SvOBJECT(sv))
162 return FALSE;
163 stash = SvSTASH(sv);
164 }
165 else {
166 stash = gv_stashsv(sv, 0);
167 }
168
169 if (stash && isa_lookup(stash, name, len, flags))
170 return TRUE;
171
172 stash = gv_stashpvs("UNIVERSAL", 0);
173 return stash && isa_lookup(stash, name, len, flags);
174}
175
176/*
177=for apidoc sv_does_sv
178
179Returns a boolean indicating whether the SV performs a specific, named role.
180The SV can be a Perl object or the name of a Perl class.
181
182=cut
183*/
184
185#include "XSUB.h"
186
187bool
188Perl_sv_does_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
189{
190 SV *classname;
191 bool does_it;
192 SV *methodname;
193 dSP;
194
195 PERL_ARGS_ASSERT_SV_DOES_SV;
196 PERL_UNUSED_ARG(flags);
197
198 ENTER;
199 SAVETMPS;
200
201 SvGETMAGIC(sv);
202
203 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv)))) {
204 LEAVE;
205 return FALSE;
206 }
207
208 if (SvROK(sv) && SvOBJECT(SvRV(sv))) {
209 classname = sv_ref(NULL,SvRV(sv),TRUE);
210 } else {
211 classname = sv;
212 }
213
214 if (sv_eq(classname, namesv)) {
215 LEAVE;
216 return TRUE;
217 }
218
219 PUSHMARK(SP);
220 EXTEND(SP, 2);
221 PUSHs(sv);
222 PUSHs(namesv);
223 PUTBACK;
224
225 /* create a PV with value "isa", but with a special address
226 * so that perl knows we're really doing "DOES" instead */
227 methodname = newSV_type(SVt_PV);
228 SvLEN(methodname) = 0;
229 SvCUR(methodname) = strlen(PL_isa_DOES);
230 SvPVX(methodname) = (char *)PL_isa_DOES; /* discard 'const' qualifier */
231 SvPOK_on(methodname);
232 sv_2mortal(methodname);
233 call_sv(methodname, G_SCALAR | G_METHOD);
234 SPAGAIN;
235
236 does_it = SvTRUE( TOPs );
237 FREETMPS;
238 LEAVE;
239
240 return does_it;
241}
242
243/*
244=for apidoc sv_does
245
246Like L</sv_does_pv>, but doesn't take a C<flags> parameter.
247
248=cut
249*/
250
251bool
252Perl_sv_does(pTHX_ SV *sv, const char *const name)
253{
254 PERL_ARGS_ASSERT_SV_DOES;
255 return sv_does_sv(sv, newSVpvn_flags(name, strlen(name), SVs_TEMP), 0);
256}
257
258/*
259=for apidoc sv_does_pv
260
261Like L</sv_does_sv>, but takes a nul-terminated string instead of an SV.
262
263=cut
264*/
265
266
267bool
268Perl_sv_does_pv(pTHX_ SV *sv, const char *const name, U32 flags)
269{
270 PERL_ARGS_ASSERT_SV_DOES_PV;
271 return sv_does_sv(sv, newSVpvn_flags(name, strlen(name), SVs_TEMP | flags), flags);
272}
273
274/*
275=for apidoc sv_does_pvn
276
277Like L</sv_does_sv>, but takes a string/length pair instead of an SV.
278
279=cut
280*/
281
282bool
283Perl_sv_does_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len, U32 flags)
284{
285 PERL_ARGS_ASSERT_SV_DOES_PVN;
286
287 return sv_does_sv(sv, newSVpvn_flags(name, len, flags | SVs_TEMP), flags);
288}
289
290/*
291=for apidoc croak_xs_usage
292
293A specialised variant of C<croak()> for emitting the usage message for xsubs
294
295 croak_xs_usage(cv, "eee_yow");
296
297works out the package name and subroutine name from C<cv>, and then calls
298C<croak()>. Hence if C<cv> is C<&ouch::awk>, it would call C<croak> as:
299
300 Perl_croak(aTHX_ "Usage: %" SVf "::%" SVf "(%s)", "ouch" "awk",
301 "eee_yow");
302
303=cut
304*/
305
306void
307Perl_croak_xs_usage(const CV *const cv, const char *const params)
308{
309 /* Avoid CvGV as it requires aTHX. */
310 const GV *gv = CvNAMED(cv) ? NULL : cv->sv_any->xcv_gv_u.xcv_gv;
311
312 PERL_ARGS_ASSERT_CROAK_XS_USAGE;
313
314 if (gv) got_gv: {
315 const HV *const stash = GvSTASH(gv);
316
317 if (HvNAME_get(stash))
318 /* diag_listed_as: SKIPME */
319 Perl_croak_nocontext("Usage: %" HEKf "::%" HEKf "(%s)",
320 HEKfARG(HvNAME_HEK(stash)),
321 HEKfARG(GvNAME_HEK(gv)),
322 params);
323 else
324 /* diag_listed_as: SKIPME */
325 Perl_croak_nocontext("Usage: %" HEKf "(%s)",
326 HEKfARG(GvNAME_HEK(gv)), params);
327 } else {
328 dTHX;
329 if ((gv = CvGV(cv))) goto got_gv;
330
331 /* Pants. I don't think that it should be possible to get here. */
332 /* diag_listed_as: SKIPME */
333 Perl_croak(aTHX_ "Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
334 }
335}
336
337XS(XS_UNIVERSAL_isa); /* prototype to pass -Wmissing-prototypes */
338XS(XS_UNIVERSAL_isa)
339{
340 dXSARGS;
341
342 if (items != 2)
343 croak_xs_usage(cv, "reference, kind");
344 else {
345 SV * const sv = ST(0);
346
347 SvGETMAGIC(sv);
348
349 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))))
350 XSRETURN_UNDEF;
351
352 ST(0) = boolSV(sv_derived_from_sv(sv, ST(1), 0));
353 XSRETURN(1);
354 }
355}
356
357XS(XS_UNIVERSAL_can); /* prototype to pass -Wmissing-prototypes */
358XS(XS_UNIVERSAL_can)
359{
360 dXSARGS;
361 SV *sv;
362 SV *rv;
363 HV *pkg = NULL;
364 GV *iogv;
365
366 if (items != 2)
367 croak_xs_usage(cv, "object-ref, method");
368
369 sv = ST(0);
370
371 SvGETMAGIC(sv);
372
373 /* Reject undef and empty string. Note that the string form takes
374 precedence here over the numeric form, as (!1)->foo treats the
375 invocant as the empty string, though it is a dualvar. */
376 if (!SvOK(sv) || (SvPOK(sv) && !SvCUR(sv)))
377 XSRETURN_UNDEF;
378
379 rv = &PL_sv_undef;
380
381 if (SvROK(sv)) {
382 sv = MUTABLE_SV(SvRV(sv));
383 if (SvOBJECT(sv))
384 pkg = SvSTASH(sv);
385 else if (isGV_with_GP(sv) && GvIO(sv))
386 pkg = SvSTASH(GvIO(sv));
387 }
388 else if (isGV_with_GP(sv) && GvIO(sv))
389 pkg = SvSTASH(GvIO(sv));
390 else if ((iogv = gv_fetchsv_nomg(sv, 0, SVt_PVIO)) && GvIO(iogv))
391 pkg = SvSTASH(GvIO(iogv));
392 else {
393 pkg = gv_stashsv(sv, 0);
394 if (!pkg)
395 pkg = gv_stashpvs("UNIVERSAL", 0);
396 }
397
398 if (pkg) {
399 GV * const gv = gv_fetchmethod_sv_flags(pkg, ST(1), 0);
400 if (gv && isGV(gv))
401 rv = sv_2mortal(newRV(MUTABLE_SV(GvCV(gv))));
402 }
403
404 ST(0) = rv;
405 XSRETURN(1);
406}
407
408XS(XS_UNIVERSAL_DOES); /* prototype to pass -Wmissing-prototypes */
409XS(XS_UNIVERSAL_DOES)
410{
411 dXSARGS;
412 PERL_UNUSED_ARG(cv);
413
414 if (items != 2)
415 Perl_croak(aTHX_ "Usage: invocant->DOES(kind)");
416 else {
417 SV * const sv = ST(0);
418 if (sv_does_sv( sv, ST(1), 0 ))
419 XSRETURN_YES;
420
421 XSRETURN_NO;
422 }
423}
424
425XS(XS_utf8_is_utf8); /* prototype to pass -Wmissing-prototypes */
426XS(XS_utf8_is_utf8)
427{
428 dXSARGS;
429 if (items != 1)
430 croak_xs_usage(cv, "sv");
431 else {
432 SV * const sv = ST(0);
433 SvGETMAGIC(sv);
434 if (SvUTF8(sv))
435 XSRETURN_YES;
436 else
437 XSRETURN_NO;
438 }
439 XSRETURN_EMPTY;
440}
441
442XS(XS_utf8_valid); /* prototype to pass -Wmissing-prototypes */
443XS(XS_utf8_valid)
444{
445 dXSARGS;
446 if (items != 1)
447 croak_xs_usage(cv, "sv");
448 else {
449 SV * const sv = ST(0);
450 STRLEN len;
451 const char * const s = SvPV_const(sv,len);
452 if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len))
453 XSRETURN_YES;
454 else
455 XSRETURN_NO;
456 }
457 XSRETURN_EMPTY;
458}
459
460XS(XS_utf8_encode); /* prototype to pass -Wmissing-prototypes */
461XS(XS_utf8_encode)
462{
463 dXSARGS;
464 if (items != 1)
465 croak_xs_usage(cv, "sv");
466 sv_utf8_encode(ST(0));
467 SvSETMAGIC(ST(0));
468 XSRETURN_EMPTY;
469}
470
471XS(XS_utf8_decode); /* prototype to pass -Wmissing-prototypes */
472XS(XS_utf8_decode)
473{
474 dXSARGS;
475 if (items != 1)
476 croak_xs_usage(cv, "sv");
477 else {
478 SV * const sv = ST(0);
479 bool RETVAL;
480 SvPV_force_nolen(sv);
481 RETVAL = sv_utf8_decode(sv);
482 SvSETMAGIC(sv);
483 ST(0) = boolSV(RETVAL);
484 }
485 XSRETURN(1);
486}
487
488XS(XS_utf8_upgrade); /* prototype to pass -Wmissing-prototypes */
489XS(XS_utf8_upgrade)
490{
491 dXSARGS;
492 if (items != 1)
493 croak_xs_usage(cv, "sv");
494 else {
495 SV * const sv = ST(0);
496 STRLEN RETVAL;
497 dXSTARG;
498
499 RETVAL = sv_utf8_upgrade(sv);
500 XSprePUSH; PUSHi((IV)RETVAL);
501 }
502 XSRETURN(1);
503}
504
505XS(XS_utf8_downgrade); /* prototype to pass -Wmissing-prototypes */
506XS(XS_utf8_downgrade)
507{
508 dXSARGS;
509 if (items < 1 || items > 2)
510 croak_xs_usage(cv, "sv, failok=0");
511 else {
512 SV * const sv = ST(0);
513 const bool failok = (items < 2) ? 0 : SvTRUE(ST(1)) ? 1 : 0;
514 const bool RETVAL = sv_utf8_downgrade(sv, failok);
515
516 ST(0) = boolSV(RETVAL);
517 }
518 XSRETURN(1);
519}
520
521XS(XS_utf8_native_to_unicode); /* prototype to pass -Wmissing-prototypes */
522XS(XS_utf8_native_to_unicode)
523{
524 dXSARGS;
525 const UV uv = SvUV(ST(0));
526
527 if (items > 1)
528 croak_xs_usage(cv, "sv");
529
530 ST(0) = sv_2mortal(newSVuv(NATIVE_TO_UNI(uv)));
531 XSRETURN(1);
532}
533
534XS(XS_utf8_unicode_to_native); /* prototype to pass -Wmissing-prototypes */
535XS(XS_utf8_unicode_to_native)
536{
537 dXSARGS;
538 const UV uv = SvUV(ST(0));
539
540 if (items > 1)
541 croak_xs_usage(cv, "sv");
542
543 ST(0) = sv_2mortal(newSVuv(UNI_TO_NATIVE(uv)));
544 XSRETURN(1);
545}
546
547XS(XS_Internals_SvREADONLY); /* prototype to pass -Wmissing-prototypes */
548XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
549{
550 dXSARGS;
551 SV * const svz = ST(0);
552 SV * sv;
553
554 /* [perl #77776] - called as &foo() not foo() */
555 if (!SvROK(svz))
556 croak_xs_usage(cv, "SCALAR[, ON]");
557
558 sv = SvRV(svz);
559
560 if (items == 1) {
561 if (SvREADONLY(sv))
562 XSRETURN_YES;
563 else
564 XSRETURN_NO;
565 }
566 else if (items == 2) {
567 if (SvTRUE(ST(1))) {
568 SvFLAGS(sv) |= SVf_READONLY;
569 XSRETURN_YES;
570 }
571 else {
572 /* I hope you really know what you are doing. */
573 SvFLAGS(sv) &=~ SVf_READONLY;
574 XSRETURN_NO;
575 }
576 }
577 XSRETURN_UNDEF; /* Can't happen. */
578}
579
580XS(XS_constant__make_const); /* prototype to pass -Wmissing-prototypes */
581XS(XS_constant__make_const) /* This is dangerous stuff. */
582{
583 dXSARGS;
584 SV * const svz = ST(0);
585 SV * sv;
586
587 /* [perl #77776] - called as &foo() not foo() */
588 if (!SvROK(svz) || items != 1)
589 croak_xs_usage(cv, "SCALAR");
590
591 sv = SvRV(svz);
592
593 SvREADONLY_on(sv);
594 if (SvTYPE(sv) == SVt_PVAV && AvFILLp(sv) != -1) {
595 /* for constant.pm; nobody else should be calling this
596 on arrays anyway. */
597 SV **svp;
598 for (svp = AvARRAY(sv) + AvFILLp(sv)
599 ; svp >= AvARRAY(sv)
600 ; --svp)
601 if (*svp) SvPADTMP_on(*svp);
602 }
603 XSRETURN(0);
604}
605
606XS(XS_Internals_SvREFCNT); /* prototype to pass -Wmissing-prototypes */
607XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
608{
609 dXSARGS;
610 SV * const svz = ST(0);
611 SV * sv;
612 U32 refcnt;
613
614 /* [perl #77776] - called as &foo() not foo() */
615 if ((items != 1 && items != 2) || !SvROK(svz))
616 croak_xs_usage(cv, "SCALAR[, REFCOUNT]");
617
618 sv = SvRV(svz);
619
620 /* I hope you really know what you are doing. */
621 /* idea is for SvREFCNT(sv) to be accessed only once */
622 refcnt = items == 2 ?
623 /* we free one ref on exit */
624 (SvREFCNT(sv) = SvUV(ST(1)) + 1)
625 : SvREFCNT(sv);
626 XSRETURN_UV(refcnt - 1); /* Minus the ref created for us. */
627
628}
629
630XS(XS_Internals_hv_clear_placehold); /* prototype to pass -Wmissing-prototypes */
631XS(XS_Internals_hv_clear_placehold)
632{
633 dXSARGS;
634
635 if (items != 1 || !SvROK(ST(0)))
636 croak_xs_usage(cv, "hv");
637 else {
638 HV * const hv = MUTABLE_HV(SvRV(ST(0)));
639 hv_clear_placeholders(hv);
640 XSRETURN(0);
641 }
642}
643
644XS(XS_PerlIO_get_layers); /* prototype to pass -Wmissing-prototypes */
645XS(XS_PerlIO_get_layers)
646{
647 dXSARGS;
648 if (items < 1 || items % 2 == 0)
649 croak_xs_usage(cv, "filehandle[,args]");
650#if defined(USE_PERLIO)
651 {
652 SV * sv;
653 GV * gv;
654 IO * io;
655 bool input = TRUE;
656 bool details = FALSE;
657
658 if (items > 1) {
659 SV * const *svp;
660 for (svp = MARK + 2; svp <= SP; svp += 2) {
661 SV * const * const varp = svp;
662 SV * const * const valp = svp + 1;
663 STRLEN klen;
664 const char * const key = SvPV_const(*varp, klen);
665
666 switch (*key) {
667 case 'i':
668 if (memEQs(key, klen, "input")) {
669 input = SvTRUE(*valp);
670 break;
671 }
672 goto fail;
673 case 'o':
674 if (memEQs(key, klen, "output")) {
675 input = !SvTRUE(*valp);
676 break;
677 }
678 goto fail;
679 case 'd':
680 if (memEQs(key, klen, "details")) {
681 details = SvTRUE(*valp);
682 break;
683 }
684 goto fail;
685 default:
686 fail:
687 Perl_croak(aTHX_
688 "get_layers: unknown argument '%s'",
689 key);
690 }
691 }
692
693 SP -= (items - 1);
694 }
695
696 sv = POPs;
697 gv = MAYBE_DEREF_GV(sv);
698
699 if (!gv && !SvROK(sv))
700 gv = gv_fetchsv_nomg(sv, 0, SVt_PVIO);
701
702 if (gv && (io = GvIO(gv))) {
703 AV* const av = PerlIO_get_layers(aTHX_ input ?
704 IoIFP(io) : IoOFP(io));
705 SSize_t i;
706 const SSize_t last = av_tindex(av);
707 SSize_t nitem = 0;
708
709 for (i = last; i >= 0; i -= 3) {
710 SV * const * const namsvp = av_fetch(av, i - 2, FALSE);
711 SV * const * const argsvp = av_fetch(av, i - 1, FALSE);
712 SV * const * const flgsvp = av_fetch(av, i, FALSE);
713
714 const bool namok = namsvp && *namsvp && SvPOK(*namsvp);
715 const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
716 const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
717
718 EXTEND(SP, 3); /* Three is the max in all branches: better check just once */
719 if (details) {
720 /* Indents of 5? Yuck. */
721 /* We know that PerlIO_get_layers creates a new SV for
722 the name and flags, so we can just take a reference
723 and "steal" it when we free the AV below. */
724 PUSHs(namok
725 ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
726 : &PL_sv_undef);
727 PUSHs(argok
728 ? newSVpvn_flags(SvPVX_const(*argsvp),
729 SvCUR(*argsvp),
730 (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
731 | SVs_TEMP)
732 : &PL_sv_undef);
733 PUSHs(flgok
734 ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
735 : &PL_sv_undef);
736 nitem += 3;
737 }
738 else {
739 if (namok && argok)
740 PUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%" SVf "(%" SVf ")",
741 SVfARG(*namsvp),
742 SVfARG(*argsvp))));
743 else if (namok)
744 PUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
745 else
746 PUSHs(&PL_sv_undef);
747 nitem++;
748 if (flgok) {
749 const IV flags = SvIVX(*flgsvp);
750
751 if (flags & PERLIO_F_UTF8) {
752 PUSHs(newSVpvs_flags("utf8", SVs_TEMP));
753 nitem++;
754 }
755 }
756 }
757 }
758
759 SvREFCNT_dec(av);
760
761 XSRETURN(nitem);
762 }
763 }
764#endif
765
766 XSRETURN(0);
767}
768
769XS(XS_re_is_regexp); /* prototype to pass -Wmissing-prototypes */
770XS(XS_re_is_regexp)
771{
772 dXSARGS;
773
774 if (items != 1)
775 croak_xs_usage(cv, "sv");
776
777 if (SvRXOK(ST(0))) {
778 XSRETURN_YES;
779 } else {
780 XSRETURN_NO;
781 }
782}
783
784XS(XS_re_regnames_count); /* prototype to pass -Wmissing-prototypes */
785XS(XS_re_regnames_count)
786{
787 REGEXP *rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
788 SV * ret;
789 dXSARGS;
790
791 if (items != 0)
792 croak_xs_usage(cv, "");
793
794 if (!rx)
795 XSRETURN_UNDEF;
796
797 ret = CALLREG_NAMED_BUFF_COUNT(rx);
798
799 SPAGAIN;
800 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
801 XSRETURN(1);
802}
803
804XS(XS_re_regname); /* prototype to pass -Wmissing-prototypes */
805XS(XS_re_regname)
806{
807 dXSARGS;
808 REGEXP * rx;
809 U32 flags;
810 SV * ret;
811
812 if (items < 1 || items > 2)
813 croak_xs_usage(cv, "name[, all ]");
814
815 SP -= items;
816 PUTBACK;
817
818 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
819
820 if (!rx)
821 XSRETURN_UNDEF;
822
823 if (items == 2 && SvTRUE(ST(1))) {
824 flags = RXapif_ALL;
825 } else {
826 flags = RXapif_ONE;
827 }
828 ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(0), (flags | RXapif_REGNAME));
829
830 SPAGAIN;
831 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
832 XSRETURN(1);
833}
834
835
836XS(XS_re_regnames); /* prototype to pass -Wmissing-prototypes */
837XS(XS_re_regnames)
838{
839 dXSARGS;
840 REGEXP * rx;
841 U32 flags;
842 SV *ret;
843 AV *av;
844 SSize_t length;
845 SSize_t i;
846 SV **entry;
847
848 if (items > 1)
849 croak_xs_usage(cv, "[all]");
850
851 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
852
853 if (!rx)
854 XSRETURN_UNDEF;
855
856 if (items == 1 && SvTRUE(ST(0))) {
857 flags = RXapif_ALL;
858 } else {
859 flags = RXapif_ONE;
860 }
861
862 SP -= items;
863 PUTBACK;
864
865 ret = CALLREG_NAMED_BUFF_ALL(rx, (flags | RXapif_REGNAMES));
866
867 SPAGAIN;
868
869 if (!ret)
870 XSRETURN_UNDEF;
871
872 av = MUTABLE_AV(SvRV(ret));
873 length = av_tindex(av);
874
875 EXTEND(SP, length+1); /* better extend stack just once */
876 for (i = 0; i <= length; i++) {
877 entry = av_fetch(av, i, FALSE);
878
879 if (!entry)
880 Perl_croak(aTHX_ "NULL array element in re::regnames()");
881
882 mPUSHs(SvREFCNT_inc_simple_NN(*entry));
883 }
884
885 SvREFCNT_dec(ret);
886
887 PUTBACK;
888 return;
889}
890
891XS(XS_re_regexp_pattern); /* prototype to pass -Wmissing-prototypes */
892XS(XS_re_regexp_pattern)
893{
894 dXSARGS;
895 REGEXP *re;
896 U8 const gimme = GIMME_V;
897
898 EXTEND(SP, 2);
899 SP -= items;
900 if (items != 1)
901 croak_xs_usage(cv, "sv");
902
903 /*
904 Checks if a reference is a regex or not. If the parameter is
905 not a ref, or is not the result of a qr// then returns false
906 in scalar context and an empty list in list context.
907 Otherwise in list context it returns the pattern and the
908 modifiers, in scalar context it returns the pattern just as it
909 would if the qr// was stringified normally, regardless as
910 to the class of the variable and any stringification overloads
911 on the object.
912 */
913
914 if ((re = SvRX(ST(0)))) /* assign deliberate */
915 {
916 /* Houston, we have a regex! */
917 SV *pattern;
918
919 if ( gimme == G_ARRAY ) {
920 STRLEN left = 0;
921 char reflags[sizeof(INT_PAT_MODS) + MAX_CHARSET_NAME_LENGTH];
922 const char *fptr;
923 char ch;
924 U16 match_flags;
925
926 /*
927 we are in list context so stringify
928 the modifiers that apply. We ignore "negative
929 modifiers" in this scenario, and the default character set
930 */
931
932 if (get_regex_charset(RX_EXTFLAGS(re)) != REGEX_DEPENDS_CHARSET) {
933 STRLEN len;
934 const char* const name = get_regex_charset_name(RX_EXTFLAGS(re),
935 &len);
936 Copy(name, reflags + left, len, char);
937 left += len;
938 }
939 fptr = INT_PAT_MODS;
940 match_flags = (U16)((RX_EXTFLAGS(re) & RXf_PMf_COMPILETIME)
941 >> RXf_PMf_STD_PMMOD_SHIFT);
942
943 while((ch = *fptr++)) {
944 if(match_flags & 1) {
945 reflags[left++] = ch;
946 }
947 match_flags >>= 1;
948 }
949
950 pattern = newSVpvn_flags(RX_PRECOMP(re),RX_PRELEN(re),
951 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
952
953 /* return the pattern and the modifiers */
954 PUSHs(pattern);
955 PUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
956 XSRETURN(2);
957 } else {
958 /* Scalar, so use the string that Perl would return */
959 /* return the pattern in (?msixn:..) format */
960 pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
961 PUSHs(pattern);
962 XSRETURN(1);
963 }
964 } else {
965 /* It ain't a regexp folks */
966 if ( gimme == G_ARRAY ) {
967 /* return the empty list */
968 XSRETURN_EMPTY;
969 } else {
970 /* Because of the (?:..) wrapping involved in a
971 stringified pattern it is impossible to get a
972 result for a real regexp that would evaluate to
973 false. Therefore we can return PL_sv_no to signify
974 that the object is not a regex, this means that one
975 can say
976
977 if (regex($might_be_a_regex) eq '(?:foo)') { }
978
979 and not worry about undefined values.
980 */
981 XSRETURN_NO;
982 }
983 }
984 NOT_REACHED; /* NOTREACHED */
985}
986
987#include "vutil.h"
988#include "vxs.inc"
989
990struct xsub_details {
991 const char *name;
992 XSUBADDR_t xsub;
993 const char *proto;
994};
995
996static const struct xsub_details details[] = {
997 {"UNIVERSAL::isa", XS_UNIVERSAL_isa, NULL},
998 {"UNIVERSAL::can", XS_UNIVERSAL_can, NULL},
999 {"UNIVERSAL::DOES", XS_UNIVERSAL_DOES, NULL},
1000#define VXS_XSUB_DETAILS
1001#include "vxs.inc"
1002#undef VXS_XSUB_DETAILS
1003 {"utf8::is_utf8", XS_utf8_is_utf8, NULL},
1004 {"utf8::valid", XS_utf8_valid, NULL},
1005 {"utf8::encode", XS_utf8_encode, NULL},
1006 {"utf8::decode", XS_utf8_decode, NULL},
1007 {"utf8::upgrade", XS_utf8_upgrade, NULL},
1008 {"utf8::downgrade", XS_utf8_downgrade, NULL},
1009 {"utf8::native_to_unicode", XS_utf8_native_to_unicode, NULL},
1010 {"utf8::unicode_to_native", XS_utf8_unicode_to_native, NULL},
1011 {"Internals::SvREADONLY", XS_Internals_SvREADONLY, "\\[$%@];$"},
1012 {"Internals::SvREFCNT", XS_Internals_SvREFCNT, "\\[$%@];$"},
1013 {"Internals::hv_clear_placeholders", XS_Internals_hv_clear_placehold, "\\%"},
1014 {"constant::_make_const", XS_constant__make_const, "\\[$@]"},
1015 {"PerlIO::get_layers", XS_PerlIO_get_layers, "*;@"},
1016 {"re::is_regexp", XS_re_is_regexp, "$"},
1017 {"re::regname", XS_re_regname, ";$$"},
1018 {"re::regnames", XS_re_regnames, ";$"},
1019 {"re::regnames_count", XS_re_regnames_count, ""},
1020 {"re::regexp_pattern", XS_re_regexp_pattern, "$"},
1021};
1022
1023STATIC OP*
1024optimize_out_native_convert_function(pTHX_ OP* entersubop,
1025 GV* namegv,
1026 SV* protosv)
1027{
1028 /* Optimizes out an identity function, i.e., one that just returns its
1029 * argument. The passed in function is assumed to be an identity function,
1030 * with no checking. This is designed to be called for utf8_to_native()
1031 * and native_to_utf8() on ASCII platforms, as they just return their
1032 * arguments, but it could work on any such function.
1033 *
1034 * The code is mostly just cargo-culted from Memoize::Lift */
1035
1036 OP *pushop, *argop;
1037 OP *parent;
1038 SV* prototype = newSVpvs("$");
1039
1040 PERL_UNUSED_ARG(protosv);
1041
1042 assert(entersubop->op_type == OP_ENTERSUB);
1043
1044 entersubop = ck_entersub_args_proto(entersubop, namegv, prototype);
1045 parent = entersubop;
1046
1047 SvREFCNT_dec(prototype);
1048
1049 pushop = cUNOPx(entersubop)->op_first;
1050 if (! OpHAS_SIBLING(pushop)) {
1051 parent = pushop;
1052 pushop = cUNOPx(pushop)->op_first;
1053 }
1054 argop = OpSIBLING(pushop);
1055
1056 /* Carry on without doing the optimization if it is not something we're
1057 * expecting, so continues to work */
1058 if ( ! argop
1059 || ! OpHAS_SIBLING(argop)
1060 || OpHAS_SIBLING(OpSIBLING(argop))
1061 ) {
1062 return entersubop;
1063 }
1064
1065 /* cut argop from the subtree */
1066 (void)op_sibling_splice(parent, pushop, 1, NULL);
1067
1068 op_free(entersubop);
1069 return argop;
1070}
1071
1072void
1073Perl_boot_core_UNIVERSAL(pTHX)
1074{
1075 static const char file[] = __FILE__;
1076 const struct xsub_details *xsub = details;
1077 const struct xsub_details *end = C_ARRAY_END(details);
1078
1079 do {
1080 newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
1081 } while (++xsub < end);
1082
1083#ifndef EBCDIC
1084 { /* On ASCII platforms these functions just return their argument, so can
1085 be optimized away */
1086
1087 CV* to_native_cv = get_cv("utf8::unicode_to_native", 0);
1088 CV* to_unicode_cv = get_cv("utf8::native_to_unicode", 0);
1089
1090 cv_set_call_checker(to_native_cv,
1091 optimize_out_native_convert_function,
1092 (SV*) to_native_cv);
1093 cv_set_call_checker(to_unicode_cv,
1094 optimize_out_native_convert_function,
1095 (SV*) to_unicode_cv);
1096 }
1097#endif
1098
1099 /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */
1100 {
1101 CV * const cv =
1102 newCONSTSUB(get_hv("Regexp::", GV_ADD), "DESTROY", NULL);
1103 char ** cvfile = &CvFILE(cv);
1104 char * oldfile = *cvfile;
1105 CvDYNFILE_off(cv);
1106 *cvfile = (char *)file;
1107 Safefree(oldfile);
1108 }
1109}
1110
1111/*
1112 * ex: set ts=8 sts=4 sw=4 et:
1113 */