|
|
1.1 root 1: /* move2.c */
2:
3: /* Author:
4: * Steve Kirkendall
5: * 16820 SW Tallac Way
6: * Beaverton, OR 97006
7: * [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
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:
17: extern long atol();
18:
19: static regexp *re; /* compiled version of the pattern to search for */
20: static prevsf; /* boolean: previous search direction was forward? */
21:
22: MARK m_nsrch(m)
23: MARK m; /* where to start searching */
24: {
25: if (prevsf)
26: {
27: m = m_fsrch(m, (char *)0);
28: prevsf = TRUE;
29: }
30: else
31: {
32: m = m_bsrch(m, (char *)0);
33: prevsf = FALSE;
34: }
35: return m;
36: }
37:
38: MARK m_Nsrch(m)
39: MARK m; /* where to start searching */
40: {
41: if (prevsf)
42: {
43: m = m_bsrch(m, (char *)0);
44: prevsf = TRUE;
45: }
46: else
47: {
48: m = m_fsrch(m, (char *)0);
49: prevsf = FALSE;
50: }
51: return m;
52: }
53:
54: MARK m_fsrch(m, ptrn)
55: MARK m; /* where to start searching */
56: char *ptrn; /* pattern to search for */
57: {
58: long l; /* line# of line to be searched */
59: char *line; /* text of line to be searched */
60: int wrapped;/* boolean: has our search wrapped yet? */
61: int pos; /* where we are in the line */
62: long delta; /* line offset, for things like "/foo/+1" */
63:
64: /* remember: "previous search was forward" */
65: prevsf = TRUE;
66:
67: delta = 0L;
68: if (ptrn && *ptrn)
69: {
70: /* locate the closing '/', if any */
71: line = parseptrn(ptrn);
72: if (*line)
73: {
74: delta = atol(line);
75: }
76: ptrn++;
77:
78: /* free the previous pattern */
79: if (re) free(re);
80:
81: /* compile the pattern */
82: re = regcomp(ptrn);
83: if (!re)
84: {
85: return MARK_UNSET;
86: }
87: }
88: else if (!re)
89: {
90: msg("No previous expression");
91: return MARK_UNSET;
92: }
93:
94: /* search forward for the pattern */
95: pos = markidx(m) + 1;
96: pfetch(markline(m));
97: if (pos >= plen)
98: {
99: pos = 0;
100: m = (m | (BLKSIZE - 1)) + 1;
101: }
102: wrapped = FALSE;
103: for (l = markline(m); l != markline(m) + 1 || !wrapped; l++)
104: {
105: /* wrap search */
106: if (l > nlines)
107: {
108: /* if we wrapped once already, then the search failed */
109: if (wrapped)
110: {
111: break;
112: }
113:
114: /* else maybe we should wrap now? */
115: if (*o_wrapscan)
116: {
117: l = 0;
118: wrapped = TRUE;
119: continue;
120: }
121: else
122: {
123: break;
124: }
125: }
126:
127: /* get this line */
128: line = fetchline(l);
129:
130: /* check this line */
131: if (regexec(re, &line[pos], (pos == 0)))
132: {
133: /* match! */
134: if (wrapped && *o_warn)
135: msg("(wrapped)");
136: if (delta != 0L)
137: {
138: l += delta;
139: if (l < 1 || l > nlines)
140: {
141: msg("search offset too big");
142: return MARK_UNSET;
143: }
144: return m_front(MARK_AT_LINE(l), 0L);
145: }
146: return MARK_AT_LINE(l) + (int)(re->startp[0] - line);
147: }
148: pos = 0;
149: }
150:
151: /* not found */
152: msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE");
153: return MARK_UNSET;
154: }
155:
156: MARK m_bsrch(m, ptrn)
157: MARK m; /* where to start searching */
158: char *ptrn; /* pattern to search for */
159: {
160: long l; /* line# of line to be searched */
161: char *line; /* text of line to be searched */
162: int wrapped;/* boolean: has our search wrapped yet? */
163: int pos; /* last acceptable idx for a match on this line */
164: int last; /* remembered idx of the last acceptable match on this line */
165: int try; /* an idx at which we strat searching for another match */
166:
167: /* remember: "previous search was not forward" */
168: prevsf = FALSE;
169:
170: if (ptrn && *ptrn)
171: {
172: /* locate the closing '?', if any */
173: line = parseptrn(ptrn);
174: ptrn++;
175:
176: /* free the previous pattern, if any */
177: if (re) free(re);
178:
179: /* compile the pattern */
180: re = regcomp(ptrn);
181: if (!re)
182: {
183: return MARK_UNSET;
184: }
185: }
186: else if (!re)
187: {
188: msg("No previous expression");
189: return MARK_UNSET;
190: }
191:
192: /* search backward for the pattern */
193: pos = markidx(m);
194: wrapped = FALSE;
195: for (l = markline(m); l != markline(m) - 1 || !wrapped; l--)
196: {
197: /* wrap search */
198: if (l < 1)
199: {
200: if (*o_wrapscan)
201: {
202: l = nlines + 1;
203: wrapped = TRUE;
204: continue;
205: }
206: else
207: {
208: break;
209: }
210: }
211:
212: /* get this line */
213: line = fetchline(l);
214:
215: /* check this line */
216: if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos)
217: {
218: /* match! now find the last acceptable one in this line */
219: do
220: {
221: last = (int)(re->startp[0] - line);
222: try = (int)(re->endp[0] - line);
223: } while (try > 0
224: && regexec(re, &line[try], FALSE)
225: && (int)(re->startp[0] - line) < pos);
226:
227: if (wrapped && *o_warn)
228: msg("(wrapped)");
229: return MARK_AT_LINE(l) + last;
230: }
231: pos = BLKSIZE;
232: }
233:
234: /* not found */
235: msg(*o_wrapscan ? "Not found" : "Hit top without finding RE");
236: return MARK_UNSET;
237: }
238:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.