home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- *** input.c (JJB TEMPLAR) ***
- *** Date modifications begun: 7/8/89. ***
- *** Last modified: 27/8/89. ***
- *************************************************************************/
- /*** High level routines dealing with getting lines of input from the ***
- *** file being viewed. When we speak of "lines" here, we mean ***
- *** PRINTABLE lines; lines processed with respect to the screen width.***
- *** We use the term "raw line" to refer to lines simply delimited by ***
- *** newlines; not processed with respect to screen width. ***
- *************************************************************************/
-
- #include "less.h"
-
- extern int do_bs;
- extern int squeeze;
- extern char *line;
-
- int page_break;
-
- LONG forw_line(curr_pos) /*===========================================*/
- LONG curr_pos; /* Get next line, given old position. */
- {
- LONG new_pos;
- register int c;
-
- if ((curr_pos == NULL_POSITION) || ch_seek(curr_pos)) return(NULL_POSITION);
- prewind();
- if (page_break) {
- new_pos = curr_pos;
- goto PAGE_SKIP;
- }
- if ((c = ch_forw_get()) == EOF) return(NULL_POSITION);
- if (c == '') { /* Must be first char on line */
- page_break = 1;
- }
-
- for (;;) {
- /* Check for EOF too, since file may not end with '\n' */
- if ((c == '\n') || (c == EOF)) {
- new_pos = ch_tell(); /* End of line */
- break;
- }
-
- /* Append the char to the line and get the next char. */
- if (pappend(c)) {
- /* The char won't fit in the line; the line
- is too long to print in the screen width.
- End the line here. */
- new_pos = ch_tell() - 1;
- break;
- }
- c = ch_forw_get();
- }
- PAGE_SKIP:
- pappend('\0');
-
- if (squeeze && !(*line) && !page_break) {
- /* This line is blank.
- Skip down to the last contiguous blank line
- and pretend it is the one which we are returning. */
- while ((c = ch_forw_get()) == '\n') ;
- if (c != EOF) ch_back_get();
- new_pos = ch_tell();
- }
- return(new_pos);
- }
-
- LONG back_line(curr_pos) /*===========================================*/
- LONG curr_pos; /* Get previous line. */
- {
- LONG new_pos, begin_new_pos;
- register int c;
-
- if ((curr_pos == NULL_POSITION) || (curr_pos <= 0) || ch_seek(curr_pos-1))
- return (NULL_POSITION);
-
- if (page_break) {
- begin_new_pos = curr_pos;
- prewind();
- goto PAGE_BREAK;
- }
-
- if (squeeze) { /* page_break disables squeeze */
- /* Find out if the "current" line was blank. */
- ch_forw_get(); /* Skip the newline */
- c = ch_forw_get(); /* First char of "current" line */
- ch_back_get(); /* Restore our position */
- ch_back_get();
-
- if (c == '\n') {
- /* The "current" line was blank.
- Skip over any preceeding blank lines,
- since we skipped them in forw_line(). */
- while ((c = ch_back_get()) == '\n') ;
- if (c == EOF) return (NULL_POSITION);
- ch_forw_get();
- }
- }
-
- /* Scan backwards until we hit the beginning of the line. */
- for (;;) {
- c = ch_back_get();
- if (c == '\n') {
- /* This is the newline ending the previous line.
- We have hit the beginning of the line. */
- new_pos = ch_tell() + 1;
- break;
- }
- if (c == EOF) {
- /* We have hit the beginning of the file.
- This must be the first line in the file.
- This must, of course, be the beginning of the line. */
- new_pos = 0;
- break;
- }
- }
-
- /* Now scan forwards from the beginning of this line.
- We keep discarding "printable lines" (based on screen width)
- until we reach the curr_pos. */
-
- if (ch_seek(new_pos)) return(NULL_POSITION);
- loop:
- begin_new_pos = new_pos;
- prewind();
-
- do {
- c = ch_forw_get();
- new_pos++;
- if (c == '\n') break;
- if (pappend(c)) {
- /* Got a full printable line, but we haven't reached our curr_pos yet.
- Discard the line and start a new one. */
- pappend('\0');
- ch_back_get();
- new_pos--;
- goto loop; /* Hey hey hey! */
- }
- } while (new_pos < curr_pos);
- PAGE_BREAK:
- pappend('\0');
-
- if (*line == '') page_break = 1;
-
- return(begin_new_pos);
- }
-