xref: /freebsd/bin/ed/re.c (revision 30154ac8a86b4987758047cd7b94de39dab9d8d8)
130154ac8SAndrew Moore /* re.c: This file contains the regular expression interface routines for
230154ac8SAndrew Moore    the ed line editor. */
330154ac8SAndrew Moore /*-
430154ac8SAndrew Moore  * Copyright (c) 1993 The Regents of the University of California.
530154ac8SAndrew Moore  * All rights reserved.
630154ac8SAndrew Moore  *
730154ac8SAndrew Moore  * This code is derived from software contributed to Berkeley
830154ac8SAndrew Moore  * by Andrew Moore, Talke Studio.
930154ac8SAndrew Moore  *
1030154ac8SAndrew Moore  * Redistribution and use in source and binary forms, with or without
1130154ac8SAndrew Moore  * modification, are permitted provided that the following conditions
1230154ac8SAndrew Moore  * are met:
1330154ac8SAndrew Moore  * 1. Redistributions of source code must retain the above copyright
1430154ac8SAndrew Moore  *    notice, this list of conditions and the following disclaimer.
1530154ac8SAndrew Moore  * 2. Redistributions in binary form must reproduce the above copyright
1630154ac8SAndrew Moore  *    notice, this list of conditions and the following disclaimer in the
1730154ac8SAndrew Moore  *    documentation and/or other materials provided with the distribution.
1830154ac8SAndrew Moore  * 3. All advertising materials mentioning features or use of this software
1930154ac8SAndrew Moore  *    must display the following acknowledgement:
2030154ac8SAndrew Moore  *	This product includes software developed by the University of
2130154ac8SAndrew Moore  *	California, Berkeley and its contributors.
2230154ac8SAndrew Moore  * 4. Neither the name of the University nor the names of its contributors
2330154ac8SAndrew Moore  *    may be used to endorse or promote products derived from this software
2430154ac8SAndrew Moore  *    without specific prior written permission.
2530154ac8SAndrew Moore  *
2630154ac8SAndrew Moore  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2730154ac8SAndrew Moore  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2830154ac8SAndrew Moore  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2930154ac8SAndrew Moore  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3030154ac8SAndrew Moore  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3130154ac8SAndrew Moore  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3230154ac8SAndrew Moore  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3330154ac8SAndrew Moore  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3430154ac8SAndrew Moore  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3530154ac8SAndrew Moore  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3630154ac8SAndrew Moore  * SUCH DAMAGE.
3730154ac8SAndrew Moore  */
3830154ac8SAndrew Moore 
3930154ac8SAndrew Moore #ifndef lint
4030154ac8SAndrew Moore static char sccsid[] = "@(#)re.c	5.5 (Berkeley) 3/28/93";
4130154ac8SAndrew Moore #endif /* not lint */
4230154ac8SAndrew Moore 
4330154ac8SAndrew Moore #include <stdio.h>
4430154ac8SAndrew Moore #include <stdlib.h>
4530154ac8SAndrew Moore #include <string.h>
4630154ac8SAndrew Moore 
4730154ac8SAndrew Moore #include "ed.h"
4830154ac8SAndrew Moore 
4930154ac8SAndrew Moore extern char *lhbuf;
5030154ac8SAndrew Moore extern int lhbufsz;
5130154ac8SAndrew Moore extern char *ibufp;
5230154ac8SAndrew Moore extern int ibufsz;
5330154ac8SAndrew Moore extern int patlock;
5430154ac8SAndrew Moore 
5530154ac8SAndrew Moore char errmsg[MAXFNAME + 40] = "";
5630154ac8SAndrew Moore 
5730154ac8SAndrew Moore /* optpat: return pointer to compiled pattern from command buffer */
5830154ac8SAndrew Moore pattern_t *
5930154ac8SAndrew Moore optpat()
6030154ac8SAndrew Moore {
6130154ac8SAndrew Moore 	static pattern_t *exp = NULL;
6230154ac8SAndrew Moore 
6330154ac8SAndrew Moore 	char *exps;
6430154ac8SAndrew Moore 	char delim;
6530154ac8SAndrew Moore 	int n;
6630154ac8SAndrew Moore 
6730154ac8SAndrew Moore 	if ((delim = *ibufp) == '\n') {
6830154ac8SAndrew Moore 		if (!exp) sprintf(errmsg, "no previous pattern");
6930154ac8SAndrew Moore 		return exp;
7030154ac8SAndrew Moore 	} else if (delim == ' ' || *++ibufp == '\n') {
7130154ac8SAndrew Moore 		sprintf(errmsg, "invalid pattern delimiter");
7230154ac8SAndrew Moore 		return NULL;
7330154ac8SAndrew Moore 	} else if (*ibufp == delim) {
7430154ac8SAndrew Moore 		sprintf(errmsg, "no previous pattern");
7530154ac8SAndrew Moore 		return exp;
7630154ac8SAndrew Moore 	} else if ((exps = getlhs(delim)) == NULL)
7730154ac8SAndrew Moore 		return NULL;
7830154ac8SAndrew Moore 	/* buffer alloc'd && not reserved */
7930154ac8SAndrew Moore 	if (exp && !patlock)
8030154ac8SAndrew Moore 		regfree(exp);
8130154ac8SAndrew Moore 	else if ((exp = (pattern_t *) malloc(sizeof(pattern_t))) == NULL) {
8230154ac8SAndrew Moore 		fprintf(stderr, "%s\n", strerror(errno));
8330154ac8SAndrew Moore 		sprintf(errmsg, "out of memory");
8430154ac8SAndrew Moore 		return NULL;
8530154ac8SAndrew Moore 	}
8630154ac8SAndrew Moore 	patlock = 0;
8730154ac8SAndrew Moore #ifdef GNU_REGEX
8830154ac8SAndrew Moore 	/* initialize pattern buffer */
8930154ac8SAndrew Moore 	exp->buffer = NULL;
9030154ac8SAndrew Moore 	exp->allocated = 0L;
9130154ac8SAndrew Moore 	exp->fastmap = 0;		/* not used by GNU regex after 0.12 */
9230154ac8SAndrew Moore 	exp->translate = 0;
9330154ac8SAndrew Moore #endif
9430154ac8SAndrew Moore 	if (n = regcomp(exp, exps, 0)) {
9530154ac8SAndrew Moore 		regerror(n, exp, errmsg, sizeof errmsg);
9630154ac8SAndrew Moore 		return NULL;
9730154ac8SAndrew Moore 	}
9830154ac8SAndrew Moore 	return exp;
9930154ac8SAndrew Moore }
10030154ac8SAndrew Moore 
10130154ac8SAndrew Moore 
10230154ac8SAndrew Moore extern int isbinary;
10330154ac8SAndrew Moore 
10430154ac8SAndrew Moore /* getlhs: copy a pattern string from the command buffer; return pointer
10530154ac8SAndrew Moore    to the copy */
10630154ac8SAndrew Moore char *
10730154ac8SAndrew Moore getlhs(delim)
10830154ac8SAndrew Moore 	int delim;
10930154ac8SAndrew Moore {
11030154ac8SAndrew Moore 	char *nd;
11130154ac8SAndrew Moore 	int len;
11230154ac8SAndrew Moore 
11330154ac8SAndrew Moore 	for (nd = ibufp; *nd != delim && *nd != '\n'; nd++)
11430154ac8SAndrew Moore 		switch (*nd) {
11530154ac8SAndrew Moore 		default:
11630154ac8SAndrew Moore 			break;
11730154ac8SAndrew Moore 		case '[':
11830154ac8SAndrew Moore 			if ((nd = ccl(++nd)) == NULL) {
11930154ac8SAndrew Moore 				sprintf(errmsg, "unbalanced brackets ([])");
12030154ac8SAndrew Moore 				return NULL;
12130154ac8SAndrew Moore 			}
12230154ac8SAndrew Moore 			break;
12330154ac8SAndrew Moore 		case '\\':
12430154ac8SAndrew Moore 			if (*++nd == '\n') {
12530154ac8SAndrew Moore 				sprintf(errmsg, "trailing backslash (\\)");
12630154ac8SAndrew Moore 				return NULL;
12730154ac8SAndrew Moore 			}
12830154ac8SAndrew Moore 			break;
12930154ac8SAndrew Moore 		}
13030154ac8SAndrew Moore 	len = nd - ibufp;
13130154ac8SAndrew Moore 	CKBUF(lhbuf, lhbufsz, len + 1, NULL);
13230154ac8SAndrew Moore 	memcpy(lhbuf, ibufp, len);
13330154ac8SAndrew Moore 	lhbuf[len] = '\0';
13430154ac8SAndrew Moore 	ibufp = nd;
13530154ac8SAndrew Moore 	return (isbinary) ? nultonl(lhbuf, len) : lhbuf;
13630154ac8SAndrew Moore }
13730154ac8SAndrew Moore 
13830154ac8SAndrew Moore 
13930154ac8SAndrew Moore /* ccl: expand a POSIX character class */
14030154ac8SAndrew Moore char *
14130154ac8SAndrew Moore ccl(s)
14230154ac8SAndrew Moore 	char *s;
14330154ac8SAndrew Moore {
14430154ac8SAndrew Moore 	int c, d;
14530154ac8SAndrew Moore 
14630154ac8SAndrew Moore 	if (*s == '^')
14730154ac8SAndrew Moore 		s++;
14830154ac8SAndrew Moore 	if (*s == ']')
14930154ac8SAndrew Moore 		s++;
15030154ac8SAndrew Moore 	for (; *s != ']' && *s != '\n'; s++)
15130154ac8SAndrew Moore 		if (*s == '[' && ((d = *(s+1)) == '.' || d == ':' || d == '='))
15230154ac8SAndrew Moore 			for (s++, c = *++s; *s != ']' || c != d; s++)
15330154ac8SAndrew Moore 				if ((c = *s) == '\n')
15430154ac8SAndrew Moore 					return NULL;
15530154ac8SAndrew Moore 	return  (*s == ']') ? s : NULL;
15630154ac8SAndrew Moore }
157