Annotation of 43BSD/contrib/mh/miscellany/less/input.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.