1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rodney Ruddock of the University of Guelph.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 05/31/93";
13 #endif /* not lint */
14
15 #include <sys/types.h>
16
17 #include <regex.h>
18 #include <setjmp.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #ifdef DBI
24 #include <db.h>
25 #endif
26
27 #include "ed.h"
28 #include "extern.h"
29
30 /*
31 * searches forward through the buffer (wrapping if necessary) for a
32 * line that contains a match to the RE.
33 */
34
35 LINE *
search(inputt,errnum)36 search(inputt, errnum)
37 FILE *inputt;
38 int *errnum;
39 {
40 LINE *l_temp;
41 int l_err;
42 char *l_patt;
43
44 if (current)
45 l_temp = current->below;
46 else {
47 *errnum = -1;
48 ungetc(ss, inputt);
49 strcpy(help_msg, "buffer empty");
50 return(NULL);
51 }
52 /* Get the RE. */
53 l_patt = get_pattern(ss, inputt, errnum, 0);
54 if (*errnum < -1)
55 return (NULL);
56 *errnum = 0;
57 if ((RE_flag == 0) && (l_patt[1] == '\0')) {
58 *errnum = -1;
59 ungetc(ss, inputt);
60 return (NULL);
61 } else
62 if (l_patt[1] || (RE_patt == NULL)) {
63 sigspecial++;
64 free(RE_patt);
65 RE_patt = l_patt;
66 sigspecial--;
67 if (sigint_flag && (!sigspecial))
68 SIGINT_ACTION;
69 }
70 RE_sol = (RE_patt[1] == '^') ? 1 : 0;
71
72 /* Compile it up. */
73 if ((l_patt[1]) &&
74 (regfree(&RE_comp), l_err = regcomp(&RE_comp, &RE_patt[1], 0))) {
75 regerror(l_err, &RE_comp, help_msg, 128);
76 *errnum = -1;
77 RE_flag = 0;
78 ungetc(ss, inputt);
79 return (NULL);
80 }
81 RE_flag = 1;
82
83 /* Find a line that has the RE in it. */
84 for (;;) { /* (l_temp != current) */
85 if (l_temp == NULL) {
86 if (top != NULL)
87 l_temp = top;
88 else
89 break;
90 }
91 get_line(l_temp->handle, l_temp->len);
92 if (sigint_flag && (!sigspecial))
93 SIGINT_ACTION;
94 if (regexec(&RE_comp, text, (size_t) RE_SEC, RE_match, 0)) {
95 l_temp = l_temp->below;
96 if (l_temp == (current->below))
97 break;
98 } else {
99 *errnum = 0;
100 return (l_temp);
101 }
102 }
103 strcpy(help_msg, "RE not found");
104 *errnum = -1;
105 return (NULL);
106 }
107
108 /*
109 * Searches backward through the buffer (wrapping if necessary) to find
110 * a line that contains a match to the RE.
111 */
112 LINE *
search_r(inputt,errnum)113 search_r(inputt, errnum)
114 FILE *inputt;
115 int *errnum;
116 {
117 LINE *l_temp;
118 int l_err;
119 char *l_patt;
120
121 if (current)
122 l_temp = current->above;
123 else {
124 *errnum = -1;
125 ungetc(ss, inputt);
126 strcpy(help_msg, "buffer empty");
127 return(NULL);
128 }
129
130 /* Get the RE. */
131 l_patt = get_pattern(ss, inputt, errnum, 0);
132 if (*errnum < -1)
133 return (NULL);
134 *errnum = 0;
135 if ((RE_flag == 0) && (l_patt[1] == '\0')) {
136 *errnum = -1;
137 ungetc(ss, inputt);
138 return (NULL);
139 } else
140 if (l_patt[1] || (RE_patt == NULL)) {
141 sigspecial++;
142 free(RE_patt);
143 RE_patt = l_patt;
144 sigspecial--;
145 if (sigint_flag && (!sigspecial))
146 SIGINT_ACTION;
147 }
148 RE_sol = (RE_patt[1] == '^') ? 1 : 0;
149
150 /* Compile up the RE. */
151 if ((l_patt[1]) &&
152 (regfree(&RE_comp), l_err = regcomp(&RE_comp, &RE_patt[1], 0))) {
153 regerror(l_err, &RE_comp, help_msg, 128);
154 *errnum = -1;
155 RE_flag = 0;
156 ungetc(ss, inputt);
157 return (NULL);
158 }
159 RE_flag = 1;
160
161 /* Search for a line that has the RE in it. */
162 for (;;) { /* (l_temp != (current->above)) */
163 if (l_temp == NULL) {
164 if (bottom != NULL)
165 l_temp = bottom;
166 else
167 break;
168 }
169 get_line(l_temp->handle, l_temp->len);
170 if (sigint_flag && (!sigspecial))
171 SIGINT_ACTION;
172 if (regexec(&RE_comp, text, (size_t) RE_SEC, RE_match, 0)) {
173 l_temp = l_temp->above;
174 if (l_temp == (current->above))
175 break;
176 } else {
177 *errnum = 0;
178 return (l_temp);
179 }
180 }
181 strcpy(help_msg, "RE not found");
182 *errnum = -1;
183 return (NULL);
184 }
185