1 /* $NetBSD: input.c,v 1.5 2003/08/07 09:27:59 agc Exp $ */
4 * Copyright (c) 1988 Mark Nudelman
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
36 static char sccsid
[] = "@(#)input.c 8.1 (Berkeley) 6/6/93";
38 __RCSID("$NetBSD: input.c,v 1.5 2003/08/07 09:27:59 agc Exp $");
43 * High level routines dealing with getting lines of input
44 * from the file being viewed.
46 * When we speak of "lines" here, we mean PRINTABLE lines;
47 * lines processed with respect to the screen width.
48 * We use the term "raw line" to refer to lines simply
49 * delimited by newlines; not processed with respect to screen width.
52 #include <sys/types.h>
59 * A "current" position is passed and a "new" position is returned.
60 * The current position is the position of the first character of
61 * a line. The new position is the position of the first character
62 * of the NEXT line. The line obtained is the line starting at curr_pos.
71 if (curr_pos
== NULL_POSITION
|| ch_seek(curr_pos
))
72 return (NULL_POSITION
);
76 return (NULL_POSITION
);
82 return (NULL_POSITION
);
83 if (c
== '\n' || c
== EOI
)
93 * Append the char to the line and get the next char.
98 * The char won't fit in the line; the line
99 * is too long to print in the screen width.
102 new_pos
= ch_tell() - 1;
107 (void) pappend('\0');
109 if (squeeze
&& *line
== '\0')
112 * This line is blank.
113 * Skip down to the last contiguous blank line
114 * and pretend it is the one which we are returning.
116 while ((c
= ch_forw_get()) == '\n')
118 return (NULL_POSITION
);
120 (void) ch_back_get();
128 * Get the previous line.
129 * A "current" position is passed and a "new" position is returned.
130 * The current position is the position of the first character of
131 * a line. The new position is the position of the first character
132 * of the PREVIOUS line. The line obtained is the one starting at new_pos.
138 off_t new_pos
, begin_new_pos
;
141 if (curr_pos
== NULL_POSITION
|| curr_pos
<= (off_t
)0 ||
143 return (NULL_POSITION
);
148 * Find out if the "current" line was blank.
150 (void) ch_forw_get(); /* Skip the newline */
151 c
= ch_forw_get(); /* First char of "current" line */
152 (void) ch_back_get(); /* Restore our position */
153 (void) ch_back_get();
158 * The "current" line was blank.
159 * Skip over any preceding blank lines,
160 * since we skipped them in forw_line().
162 while ((c
= ch_back_get()) == '\n')
164 return (NULL_POSITION
);
166 return (NULL_POSITION
);
167 (void) ch_forw_get();
172 * Scan backwards until we hit the beginning of the line.
177 return (NULL_POSITION
);
182 * This is the newline ending the previous line.
183 * We have hit the beginning of the line.
185 new_pos
= ch_tell() + 1;
191 * We have hit the beginning of the file.
192 * This must be the first line in the file.
193 * This must, of course, be the beginning of the line.
201 * Now scan forwards from the beginning of this line.
202 * We keep discarding "printable lines" (based on screen width)
203 * until we reach the curr_pos.
205 * {{ This algorithm is pretty inefficient if the lines
206 * are much longer than the screen width,
207 * but I don't know of any better way. }}
209 if (ch_seek(new_pos
))
210 return (NULL_POSITION
);
212 begin_new_pos
= new_pos
;
218 if (c
== EOI
|| sigs
)
219 return (NULL_POSITION
);
226 * Got a full printable line, but we haven't
227 * reached our curr_pos yet. Discard the line
228 * and start a new one.
230 (void) pappend('\0');
231 (void) ch_back_get();
235 } while (new_pos
< curr_pos
);
237 (void) pappend('\0');
239 return (begin_new_pos
);