1: /*
   2:  * High level routines dealing with getting lines of input
   3:  * from the file being viewed.
   4:  *
   5:  * When we speak of "lines" here, we mean PRINTABLE lines;
   6:  * lines processed with respect to the screen width.
   7:  * We use the term "raw line" to refer to lines simply
   8:  * delimited by newlines; not processed with respect to screen width.
   9:  */
  10: 
  11: #include "less.h"
  12: 
  13: extern int squeeze;
  14: extern char *line;
  15: 
  16: /*
  17:  * Get the next line.
  18:  * A "current" position is passed and a "new" position is returned.
  19:  * The current position is the position of the first character of
  20:  * a line.  The new position is the position of the first character
  21:  * of the NEXT line.  The line obtained is the line starting at curr_pos.
  22:  */
  23:     public POSITION
  24: forw_line(curr_pos)
  25:     POSITION curr_pos;
  26: {
  27:     POSITION new_pos;
  28:     register int c;
  29: 
  30:     if (curr_pos == NULL_POSITION || ch_seek(curr_pos))
  31:         return (NULL_POSITION);
  32: 
  33:     c = ch_forw_get();
  34:     if (c == EOF)
  35:         return (NULL_POSITION);
  36: 
  37:     prewind();
  38:     for (;;)
  39:     {
  40:         if (c == '\n' || c == EOF)
  41:         {
  42:             /*
  43: 			 * End of the line.
  44: 			 */
  45:             new_pos = ch_tell();
  46:             break;
  47:         }
  48: 
  49:         /*
  50: 		 * Append the char to the line and get the next char.
  51: 		 */
  52:         if (pappend(c))
  53:         {
  54:             /*
  55: 			 * The char won't fit in the line; the line
  56: 			 * is too long to print in the screen width.
  57: 			 * End the line here.
  58: 			 */
  59:             new_pos = ch_tell() - 1;
  60:             break;
  61:         }
  62:         c = ch_forw_get();
  63:     }
  64:     (void) pappend('\0');
  65: 
  66:     if (squeeze && *line == '\0')
  67:     {
  68:         /*
  69: 		 * This line is blank.
  70: 		 * Skip down to the last contiguous blank line
  71: 		 * and pretend it is the one which we are returning.
  72: 		 */
  73:         while ((c = ch_forw_get()) == '\n')
  74:             ;
  75:         if (c != EOF)
  76:             (void) ch_back_get();
  77:         new_pos = ch_tell();
  78:     }
  79: 
  80:     return (new_pos);
  81: }
  82: 
  83: /*
  84:  * Get the previous line.
  85:  * A "current" position is passed and a "new" position is returned.
  86:  * The current position is the position of the first character of
  87:  * a line.  The new position is the position of the first character
  88:  * of the PREVIOUS line.  The line obtained is the one starting at new_pos.
  89:  */
  90:     public POSITION
  91: back_line(curr_pos)
  92:     POSITION curr_pos;
  93: {
  94:     POSITION new_pos, begin_new_pos;
  95:     int c;
  96: 
  97:     if (curr_pos == NULL_POSITION || curr_pos <= (POSITION)0 ||
  98:         ch_seek(curr_pos-1))
  99:         return (NULL_POSITION);
 100: 
 101:     if (squeeze)
 102:     {
 103:         /*
 104: 		 * Find out if the "current" line was blank.
 105: 		 */
 106:         (void) ch_forw_get();   /* Skip the newline */
 107:         c = ch_forw_get();  /* First char of "current" line */
 108:         (void) ch_back_get();   /* Restore our position */
 109:         (void) ch_back_get();
 110: 
 111:         if (c == '\n')
 112:         {
 113:             /*
 114: 			 * The "current" line was blank.
 115: 			 * Skip over any preceeding blank lines,
 116: 			 * since we skipped them in forw_line().
 117: 			 */
 118:             while ((c = ch_back_get()) == '\n')
 119:                 ;
 120:             if (c == EOF)
 121:                 return (NULL_POSITION);
 122:             (void) ch_forw_get();
 123:         }
 124:     }
 125: 
 126:     /*
 127: 	 * Scan backwards until we hit the beginning of the line.
 128: 	 */
 129:     for (;;)
 130:     {
 131:         c = ch_back_get();
 132:         if (c == '\n')
 133:         {
 134:             /*
 135: 			 * This is the newline ending the previous line.
 136: 			 * We have hit the beginning of the line.
 137: 			 */
 138:             new_pos = ch_tell() + 1;
 139:             break;
 140:         }
 141:         if (c == EOF)
 142:         {
 143:             /*
 144: 			 * We have hit the beginning of the file.
 145: 			 * This must be the first line in the file.
 146: 			 * This must, of course, be the beginning of the line.
 147: 			 */
 148:             new_pos = ch_tell();
 149:             break;
 150:         }
 151:     }
 152: 
 153:     /*
 154: 	 * Now scan forwards from the beginning of this line.
 155: 	 * We keep discarding "printable lines" (based on screen width)
 156: 	 * until we reach the curr_pos.
 157: 	 *
 158: 	 * {{ This algorithm is pretty inefficient if the lines
 159: 	 *    are much longer than the screen width,
 160: 	 *    but I don't know of any better way. }}
 161: 	 */
 162:     if (ch_seek(new_pos))
 163:         return (NULL_POSITION);
 164:     loop:
 165:     begin_new_pos = new_pos;
 166:     prewind();
 167: 
 168:     do
 169:     {
 170:         c = ch_forw_get();
 171:         new_pos++;
 172:         if (c == '\n')
 173:             break;
 174:         if (pappend(c))
 175:         {
 176:             /*
 177: 			 * Got a full printable line, but we haven't
 178: 			 * reached our curr_pos yet.  Discard the line
 179: 			 * and start a new one.
 180: 			 */
 181:             (void) pappend('\0');
 182:             (void) ch_back_get();
 183:             new_pos--;
 184:             goto loop;
 185:         }
 186:     } while (new_pos < curr_pos);
 187: 
 188:     (void) pappend('\0');
 189: 
 190:     return (begin_new_pos);
 191: }

Defined functions

back_line defined in line 90; used 3 times
forw_line defined in line 23; used 2 times
Last modified: 1990-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2319
Valid CSS Valid XHTML 1.0 Strict