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