source: trunk/third/nvi/vi/getc.c @ 14302

Revision 14302, 4.7 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14301, which included commits to RCS files with non-trunk default branches.
RevLine 
[14301]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.
6 *
7 * See the LICENSE file for redistribution information.
8 */
9
10#include "config.h"
11
12#ifndef lint
13static const char sccsid[] = "@(#)getc.c        10.10 (Berkeley) 3/6/96";
14#endif /* not lint */
15
16#include <sys/types.h>
17#include <sys/queue.h>
18#include <sys/time.h>
19
20#include <bitstring.h>
21#include <ctype.h>
22#include <limits.h>
23#include <stdio.h>
24#include <stdlib.h>
25
26#include "../common/common.h"
27#include "vi.h"
28
29/*
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.
37 */
38
39/*
40 * cs_init --
41 *      Initialize character stream routines.
42 *
43 * PUBLIC: int cs_init __P((SCR *, VCS *));
44 */
45int
46cs_init(sp, csp)
47        SCR *sp;
48        VCS *csp;
49{
50        int isempty;
51
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);
56        }
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];
63        }
64        return (0);
65}
66
67/*
68 * cs_next --
69 *      Retrieve the next character.
70 *
71 * PUBLIC: int cs_next __P((SCR *, VCS *));
72 */
73int
74cs_next(sp, csp)
75        SCR *sp;
76        VCS *csp;
77{
78        char *p;
79
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];
95                        }
96                }
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 */
109        }
110        return (0);
111}
112
113/*
114 * cs_fspace --
115 *      If on a space, eat forward until something other than a
116 *      whitespace character.
117 *
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.
122 *
123 * PUBLIC: int cs_fspace __P((SCR *, VCS *));
124 */
125int
126cs_fspace(sp, csp)
127        SCR *sp;
128        VCS *csp;
129{
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;
137        }
138        return (0);
139}
140
141/*
142 * cs_fblank --
143 *      Eat forward to the next non-whitespace character.
144 *
145 * PUBLIC: int cs_fblank __P((SCR *, VCS *));
146 */
147int
148cs_fblank(sp, csp)
149        SCR *sp;
150        VCS *csp;
151{
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;
159        }
160        return (0);
161}
162
163/*
164 * cs_prev --
165 *      Retrieve the previous character.
166 *
167 * PUBLIC: int cs_prev __P((SCR *, VCS *));
168 */
169int
170cs_prev(sp, csp)
171        SCR *sp;
172        VCS *csp;
173{
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;
180                }
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);
185                }
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];
193                }
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 */
210        }
211        return (0);
212}
213
214/*
215 * cs_bblank --
216 *      Eat backward to the next non-whitespace character.
217 *
218 * PUBLIC: int cs_bblank __P((SCR *, VCS *));
219 */
220int
221cs_bblank(sp, csp)
222        SCR *sp;
223        VCS *csp;
224{
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;
232        }
233        return (0);
234}
Note: See TracBrowser for help on using the repository browser.