perl 5.0 alpha 3
[p5sagit/p5-mst-13.2.git] / do / match
CommitLineData
79072805 1int
2do_match(TARG,arg,gimme,arglast)
3STR *TARG;
4register ARG *arg;
5int gimme;
6int *arglast;
7{
8 register STR **st = stack->ary_array;
9 register SPAT *spat = arg[2].arg_ptr.arg_spat;
10 register char *t;
11 register int sp = arglast[0] + 1;
12 STR *srchstr = st[sp];
13 register char *s = str_get(st[sp]);
14 char *strend = s + st[sp]->str_cur;
15 STR *tmpstr;
16 char *myhint = hint;
17 int global;
18 int safebase;
19 char *truebase = s;
20 register REGEXP *rx = spat->spat_regexp;
21
22 hint = Nullch;
23 if (!spat) {
24 if (gimme == G_ARRAY)
25 return --sp;
26 str_set(TARG,Yes);
27 STABSET(TARG);
28 st[sp] = TARG;
29 return sp;
30 }
31 global = spat->spat_flags & SPAT_GLOBAL;
32 safebase = (gimme == G_ARRAY) || global;
33 if (!s)
34 fatal("panic: do_match");
35 if (spat->spat_flags & SPAT_USED) {
36#ifdef DEBUGGING
37 if (debug & 8)
38 deb("2.SPAT USED\n");
39#endif
40 if (gimme == G_ARRAY)
41 return --sp;
42 str_set(TARG,No);
43 STABSET(TARG);
44 st[sp] = TARG;
45 return sp;
46 }
47 --sp;
48 if (spat->spat_runtime) {
49 nointrp = "|)";
50 sp = eval(spat->spat_runtime,G_SCALAR,sp);
51 st = stack->ary_array;
52 t = str_get(tmpstr = st[sp--]);
53 nointrp = "";
54#ifdef DEBUGGING
55 if (debug & 8)
56 deb("2.SPAT /%s/\n",t);
57#endif
58 if (!global && rx)
59 regfree(rx);
60 spat->spat_regexp = Null(REGEXP*); /* crucial if regcomp aborts */
61 spat->spat_regexp = regcomp(t,t+tmpstr->str_cur,
62 spat->spat_flags & SPAT_FOLD);
63 if (!spat->spat_regexp->prelen && lastspat)
64 spat = lastspat;
65 if (spat->spat_flags & SPAT_KEEP) {
66 if (!(spat->spat_flags & SPAT_FOLD))
67 scanconst(spat,spat->spat_regexp->precomp,
68 spat->spat_regexp->prelen);
69 if (spat->spat_runtime)
70 arg_free(spat->spat_runtime); /* it won't change, so */
71 spat->spat_runtime = Nullarg; /* no point compiling again */
72 hoistmust(spat);
73 if (curcmd->c_expr && (curcmd->c_flags & CF_OPTIMIZE) == CFT_EVAL) {
74 curcmd->c_flags &= ~CF_OPTIMIZE;
75 opt_arg(curcmd, 1, curcmd->c_type == C_EXPR);
76 }
77 }
78 if (global) {
79 if (rx) {
80 if (rx->startp[0]) {
81 s = rx->endp[0];
82 if (s == rx->startp[0])
83 s++;
84 if (s > strend) {
85 regfree(rx);
86 rx = spat->spat_regexp;
87 goto nope;
88 }
89 }
90 regfree(rx);
91 }
92 }
93 else if (!spat->spat_regexp->nparens)
94 gimme = G_SCALAR; /* accidental array context? */
95 rx = spat->spat_regexp;
96 if (regexec(rx, s, strend, s, 0,
97 srchstr->str_pok & SP_STUDIED ? srchstr : Nullstr,
98 safebase)) {
99 if (rx->subbase || global)
100 curspat = spat;
101 lastspat = spat;
102 goto gotcha;
103 }
104 else {
105 if (gimme == G_ARRAY)
106 return sp;
107 str_sset(TARG,&str_no);
108 STABSET(TARG);
109 st[++sp] = TARG;
110 return sp;
111 }
112 }
113 else {
114#ifdef DEBUGGING
115 if (debug & 8) {
116 char ch;
117
118 if (spat->spat_flags & SPAT_ONCE)
119 ch = '?';
120 else
121 ch = '/';
122 deb("2.SPAT %c%s%c\n",ch,rx->precomp,ch);
123 }
124#endif
125 if (!rx->prelen && lastspat) {
126 spat = lastspat;
127 rx = spat->spat_regexp;
128 }
129 t = s;
130 play_it_again:
131 if (global && rx->startp[0]) {
132 t = s = rx->endp[0];
133 if (s == rx->startp[0])
134 s++,t++;
135 if (s > strend)
136 goto nope;
137 }
138 if (myhint) {
139 if (myhint < s || myhint > strend)
140 fatal("panic: hint in do_match");
141 s = myhint;
142 if (rx->regback >= 0) {
143 s -= rx->regback;
144 if (s < t)
145 s = t;
146 }
147 else
148 s = t;
149 }
150 else if (spat->spat_short) {
151 if (spat->spat_flags & SPAT_SCANFIRST) {
152 if (srchstr->str_pok & SP_STUDIED) {
153 if (screamfirst[spat->spat_short->str_rare] < 0)
154 goto nope;
155 else if (!(s = screaminstr(srchstr,spat->spat_short)))
156 goto nope;
157 else if (spat->spat_flags & SPAT_ALL)
158 goto yup;
159 }
160#ifndef lint
161 else if (!(s = fbminstr((unsigned char*)s,
162 (unsigned char*)strend, spat->spat_short)))
163 goto nope;
164#endif
165 else if (spat->spat_flags & SPAT_ALL)
166 goto yup;
167 if (s && rx->regback >= 0) {
168 ++spat->spat_short->str_u.str_useful;
169 s -= rx->regback;
170 if (s < t)
171 s = t;
172 }
173 else
174 s = t;
175 }
176 else if (!multiline && (*spat->spat_short->str_ptr != *s ||
177 bcmp(spat->spat_short->str_ptr, s, spat->spat_slen) ))
178 goto nope;
179 if (--spat->spat_short->str_u.str_useful < 0) {
180 str_free(spat->spat_short);
181 spat->spat_short = Nullstr; /* opt is being useless */
182 }
183 }
184 if (!rx->nparens && !global) {
185 gimme = G_SCALAR; /* accidental array context? */
186 safebase = FALSE;
187 }
188 if (regexec(rx, s, strend, truebase, 0,
189 srchstr->str_pok & SP_STUDIED ? srchstr : Nullstr,
190 safebase)) {
191 if (rx->subbase || global)
192 curspat = spat;
193 lastspat = spat;
194 if (spat->spat_flags & SPAT_ONCE)
195 spat->spat_flags |= SPAT_USED;
196 goto gotcha;
197 }
198 else {
199 if (global)
200 rx->startp[0] = Nullch;
201 if (gimme == G_ARRAY)
202 return sp;
203 str_sset(TARG,&str_no);
204 STABSET(TARG);
205 st[++sp] = TARG;
206 return sp;
207 }
208 }
209 /*NOTREACHED*/
210
211 gotcha:
212 if (gimme == G_ARRAY) {
213 int iters, i, len;
214
215 iters = rx->nparens;
216 if (global && !iters)
217 i = 1;
218 else
219 i = 0;
220 if (sp + iters + i >= stack->ary_max) {
221 astore(stack,sp + iters + i, Nullstr);
222 st = stack->ary_array; /* possibly realloced */
223 }
224
225 for (i = !i; i <= iters; i++) {
226 st[++sp] = str_mortal(&str_no);
227 /*SUPPRESS 560*/
228 if (s = rx->startp[i]) {
229 len = rx->endp[i] - s;
230 if (len > 0)
231 str_nset(st[sp],s,len);
232 }
233 }
234 if (global) {
235 truebase = rx->subbeg;
236 goto play_it_again;
237 }
238 return sp;
239 }
240 else {
241 str_sset(TARG,&str_yes);
242 STABSET(TARG);
243 st[++sp] = TARG;
244 return sp;
245 }
246
247yup:
248 ++spat->spat_short->str_u.str_useful;
249 lastspat = spat;
250 if (spat->spat_flags & SPAT_ONCE)
251 spat->spat_flags |= SPAT_USED;
252 if (global) {
253 rx->subbeg = t;
254 rx->subend = strend;
255 rx->startp[0] = s;
256 rx->endp[0] = s + spat->spat_short->str_cur;
257 curspat = spat;
258 goto gotcha;
259 }
260 if (sawampersand) {
261 char *tmps;
262
263 if (rx->subbase)
264 Safefree(rx->subbase);
265 tmps = rx->subbase = nsavestr(t,strend-t);
266 rx->subbeg = tmps;
267 rx->subend = tmps + (strend-t);
268 tmps = rx->startp[0] = tmps + (s - t);
269 rx->endp[0] = tmps + spat->spat_short->str_cur;
270 curspat = spat;
271 }
272 str_sset(TARG,&str_yes);
273 STABSET(TARG);
274 st[++sp] = TARG;
275 return sp;
276
277nope:
278 rx->startp[0] = Nullch;
279 if (spat->spat_short)
280 ++spat->spat_short->str_u.str_useful;
281 if (gimme == G_ARRAY)
282 return sp;
283 str_sset(TARG,&str_no);
284 STABSET(TARG);
285 st[++sp] = TARG;
286 return sp;
287}
288