import less(1)
[unleashed/tickless.git] / usr / src / lib / libast / common / regex / regsub.c
blob288ed1418fc5df57f278b7285b3e8e4318a531ce
1 /***********************************************************************
2 * *
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 *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
25 * OBSOLETE Sfio_t buffer interface -- use regsubcomp(),regsubexec()
28 #include "reglib.h"
31 * do a single substitution
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)
37 register int c;
38 char* s;
39 char* e;
40 const char* b;
41 regflags_t f;
43 f = flags &= (REG_SUB_LOWER|REG_SUB_UPPER);
44 for (;;)
46 switch (c = *sp++)
48 case 0:
49 return 0;
50 case '~':
51 if (!sre || *sp != '(')
53 sfputc(dp, c);
54 continue;
56 b = sp - 1;
57 sp++;
58 break;
59 case '\\':
60 if (sre)
62 sfputc(dp, chresc(sp - 1, &s));
63 sp = (const char*)s;
64 continue;
66 if (*sp == '&')
68 c = *sp++;
69 sfputc(dp, c);
70 continue;
72 break;
73 case '&':
74 if (sre)
76 sfputc(dp, c);
77 continue;
79 sp--;
80 break;
81 default:
82 switch (flags)
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;
99 sfputc(dp, c);
100 continue;
102 switch (c = *sp++)
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 != ')')
120 c = -1;
121 break;
123 if (c = *sp)
125 sp++;
126 if (isupper(c))
127 c = tolower(c);
128 sfputc(dp, c);
130 continue;
131 case 'u':
132 if (sre)
134 if (*sp != ')')
136 c = -1;
137 break;
139 sp++;
141 if (c = *sp)
143 sp++;
144 if (islower(c))
145 c = toupper(c);
146 sfputc(dp, c);
148 continue;
149 case 'E':
150 if (sre)
152 if (*sp != ')')
154 c = -1;
155 break;
157 sp++;
159 flags = f;
160 continue;
161 case 'L':
162 if (sre)
164 if (*sp != ')')
166 c = -1;
167 break;
169 sp++;
171 f = flags;
172 flags = REG_SUB_LOWER;
173 continue;
174 case 'U':
175 if (sre)
177 if (*sp != ')')
179 c = -1;
180 break;
182 sp++;
184 f = flags;
185 flags = REG_SUB_UPPER;
186 continue;
187 default:
188 if (!sre)
190 sfputc(dp, chresc(sp - 2, &s));
191 sp = (const char*)s;
192 continue;
194 sp--;
195 c = -1;
196 break;
198 if (sre)
200 if (c < 0 || *sp != ')')
202 for (; b < sp; b++)
203 sfputc(dp, *b);
204 continue;
206 sp++;
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)
214 c = *s++;
215 switch (flags)
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;
232 sfputc(dp, c);
238 * ed(1) style substitute using matches from last regexec()
242 regsub(const regex_t* p, Sfio_t* dp, const char* op, const char* sp, size_t nmatch, regmatch_t* match, regflags_t flags)
244 int m;
245 int r;
246 int sre;
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;
255 if (--m > 0)
256 sfwrite(dp, op, match->rm_eo);
257 else
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);
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;