bug, wrong value to getcount for 'z' command
[nvi.git] / vi / v_ch.c
blobb7da1f5689ca0ea0ec38e13ece2d11b13132de8b
1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
6 */
8 #ifndef lint
9 static char sccsid[] = "$Id: v_ch.c,v 8.1 1993/06/09 22:26:44 bostic Exp $ (Berkeley) $Date: 1993/06/09 22:26:44 $";
10 #endif /* not lint */
12 #include <sys/types.h>
14 #include <stdlib.h>
16 #include "vi.h"
17 #include "vcmd.h"
19 #define NOPREV { \
20 msgq(sp, M_BERR, "No previous F, f, T or t search."); \
21 return (1); \
24 #define NOTFOUND(ch) { \
25 msgq(sp, M_BERR, "%s not found.", charname(sp, ch)); \
26 return (1); \
30 * v_chrepeat -- [count];
31 * Repeat the last F, f, T or t search.
33 int
34 v_chrepeat(sp, ep, vp, fm, tm, rp)
35 SCR *sp;
36 EXF *ep;
37 VICMDARG *vp;
38 MARK *fm, *tm, *rp;
40 vp->character = sp->lastckey;
42 switch (sp->csearchdir) {
43 case CNOTSET:
44 NOPREV;
45 case FSEARCH:
46 return (v_chF(sp, ep, vp, fm, tm, rp));
47 case fSEARCH:
48 return (v_chf(sp, ep, vp, fm, tm, rp));
49 case TSEARCH:
50 return (v_chT(sp, ep, vp, fm, tm, rp));
51 case tSEARCH:
52 return (v_cht(sp, ep, vp, fm, tm, rp));
53 default:
54 abort();
56 /* NOTREACHED */
60 * v_chrrepeat -- [count],
61 * Repeat the last F, f, T or t search in the reverse direction.
63 int
64 v_chrrepeat(sp, ep, vp, fm, tm, rp)
65 SCR *sp;
66 EXF *ep;
67 VICMDARG *vp;
68 MARK *fm, *tm, *rp;
70 int rval;
71 enum cdirection savedir;
73 vp->character = sp->lastckey;
74 savedir = sp->csearchdir;
76 switch (sp->csearchdir) {
77 case CNOTSET:
78 NOPREV;
79 case FSEARCH:
80 rval = v_chf(sp, ep, vp, fm, tm, rp);
81 break;
82 case fSEARCH:
83 rval = v_chF(sp, ep, vp, fm, tm, rp);
84 break;
85 case TSEARCH:
86 rval = v_cht(sp, ep, vp, fm, tm, rp);
87 break;
88 case tSEARCH:
89 rval = v_chT(sp, ep, vp, fm, tm, rp);
90 break;
91 default:
92 abort();
94 sp->csearchdir = savedir;
95 return (rval);
99 * v_cht -- [count]tc
100 * Search forward in the line for the next occurrence of the character.
101 * Place the cursor on it if a motion command, or to its left if not.
104 v_cht(sp, ep, vp, fm, tm, rp)
105 SCR *sp;
106 EXF *ep;
107 VICMDARG *vp;
108 MARK *fm, *tm, *rp;
110 int rval;
112 rval = v_chf(sp, ep, vp, fm, tm, rp);
113 if (!rval)
114 --rp->cno; /* XXX: Motion interaction with v_chf. */
115 sp->csearchdir = tSEARCH;
116 return (rval);
120 * v_chf -- [count]fc
121 * Search forward in the line for the next occurrence of the character.
122 * Place the cursor to it's right if a motion command, or on it if not.
125 v_chf(sp, ep, vp, fm, tm, rp)
126 SCR *sp;
127 EXF *ep;
128 VICMDARG *vp;
129 MARK *fm, *tm, *rp;
131 register int key;
132 register char *endp, *p;
133 size_t len;
134 recno_t lno;
135 u_long cnt;
136 char *startp;
138 sp->csearchdir = fSEARCH;
139 sp->lastckey = key = vp->character;
141 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
142 if (file_lline(sp, ep, &lno))
143 return (1);
144 if (lno == 0)
145 NOTFOUND(key);
146 GETLINE_ERR(sp, fm->lno);
147 return (1);
150 if (len == 0)
151 NOTFOUND(key);
153 startp = p;
154 endp = p + len;
155 p += fm->cno;
156 for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
157 while (++p < endp && *p != key);
158 if (p == endp)
159 NOTFOUND(key);
161 rp->lno = fm->lno;
162 rp->cno = p - startp;
163 if (F_ISSET(vp, VC_C | VC_D | VC_Y))
164 ++rp->cno;
165 return (0);
169 * v_chT -- [count]Tc
170 * Search backward in the line for the next occurrence of the character.
171 * Place the cursor to its right.
174 v_chT(sp, ep, vp, fm, tm, rp)
175 SCR *sp;
176 EXF *ep;
177 VICMDARG *vp;
178 MARK *fm, *tm, *rp;
180 int rval;
182 rval = v_chF(sp, ep, vp, fm, tm, rp);
183 if (!rval)
184 ++rp->cno;
185 sp->csearchdir = TSEARCH;
186 return (0);
190 * v_chF -- [count]Fc
191 * Search backward in the line for the next occurrence of the character.
192 * Place the cursor on it.
195 v_chF(sp, ep, vp, fm, tm, rp)
196 SCR *sp;
197 EXF *ep;
198 VICMDARG *vp;
199 MARK *fm, *tm, *rp;
201 register int key;
202 register char *p, *endp;
203 recno_t lno;
204 size_t len;
205 u_long cnt;
207 sp->csearchdir = FSEARCH;
208 sp->lastckey = key = vp->character;
210 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
211 if (file_lline(sp, ep, &lno))
212 return (1);
213 if (lno == 0)
214 NOTFOUND(key);
215 GETLINE_ERR(sp, fm->lno);
216 return (1);
219 if (len == 0)
220 NOTFOUND(key);
222 endp = p - 1;
223 p += fm->cno;
224 for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
225 while (--p > endp && *p != key);
226 if (p == endp)
227 NOTFOUND(key);
229 rp->lno = fm->lno;
230 rp->cno = (p - endp) - 1;
231 return (0);