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