This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
The new regexp compilation function must be added to the engine structure.
[perl5.git] / ext / re / re.xs
CommitLineData
41b16711
AD
1#if defined(PERL_EXT_RE_DEBUG) && !defined(DEBUGGING)
2# define DEBUGGING
3#endif
4
c5be433b 5#define PERL_NO_GET_CONTEXT
56953603
IZ
6#include "EXTERN.h"
7#include "perl.h"
8#include "XSUB.h"
256ddcd0 9#include "re_comp.h"
56953603 10
f9f4320a 11
97f88e98
JH
12START_EXTERN_C
13
cea2e8a9 14extern regexp* my_regcomp (pTHX_ char* exp, char* xend, PMOP* pm);
3c6f95d1 15extern regexp* my_re_compile(pTHX_ char *exp, char *xend, PMOP *pm);
cea2e8a9 16extern I32 my_regexec (pTHX_ regexp* prog, char* stringarg, char* strend,
20ce7b12
GS
17 char* strbeg, I32 minend, SV* screamer,
18 void* data, U32 flags);
f8149455 19
f722798b
IZ
20extern char* my_re_intuit_start (pTHX_ regexp *prog, SV *sv, char *strpos,
21 char *strend, U32 flags,
22 struct re_scream_pos_data_s *data);
23extern SV* my_re_intuit_string (pTHX_ regexp *prog);
56953603 24
f8149455 25extern void my_regfree (pTHX_ struct regexp* r);
a3c0e9ca 26#if defined(USE_ITHREADS)
f9f4320a 27extern regexp* my_regdupe (pTHX_ const regexp *r, CLONE_PARAMS *param);
a3c0e9ca 28#endif
0a28d81c 29
70685ca0
JH
30EXTERN_C const struct regexp_engine my_reg_engine;
31
32END_EXTERN_C
33
34const struct regexp_engine my_reg_engine = {
f9f4320a 35 my_regcomp,
3c6f95d1 36 my_re_compile,
f9f4320a
YO
37 my_regexec,
38 my_re_intuit_start,
39 my_re_intuit_string,
40 my_regfree,
a3c0e9ca 41#if defined(USE_ITHREADS)
f9f4320a 42 my_regdupe
a3c0e9ca 43#endif
0a28d81c
NC
44};
45
56953603
IZ
46MODULE = re PACKAGE = re
47
48void
f9f4320a
YO
49install()
50 PPCODE:
51 PL_colorset = 0; /* Allow reinspection of ENV. */
52 /* PL_debug |= DEBUG_r_FLAG; */
53 XPUSHs(sv_2mortal(newSViv(PTR2IV(&my_reg_engine))));
54
de8c5301
YO
55
56void
57is_regexp(sv)
58 SV * sv
59PROTOTYPE: $
60PREINIT:
61 MAGIC *mg;
62PPCODE:
63{
64 if (SvMAGICAL(sv))
65 mg_get(sv);
66 if (SvROK(sv) &&
67 (sv = (SV*)SvRV(sv)) && /* assign deliberate */
68 SvTYPE(sv) == SVt_PVMG &&
69 (mg = mg_find(sv, PERL_MAGIC_qr))) /* assign deliberate */
70 {
71 XSRETURN_YES;
72 } else {
73 XSRETURN_NO;
74 }
75 /* NOTREACHED */
76}
77
78void
79regexp_pattern(sv)
80 SV * sv
81PROTOTYPE: $
82PREINIT:
83 MAGIC *mg;
84PPCODE:
85{
86 /*
87 Checks if a reference is a regex or not. If the parameter is
88 not a ref, or is not the result of a qr// then returns false
89 in scalar context and an empty list in list context.
90 Otherwise in list context it returns the pattern and the
91 modifiers, in scalar context it returns the pattern just as it
92 would if the qr// was stringified normally, regardless as
93 to the class of the variable and any strigification overloads
94 on the object.
95 */
96
97 if (SvMAGICAL(sv))
98 mg_get(sv);
99 if (SvROK(sv) &&
100 (sv = (SV*)SvRV(sv)) && /* assign deliberate */
101 SvTYPE(sv) == SVt_PVMG &&
102 (mg = mg_find(sv, PERL_MAGIC_qr))) /* assign deliberate */
103 {
104
105 /* Housten, we have a regex! */
106 SV *pattern;
107 regexp *re = (regexp *)mg->mg_obj;
108 STRLEN patlen = 0;
109 STRLEN left = 0;
110 char reflags[6];
111
112 if ( GIMME_V == G_ARRAY ) {
113 /*
114 we are in list context so stringify
115 the modifiers that apply. We ignore "negative
116 modifiers" in this scenario.
117 */
118
119 char *fptr = "msix";
120 char ch;
bbe252da 121 U16 match_flags = (U16)((re->extflags & PMf_COMPILETIME) >> 12);
de8c5301
YO
122
123 while((ch = *fptr++)) {
bbe252da 124 if(match_flags & 1) {
de8c5301
YO
125 reflags[left++] = ch;
126 }
bbe252da 127 match_flags >>= 1;
de8c5301
YO
128 }
129
130 pattern = sv_2mortal(newSVpvn(re->precomp,re->prelen));
bbe252da 131 if (re->extflags & RXf_UTF8) SvUTF8_on(pattern);
de8c5301
YO
132
133 /* return the pattern and the modifiers */
134 XPUSHs(pattern);
135 XPUSHs(sv_2mortal(newSVpvn(reflags,left)));
136 XSRETURN(2);
137 } else {
138 /* Scalar, so use the string that Perl would return */
139 if (!mg->mg_ptr)
140 CALLREG_STRINGIFY(mg,0,0);
141
142 /* return the pattern in (?msix:..) format */
143 pattern = sv_2mortal(newSVpvn(mg->mg_ptr,mg->mg_len));
bbe252da 144 if (re->extflags & RXf_UTF8)
de8c5301
YO
145 SvUTF8_on(pattern);
146 XPUSHs(pattern);
147 XSRETURN(1);
148 }
149 } else {
150 /* It ain't a regexp folks */
151 if ( GIMME_V == G_ARRAY ) {
152 /* return the empty list */
153 XSRETURN_UNDEF;
154 } else {
155 /* Because of the (?:..) wrapping involved in a
156 stringified pattern it is impossible to get a
157 result for a real regexp that would evaluate to
158 false. Therefore we can return PL_sv_no to signify
159 that the object is not a regex, this means that one
160 can say
161
162 if (regex($might_be_a_regex) eq '(?:foo)') { }
163
164 and not worry about undefined values.
165 */
166 XSRETURN_NO;
167 }
168 }
169 /* NOT-REACHED */
256ddcd0
YO
170}
171
172
173void
174regmust(sv)
175 SV * sv
176PROTOTYPE: $
177PREINIT:
178 MAGIC *mg;
179PPCODE:
180{
181 if (SvMAGICAL(sv))
182 mg_get(sv);
183 if (SvROK(sv) &&
184 (sv = (SV*)SvRV(sv)) && /* assign deliberate */
185 SvTYPE(sv) == SVt_PVMG &&
186 (mg = mg_find(sv, PERL_MAGIC_qr))) /* assign deliberate */
187 {
188 SV *an = &PL_sv_no;
189 SV *fl = &PL_sv_no;
190 regexp *re = (regexp *)mg->mg_obj;
191 if (re->anchored_substr) {
192 an = newSVsv(re->anchored_substr);
193 } else if (re->anchored_utf8) {
194 an = newSVsv(re->anchored_utf8);
195 }
196 if (re->float_substr) {
197 fl = newSVsv(re->float_substr);
198 } else if (re->float_utf8) {
199 fl = newSVsv(re->float_utf8);
200 }
201 XPUSHs(an);
202 XPUSHs(fl);
203 XSRETURN(2);
204 }
205 XSRETURN_UNDEF;
206}