BSD 4_4_Lite1 release
[unix-history] / usr / src / contrib / nvi.1.14 / vi / getc.c
CommitLineData
ed554bc5
C
1/*-
2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)getc.c 8.8 (Berkeley) 3/8/94";
36#endif /* not lint */
37
38#include <sys/types.h>
39#include <sys/queue.h>
40#include <sys/time.h>
41
42#include <bitstring.h>
43#include <ctype.h>
44#include <limits.h>
45#include <signal.h>
46#include <stdio.h>
47#include <termios.h>
48
49#include "compat.h"
50#include <db.h>
51#include <regex.h>
52
53#include "vi.h"
54#include "vcmd.h"
55
56/*
57 * Character stream routines --
58 * These routines return the file a character at a time. There are two
59 * special cases. First, the end of a line, end of a file, start of a
60 * file and empty lines are returned as special cases, and no character
61 * is returned. Second, empty lines include lines that have only white
62 * space in them, because the vi search functions don't care about white
63 * space, and this makes it easier for them to be consistent.
64 */
65
66/*
67 * cs_init --
68 * Initialize character stream routines.
69 */
70int
71cs_init(sp, ep, csp)
72 SCR *sp;
73 EXF *ep;
74 VCS *csp;
75{
76 recno_t lno;
77
78 if ((csp->cs_bp =
79 file_gline(sp, ep, csp->cs_lno, &csp->cs_len)) == NULL) {
80 if (file_lline(sp, ep, &lno))
81 return (1);
82 if (lno == 0)
83 msgq(sp, M_BERR, "Empty file.");
84 else
85 GETLINE_ERR(sp, csp->cs_lno);
86 return (1);
87 }
88 if (csp->cs_len == 0 || 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];
94 }
95 return (0);
96}
97
98/*
99 * cs_next --
100 * Retrieve the next character.
101 */
102int
103cs_next(sp, ep, csp)
104 SCR *sp;
105 EXF *ep;
106 VCS *csp;
107{
108 recno_t slno;
109
110 switch (csp->cs_flags) {
111 case CS_EMP: /* EMP; get next line. */
112 case CS_EOL: /* EOL; get next line. */
113 slno = csp->cs_lno; /* Save current line. */
114 if ((csp->cs_bp =
115 file_gline(sp, ep, ++csp->cs_lno, &csp->cs_len)) == NULL) {
116 csp->cs_lno = slno;
117 if (file_lline(sp, ep, &slno))
118 return (1);
119 if (slno > csp->cs_lno) {
120 GETLINE_ERR(sp, csp->cs_lno);
121 return (1);
122 }
123 csp->cs_flags = CS_EOF;
124 } else if (csp->cs_len == 0 ||
125 v_isempty(csp->cs_bp, csp->cs_len)) {
126 csp->cs_cno = 0;
127 csp->cs_flags = CS_EMP;
128 } else {
129 csp->cs_flags = 0;
130 csp->cs_ch = csp->cs_bp[csp->cs_cno = 0];
131 }
132 break;
133 case 0:
134 if (csp->cs_cno == csp->cs_len - 1)
135 csp->cs_flags = CS_EOL;
136 else
137 csp->cs_ch = csp->cs_bp[++csp->cs_cno];
138 break;
139 case CS_EOF: /* EOF. */
140 break;
141 default:
142 abort();
143 /* NOTREACHED */
144 }
145 return (0);
146}
147
148/*
149 * cs_fspace --
150 * If on a space, eat forward until something other than a
151 * whitespace character.
152 *
153 * XXX
154 * Semantics of checking the current character were coded for the fword()
155 * function -- once the other word routines are converted, they may have
156 * to change.
157 */
158int
159cs_fspace(sp, ep, csp)
160 SCR *sp;
161 EXF *ep;
162 VCS *csp;
163{
164 if (csp->cs_flags != 0 || !isblank(csp->cs_ch))
165 return (0);
166 for (;;) {
167 if (cs_next(sp, ep, csp))
168 return (1);
169 if (csp->cs_flags != 0 || !isblank(csp->cs_ch))
170 break;
171 }
172 return (0);
173}
174
175/*
176 * cs_fblank --
177 * Eat forward to the next non-whitespace character.
178 */
179int
180cs_fblank(sp, ep, csp)
181 SCR *sp;
182 EXF *ep;
183 VCS *csp;
184{
185 for (;;) {
186 if (cs_next(sp, ep, csp))
187 return (1);
188 if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP ||
189 csp->cs_flags == 0 && isblank(csp->cs_ch))
190 continue;
191 break;
192 }
193 return (0);
194}
195
196/*
197 * cs_prev --
198 * Retrieve the previous character.
199 */
200int
201cs_prev(sp, ep, csp)
202 SCR *sp;
203 EXF *ep;
204 VCS *csp;
205{
206 recno_t slno;
207
208 switch (csp->cs_flags) {
209 case CS_EMP: /* EMP; get previous line. */
210 case CS_EOL: /* EOL; get previous line. */
211 if (csp->cs_lno == 1) { /* SOF. */
212 csp->cs_flags = CS_SOF;
213 break;
214 }
215 slno = csp->cs_lno; /* Save current line. */
216 if ((csp->cs_bp = /* Line should exist. */
217 file_gline(sp, ep, --csp->cs_lno, &csp->cs_len)) == NULL) {
218 GETLINE_ERR(sp, csp->cs_lno);
219 csp->cs_lno = slno;
220 return (1);
221 }
222 if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) {
223 csp->cs_cno = 0;
224 csp->cs_flags = CS_EMP;
225 } else {
226 csp->cs_flags = 0;
227 csp->cs_cno = csp->cs_len - 1;
228 csp->cs_ch = csp->cs_bp[csp->cs_cno];
229 }
230 break;
231 case 0:
232 if (csp->cs_cno == 0)
233 if (csp->cs_lno == 1)
234 csp->cs_flags = CS_SOF;
235 else
236 csp->cs_flags = CS_EOL;
237 else
238 csp->cs_ch = csp->cs_bp[--csp->cs_cno];
239 break;
240 case CS_SOF: /* SOF. */
241 break;
242 default:
243 abort();
244 /* NOTREACHED */
245 }
246 return (0);
247}
248
249/*
250 * cs_bblank --
251 * Eat backward to the next non-whitespace character.
252 */
253int
254cs_bblank(sp, ep, csp)
255 SCR *sp;
256 EXF *ep;
257 VCS *csp;
258{
259 for (;;) {
260 if (cs_prev(sp, ep, csp))
261 return (1);
262 if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP ||
263 csp->cs_flags == 0 && isblank(csp->cs_ch))
264 continue;
265 break;
266 }
267 return (0);
268}