Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 318 lines (280 sloc) 6.291 kb
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
1 /* move2.c */
2
3 /* Author:
4 * Steve Kirkendall
5 * 1500 SW Park #326
6 * Portland OR, 97201
7 * kirkenda@cs.pdx.edu
8 */
9
10
11 /* This function contains the movement functions that perform RE searching */
12
13 #include "config.h"
14 #include "vi.h"
15 #include "regexp.h"
16 #include <string.h>
17
18
19 static regexp *re; /* compiled version of the pattern to search for */
20 static prevsf; /* boolean: previous search direction was forward? */
21
22 #ifndef NO_EXTENSIONS
23 /*ARGSUSED*/
24 MARK m_wsrch(word, m, cnt)
25 char *word; /* the word to search for */
26 MARK m; /* the starting point */
27 int cnt; /* ignored */
28 {
29 char buffer[WSRCH_MAX + 6];
30
31 /* wrap \< and \> around the word */
32 strncpy(buffer, "/\\<", WSRCH_MAX + 6);
33 strncat(buffer, word, WSRCH_MAX);
34 strcat(buffer, "\\>");
35
36 /* show the searched-for word on the bottom line */
37 move(LINES - 1, 0);
38 qaddstr(buffer);
39 clrtoeol();
40 refresh();
41
42 /* search for the word */
43 return m_fsrch(m, buffer);
44 }
45 #endif
46
47 MARK m_nsrch(m, cnt, cmd)
48 MARK m; /* where to start searching */
49 long cnt; /* number of searches to do */
50 int cmd; /* command character -- 'n' or 'N' */
51 {
52 int oldprevsf; /* original value of prevsf, so we can fix any changes */
53
54 DEFAULT(1L);
55
56 /* clear the bottom line. In particular, we want to loose any
57 * "(wrapped)" notice.
58 */
59 move(LINES - 1, 0);
60 clrtoeol();
61
62 /* if 'N' command, then invert the "prevsf" variable */
63 oldprevsf = prevsf;
64 if (cmd == 'N')
65 {
66 prevsf = !prevsf;
67 }
68
69 /* search forward if prevsf -- i.e., if previous search was forward */
70 while (--cnt >= 0L && m != MARK_UNSET)
71 {
72 if (prevsf)
73 {
74 m = m_fsrch(m, (char *)0);
75 }
76 else
77 {
78 m = m_bsrch(m, (char *)0);
79 }
80 }
81
82 /* restore the old value of prevsf -- if cmd=='N' then it was inverted,
83 * and the m_fsrch() and m_bsrch() functions force it to a (possibly
84 * incorrect) value. The value of prevsf isn't supposed to be changed
85 * at all here!
86 */
87 prevsf = oldprevsf;
88 return m;
89 }
90
91
92 MARK m_fsrch(m, ptrn)
93 MARK m; /* where to start searching */
94 char *ptrn; /* pattern to search for */
95 {
96 long l; /* line# of line to be searched */
97 char *line; /* text of line to be searched */
98 int wrapped;/* boolean: has our search wrapped yet? */
99 int pos; /* where we are in the line */
100 #ifndef CRUNCH
101 long delta = INFINITY;/* line offset, for things like "/foo/+1" */
102 #endif
103
104 /* remember: "previous search was forward" */
105 prevsf = TRUE;
106
107 if (ptrn && *ptrn)
108 {
109 /* locate the closing '/', if any */
110 line = parseptrn(ptrn);
111 #ifndef CRUNCH
112 if (*line)
113 {
114 delta = atol(line);
115 }
116 #endif
117 ptrn++;
118
119 /* free the previous pattern */
120 if (re) _free_(re);
121
122 /* compile the pattern */
123 re = regcomp(ptrn);
124 if (!re)
125 {
126 return MARK_UNSET;
127 }
128 }
129 else if (!re)
130 {
131 msg("No previous expression");
132 return MARK_UNSET;
133 }
134
135 /* search forward for the pattern */
136 pos = markidx(m) + 1;
137 pfetch(markline(m));
138 if (pos >= plen)
139 {
140 pos = 0;
141 m = (m | (BLKSIZE - 1)) + 1;
142 }
143 wrapped = FALSE;
144 for (l = markline(m); l != markline(m) + 1 || !wrapped; l++)
145 {
146 /* wrap search */
147 if (l > nlines)
148 {
149 /* if we wrapped once already, then the search failed */
150 if (wrapped)
151 {
152 break;
153 }
154
155 /* else maybe we should wrap now? */
156 if (*o_wrapscan)
157 {
158 l = 0;
159 wrapped = TRUE;
160 continue;
161 }
162 else
163 {
164 break;
165 }
166 }
167
168 /* get this line */
169 line = fetchline(l);
170
171 /* check this line */
172 if (regexec(re, &line[pos], (pos == 0)))
173 {
174 /* match! */
175 if (wrapped && *o_warn)
176 msg("(wrapped)");
177 #ifndef CRUNCH
178 if (delta != INFINITY)
179 {
180 l += delta;
181 if (l < 1 || l > nlines)
182 {
183 msg("search offset too big");
184 return MARK_UNSET;
185 }
186 force_flags = LNMD|INCL;
187 return MARK_AT_LINE(l);
188 }
189 #endif
190 if (re->leavep)
191 return MARK_AT_LINE(l) + (int)(re->leavep - line);
192 else
193 return MARK_AT_LINE(l) + (int)(re->startp[0] - line);
194 }
195 pos = 0;
196 }
197
198 /* not found */
199 #ifdef DEBUG
200 msg("/%s/ not found", ptrn);
201 #else
202 msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE");
203 #endif
204 return MARK_UNSET;
205 }
206
207 MARK m_bsrch(m, ptrn)
208 MARK m; /* where to start searching */
209 char *ptrn; /* pattern to search for */
210 {
211 long l; /* line# of line to be searched */
212 char *line; /* text of line to be searched */
213 int wrapped;/* boolean: has our search wrapped yet? */
214 int pos; /* last acceptable idx for a match on this line */
215 int last; /* remembered idx of the last acceptable match on this line */
216 int try; /* an idx at which we strat searching for another match */
217 #ifndef CRUNCH
218 long delta = INFINITY;/* line offset, for things like "/foo/+1" */
219 #endif
220
221 /* remember: "previous search was not forward" */
222 prevsf = FALSE;
223
224 if (ptrn && *ptrn)
225 {
226 /* locate the closing '?', if any */
227 line = parseptrn(ptrn);
228 #ifndef CRUNCH
229 if (*line)
230 {
231 delta = atol(line);
232 }
233 #endif
234 ptrn++;
235
236 /* free the previous pattern, if any */
237 if (re) _free_(re);
238
239 /* compile the pattern */
240 re = regcomp(ptrn);
241 if (!re)
242 {
243 return MARK_UNSET;
244 }
245 }
246 else if (!re)
247 {
248 msg("No previous expression");
249 return MARK_UNSET;
250 }
251
252 /* search backward for the pattern */
253 pos = markidx(m);
254 wrapped = FALSE;
255 for (l = markline(m); l != markline(m) - 1 || !wrapped; l--)
256 {
257 /* wrap search */
258 if (l < 1)
259 {
260 if (*o_wrapscan)
261 {
262 l = nlines + 1;
263 wrapped = TRUE;
264 continue;
265 }
266 else
267 {
268 break;
269 }
270 }
271
272 /* get this line */
273 line = fetchline(l);
274
275 /* check this line */
276 if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos)
277 {
278 /* match! now find the last acceptable one in this line */
279 do
280 {
281 if (re->leavep)
282 last = (int)(re->leavep - line);
283 else
284 last = (int)(re->startp[0] - line);
285 try = (int)(re->endp[0] - line);
286 } while (try > 0
287 && regexec(re, &line[try], FALSE)
288 && (int)(re->startp[0] - line) < pos);
289
290 if (wrapped && *o_warn)
291 msg("(wrapped)");
292 #ifndef CRUNCH
293 if (delta != INFINITY)
294 {
295 l += delta;
296 if (l < 1 || l > nlines)
297 {
298 msg("search offset too big");
299 return MARK_UNSET;
300 }
301 force_flags = LNMD|INCL;
302 return MARK_AT_LINE(l);
303 }
304 #endif
305 return MARK_AT_LINE(l) + last;
306 }
307 pos = BLKSIZE;
308 }
309
310 /* not found */
311 #ifdef DEBUG
312 msg("?%s? not found", ptrn);
313 #else
314 msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE");
315 #endif
316 return MARK_UNSET;
317 }
Something went wrong with that request. Please try again.