only clean out gs when last window goes
[nvi.git] / vi / getc.c
blob1e9f987666bb8b43087340b609f08f8419d76aff
1 /*-
2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "$Id: getc.c,v 10.11 2000/06/27 17:19:07 skimo Exp $ (Berkeley) $Date: 2000/06/27 17:19:07 $";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
18 #include <sys/time.h>
20 #include <bitstring.h>
21 #include <ctype.h>
22 #include <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
26 #include "../common/common.h"
27 #include "vi.h"
30 * Character stream routines --
31 * These routines return the file a character at a time. There are two
32 * special cases. First, the end of a line, end of a file, start of a
33 * file and empty lines are returned as special cases, and no character
34 * is returned. Second, empty lines include lines that have only white
35 * space in them, because the vi search functions don't care about white
36 * space, and this makes it easier for them to be consistent.
40 * cs_init --
41 * Initialize character stream routines.
43 * PUBLIC: int cs_init __P((SCR *, VCS *));
45 int
46 cs_init(sp, csp)
47 SCR *sp;
48 VCS *csp;
50 int isempty;
52 if (db_eget(sp, csp->cs_lno, &csp->cs_bp, &csp->cs_len, &isempty)) {
53 if (isempty)
54 msgq(sp, M_BERR, "177|Empty file");
55 return (1);
57 if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) {
58 csp->cs_cno = 0;
59 csp->cs_flags = CS_EMP;
60 } else {
61 csp->cs_flags = 0;
62 csp->cs_ch = csp->cs_bp[csp->cs_cno];
64 return (0);
68 * cs_next --
69 * Retrieve the next character.
71 * PUBLIC: int cs_next __P((SCR *, VCS *));
73 int
74 cs_next(sp, csp)
75 SCR *sp;
76 VCS *csp;
78 CHAR_T *p;
80 switch (csp->cs_flags) {
81 case CS_EMP: /* EMP; get next line. */
82 case CS_EOL: /* EOL; get next line. */
83 if (db_get(sp, ++csp->cs_lno, 0, &p, &csp->cs_len)) {
84 --csp->cs_lno;
85 csp->cs_flags = CS_EOF;
86 } else {
87 csp->cs_bp = p;
88 if (csp->cs_len == 0 ||
89 v_isempty(csp->cs_bp, csp->cs_len)) {
90 csp->cs_cno = 0;
91 csp->cs_flags = CS_EMP;
92 } else {
93 csp->cs_flags = 0;
94 csp->cs_ch = csp->cs_bp[csp->cs_cno = 0];
97 break;
98 case 0:
99 if (csp->cs_cno == csp->cs_len - 1)
100 csp->cs_flags = CS_EOL;
101 else
102 csp->cs_ch = csp->cs_bp[++csp->cs_cno];
103 break;
104 case CS_EOF: /* EOF. */
105 break;
106 default:
107 abort();
108 /* NOTREACHED */
110 return (0);
114 * cs_fspace --
115 * If on a space, eat forward until something other than a
116 * whitespace character.
118 * XXX
119 * Semantics of checking the current character were coded for the fword()
120 * function -- once the other word routines are converted, they may have
121 * to change.
123 * PUBLIC: int cs_fspace __P((SCR *, VCS *));
126 cs_fspace(sp, csp)
127 SCR *sp;
128 VCS *csp;
130 if (csp->cs_flags != 0 || !isblank(csp->cs_ch))
131 return (0);
132 for (;;) {
133 if (cs_next(sp, csp))
134 return (1);
135 if (csp->cs_flags != 0 || !isblank(csp->cs_ch))
136 break;
138 return (0);
142 * cs_fblank --
143 * Eat forward to the next non-whitespace character.
145 * PUBLIC: int cs_fblank __P((SCR *, VCS *));
148 cs_fblank(sp, csp)
149 SCR *sp;
150 VCS *csp;
152 for (;;) {
153 if (cs_next(sp, csp))
154 return (1);
155 if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP ||
156 csp->cs_flags == 0 && isblank(csp->cs_ch))
157 continue;
158 break;
160 return (0);
164 * cs_prev --
165 * Retrieve the previous character.
167 * PUBLIC: int cs_prev __P((SCR *, VCS *));
170 cs_prev(sp, csp)
171 SCR *sp;
172 VCS *csp;
174 switch (csp->cs_flags) {
175 case CS_EMP: /* EMP; get previous line. */
176 case CS_EOL: /* EOL; get previous line. */
177 if (csp->cs_lno == 1) { /* SOF. */
178 csp->cs_flags = CS_SOF;
179 break;
181 if (db_get(sp, /* The line should exist. */
182 --csp->cs_lno, DBG_FATAL, &csp->cs_bp, &csp->cs_len)) {
183 ++csp->cs_lno;
184 return (1);
186 if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) {
187 csp->cs_cno = 0;
188 csp->cs_flags = CS_EMP;
189 } else {
190 csp->cs_flags = 0;
191 csp->cs_cno = csp->cs_len - 1;
192 csp->cs_ch = csp->cs_bp[csp->cs_cno];
194 break;
195 case CS_EOF: /* EOF: get previous char. */
196 case 0:
197 if (csp->cs_cno == 0)
198 if (csp->cs_lno == 1)
199 csp->cs_flags = CS_SOF;
200 else
201 csp->cs_flags = CS_EOL;
202 else
203 csp->cs_ch = csp->cs_bp[--csp->cs_cno];
204 break;
205 case CS_SOF: /* SOF. */
206 break;
207 default:
208 abort();
209 /* NOTREACHED */
211 return (0);
215 * cs_bblank --
216 * Eat backward to the next non-whitespace character.
218 * PUBLIC: int cs_bblank __P((SCR *, VCS *));
221 cs_bblank(sp, csp)
222 SCR *sp;
223 VCS *csp;
225 for (;;) {
226 if (cs_prev(sp, csp))
227 return (1);
228 if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP ||
229 csp->cs_flags == 0 && isblank(csp->cs_ch))
230 continue;
231 break;
233 return (0);