2 * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Use is subject to license terms.
5 * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
8 * University Copyright- Copyright (c) 1982, 1986, 1988
9 * The Regents of the University of California
12 * University Acknowledgment- Portions of this document are derived from
13 * software developed by the University of California, Berkeley, and its
16 * Licensed under the Apache License, Version 2.0 (the "License");
17 * you may not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 * http://www.apache.org/licenses/LICENSE-2.0.
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
29 /* Code moved from regexp.h */
43 #define GETC() ((unsigned char)*sp++)
44 #define PEEKC() ((unsigned char)*sp)
45 #define UNGETC(c) (--sp)
46 #define SEDCOMPILE_ERROR(c) { \
50 #define ecmp(s1, s2, n) (strncmp(s1, s2, n) == 0)
51 #define uletter(c) (isalpha(c) || c == '_')
54 static unsigned char bittab[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
56 static int regerr(sed_commands_t *commands, int err);
57 static void comperr(sed_commands_t *commands, char *msg);
58 static void getrnge(char *str, step_vars_storage *vars);
59 static int _advance(char *, char *, step_vars_storage *);
60 extern int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars);
63 static void comperr(sed_commands_t *commands, char *msg)
65 command_errf(commands, msg, commands->linebuf);
70 static int regerr(sed_commands_t *commands, int err)
77 comperr(commands, "Range endpoint too large: %s");
81 comperr(commands, "Bad number: %s");
85 comperr(commands, "``\\digit'' out of range: %s");
89 comperr(commands, "Illegal or missing delimiter: %s");
93 comperr(commands, "No remembered search string: %s");
97 comperr(commands, "\\( \\) imbalance: %s");
101 comperr(commands, "Too many \\(: %s");
105 comperr(commands, "More than 2 numbers given in \\{ \\}: %s");
109 comperr(commands, "} expected after \\: %s");
113 comperr(commands, "First number exceeds second in \\{ \\}: %s");
117 comperr(commands, "[ ] imbalance: %s");
121 comperr(commands, SEDERR_TMMES);
125 comperr(commands, "Unknown regexp error code %s\n");
132 char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
133 char *ep, char *endbuf, int seof)
139 char bracket[NBRA], *bracketp;
144 int iflag; /* used for non-ascii characters in brackets */
145 char *sp = commands->cp;
149 if ((c = GETC()) == eof || c == '\n') {
157 compargs->circf = closed = compargs->nbra = 0;
164 SEDCOMPILE_ERROR(50);
166 if (c != '*' && ((c != '\\') || (PEEKC() != '{')))
170 if (bracketp != bracket)
171 SEDCOMPILE_ERROR(42);
182 SEDCOMPILE_ERROR(36);
186 if (lastep == 0 || *lastep == CBRA || *lastep == CKET)
192 if (PEEKC() != eof && PEEKC() != '\n')
198 if (&ep[17] >= endbuf)
199 SEDCOMPILE_ERROR(50);
203 for (i = 0; i < 16; i++)
207 if ((c = GETC()) == '^') {
214 if (c == '\0' || c == '\n')
215 SEDCOMPILE_ERROR(49);
216 if ((c & 0200) && iflag) {
218 if (&ep[32] >= endbuf)
219 SEDCOMPILE_ERROR(50);
221 for (i = 16; i < 32; i++)
224 if (c == '-' && lc != 0) {
225 if ((c = GETC()) == ']') {
229 if ((c & 0200) && iflag) {
231 if (&ep[32] >= endbuf)
232 SEDCOMPILE_ERROR(50);
234 for (i = 16; i < 32; i++)
244 } while ((c = GETC()) != ']');
253 for (cclcnt = 0; cclcnt < iflag;
259 /* make nulls match so test fails */
269 switch (c = GETC()) {
272 if (compargs->nbra >= NBRA)
273 SEDCOMPILE_ERROR(43);
274 *bracketp++ = compargs->nbra;
276 *ep++ = compargs->nbra++;
280 if (bracketp <= bracket)
281 SEDCOMPILE_ERROR(42);
288 if (lastep == (char *) 0)
296 if ('0' <= c && c <= '9')
297 i = 10 * i + c - '0';
299 SEDCOMPILE_ERROR(16);
300 } while (((c = GETC()) != '\\') && (c != ','));
302 SEDCOMPILE_ERROR(11);
306 SEDCOMPILE_ERROR(44);
307 if ((c = GETC()) == '\\')
312 /* get 2'nd number */
316 SEDCOMPILE_ERROR(45);
317 if (!cflg) /* one number */
319 else if ((ep[-1] & 0377) < (ep[-2] & 0377))
320 SEDCOMPILE_ERROR(46);
324 SEDCOMPILE_ERROR(36);
331 if (c >= '1' && c <= '9') {
332 if ((c -= '1') >= closed)
333 SEDCOMPILE_ERROR(25);
339 /* Drop through to default to use \ to turn off special chars */
350 regerr(commands, regerrno);
353 /* XXX : Basant : what extra */
354 /* int reglength = (int)(ep - expbuf); */
358 int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars)
365 return (_advance(p1, p2, vars));
367 /* fast check for first character */
373 if (_advance(p1, p2, vars)) {
380 /* regular algorithm */
382 if (_advance(p1, p2, vars)) {
390 static int _advance(char *lp, char *ep, step_vars_storage *vars)
397 int epint; /* int value of *ep */
423 c = (unsigned char)*lp++;
435 if (((c & 0200) == 0 && ISTHERE(c)) ^ neg) {
443 vars->braslist[epint] = lp;
449 vars->braelist[epint] = lp;
483 getrnge(ep + 32, vars);
484 while (vars->low--) {
485 c = (unsigned char)*lp++;
490 while (vars->size--) {
491 c = (unsigned char)*lp++;
497 ep += 34; /* 32 + 2 */
504 getrnge(ep + 16, vars);
505 while (vars->low--) {
507 if (((c & 0200) || !ISTHERE(c)) ^ neg)
511 while (vars->size--) {
513 if (((c & 0200) || !ISTHERE(c)) ^ neg)
518 ep += 18; /* 16 + 2 */
523 bbeg = vars->braslist[epint];
524 ct = vars->braelist[epint] - bbeg;
527 if (ecmp(bbeg, lp, ct)) {
535 bbeg = vars->braslist[epint];
536 ct = vars->braelist[epint] - bbeg;
539 while (ecmp(bbeg, lp, ct))
542 while (lp >= curlp) {
543 if (_advance(lp, ep, vars))
557 while (*lp++ == *ep);
564 c = (unsigned char)*lp++;
565 } while (ISTHERE(c));
576 } while (((c & 0200) == 0 && ISTHERE(c)) ^ neg);
582 if (--lp == vars->locs)
584 if (_advance(lp, ep, vars))
586 } while (lp > curlp);
593 static void getrnge(char *str, step_vars_storage *vars)
595 vars->low = *str++ & 0377;
596 vars->size = ((*str & 0377) == 255)? 20000: (*str &0377) - vars->low;