Run pod/buildtoc --build-all
[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
c737faaf 14extern regexp* my_re_compile (pTHX_ char* exp, char* xend, U32 pm_flags);
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);
fe578d7f 27extern SV* my_reg_qr_pkg(pTHX_ const REGEXP * const rx);
a3c0e9ca 28#if defined(USE_ITHREADS)
9f33bf00 29extern void* my_regdupe (pTHX_ const regexp *r, CLONE_PARAMS *param);
a3c0e9ca 30#endif
0a28d81c 31
70685ca0 32EXTERN_C const struct regexp_engine my_reg_engine;
33
34END_EXTERN_C
35
36const struct regexp_engine my_reg_engine = {
6d5c990f 37 my_re_compile,
f9f4320a 38 my_regexec,
39 my_re_intuit_start,
40 my_re_intuit_string,
41 my_regfree,
93b32b6d 42 my_reg_numbered_buff_get,
43 my_reg_named_buff_get,
fe578d7f 44 my_reg_qr_pkg,
a3c0e9ca 45#if defined(USE_ITHREADS)
f9f4320a 46 my_regdupe
a3c0e9ca 47#endif
0a28d81c 48};
49
44a2ac75 50regexp *
51get_re_arg( pTHX_ SV *sv, U32 flags, MAGIC **mgp) {
52 MAGIC *mg;
53 if (sv) {
54 if (SvMAGICAL(sv))
55 mg_get(sv);
56 if (SvROK(sv) &&
57 (sv = (SV*)SvRV(sv)) && /* assign deliberate */
58 SvTYPE(sv) == SVt_PVMG &&
59 (mg = mg_find(sv, PERL_MAGIC_qr))) /* assign deliberate */
60 {
61 if (mgp) *mgp = mg;
62 return (regexp *)mg->mg_obj;
63 }
64 }
65 if (mgp) *mgp = NULL;
66 return ((flags && PL_curpm) ? PM_GETRE(PL_curpm) : NULL);
67}
68
56953603 69MODULE = re PACKAGE = re
70
71void
f9f4320a 72install()
73 PPCODE:
74 PL_colorset = 0; /* Allow reinspection of ENV. */
75 /* PL_debug |= DEBUG_r_FLAG; */
76 XPUSHs(sv_2mortal(newSViv(PTR2IV(&my_reg_engine))));
77
de8c5301 78
79void
de8c5301 80regexp_pattern(sv)
81 SV * sv
82PROTOTYPE: $
83PREINIT:
84 MAGIC *mg;
44a2ac75 85 regexp *re;
de8c5301 86PPCODE:
87{
88 /*
89 Checks if a reference is a regex or not. If the parameter is
90 not a ref, or is not the result of a qr// then returns false
91 in scalar context and an empty list in list context.
92 Otherwise in list context it returns the pattern and the
93 modifiers, in scalar context it returns the pattern just as it
94 would if the qr// was stringified normally, regardless as
95 to the class of the variable and any strigification overloads
96 on the object.
97 */
98
44a2ac75 99 if ( re = get_re_arg( aTHX_ sv, 0, &mg) ) /* assign deliberate */
de8c5301 100 {
de8c5301 101 /* Housten, we have a regex! */
102 SV *pattern;
de8c5301 103 STRLEN patlen = 0;
104 STRLEN left = 0;
105 char reflags[6];
106
107 if ( GIMME_V == G_ARRAY ) {
108 /*
109 we are in list context so stringify
110 the modifiers that apply. We ignore "negative
111 modifiers" in this scenario.
112 */
113
bcdf7404 114 char *fptr = INT_PAT_MODS;
de8c5301 115 char ch;
bbe252da 116 U16 match_flags = (U16)((re->extflags & PMf_COMPILETIME) >> 12);
de8c5301 117
118 while((ch = *fptr++)) {
bbe252da 119 if(match_flags & 1) {
de8c5301 120 reflags[left++] = ch;
121 }
bbe252da 122 match_flags >>= 1;
de8c5301 123 }
124
125 pattern = sv_2mortal(newSVpvn(re->precomp,re->prelen));
bbe252da 126 if (re->extflags & RXf_UTF8) SvUTF8_on(pattern);
de8c5301 127
128 /* return the pattern and the modifiers */
129 XPUSHs(pattern);
130 XPUSHs(sv_2mortal(newSVpvn(reflags,left)));
131 XSRETURN(2);
132 } else {
133 /* Scalar, so use the string that Perl would return */
de8c5301 134 /* return the pattern in (?msix:..) format */
bcdf7404 135 pattern = sv_2mortal(newSVpvn(re->wrapped,re->wraplen));
bbe252da 136 if (re->extflags & RXf_UTF8)
de8c5301 137 SvUTF8_on(pattern);
138 XPUSHs(pattern);
139 XSRETURN(1);
140 }
141 } else {
142 /* It ain't a regexp folks */
143 if ( GIMME_V == G_ARRAY ) {
144 /* return the empty list */
145 XSRETURN_UNDEF;
146 } else {
147 /* Because of the (?:..) wrapping involved in a
148 stringified pattern it is impossible to get a
149 result for a real regexp that would evaluate to
150 false. Therefore we can return PL_sv_no to signify
151 that the object is not a regex, this means that one
152 can say
153
154 if (regex($might_be_a_regex) eq '(?:foo)') { }
155
156 and not worry about undefined values.
157 */
158 XSRETURN_NO;
159 }
160 }
161 /* NOT-REACHED */
256ddcd0 162}
163
164
165void
166regmust(sv)
167 SV * sv
168PROTOTYPE: $
169PREINIT:
44a2ac75 170 regexp *re;
256ddcd0 171PPCODE:
172{
44a2ac75 173 if ( re = get_re_arg( aTHX_ sv, 0, 0) ) /* assign deliberate */
256ddcd0 174 {
175 SV *an = &PL_sv_no;
176 SV *fl = &PL_sv_no;
256ddcd0 177 if (re->anchored_substr) {
178 an = newSVsv(re->anchored_substr);
179 } else if (re->anchored_utf8) {
180 an = newSVsv(re->anchored_utf8);
181 }
182 if (re->float_substr) {
183 fl = newSVsv(re->float_substr);
184 } else if (re->float_utf8) {
185 fl = newSVsv(re->float_utf8);
186 }
187 XPUSHs(an);
188 XPUSHs(fl);
189 XSRETURN(2);
190 }
191 XSRETURN_UNDEF;
192}
44a2ac75 193