Resolve PL_curpm issues with (??{}) and fix corruption of match results when pattern...
[p5sagit/p5-mst-13.2.git] / ext / re / re.xs
CommitLineData
41b16711 1#if defined(PERL_EXT_RE_DEBUG) && !defined(DEBUGGING)
2# define DEBUGGING
3#endif
4
c5be433b 5#define PERL_NO_GET_CONTEXT
56953603 6#include "EXTERN.h"
7#include "perl.h"
8#include "XSUB.h"
256ddcd0 9#include "re_comp.h"
56953603 10
f9f4320a 11
97f88e98 12START_EXTERN_C
13
6d5c990f 14extern regexp* my_re_compile (pTHX_ char* exp, char* xend, PMOP* pm);
cea2e8a9 15extern I32 my_regexec (pTHX_ regexp* prog, char* stringarg, char* strend,
20ce7b12 16 char* strbeg, I32 minend, SV* screamer,
17 void* data, U32 flags);
f8149455 18
f722798b 19extern char* my_re_intuit_start (pTHX_ regexp *prog, SV *sv, char *strpos,
20 char *strend, U32 flags,
21 struct re_scream_pos_data_s *data);
22extern SV* my_re_intuit_string (pTHX_ regexp *prog);
56953603 23
f8149455 24extern void my_regfree (pTHX_ struct regexp* r);
93b32b6d 25extern SV* my_reg_numbered_buff_get(pTHX_ const REGEXP * const rx, I32 paren, SV* usesv);
26extern SV* my_reg_named_buff_get(pTHX_ const REGEXP * const rx, SV* namesv, U32 flags);
a3c0e9ca 27#if defined(USE_ITHREADS)
9f33bf00 28extern void* my_regdupe (pTHX_ const regexp *r, CLONE_PARAMS *param);
a3c0e9ca 29#endif
0a28d81c 30
70685ca0 31EXTERN_C const struct regexp_engine my_reg_engine;
32
33END_EXTERN_C
34
35const struct regexp_engine my_reg_engine = {
6d5c990f 36 my_re_compile,
f9f4320a 37 my_regexec,
38 my_re_intuit_start,
39 my_re_intuit_string,
40 my_regfree,
93b32b6d 41 my_reg_numbered_buff_get,
42 my_reg_named_buff_get,
a3c0e9ca 43#if defined(USE_ITHREADS)
f9f4320a 44 my_regdupe
a3c0e9ca 45#endif
0a28d81c 46};
47
44a2ac75 48regexp *
49get_re_arg( pTHX_ SV *sv, U32 flags, MAGIC **mgp) {
50 MAGIC *mg;
51 if (sv) {
52 if (SvMAGICAL(sv))
53 mg_get(sv);
54 if (SvROK(sv) &&
55 (sv = (SV*)SvRV(sv)) && /* assign deliberate */
56 SvTYPE(sv) == SVt_PVMG &&
57 (mg = mg_find(sv, PERL_MAGIC_qr))) /* assign deliberate */
58 {
59 if (mgp) *mgp = mg;
60 return (regexp *)mg->mg_obj;
61 }
62 }
63 if (mgp) *mgp = NULL;
64 return ((flags && PL_curpm) ? PM_GETRE(PL_curpm) : NULL);
65}
66
56953603 67MODULE = re PACKAGE = re
68
69void
f9f4320a 70install()
71 PPCODE:
72 PL_colorset = 0; /* Allow reinspection of ENV. */
73 /* PL_debug |= DEBUG_r_FLAG; */
74 XPUSHs(sv_2mortal(newSViv(PTR2IV(&my_reg_engine))));
75
de8c5301 76
77void
de8c5301 78regexp_pattern(sv)
79 SV * sv
80PROTOTYPE: $
81PREINIT:
82 MAGIC *mg;
44a2ac75 83 regexp *re;
de8c5301 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
44a2ac75 97 if ( re = get_re_arg( aTHX_ sv, 0, &mg) ) /* assign deliberate */
de8c5301 98 {
de8c5301 99 /* Housten, we have a regex! */
100 SV *pattern;
de8c5301 101 STRLEN patlen = 0;
102 STRLEN left = 0;
103 char reflags[6];
104
105 if ( GIMME_V == G_ARRAY ) {
106 /*
107 we are in list context so stringify
108 the modifiers that apply. We ignore "negative
109 modifiers" in this scenario.
110 */
111
bcdf7404 112 char *fptr = INT_PAT_MODS;
de8c5301 113 char ch;
bbe252da 114 U16 match_flags = (U16)((re->extflags & PMf_COMPILETIME) >> 12);
de8c5301 115
116 while((ch = *fptr++)) {
bbe252da 117 if(match_flags & 1) {
de8c5301 118 reflags[left++] = ch;
119 }
bbe252da 120 match_flags >>= 1;
de8c5301 121 }
122
123 pattern = sv_2mortal(newSVpvn(re->precomp,re->prelen));
bbe252da 124 if (re->extflags & RXf_UTF8) SvUTF8_on(pattern);
de8c5301 125
126 /* return the pattern and the modifiers */
127 XPUSHs(pattern);
128 XPUSHs(sv_2mortal(newSVpvn(reflags,left)));
129 XSRETURN(2);
130 } else {
131 /* Scalar, so use the string that Perl would return */
de8c5301 132 /* return the pattern in (?msix:..) format */
bcdf7404 133 pattern = sv_2mortal(newSVpvn(re->wrapped,re->wraplen));
bbe252da 134 if (re->extflags & RXf_UTF8)
de8c5301 135 SvUTF8_on(pattern);
136 XPUSHs(pattern);
137 XSRETURN(1);
138 }
139 } else {
140 /* It ain't a regexp folks */
141 if ( GIMME_V == G_ARRAY ) {
142 /* return the empty list */
143 XSRETURN_UNDEF;
144 } else {
145 /* Because of the (?:..) wrapping involved in a
146 stringified pattern it is impossible to get a
147 result for a real regexp that would evaluate to
148 false. Therefore we can return PL_sv_no to signify
149 that the object is not a regex, this means that one
150 can say
151
152 if (regex($might_be_a_regex) eq '(?:foo)') { }
153
154 and not worry about undefined values.
155 */
156 XSRETURN_NO;
157 }
158 }
159 /* NOT-REACHED */
256ddcd0 160}
161
162
163void
164regmust(sv)
165 SV * sv
166PROTOTYPE: $
167PREINIT:
44a2ac75 168 regexp *re;
256ddcd0 169PPCODE:
170{
44a2ac75 171 if ( re = get_re_arg( aTHX_ sv, 0, 0) ) /* assign deliberate */
256ddcd0 172 {
173 SV *an = &PL_sv_no;
174 SV *fl = &PL_sv_no;
256ddcd0 175 if (re->anchored_substr) {
176 an = newSVsv(re->anchored_substr);
177 } else if (re->anchored_utf8) {
178 an = newSVsv(re->anchored_utf8);
179 }
180 if (re->float_substr) {
181 fl = newSVsv(re->float_substr);
182 } else if (re->float_utf8) {
183 fl = newSVsv(re->float_utf8);
184 }
185 XPUSHs(an);
186 XPUSHs(fl);
187 XSRETURN(2);
188 }
189 XSRETURN_UNDEF;
190}
44a2ac75 191