rework initial error handling -- since we check for any screens on
[nvi.git] / vi / getc.c
blob42ce38aa1c145c8d9d20d365889e95b4c796e160
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: getc.c,v 8.6 1993/10/26 17:22:58 bostic Exp $ (Berkeley) $Date: 1993/10/26 17:22:58 $";
10 #endif /* not lint */
12 #include <sys/types.h>
14 #include <ctype.h>
16 #include "vi.h"
17 #include "vcmd.h"
20 * Character stream routines --
21 * These routines return the file a character at a time. There are two
22 * special cases. First, the end of a line, end of a file, start of a
23 * file and empty lines are returned as special cases, and no character
24 * is returned. Second, empty lines include lines that have only white
25 * space in them, because the vi search functions don't care about white
26 * space, and this makes it easier for them to be consistent.
30 * cs_init --
31 * Initialize character stream routines.
33 int
34 cs_init(sp, ep, csp)
35 SCR *sp;
36 EXF *ep;
37 VCS *csp;
39 recno_t lno;
41 if ((csp->cs_bp =
42 file_gline(sp, ep, csp->cs_lno, &csp->cs_len)) == NULL) {
43 if (file_lline(sp, ep, &lno))
44 return (1);
45 if (lno == 0)
46 msgq(sp, M_BERR, "Empty file.");
47 else
48 GETLINE_ERR(sp, csp->cs_lno);
49 return (1);
51 if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) {
52 csp->cs_cno = 0;
53 csp->cs_flags = CS_EMP;
54 } else {
55 csp->cs_flags = 0;
56 csp->cs_ch = csp->cs_bp[csp->cs_cno];
58 return (0);
62 * cs_next --
63 * Retrieve the next character.
65 int
66 cs_next(sp, ep, csp)
67 SCR *sp;
68 EXF *ep;
69 VCS *csp;
71 recno_t slno;
73 switch (csp->cs_flags) {
74 case CS_EMP: /* EMP; get next line. */
75 case CS_EOL: /* EOL; get next line. */
76 slno = csp->cs_lno; /* Save current line. */
77 if ((csp->cs_bp =
78 file_gline(sp, ep, ++csp->cs_lno, &csp->cs_len)) == NULL) {
79 csp->cs_lno = slno;
80 if (file_lline(sp, ep, &slno))
81 return (1);
82 if (slno > csp->cs_lno) {
83 GETLINE_ERR(sp, csp->cs_lno);
84 return (1);
86 csp->cs_flags = CS_EOF;
87 } else if (csp->cs_len == 0 ||
88 v_isempty(csp->cs_bp, csp->cs_len)) {
89 csp->cs_cno = 0;
90 csp->cs_flags = CS_EMP;
91 } else {
92 csp->cs_flags = 0;
93 csp->cs_ch = csp->cs_bp[csp->cs_cno = 0];
95 break;
96 case 0:
97 if (csp->cs_cno == csp->cs_len - 1)
98 csp->cs_flags = CS_EOL;
99 else
100 csp->cs_ch = csp->cs_bp[++csp->cs_cno];
101 break;
102 case CS_EOF: /* EOF; only returned once. */
103 default:
104 abort();
105 /* NOTREACHED */
107 return (0);
111 * cs_fspace --
112 * If on a space, eat forward until something other than a
113 * whitespace character.
115 * XXX
116 * Semantics of checking the current character were coded for the fword()
117 * function -- once the other word routines are converted, they may have
118 * to change.
121 cs_fspace(sp, ep, csp)
122 SCR *sp;
123 EXF *ep;
124 VCS *csp;
126 if (csp->cs_flags != 0 || !isblank(csp->cs_ch))
127 return (0);
128 for (;;) {
129 if (cs_next(sp, ep, csp))
130 return (1);
131 if (csp->cs_flags != 0 || !isblank(csp->cs_ch))
132 break;
134 return (0);
138 * cs_fblank --
139 * Eat forward to the next non-whitespace character.
142 cs_fblank(sp, ep, csp)
143 SCR *sp;
144 EXF *ep;
145 VCS *csp;
147 for (;;) {
148 if (cs_next(sp, ep, csp))
149 return (1);
150 if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP ||
151 csp->cs_flags == 0 && isblank(csp->cs_ch))
152 continue;
153 break;
155 return (0);
159 * cs_prev --
160 * Retrieve the previous character.
163 cs_prev(sp, ep, csp)
164 SCR *sp;
165 EXF *ep;
166 VCS *csp;
168 recno_t slno;
170 switch (csp->cs_flags) {
171 case CS_EMP: /* EMP; get previous line. */
172 case CS_EOL: /* EOL; get previous line. */
173 if (csp->cs_lno == 1) { /* SOF. */
174 csp->cs_flags = CS_SOF;
175 break;
177 slno = csp->cs_lno; /* Save current line. */
178 if ((csp->cs_bp = /* Line should exist. */
179 file_gline(sp, ep, --csp->cs_lno, &csp->cs_len)) == NULL) {
180 GETLINE_ERR(sp, csp->cs_lno);
181 csp->cs_lno = slno;
182 return (1);
184 if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) {
185 csp->cs_cno = 0;
186 csp->cs_flags = CS_EMP;
187 } else {
188 csp->cs_flags = 0;
189 csp->cs_cno = csp->cs_len - 1;
190 csp->cs_ch = csp->cs_bp[csp->cs_cno];
192 break;
193 case 0:
194 if (csp->cs_cno == 0)
195 csp->cs_flags = CS_EOL;
196 else
197 csp->cs_ch = csp->cs_bp[--csp->cs_cno];
198 break;
199 case CS_SOF: /* SOF; only returned once. */
200 default:
201 abort();
202 /* NOTREACHED */
204 return (0);
208 * cs_bblank --
209 * Eat backward to the next non-whitespace character.
212 cs_bblank(sp, ep, csp)
213 SCR *sp;
214 EXF *ep;
215 VCS *csp;
217 for (;;) {
218 if (cs_prev(sp, ep, csp))
219 return (1);
220 if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP ||
221 csp->cs_flags == 0 && isblank(csp->cs_ch))
222 continue;
223 break;
225 return (0);