Abolish wrapped in struct regexp - store the wrapped pattern pointer
[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
973f7e2e 14extern REGEXP* my_re_compile (pTHX_ const SV * const pattern, const U32 pm_flags);
49d7dfbc 15extern I32 my_regexec (pTHX_ REGEXP * const prog, char* stringarg, char* strend,
20ce7b12 16 char* strbeg, I32 minend, SV* screamer,
17 void* data, U32 flags);
f8149455 18
49d7dfbc 19extern char* my_re_intuit_start (pTHX_ REGEXP * const prog, SV *sv, char *strpos,
973f7e2e 20 char *strend, const U32 flags,
f722798b 21 struct re_scream_pos_data_s *data);
49d7dfbc 22extern SV* my_re_intuit_string (pTHX_ REGEXP * const prog);
23
24extern void my_regfree (pTHX_ REGEXP * const r);
2fdbfb4d 25
d932daed 26extern void my_reg_numbered_buff_fetch(pTHX_ REGEXP * const rx, const I32 paren,
27 SV * const usesv);
28extern void my_reg_numbered_buff_store(pTHX_ REGEXP * const rx, const I32 paren,
29 SV const * const value);
30extern I32 my_reg_numbered_buff_length(pTHX_ REGEXP * const rx,
31 const SV * const sv, const I32 paren);
32
192b9cd1 33extern SV* my_reg_named_buff(pTHX_ REGEXP * const, SV * const, SV * const,
34 const U32);
35extern SV* my_reg_named_buff_iter(pTHX_ REGEXP * const rx,
36 const SV * const lastkey, const U32 flags);
2fdbfb4d 37
49d7dfbc 38extern SV* my_reg_qr_package(pTHX_ REGEXP * const rx);
a3c0e9ca 39#if defined(USE_ITHREADS)
49d7dfbc 40extern void* my_regdupe (pTHX_ REGEXP * const r, CLONE_PARAMS *param);
a3c0e9ca 41#endif
0a28d81c 42
70685ca0 43EXTERN_C const struct regexp_engine my_reg_engine;
44
45END_EXTERN_C
46
47const struct regexp_engine my_reg_engine = {
6d5c990f 48 my_re_compile,
f9f4320a 49 my_regexec,
50 my_re_intuit_start,
51 my_re_intuit_string,
52 my_regfree,
2fdbfb4d 53 my_reg_numbered_buff_fetch,
54 my_reg_numbered_buff_store,
55 my_reg_numbered_buff_length,
192b9cd1 56 my_reg_named_buff,
57 my_reg_named_buff_iter,
49d7dfbc 58 my_reg_qr_package,
a3c0e9ca 59#if defined(USE_ITHREADS)
f9f4320a 60 my_regdupe
a3c0e9ca 61#endif
0a28d81c 62};
63
56953603 64MODULE = re PACKAGE = re
65
66void
f9f4320a 67install()
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
de8c5301 73
74void
de8c5301 75regexp_pattern(sv)
76 SV * sv
77PROTOTYPE: $
78PREINIT:
49d7dfbc 79 REGEXP *re;
de8c5301 80PPCODE:
81{
82 /*
83 Checks if a reference is a regex or not. If the parameter is
84 not a ref, or is not the result of a qr// then returns false
85 in scalar context and an empty list in list context.
86 Otherwise in list context it returns the pattern and the
87 modifiers, in scalar context it returns the pattern just as it
88 would if the qr// was stringified normally, regardless as
89 to the class of the variable and any strigification overloads
90 on the object.
91 */
92
f7e71195 93 if ((re = SvRX(sv))) /* assign deliberate */
de8c5301 94 {
de8c5301 95 /* Housten, we have a regex! */
96 SV *pattern;
de8c5301 97 STRLEN patlen = 0;
98 STRLEN left = 0;
99 char reflags[6];
100
101 if ( GIMME_V == G_ARRAY ) {
102 /*
103 we are in list context so stringify
104 the modifiers that apply. We ignore "negative
105 modifiers" in this scenario.
106 */
107
d3f5e399 108 const char *fptr = INT_PAT_MODS;
de8c5301 109 char ch;
07bc277f 110 U16 match_flags = (U16)((RX_EXTFLAGS(re) & PMf_COMPILETIME)
14f3b9f2 111 >> RXf_PMf_STD_PMMOD_SHIFT);
de8c5301 112
113 while((ch = *fptr++)) {
bbe252da 114 if(match_flags & 1) {
de8c5301 115 reflags[left++] = ch;
116 }
bbe252da 117 match_flags >>= 1;
de8c5301 118 }
119
220fc49f 120 pattern = sv_2mortal(newSVpvn(RX_PRECOMP(re),RX_PRELEN(re)));
07bc277f 121 if (RX_EXTFLAGS(re) & RXf_UTF8) SvUTF8_on(pattern);
de8c5301 122
123 /* return the pattern and the modifiers */
124 XPUSHs(pattern);
125 XPUSHs(sv_2mortal(newSVpvn(reflags,left)));
126 XSRETURN(2);
127 } else {
128 /* Scalar, so use the string that Perl would return */
de8c5301 129 /* return the pattern in (?msix:..) format */
866c78d1 130 pattern = sv_2mortal(newSVpvn(RX_WRAPPED(re),RX_WRAPLEN(re)));
07bc277f 131 if (RX_EXTFLAGS(re) & RXf_UTF8)
de8c5301 132 SvUTF8_on(pattern);
133 XPUSHs(pattern);
134 XSRETURN(1);
135 }
136 } else {
137 /* It ain't a regexp folks */
138 if ( GIMME_V == G_ARRAY ) {
139 /* return the empty list */
140 XSRETURN_UNDEF;
141 } else {
142 /* Because of the (?:..) wrapping involved in a
143 stringified pattern it is impossible to get a
144 result for a real regexp that would evaluate to
145 false. Therefore we can return PL_sv_no to signify
146 that the object is not a regex, this means that one
147 can say
148
149 if (regex($might_be_a_regex) eq '(?:foo)') { }
150
151 and not worry about undefined values.
152 */
153 XSRETURN_NO;
154 }
155 }
156 /* NOT-REACHED */
256ddcd0 157}
158
159
160void
161regmust(sv)
162 SV * sv
163PROTOTYPE: $
164PREINIT:
49d7dfbc 165 REGEXP *re;
256ddcd0 166PPCODE:
167{
f7e71195 168 if ((re = SvRX(sv))) /* assign deliberate */
256ddcd0 169 {
170 SV *an = &PL_sv_no;
171 SV *fl = &PL_sv_no;
07bc277f 172 if (RX_ANCHORED_SUBSTR(re)) {
173 an = newSVsv(RX_ANCHORED_SUBSTR(re));
174 } else if (RX_ANCHORED_UTF8(re)) {
175 an = newSVsv(RX_ANCHORED_UTF8(re));
256ddcd0 176 }
07bc277f 177 if (RX_FLOAT_SUBSTR(re)) {
178 fl = newSVsv(RX_FLOAT_SUBSTR(re));
179 } else if (RX_FLOAT_UTF8(re)) {
180 fl = newSVsv(RX_FLOAT_UTF8(re));
256ddcd0 181 }
182 XPUSHs(an);
183 XPUSHs(fl);
184 XSRETURN(2);
185 }
186 XSRETURN_UNDEF;
187}
44a2ac75 188