1 /* @(#)searchcmds.c	1.23 09/07/09 Copyright 1984-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)searchcmds.c	1.23 09/07/09 Copyright 1984-2009 J. Schilling";
6 #endif
7 /*
8  *	Commands that deal with searching patterns.
9  *
10  *	Copyright (c) 1984-2009 J. Schilling
11  */
12 /*
13  * The contents of this file are subject to the terms of the
14  * Common Development and Distribution License, Version 1.0 only
15  * (the "License").  You may not use this file except in compliance
16  * with the License.
17  *
18  * See the file CDDL.Schily.txt in this distribution for details.
19  * A copy of the CDDL is also available via the Internet at
20  * http://www.opensource.org/licenses/cddl1.txt
21  *
22  * When distributing Covered Code, include this CDDL HEADER in each
23  * file and include the License file CDDL.Schily.txt from this distribution.
24  */
25 
26 #include "ved.h"
27 
28 /*
29  * XXX EXPORT ???
30  */
31 EXPORT	Uchar	sbuf[NAMESIZE];		/* buffer containing last search str */
32 EXPORT	int	sflg = 0;		/* size of search string	    */
33 					/* if >0 : search forward,	    */
34 					/* if <0 : search backwards	    */
35 
36 EXPORT	void	vsearch		__PR((ewin_t *wp));
37 EXPORT	void	vssearch	__PR((ewin_t *wp));
38 LOCAL	void	xsearch		__PR((ewin_t *wp, BOOL domark));
39 EXPORT	void	vrsearch	__PR((ewin_t *wp));
40 EXPORT	void	vsrsearch	__PR((ewin_t *wp));
41 LOCAL	void	xrsearch	__PR((ewin_t *wp, BOOL domark));
42 EXPORT	void	vagainsrch	__PR((ewin_t *wp));
43 EXPORT	void	vsagainsrch	__PR((ewin_t *wp));
44 LOCAL	void	againsearch	__PR((ewin_t *wp, BOOL domark, BOOL rev));
45 EXPORT	void	vrevsrch	__PR((ewin_t *wp));
46 EXPORT	void	vsrevsrch	__PR((ewin_t *wp));
47 LOCAL	void	xreverse	__PR((ewin_t *wp, BOOL domark));
48 EXPORT	void	not_found	__PR((ewin_t *wp));
49 
50 /*
51  * Search forwards
52  */
53 EXPORT void
vsearch(wp)54 vsearch(wp)
55 	ewin_t	*wp;
56 {
57 	xsearch(wp, FALSE);
58 }
59 
60 /*
61  * Search forwards and set mark at start of found pattern
62  */
63 EXPORT void
vssearch(wp)64 vssearch(wp)
65 	ewin_t	*wp;
66 {
67 	xsearch(wp, TRUE);
68 }
69 
70 /*
71  * Search forwards for the 'curnum' th orrurence of a pattern,
72  * set mark at start of found pattern if required.
73  */
74 LOCAL void
xsearch(wp,domark)75 xsearch(wp, domark)
76 	ewin_t	*wp;
77 	BOOL	domark;
78 {
79 	/* forward search */
80 
81 	register int	i;
82 	register ecnt_t	n = wp->curnum;
83 		epos_t	newdot;
84 		Uchar	buf[NAMESIZE];
85 
86 	i = getcmdline(wp, buf, sizeof (buf), "+Search: ");
87 	if (i == 0)
88 		return;
89 	movebytes(C buf, C sbuf, i + 1);
90 	sflg = i;
91 	while (--n >= 0) {
92 		if ((newdot = search(wp, wp->dot, sbuf, i, domark)) > wp->eof) {
93 			if (newdot == (wp->eof+2))
94 				not_found(wp);
95 			break;
96 		} else {
97 			wp->dot = newdot;
98 		}
99 	}
100 }
101 
102 /*
103  * Search backwards
104  */
105 EXPORT void
vrsearch(wp)106 vrsearch(wp)
107 	ewin_t	*wp;
108 {
109 	xrsearch(wp, FALSE);
110 }
111 
112 /*
113  * Search backwards and set mark at start of found pattern
114  */
115 EXPORT void
vsrsearch(wp)116 vsrsearch(wp)
117 	ewin_t	*wp;
118 {
119 	xrsearch(wp, TRUE);
120 }
121 
122 /*
123  * Search backwards for the 'curnum' th orrurence of a pattern,
124  * set mark at start of found pattern if required.
125  */
126 LOCAL void
xrsearch(wp,domark)127 xrsearch(wp, domark)
128 	ewin_t	*wp;
129 	BOOL	domark;
130 {
131 	register int	i;
132 	register ecnt_t	n = wp->curnum;
133 		epos_t newdot;
134 		Uchar	buf[NAMESIZE];
135 
136 	i = getcmdline(wp, buf, sizeof (buf), "-Search: ");
137 	if (i == 0)
138 		return;
139 	movebytes(C buf, C sbuf, i + 1);
140 	sflg = -i;
141 	while (--n >= 0) {
142 		if ((newdot = reverse(wp, wp->dot, sbuf, i, domark)) > wp->eof) {
143 			if (newdot == (wp->eof+2))
144 				not_found(wp);
145 			break;
146 		} else {
147 			wp->dot = newdot;
148 		}
149 	}
150 }
151 
152 /*
153  * Repeat the last search in same search direction
154  */
155 EXPORT void
vagainsrch(wp)156 vagainsrch(wp)
157 	ewin_t	*wp;
158 {
159 	againsearch(wp, FALSE, FALSE);
160 }
161 
162 /*
163  * Repeat the last search in same search direction,
164  * set mark at start of found pattern if required.
165  */
166 EXPORT void
vsagainsrch(wp)167 vsagainsrch(wp)
168 	ewin_t	*wp;
169 {
170 	againsearch(wp, TRUE, FALSE);
171 }
172 
173 /*
174  * Repeat the last search, reverse search direction if required,
175  * set mark at start of found pattern if required.
176  */
177 LOCAL void
againsearch(wp,domark,rev)178 againsearch(wp, domark, rev)
179 	ewin_t	*wp;
180 	BOOL	domark;
181 	BOOL	rev;
182 {
183 	register ecnt_t	n = wp->curnum;
184 		epos_t	newdot;
185 
186 	if (rev)
187 		sflg = -sflg;
188 	writemsg(wp, "%sSearch: %s ...", (sflg >= 0 ? "+" : "-"), sbuf);
189 	while (--n >= 0) {
190 		if (sflg >= 0) {
191 			newdot = search(wp, wp->dot, sbuf, sflg, domark);
192 		} else {
193 			newdot = reverse(wp, wp->dot, sbuf, -sflg, domark);
194 		}
195 		if (newdot > wp->eof) {
196 			if (newdot == (wp->eof+2))
197 				not_found(wp);
198 			break;
199 		} else {
200 			wp->dot = newdot;
201 		}
202 	}
203 }
204 
205 /*
206  * Repeat the last search, reverse search direction
207  */
208 EXPORT void
vrevsrch(wp)209 vrevsrch(wp)
210 	ewin_t	*wp;
211 {
212 	xreverse(wp, FALSE);
213 }
214 
215 /*
216  * Repeat the last search, reverse search direction
217  * and set mark at start of found pattern
218  */
219 EXPORT void
vsrevsrch(wp)220 vsrevsrch(wp)
221 	ewin_t	*wp;
222 {
223 	xreverse(wp, TRUE);
224 }
225 
226 /*
227  * Repeat the last search, reverse search direction,
228  * set mark at start of found pattern if required.
229  */
230 LOCAL void
xreverse(wp,domark)231 xreverse(wp, domark)
232 	ewin_t	*wp;
233 	BOOL	domark;
234 {
235 	againsearch(wp, domark, TRUE);
236 }
237 
238 /*
239  * write not found message
240  */
241 EXPORT void
not_found(wp)242 not_found(wp)
243 	ewin_t	*wp;
244 {
245 	writeerr(wp, "NOT FOUND");
246 }
247