Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/regex/regsub.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 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
* OBSOLETE Sfio_t buffer interface -- use regsubcomp(),regsubexec()
26
*/
27
28
#include "reglib.h"
29
30
/*
31
* do a single substitution
32
*/
33
34
static int
35
subold(register Sfio_t* dp, const char* op, register const char* sp, size_t nmatch, register regmatch_t* match, register regflags_t flags, int sre)
36
{
37
register int c;
38
char* s;
39
char* e;
40
const char* b;
41
regflags_t f;
42
43
f = flags &= (REG_SUB_LOWER|REG_SUB_UPPER);
44
for (;;)
45
{
46
switch (c = *sp++)
47
{
48
case 0:
49
return 0;
50
case '~':
51
if (!sre || *sp != '(')
52
{
53
sfputc(dp, c);
54
continue;
55
}
56
b = sp - 1;
57
sp++;
58
break;
59
case '\\':
60
if (sre)
61
{
62
sfputc(dp, chresc(sp - 1, &s));
63
sp = (const char*)s;
64
continue;
65
}
66
if (*sp == '&')
67
{
68
c = *sp++;
69
sfputc(dp, c);
70
continue;
71
}
72
break;
73
case '&':
74
if (sre)
75
{
76
sfputc(dp, c);
77
continue;
78
}
79
sp--;
80
break;
81
default:
82
switch (flags)
83
{
84
case REG_SUB_UPPER:
85
if (islower(c))
86
c = toupper(c);
87
break;
88
case REG_SUB_LOWER:
89
if (isupper(c))
90
c = tolower(c);
91
break;
92
case REG_SUB_UPPER|REG_SUB_LOWER:
93
if (isupper(c))
94
c = tolower(c);
95
else if (islower(c))
96
c = toupper(c);
97
break;
98
}
99
sfputc(dp, c);
100
continue;
101
}
102
switch (c = *sp++)
103
{
104
case 0:
105
sp--;
106
continue;
107
case '&':
108
c = 0;
109
break;
110
case '0': case '1': case '2': case '3': case '4':
111
case '5': case '6': case '7': case '8': case '9':
112
c -= '0';
113
if (sre)
114
while (isdigit(*sp))
115
c = c * 10 + *sp++ - '0';
116
break;
117
case 'l':
118
if (sre && *sp != ')')
119
{
120
c = -1;
121
break;
122
}
123
if (c = *sp)
124
{
125
sp++;
126
if (isupper(c))
127
c = tolower(c);
128
sfputc(dp, c);
129
}
130
continue;
131
case 'u':
132
if (sre)
133
{
134
if (*sp != ')')
135
{
136
c = -1;
137
break;
138
}
139
sp++;
140
}
141
if (c = *sp)
142
{
143
sp++;
144
if (islower(c))
145
c = toupper(c);
146
sfputc(dp, c);
147
}
148
continue;
149
case 'E':
150
if (sre)
151
{
152
if (*sp != ')')
153
{
154
c = -1;
155
break;
156
}
157
sp++;
158
}
159
flags = f;
160
continue;
161
case 'L':
162
if (sre)
163
{
164
if (*sp != ')')
165
{
166
c = -1;
167
break;
168
}
169
sp++;
170
}
171
f = flags;
172
flags = REG_SUB_LOWER;
173
continue;
174
case 'U':
175
if (sre)
176
{
177
if (*sp != ')')
178
{
179
c = -1;
180
break;
181
}
182
sp++;
183
}
184
f = flags;
185
flags = REG_SUB_UPPER;
186
continue;
187
default:
188
if (!sre)
189
{
190
sfputc(dp, chresc(sp - 2, &s));
191
sp = (const char*)s;
192
continue;
193
}
194
sp--;
195
c = -1;
196
break;
197
}
198
if (sre)
199
{
200
if (c < 0 || *sp != ')')
201
{
202
for (; b < sp; b++)
203
sfputc(dp, *b);
204
continue;
205
}
206
sp++;
207
}
208
if (c >= nmatch)
209
return REG_ESUBREG;
210
s = (char*)op + match[c].rm_so;
211
e = (char*)op + match[c].rm_eo;
212
while (s < e)
213
{
214
c = *s++;
215
switch (flags)
216
{
217
case REG_SUB_UPPER:
218
if (islower(c))
219
c = toupper(c);
220
break;
221
case REG_SUB_LOWER:
222
if (isupper(c))
223
c = tolower(c);
224
break;
225
case REG_SUB_UPPER|REG_SUB_LOWER:
226
if (isupper(c))
227
c = tolower(c);
228
else if (islower(c))
229
c = toupper(c);
230
break;
231
}
232
sfputc(dp, c);
233
}
234
}
235
}
236
237
/*
238
* ed(1) style substitute using matches from last regexec()
239
*/
240
241
int
242
regsub(const regex_t* p, Sfio_t* dp, const char* op, const char* sp, size_t nmatch, regmatch_t* match, regflags_t flags)
243
{
244
int m;
245
int r;
246
int sre;
247
248
if ((p->env->flags & REG_NOSUB) || !nmatch)
249
return fatal(p->env->disc, REG_BADPAT, NiL);
250
m = (flags >> 16) & 0x3fff;
251
sre = !!(p->env->flags & REG_SHELL);
252
r = 0;
253
do
254
{
255
if (--m > 0)
256
sfwrite(dp, op, match->rm_eo);
257
else
258
{
259
sfwrite(dp, op, match->rm_so);
260
if (r = subold(dp, op, sp, nmatch, match, flags, sre))
261
return fatal(p->env->disc, r, NiL);
262
}
263
op += match->rm_eo;
264
} while ((m > 0 || (flags & REG_SUB_ALL)) && !(r = regexec(p, op, nmatch, match, p->env->flags|(match->rm_so == match->rm_eo ? REG_ADVANCE : 0))));
265
if (r && r != REG_NOMATCH)
266
return fatal(p->env->disc, r, NiL);
267
sfputr(dp, op, -1);
268
return 0;
269
}
270
271