re.c revision 1.1 1 /* re.c: This file contains the regular expression interface routines for
2 the ed line editor. */
3 /*-
4 * Copyright (c) 1993 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley
8 * by Andrew Moore, Talke Studio.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39 #ifndef lint
40 static char sccsid[] = "@(#)re.c 5.5 (Berkeley) 3/28/93";
41 #endif /* not lint */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46
47 #include "ed.h"
48
49 extern char *ibufp;
50 extern int patlock;
51
52 char errmsg[MAXFNAME + 40] = "";
53
54 /* optpat: return pointer to compiled pattern from command buffer */
55 pattern_t *
56 optpat()
57 {
58 static pattern_t *exp = NULL;
59
60 char *exps;
61 char delim;
62 int n;
63
64 if ((delim = *ibufp) == '\n')
65 return exp;
66 else if (delim == ' ' || *++ibufp == '\n') {
67 sprintf(errmsg, "invalid pattern delimiter");
68 return NULL;
69 } else if (*ibufp == delim)
70 return exp;
71 else if ((exps = getlhs(delim)) == NULL)
72 return NULL;
73 /* buffer alloc'd && not reserved */
74 if (exp && !patlock)
75 regfree(exp);
76 else if ((exp = (pattern_t *) malloc(sizeof(pattern_t))) == NULL) {
77 fprintf(stderr, "out of memory\n");
78 return NULL;
79 }
80 patlock = 0;
81 #ifdef GNU_REGEX
82 /* initialize pattern buffer */
83 exp->buffer = NULL;
84 exp->allocated = 0L;
85 exp->fastmap = (char *) malloc(FASTMAP_SIZE);
86 exp->translate = 0;
87 #endif
88 if (n = regcomp(exp, exps, 0)) {
89 regerror(n, exp, errmsg, sizeof errmsg);
90 return NULL;
91 }
92 return exp;
93 }
94
95
96 /* getlhs: copy a pattern string from the command buffer; return pointer
97 to the copy */
98 char *
99 getlhs(delim)
100 int delim;
101 {
102 static char buf[MAXLINE];
103 char *nd;
104
105 for (nd = ibufp; *nd != delim && *nd != '\n'; nd++)
106 switch (*nd) {
107 default:
108 break;
109 case CCL:
110 if ((nd = ccl(CCLEND, ++nd)) == NULL) {
111 sprintf(errmsg, "unbalanced brackets ([])");
112 return NULL;
113 }
114 break;
115 case ESCHAR:
116 if (*++nd == '\n') {
117 sprintf(errmsg, "trailing backslash (\\)");
118 return NULL;
119 }
120 break;
121 }
122 strncpy(buf, ibufp, nd - ibufp);
123 buf[nd - ibufp] = '\0';
124 ibufp = nd;
125 return buf;
126 }
127
128
129 /* ccl: expand a character class */
130 char *
131 ccl(delim, src)
132 int delim;
133 char *src;
134 {
135 if (*src == '^')
136 src++;
137 if (*src == delim)
138 src++;
139 while (*src != delim && *src != '\n')
140 src++;
141 return (*src == delim) ? src : NULL;
142 }
143