1 |
|
|
/* $OpenBSD: getc.c,v 1.10 2016/01/06 22:28:52 millert Exp $ */ |
2 |
|
|
|
3 |
|
|
/*- |
4 |
|
|
* Copyright (c) 1992, 1993, 1994 |
5 |
|
|
* The Regents of the University of California. All rights reserved. |
6 |
|
|
* Copyright (c) 1992, 1993, 1994, 1995, 1996 |
7 |
|
|
* Keith Bostic. All rights reserved. |
8 |
|
|
* |
9 |
|
|
* See the LICENSE file for redistribution information. |
10 |
|
|
*/ |
11 |
|
|
|
12 |
|
|
#include "config.h" |
13 |
|
|
|
14 |
|
|
#include <sys/types.h> |
15 |
|
|
#include <sys/queue.h> |
16 |
|
|
#include <sys/time.h> |
17 |
|
|
|
18 |
|
|
#include <bitstring.h> |
19 |
|
|
#include <ctype.h> |
20 |
|
|
#include <limits.h> |
21 |
|
|
#include <stdio.h> |
22 |
|
|
#include <stdlib.h> |
23 |
|
|
|
24 |
|
|
#include "../common/common.h" |
25 |
|
|
#include "vi.h" |
26 |
|
|
|
27 |
|
|
/* |
28 |
|
|
* Character stream routines -- |
29 |
|
|
* These routines return the file a character at a time. There are two |
30 |
|
|
* special cases. First, the end of a line, end of a file, start of a |
31 |
|
|
* file and empty lines are returned as special cases, and no character |
32 |
|
|
* is returned. Second, empty lines include lines that have only white |
33 |
|
|
* space in them, because the vi search functions don't care about white |
34 |
|
|
* space, and this makes it easier for them to be consistent. |
35 |
|
|
*/ |
36 |
|
|
|
37 |
|
|
/* |
38 |
|
|
* cs_init -- |
39 |
|
|
* Initialize character stream routines. |
40 |
|
|
* |
41 |
|
|
* PUBLIC: int cs_init(SCR *, VCS *); |
42 |
|
|
*/ |
43 |
|
|
int |
44 |
|
|
cs_init(SCR *sp, VCS *csp) |
45 |
|
|
{ |
46 |
|
|
int isempty; |
47 |
|
|
|
48 |
|
|
if (db_eget(sp, csp->cs_lno, (char **) &csp->cs_bp, &csp->cs_len, |
49 |
|
|
&isempty)) { |
50 |
|
|
if (isempty) |
51 |
|
|
msgq(sp, M_BERR, "Empty file"); |
52 |
|
|
return (1); |
53 |
|
|
} |
54 |
|
|
if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) { |
55 |
|
|
csp->cs_cno = 0; |
56 |
|
|
csp->cs_flags = CS_EMP; |
57 |
|
|
} else { |
58 |
|
|
csp->cs_flags = 0; |
59 |
|
|
csp->cs_ch = csp->cs_bp[csp->cs_cno]; |
60 |
|
|
} |
61 |
|
|
return (0); |
62 |
|
|
} |
63 |
|
|
|
64 |
|
|
/* |
65 |
|
|
* cs_next -- |
66 |
|
|
* Retrieve the next character. |
67 |
|
|
* |
68 |
|
|
* PUBLIC: int cs_next(SCR *, VCS *); |
69 |
|
|
*/ |
70 |
|
|
int |
71 |
|
|
cs_next(SCR *sp, VCS *csp) |
72 |
|
|
{ |
73 |
|
|
char *p; |
74 |
|
|
|
75 |
|
|
switch (csp->cs_flags) { |
76 |
|
|
case CS_EMP: /* EMP; get next line. */ |
77 |
|
|
case CS_EOL: /* EOL; get next line. */ |
78 |
|
|
if (db_get(sp, ++csp->cs_lno, 0, &p, &csp->cs_len)) { |
79 |
|
|
--csp->cs_lno; |
80 |
|
|
csp->cs_flags = CS_EOF; |
81 |
|
|
} else { |
82 |
|
|
csp->cs_bp = p; |
83 |
|
|
if (csp->cs_len == 0 || |
84 |
|
|
v_isempty(csp->cs_bp, csp->cs_len)) { |
85 |
|
|
csp->cs_cno = 0; |
86 |
|
|
csp->cs_flags = CS_EMP; |
87 |
|
|
} else { |
88 |
|
|
csp->cs_flags = 0; |
89 |
|
|
csp->cs_ch = csp->cs_bp[csp->cs_cno = 0]; |
90 |
|
|
} |
91 |
|
|
} |
92 |
|
|
break; |
93 |
|
|
case 0: |
94 |
|
|
if (csp->cs_cno == csp->cs_len - 1) |
95 |
|
|
csp->cs_flags = CS_EOL; |
96 |
|
|
else |
97 |
|
|
csp->cs_ch = csp->cs_bp[++csp->cs_cno]; |
98 |
|
|
break; |
99 |
|
|
case CS_EOF: /* EOF. */ |
100 |
|
|
break; |
101 |
|
|
default: |
102 |
|
|
abort(); |
103 |
|
|
/* NOTREACHED */ |
104 |
|
|
} |
105 |
|
|
return (0); |
106 |
|
|
} |
107 |
|
|
|
108 |
|
|
/* |
109 |
|
|
* cs_fspace -- |
110 |
|
|
* If on a space, eat forward until something other than a |
111 |
|
|
* whitespace character. |
112 |
|
|
* |
113 |
|
|
* XXX |
114 |
|
|
* Semantics of checking the current character were coded for the fword() |
115 |
|
|
* function -- once the other word routines are converted, they may have |
116 |
|
|
* to change. |
117 |
|
|
* |
118 |
|
|
* PUBLIC: int cs_fspace(SCR *, VCS *); |
119 |
|
|
*/ |
120 |
|
|
int |
121 |
|
|
cs_fspace(SCR *sp, VCS *csp) |
122 |
|
|
{ |
123 |
|
|
if (csp->cs_flags != 0 || !isblank(csp->cs_ch)) |
124 |
|
|
return (0); |
125 |
|
|
for (;;) { |
126 |
|
|
if (cs_next(sp, csp)) |
127 |
|
|
return (1); |
128 |
|
|
if (csp->cs_flags != 0 || !isblank(csp->cs_ch)) |
129 |
|
|
break; |
130 |
|
|
} |
131 |
|
|
return (0); |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
/* |
135 |
|
|
* cs_fblank -- |
136 |
|
|
* Eat forward to the next non-whitespace character. |
137 |
|
|
* |
138 |
|
|
* PUBLIC: int cs_fblank(SCR *, VCS *); |
139 |
|
|
*/ |
140 |
|
|
int |
141 |
|
|
cs_fblank(SCR *sp, VCS *csp) |
142 |
|
|
{ |
143 |
|
|
for (;;) { |
144 |
|
|
if (cs_next(sp, csp)) |
145 |
|
|
return (1); |
146 |
|
|
if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP || |
147 |
|
|
(csp->cs_flags == 0 && isblank(csp->cs_ch))) |
148 |
|
|
continue; |
149 |
|
|
break; |
150 |
|
|
} |
151 |
|
|
return (0); |
152 |
|
|
} |
153 |
|
|
|
154 |
|
|
/* |
155 |
|
|
* cs_prev -- |
156 |
|
|
* Retrieve the previous character. |
157 |
|
|
* |
158 |
|
|
* PUBLIC: int cs_prev(SCR *, VCS *); |
159 |
|
|
*/ |
160 |
|
|
int |
161 |
|
|
cs_prev(SCR *sp, VCS *csp) |
162 |
|
|
{ |
163 |
|
|
switch (csp->cs_flags) { |
164 |
|
|
case CS_EMP: /* EMP; get previous line. */ |
165 |
|
|
case CS_EOL: /* EOL; get previous line. */ |
166 |
|
|
if (csp->cs_lno == 1) { /* SOF. */ |
167 |
|
|
csp->cs_flags = CS_SOF; |
168 |
|
|
break; |
169 |
|
|
} |
170 |
|
|
if (db_get(sp, /* The line should exist. */ |
171 |
|
|
--csp->cs_lno, DBG_FATAL, (char **) &csp->cs_bp, |
172 |
|
|
&csp->cs_len)) { |
173 |
|
|
++csp->cs_lno; |
174 |
|
|
return (1); |
175 |
|
|
} |
176 |
|
|
if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) { |
177 |
|
|
csp->cs_cno = 0; |
178 |
|
|
csp->cs_flags = CS_EMP; |
179 |
|
|
} else { |
180 |
|
|
csp->cs_flags = 0; |
181 |
|
|
csp->cs_cno = csp->cs_len - 1; |
182 |
|
|
csp->cs_ch = csp->cs_bp[csp->cs_cno]; |
183 |
|
|
} |
184 |
|
|
break; |
185 |
|
|
case CS_EOF: /* EOF: get previous char. */ |
186 |
|
|
case 0: |
187 |
|
|
if (csp->cs_cno == 0) |
188 |
|
|
if (csp->cs_lno == 1) |
189 |
|
|
csp->cs_flags = CS_SOF; |
190 |
|
|
else |
191 |
|
|
csp->cs_flags = CS_EOL; |
192 |
|
|
else |
193 |
|
|
csp->cs_ch = csp->cs_bp[--csp->cs_cno]; |
194 |
|
|
break; |
195 |
|
|
case CS_SOF: /* SOF. */ |
196 |
|
|
break; |
197 |
|
|
default: |
198 |
|
|
abort(); |
199 |
|
|
/* NOTREACHED */ |
200 |
|
|
} |
201 |
|
|
return (0); |
202 |
|
|
} |
203 |
|
|
|
204 |
|
|
/* |
205 |
|
|
* cs_bblank -- |
206 |
|
|
* Eat backward to the next non-whitespace character. |
207 |
|
|
* |
208 |
|
|
* PUBLIC: int cs_bblank(SCR *, VCS *); |
209 |
|
|
*/ |
210 |
|
|
int |
211 |
|
|
cs_bblank(SCR *sp, VCS *csp) |
212 |
|
|
{ |
213 |
|
|
for (;;) { |
214 |
|
|
if (cs_prev(sp, csp)) |
215 |
|
|
return (1); |
216 |
|
|
if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP || |
217 |
|
|
(csp->cs_flags == 0 && isblank(csp->cs_ch))) |
218 |
|
|
continue; |
219 |
|
|
break; |
220 |
|
|
} |
221 |
|
|
return (0); |
222 |
|
|
} |