This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Avoid segfault in re::regmust with pluggable RE engines
[perl5.git] / ext / re / re.xs
1 #if defined(PERL_EXT_RE_DEBUG) && !defined(DEBUGGING)
2 #  define DEBUGGING
3 #endif
4
5 #define PERL_NO_GET_CONTEXT
6 #include "EXTERN.h"
7 #include "perl.h"
8 #include "XSUB.h"
9 #include "re_comp.h"
10
11
12 START_EXTERN_C
13
14 extern REGEXP*  my_re_compile (pTHX_ SV * const pattern, const U32 pm_flags);
15 extern I32      my_regexec (pTHX_ REGEXP * const prog, char* stringarg, char* strend,
16                             char* strbeg, I32 minend, SV* screamer,
17                             void* data, U32 flags);
18
19 extern char*    my_re_intuit_start (pTHX_ REGEXP * const prog, SV *sv, char *strpos,
20                                     char *strend, const U32 flags,
21                                     struct re_scream_pos_data_s *data);
22 extern SV*      my_re_intuit_string (pTHX_ REGEXP * const prog);
23
24 extern void     my_regfree (pTHX_ REGEXP * const r);
25
26 extern void     my_reg_numbered_buff_fetch(pTHX_ REGEXP * const rx, const I32 paren,
27                                            SV * const usesv);
28 extern void     my_reg_numbered_buff_store(pTHX_ REGEXP * const rx, const I32 paren,
29                                            SV const * const value);
30 extern I32      my_reg_numbered_buff_length(pTHX_ REGEXP * const rx,
31                                             const SV * const sv, const I32 paren);
32
33 extern SV*      my_reg_named_buff(pTHX_ REGEXP * const, SV * const, SV * const,
34                               const U32);
35 extern SV*      my_reg_named_buff_iter(pTHX_ REGEXP * const rx,
36                                    const SV * const lastkey, const U32 flags);
37
38 extern SV*      my_reg_qr_package(pTHX_ REGEXP * const rx);
39 #if defined(USE_ITHREADS)
40 extern void*    my_regdupe (pTHX_ REGEXP * const r, CLONE_PARAMS *param);
41 #endif
42
43 EXTERN_C const struct regexp_engine my_reg_engine;
44
45 END_EXTERN_C
46
47 const struct regexp_engine my_reg_engine = { 
48         my_re_compile, 
49         my_regexec, 
50         my_re_intuit_start, 
51         my_re_intuit_string, 
52         my_regfree, 
53         my_reg_numbered_buff_fetch,
54         my_reg_numbered_buff_store,
55         my_reg_numbered_buff_length,
56         my_reg_named_buff,
57         my_reg_named_buff_iter,
58         my_reg_qr_package,
59 #if defined(USE_ITHREADS)
60         my_regdupe 
61 #endif
62 };
63
64 MODULE = re     PACKAGE = re
65
66 void
67 install()
68     PPCODE:
69         PL_colorset = 0;        /* Allow reinspection of ENV. */
70         /* PL_debug |= DEBUG_r_FLAG; */
71         XPUSHs(sv_2mortal(newSViv(PTR2IV(&my_reg_engine))));
72
73 void
74 regmust(sv)
75     SV * sv
76 PROTOTYPE: $
77 PREINIT:
78     REGEXP *re;
79 PPCODE:
80 {
81     if ((re = SvRX(sv)) /* assign deliberate */
82        /* only for re engines we know about */
83        && (RX_ENGINE(re) == &my_reg_engine
84            || RX_ENGINE(re) == &PL_core_reg_engine))
85     {
86         SV *an = &PL_sv_no;
87         SV *fl = &PL_sv_no;
88         if (RX_ANCHORED_SUBSTR(re)) {
89             an = sv_2mortal(newSVsv(RX_ANCHORED_SUBSTR(re)));
90         } else if (RX_ANCHORED_UTF8(re)) {
91             an = sv_2mortal(newSVsv(RX_ANCHORED_UTF8(re)));
92         }
93         if (RX_FLOAT_SUBSTR(re)) {
94             fl = sv_2mortal(newSVsv(RX_FLOAT_SUBSTR(re)));
95         } else if (RX_FLOAT_UTF8(re)) {
96             fl = sv_2mortal(newSVsv(RX_FLOAT_UTF8(re)));
97         }
98         XPUSHs(an);
99         XPUSHs(fl);
100         XSRETURN(2);
101     }
102     XSRETURN_UNDEF;
103 }
104