1*d1e48962Smillert /* $OpenBSD: re.c,v 1.4 1996/10/12 19:38:40 millert Exp $ */ 2df930be7Sderaadt /* $NetBSD: re.c,v 1.14 1995/03/21 09:04:48 cgd Exp $ */ 3df930be7Sderaadt 4df930be7Sderaadt /* re.c: This file contains the regular expression interface routines for 5df930be7Sderaadt the ed line editor. */ 6df930be7Sderaadt /*- 7df930be7Sderaadt * Copyright (c) 1993 Andrew Moore, Talke Studio. 8df930be7Sderaadt * All rights reserved. 9df930be7Sderaadt * 10df930be7Sderaadt * Redistribution and use in source and binary forms, with or without 11df930be7Sderaadt * modification, are permitted provided that the following conditions 12df930be7Sderaadt * are met: 13df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright 14df930be7Sderaadt * notice, this list of conditions and the following disclaimer. 15df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 16df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the 17df930be7Sderaadt * documentation and/or other materials provided with the distribution. 18df930be7Sderaadt * 19df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29df930be7Sderaadt * SUCH DAMAGE. 30df930be7Sderaadt */ 31df930be7Sderaadt 32df930be7Sderaadt #ifndef lint 33df930be7Sderaadt #if 0 34df930be7Sderaadt static char *rcsid = "@(#)re.c,v 1.6 1994/02/01 00:34:43 alm Exp"; 35df930be7Sderaadt #else 36*d1e48962Smillert static char rcsid[] = "$OpenBSD: re.c,v 1.4 1996/10/12 19:38:40 millert Exp $"; 37df930be7Sderaadt #endif 38df930be7Sderaadt #endif /* not lint */ 39df930be7Sderaadt 40df930be7Sderaadt #include "ed.h" 41df930be7Sderaadt 42df930be7Sderaadt 43df930be7Sderaadt extern int patlock; 44df930be7Sderaadt 45df930be7Sderaadt char errmsg[MAXPATHLEN + 40] = ""; 46df930be7Sderaadt 47df930be7Sderaadt /* get_compiled_pattern: return pointer to compiled pattern from command 48df930be7Sderaadt buffer */ 49df930be7Sderaadt pattern_t * 50df930be7Sderaadt get_compiled_pattern() 51df930be7Sderaadt { 52df930be7Sderaadt static pattern_t *exp = NULL; 53df930be7Sderaadt 54df930be7Sderaadt char *exps; 55df930be7Sderaadt char delimiter; 56df930be7Sderaadt int n; 57df930be7Sderaadt 58df930be7Sderaadt if ((delimiter = *ibufp) == ' ') { 59*d1e48962Smillert strcpy(errmsg, "invalid pattern delimiter"); 60df930be7Sderaadt return NULL; 61df930be7Sderaadt } else if (delimiter == '\n' || *++ibufp == '\n' || *ibufp == delimiter) { 6245c72c98Smillert if (!exp) 63*d1e48962Smillert strcpy(errmsg, "no previous pattern"); 64df930be7Sderaadt return exp; 65df930be7Sderaadt } else if ((exps = extract_pattern(delimiter)) == NULL) 66df930be7Sderaadt return NULL; 67df930be7Sderaadt /* buffer alloc'd && not reserved */ 68df930be7Sderaadt if (exp && !patlock) 69df930be7Sderaadt regfree(exp); 70df930be7Sderaadt else if ((exp = (pattern_t *) malloc(sizeof(pattern_t))) == NULL) { 71*d1e48962Smillert perror(NULL); 72*d1e48962Smillert strcpy(errmsg, "out of memory"); 73df930be7Sderaadt return NULL; 74df930be7Sderaadt } 75df930be7Sderaadt patlock = 0; 76df930be7Sderaadt if (n = regcomp(exp, exps, 0)) { 77df930be7Sderaadt regerror(n, exp, errmsg, sizeof errmsg); 78df930be7Sderaadt free(exp); 79df930be7Sderaadt return exp = NULL; 80df930be7Sderaadt } 81df930be7Sderaadt return exp; 82df930be7Sderaadt } 83df930be7Sderaadt 84df930be7Sderaadt 85df930be7Sderaadt /* extract_pattern: copy a pattern string from the command buffer; return 86df930be7Sderaadt pointer to the copy */ 87df930be7Sderaadt char * 88df930be7Sderaadt extract_pattern(delimiter) 89df930be7Sderaadt int delimiter; 90df930be7Sderaadt { 91df930be7Sderaadt static char *lhbuf = NULL; /* buffer */ 92df930be7Sderaadt static int lhbufsz = 0; /* buffer size */ 93df930be7Sderaadt 94df930be7Sderaadt char *nd; 95df930be7Sderaadt int len; 96df930be7Sderaadt 97df930be7Sderaadt for (nd = ibufp; *nd != delimiter && *nd != '\n'; nd++) 98df930be7Sderaadt switch (*nd) { 99df930be7Sderaadt default: 100df930be7Sderaadt break; 101df930be7Sderaadt case '[': 102df930be7Sderaadt if ((nd = parse_char_class(++nd)) == NULL) { 103*d1e48962Smillert strcpy(errmsg, "unbalanced brackets ([])"); 104df930be7Sderaadt return NULL; 105df930be7Sderaadt } 106df930be7Sderaadt break; 107df930be7Sderaadt case '\\': 108df930be7Sderaadt if (*++nd == '\n') { 109*d1e48962Smillert strcpy(errmsg, "trailing backslash (\\)"); 110df930be7Sderaadt return NULL; 111df930be7Sderaadt } 112df930be7Sderaadt break; 113df930be7Sderaadt } 114df930be7Sderaadt len = nd - ibufp; 115df930be7Sderaadt REALLOC(lhbuf, lhbufsz, len + 1, NULL); 116df930be7Sderaadt memcpy(lhbuf, ibufp, len); 117df930be7Sderaadt lhbuf[len] = '\0'; 118df930be7Sderaadt ibufp = nd; 119df930be7Sderaadt return (isbinary) ? NUL_TO_NEWLINE(lhbuf, len) : lhbuf; 120df930be7Sderaadt } 121df930be7Sderaadt 122df930be7Sderaadt 123df930be7Sderaadt /* parse_char_class: expand a POSIX character class */ 124df930be7Sderaadt char * 125df930be7Sderaadt parse_char_class(s) 126df930be7Sderaadt char *s; 127df930be7Sderaadt { 128df930be7Sderaadt int c, d; 129df930be7Sderaadt 130df930be7Sderaadt if (*s == '^') 131df930be7Sderaadt s++; 132df930be7Sderaadt if (*s == ']') 133df930be7Sderaadt s++; 134df930be7Sderaadt for (; *s != ']' && *s != '\n'; s++) 135df930be7Sderaadt if (*s == '[' && ((d = *(s+1)) == '.' || d == ':' || d == '=')) 136df930be7Sderaadt for (s++, c = *++s; *s != ']' || c != d; s++) 137df930be7Sderaadt if ((c = *s) == '\n') 138df930be7Sderaadt return NULL; 139df930be7Sderaadt return (*s == ']') ? s : NULL; 140df930be7Sderaadt } 141