|
|
1.1 root 1: /* move2.c */
2:
3: /* Author:
4: * Steve Kirkendall
5: * 14407 SW Teal Blvd. #C
6: * Beaverton, OR 97005
7: * [email protected]
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: #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[30];
30:
31: /* wrap \< and \> around the word */
32: strcpy(buffer, "/\\<");
33: strcat(buffer, word);
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)
48: MARK m; /* where to start searching */
49: {
50: if (prevsf)
51: {
52: m = m_fsrch(m, (char *)0);
53: prevsf = TRUE;
54: }
55: else
56: {
57: m = m_bsrch(m, (char *)0);
58: prevsf = FALSE;
59: }
60: return m;
61: }
62:
63: MARK m_Nsrch(m)
64: MARK m; /* where to start searching */
65: {
66: if (prevsf)
67: {
68: m = m_bsrch(m, (char *)0);
69: prevsf = TRUE;
70: }
71: else
72: {
73: m = m_fsrch(m, (char *)0);
74: prevsf = FALSE;
75: }
76: return m;
77: }
78:
79: MARK m_fsrch(m, ptrn)
80: MARK m; /* where to start searching */
81: char *ptrn; /* pattern to search for */
82: {
83: long l; /* line# of line to be searched */
84: char *line; /* text of line to be searched */
85: int wrapped;/* boolean: has our search wrapped yet? */
86: int pos; /* where we are in the line */
87: #ifndef CRUNCH
88: long delta = INFINITY;/* line offset, for things like "/foo/+1" */
89: #endif
90:
91: /* remember: "previous search was forward" */
92: prevsf = TRUE;
93:
94: if (ptrn && *ptrn)
95: {
96: /* locate the closing '/', if any */
97: line = parseptrn(ptrn);
98: #ifndef CRUNCH
99: if (*line)
100: {
101: delta = atol(line);
102: }
103: #endif
104: ptrn++;
105:
106: /* free the previous pattern */
107: if (re) _free_(re);
108:
109: /* compile the pattern */
110: re = regcomp(ptrn);
111: if (!re)
112: {
113: return MARK_UNSET;
114: }
115: }
116: else if (!re)
117: {
118: msg("No previous expression");
119: return MARK_UNSET;
120: }
121:
122: /* search forward for the pattern */
123: pos = markidx(m) + 1;
124: pfetch(markline(m));
125: if (pos >= plen)
126: {
127: pos = 0;
128: m = (m | (BLKSIZE - 1)) + 1;
129: }
130: wrapped = FALSE;
131: for (l = markline(m); l != markline(m) + 1 || !wrapped; l++)
132: {
133: /* wrap search */
134: if (l > nlines)
135: {
136: /* if we wrapped once already, then the search failed */
137: if (wrapped)
138: {
139: break;
140: }
141:
142: /* else maybe we should wrap now? */
143: if (*o_wrapscan)
144: {
145: l = 0;
146: wrapped = TRUE;
147: continue;
148: }
149: else
150: {
151: break;
152: }
153: }
154:
155: /* get this line */
156: line = fetchline(l);
157:
158: /* check this line */
159: if (regexec(re, &line[pos], (pos == 0)))
160: {
161: /* match! */
162: if (wrapped && *o_warn)
163: msg("(wrapped)");
164: #ifndef CRUNCH
165: if (delta != INFINITY)
166: {
167: l += delta;
168: if (l < 1 || l > nlines)
169: {
170: msg("search offset too big");
171: return MARK_UNSET;
172: }
173: force_flags = LNMD|INCL;
174: return MARK_AT_LINE(l);
175: }
176: #endif
177: return MARK_AT_LINE(l) + (int)(re->startp[0] - line);
178: }
179: pos = 0;
180: }
181:
182: /* not found */
183: msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE");
184: return MARK_UNSET;
185: }
186:
187: MARK m_bsrch(m, ptrn)
188: MARK m; /* where to start searching */
189: char *ptrn; /* pattern to search for */
190: {
191: long l; /* line# of line to be searched */
192: char *line; /* text of line to be searched */
193: int wrapped;/* boolean: has our search wrapped yet? */
194: int pos; /* last acceptable idx for a match on this line */
195: int last; /* remembered idx of the last acceptable match on this line */
196: int try; /* an idx at which we strat searching for another match */
197: #ifndef CRUNCH
198: long delta = INFINITY;/* line offset, for things like "/foo/+1" */
199: #endif
200:
201: /* remember: "previous search was not forward" */
202: prevsf = FALSE;
203:
204: if (ptrn && *ptrn)
205: {
206: /* locate the closing '?', if any */
207: line = parseptrn(ptrn);
208: #ifndef CRUNCH
209: if (*line)
210: {
211: delta = atol(line);
212: }
213: #endif
214: ptrn++;
215:
216: /* free the previous pattern, if any */
217: if (re) _free_(re);
218:
219: /* compile the pattern */
220: re = regcomp(ptrn);
221: if (!re)
222: {
223: return MARK_UNSET;
224: }
225: }
226: else if (!re)
227: {
228: msg("No previous expression");
229: return MARK_UNSET;
230: }
231:
232: /* search backward for the pattern */
233: pos = markidx(m);
234: wrapped = FALSE;
235: for (l = markline(m); l != markline(m) - 1 || !wrapped; l--)
236: {
237: /* wrap search */
238: if (l < 1)
239: {
240: if (*o_wrapscan)
241: {
242: l = nlines + 1;
243: wrapped = TRUE;
244: continue;
245: }
246: else
247: {
248: break;
249: }
250: }
251:
252: /* get this line */
253: line = fetchline(l);
254:
255: /* check this line */
256: if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos)
257: {
258: /* match! now find the last acceptable one in this line */
259: do
260: {
261: last = (int)(re->startp[0] - line);
262: try = (int)(re->endp[0] - line);
263: } while (try > 0
264: && regexec(re, &line[try], FALSE)
265: && (int)(re->startp[0] - line) < pos);
266:
267: if (wrapped && *o_warn)
268: msg("(wrapped)");
269: #ifndef CRUNCH
270: if (delta != INFINITY)
271: {
272: l += delta;
273: if (l < 1 || l > nlines)
274: {
275: msg("search offset too big");
276: return MARK_UNSET;
277: }
278: force_flags = LNMD|INCL;
279: return MARK_AT_LINE(l);
280: }
281: #endif
282: return MARK_AT_LINE(l) + last;
283: }
284: pos = BLKSIZE;
285: }
286:
287: /* not found */
288: msg(*o_wrapscan ? "Not found" : "Hit top without finding RE");
289: return MARK_UNSET;
290: }
291:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.