1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
25 * posix regex ed(1) style substitute execute
30 #define NEED(p,b,n,r) \
33 if (((b)->re_end - (b)->re_cur) < (n)) \
35 size_t o = (b)->re_cur - (b)->re_buf; \
36 size_t a = ((b)->re_end - (b)->re_buf); \
38 a = roundof(n, 128); \
40 if (!((b)->re_buf = alloc(p->env->disc, (b)->re_buf, a))) \
42 (b)->re_buf = (b)->re_cur = (b)->re_end = 0; \
46 (b)->re_cur = (b)->re_buf + o; \
47 (b)->re_end = (b)->re_buf + a; \
51 #define PUTC(p,b,x,r) \
55 *(b)->re_cur++ = (x); \
58 #define PUTS(p,b,x,z,r) \
62 memcpy((b)->re_cur, x, z); \
67 * do a single substitution
71 sub(const regex_t
* p
, register regsub_t
* b
, const char* ss
, register regsubop_t
* op
, size_t nmatch
, register regmatch_t
* match
)
84 if (op
->off
>= nmatch
)
86 if ((c
= match
[op
->off
].rm_so
) < 0)
89 if ((c
= match
[op
->off
].rm_eo
) < 0)
92 NEED(p
, b
, e
- s
, return c
);
113 case REG_SUB_UPPER
|REG_SUB_LOWER
:
131 NEED(p
, b
, op
->len
, return c
);
132 s
= b
->re_rhs
+ op
->off
;
144 * ed(1) style substitute using matches from last regexec()
148 regsubexec(const regex_t
* p
, const char* s
, size_t nmatch
, regmatch_t
* match
)
151 register regsub_t
* b
;
155 if (!p
->env
->sub
|| (p
->env
->flags
& REG_NOSUB
) || !nmatch
)
156 return fatal(p
->env
->disc
, REG_BADPAT
, NiL
);
159 b
->re_cur
= b
->re_buf
;
160 e
= (const char*)p
->env
->end
;
165 PUTS(p
, b
, s
, match
->rm_eo
, return fatal(p
->env
->disc
, c
, NiL
));
168 PUTS(p
, b
, s
, match
->rm_so
, return fatal(p
->env
->disc
, c
, NiL
));
169 if (!c
&& (c
= sub(p
, b
, s
, b
->re_ops
, nmatch
, match
)))
170 return fatal(p
->env
->disc
, c
, NiL
);
173 if (m
<= 0 && !(b
->re_flags
& REG_SUB_ALL
) || !*s
)
175 if (c
= regnexec(p
, s
, e
- s
, nmatch
, match
, p
->env
->flags
|(match
->rm_so
== match
->rm_eo
? REG_ADVANCE
: 0)))
177 if (c
!= REG_NOMATCH
)
178 return fatal(p
->env
->disc
, c
, NiL
);
181 if (!match
->rm_so
&& !match
->rm_eo
&& *s
&& m
<= 1)
183 match
->rm_so
= match
->rm_eo
= 1;
190 PUTC(p
, b
, c
, return fatal(p
->env
->disc
, c
, NiL
));
192 NEED(p
, b
, 1, return fatal(p
->env
->disc
, c
, NiL
));
194 b
->re_len
= b
->re_cur
- b
->re_buf
;