Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/regex/regsubexec.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
/*
25
* posix regex ed(1) style substitute execute
26
*/
27
28
#include "reglib.h"
29
30
#define NEED(p,b,n,r) \
31
do \
32
{ \
33
if (((b)->re_end - (b)->re_cur) < (n)) \
34
{ \
35
size_t o = (b)->re_cur - (b)->re_buf; \
36
size_t a = ((b)->re_end - (b)->re_buf); \
37
if (a < n) \
38
a = roundof(n, 128); \
39
a *= 2; \
40
if (!((b)->re_buf = alloc(p->env->disc, (b)->re_buf, a))) \
41
{ \
42
(b)->re_buf = (b)->re_cur = (b)->re_end = 0; \
43
c = REG_ESPACE; \
44
r; \
45
} \
46
(b)->re_cur = (b)->re_buf + o; \
47
(b)->re_end = (b)->re_buf + a; \
48
} \
49
} while (0)
50
51
#define PUTC(p,b,x,r) \
52
do \
53
{ \
54
NEED(p, b, 1, r); \
55
*(b)->re_cur++ = (x); \
56
} while (0)
57
58
#define PUTS(p,b,x,z,r) \
59
do if (z) \
60
{ \
61
NEED(p, b, z, r); \
62
memcpy((b)->re_cur, x, z); \
63
(b)->re_cur += (z); \
64
} while (0)
65
66
/*
67
* do a single substitution
68
*/
69
70
static int
71
sub(const regex_t* p, register regsub_t* b, const char* ss, register regsubop_t* op, size_t nmatch, register regmatch_t* match)
72
{
73
register char* s;
74
register char* e;
75
register int c;
76
77
for (;; op++)
78
{
79
switch (op->len)
80
{
81
case -1:
82
break;
83
case 0:
84
if (op->off >= nmatch)
85
return REG_ESUBREG;
86
if ((c = match[op->off].rm_so) < 0)
87
continue;
88
s = (char*)ss + c;
89
if ((c = match[op->off].rm_eo) < 0)
90
continue;
91
e = (char*)ss + c;
92
NEED(p, b, e - s, return c);
93
switch (op->op)
94
{
95
case REG_SUB_UPPER:
96
while (s < e)
97
{
98
c = *s++;
99
if (islower(c))
100
c = toupper(c);
101
*b->re_cur++ = c;
102
}
103
break;
104
case REG_SUB_LOWER:
105
while (s < e)
106
{
107
c = *s++;
108
if (isupper(c))
109
c = tolower(c);
110
*b->re_cur++ = c;
111
}
112
break;
113
case REG_SUB_UPPER|REG_SUB_LOWER:
114
while (s < e)
115
{
116
c = *s++;
117
if (isupper(c))
118
c = tolower(c);
119
else if (islower(c))
120
c = toupper(c);
121
*b->re_cur++ = c;
122
}
123
break;
124
default:
125
while (s < e)
126
*b->re_cur++ = *s++;
127
break;
128
}
129
continue;
130
default:
131
NEED(p, b, op->len, return c);
132
s = b->re_rhs + op->off;
133
e = s + op->len;
134
while (s < e)
135
*b->re_cur++ = *s++;
136
continue;
137
}
138
break;
139
}
140
return 0;
141
}
142
143
/*
144
* ed(1) style substitute using matches from last regexec()
145
*/
146
147
int
148
regsubexec(const regex_t* p, const char* s, size_t nmatch, regmatch_t* match)
149
{
150
register int c;
151
register regsub_t* b;
152
const char* e;
153
int m;
154
155
if (!p->env->sub || (p->env->flags & REG_NOSUB) || !nmatch)
156
return fatal(p->env->disc, REG_BADPAT, NiL);
157
b = p->re_sub;
158
m = b->re_min;
159
b->re_cur = b->re_buf;
160
e = (const char*)p->env->end;
161
c = 0;
162
for (;;)
163
{
164
if (--m > 0)
165
PUTS(p, b, s, match->rm_eo, return fatal(p->env->disc, c, NiL));
166
else
167
{
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);
171
}
172
s += match->rm_eo;
173
if (m <= 0 && !(b->re_flags & REG_SUB_ALL) || !*s)
174
break;
175
if (c = regnexec(p, s, e - s, nmatch, match, p->env->flags|(match->rm_so == match->rm_eo ? REG_ADVANCE : 0)))
176
{
177
if (c != REG_NOMATCH)
178
return fatal(p->env->disc, c, NiL);
179
break;
180
}
181
if (!match->rm_so && !match->rm_eo && *s && m <= 1)
182
{
183
match->rm_so = match->rm_eo = 1;
184
c = 1;
185
}
186
}
187
while (s < e)
188
{
189
c = *s++;
190
PUTC(p, b, c, return fatal(p->env->disc, c, NiL));
191
}
192
NEED(p, b, 1, return fatal(p->env->disc, c, NiL));
193
*b->re_cur = 0;
194
b->re_len = b->re_cur - b->re_buf;
195
return 0;
196
}
197
198
/*
199
* 20120528: regoff_t changed from int to ssize_t
200
*/
201
202
#if defined(__EXPORT__)
203
#define extern __EXPORT__
204
#endif
205
206
#undef regsubexec
207
#if _map_libc
208
#define regsubexec _ast_regsubexec
209
#endif
210
211
extern int
212
regsubexec(const regex_t* p, const char* s, size_t nmatch, oldregmatch_t* oldmatch)
213
{
214
if (oldmatch)
215
{
216
regmatch_t* match;
217
ssize_t i;
218
int r;
219
220
if (!(match = oldof(0, regmatch_t, nmatch, 0)))
221
return -1;
222
for (i = 0; i < nmatch; i++)
223
{
224
match[i].rm_so = oldmatch[i].rm_so;
225
match[i].rm_eo = oldmatch[i].rm_eo;
226
}
227
if (!(r = regsubexec_20120528(p, s, nmatch, match)))
228
for (i = 0; i < nmatch; i++)
229
{
230
oldmatch[i].rm_so = match[i].rm_so;
231
oldmatch[i].rm_eo = match[i].rm_eo;
232
}
233
free(match);
234
return r;
235
}
236
return regsubexec_20120528(p, s, 0, NiL);
237
}
238
239