Annotation of 43BSD/contrib/mh/miscellany/less/input.c, revision 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.