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