* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)getc.c 8.6 (Berkeley) 10/26/93";
* Character stream routines --
* These routines return the file a character at a time. There are two
* special cases. First, the end of a line, end of a file, start of a
* file and empty lines are returned as special cases, and no character
* is returned. Second, empty lines include lines that have only white
* space in them, because the vi search functions don't care about white
* space, and this makes it easier for them to be consistent.
* Initialize character stream routines.
file_gline(sp
, ep
, csp
->cs_lno
, &csp
->cs_len
)) == NULL
) {
if (file_lline(sp
, ep
, &lno
))
msgq(sp
, M_BERR
, "Empty file.");
GETLINE_ERR(sp
, csp
->cs_lno
);
if (csp
->cs_len
== 0 || v_isempty(csp
->cs_bp
, csp
->cs_len
)) {
csp
->cs_ch
= csp
->cs_bp
[csp
->cs_cno
];
* Retrieve the next character.
case CS_EMP
: /* EMP; get next line. */
case CS_EOL
: /* EOL; get next line. */
slno
= csp
->cs_lno
; /* Save current line. */
file_gline(sp
, ep
, ++csp
->cs_lno
, &csp
->cs_len
)) == NULL
) {
if (file_lline(sp
, ep
, &slno
))
if (slno
> csp
->cs_lno
) {
GETLINE_ERR(sp
, csp
->cs_lno
);
} else if (csp
->cs_len
== 0 ||
v_isempty(csp
->cs_bp
, csp
->cs_len
)) {
csp
->cs_ch
= csp
->cs_bp
[csp
->cs_cno
= 0];
if (csp
->cs_cno
== csp
->cs_len
- 1)
csp
->cs_ch
= csp
->cs_bp
[++csp
->cs_cno
];
case CS_EOF
: /* EOF; only returned once. */
* If on a space, eat forward until something other than a
* Semantics of checking the current character were coded for the fword()
* function -- once the other word routines are converted, they may have
if (csp
->cs_flags
!= 0 || !isblank(csp
->cs_ch
))
if (cs_next(sp
, ep
, csp
))
if (csp
->cs_flags
!= 0 || !isblank(csp
->cs_ch
))
* Eat forward to the next non-whitespace character.
if (cs_next(sp
, ep
, csp
))
if (csp
->cs_flags
== CS_EOL
|| csp
->cs_flags
== CS_EMP
||
csp
->cs_flags
== 0 && isblank(csp
->cs_ch
))
* Retrieve the previous character.
case CS_EMP
: /* EMP; get previous line. */
case CS_EOL
: /* EOL; get previous line. */
if (csp
->cs_lno
== 1) { /* SOF. */
slno
= csp
->cs_lno
; /* Save current line. */
if ((csp
->cs_bp
= /* Line should exist. */
file_gline(sp
, ep
, --csp
->cs_lno
, &csp
->cs_len
)) == NULL
) {
GETLINE_ERR(sp
, csp
->cs_lno
);
if (csp
->cs_len
== 0 || v_isempty(csp
->cs_bp
, csp
->cs_len
)) {
csp
->cs_cno
= csp
->cs_len
- 1;
csp
->cs_ch
= csp
->cs_bp
[csp
->cs_cno
];
csp
->cs_ch
= csp
->cs_bp
[--csp
->cs_cno
];
case CS_SOF
: /* SOF; only returned once. */
* Eat backward to the next non-whitespace character.
if (cs_prev(sp
, ep
, csp
))
if (csp
->cs_flags
== CS_EOL
|| csp
->cs_flags
== CS_EMP
||
csp
->cs_flags
== 0 && isblank(csp
->cs_ch
))