[BACK]Return to input.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / more

Annotation of src/usr.bin/more/input.c, Revision 1.1

1.1     ! deraadt     1: /*
        !             2:  * Copyright (c) 1988 Mark Nudleman
        !             3:  * Copyright (c) 1988 Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  * 3. All advertising materials mentioning features or use of this software
        !            15:  *    must display the following acknowledgement:
        !            16:  *     This product includes software developed by the University of
        !            17:  *     California, Berkeley and its contributors.
        !            18:  * 4. Neither the name of the University nor the names of its contributors
        !            19:  *    may be used to endorse or promote products derived from this software
        !            20:  *    without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            32:  * SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35: #ifndef lint
        !            36: /* from: static char sccsid[] = "@(#)input.c   5.4 (Berkeley) 6/1/90"; */
        !            37: static char *rcsid = "$Id: input.c,v 1.2 1993/11/09 05:09:07 cgd Exp $";
        !            38: #endif /* not lint */
        !            39:
        !            40: /*
        !            41:  * High level routines dealing with getting lines of input
        !            42:  * from the file being viewed.
        !            43:  *
        !            44:  * When we speak of "lines" here, we mean PRINTABLE lines;
        !            45:  * lines processed with respect to the screen width.
        !            46:  * We use the term "raw line" to refer to lines simply
        !            47:  * delimited by newlines; not processed with respect to screen width.
        !            48:  */
        !            49:
        !            50: #include <sys/types.h>
        !            51: #include <less.h>
        !            52:
        !            53: extern int squeeze;
        !            54: extern int sigs;
        !            55: extern char *line;
        !            56:
        !            57: off_t ch_tell();
        !            58:
        !            59: /*
        !            60:  * Get the next line.
        !            61:  * A "current" position is passed and a "new" position is returned.
        !            62:  * The current position is the position of the first character of
        !            63:  * a line.  The new position is the position of the first character
        !            64:  * of the NEXT line.  The line obtained is the line starting at curr_pos.
        !            65:  */
        !            66: off_t
        !            67: forw_line(curr_pos)
        !            68:        off_t curr_pos;
        !            69: {
        !            70:        off_t new_pos;
        !            71:        register int c;
        !            72:
        !            73:        if (curr_pos == NULL_POSITION || ch_seek(curr_pos))
        !            74:                return (NULL_POSITION);
        !            75:
        !            76:        c = ch_forw_get();
        !            77:        if (c == EOI)
        !            78:                return (NULL_POSITION);
        !            79:
        !            80:        prewind();
        !            81:        for (;;)
        !            82:        {
        !            83:                if (sigs)
        !            84:                        return (NULL_POSITION);
        !            85:                if (c == '\n' || c == EOI)
        !            86:                {
        !            87:                        /*
        !            88:                         * End of the line.
        !            89:                         */
        !            90:                        new_pos = ch_tell();
        !            91:                        break;
        !            92:                }
        !            93:
        !            94:                /*
        !            95:                 * Append the char to the line and get the next char.
        !            96:                 */
        !            97:                if (pappend(c))
        !            98:                {
        !            99:                        /*
        !           100:                         * The char won't fit in the line; the line
        !           101:                         * is too long to print in the screen width.
        !           102:                         * End the line here.
        !           103:                         */
        !           104:                        new_pos = ch_tell() - 1;
        !           105:                        break;
        !           106:                }
        !           107:                c = ch_forw_get();
        !           108:        }
        !           109:        (void) pappend('\0');
        !           110:
        !           111:        if (squeeze && *line == '\0')
        !           112:        {
        !           113:                /*
        !           114:                 * This line is blank.
        !           115:                 * Skip down to the last contiguous blank line
        !           116:                 * and pretend it is the one which we are returning.
        !           117:                 */
        !           118:                while ((c = ch_forw_get()) == '\n')
        !           119:                        if (sigs)
        !           120:                                return (NULL_POSITION);
        !           121:                if (c != EOI)
        !           122:                        (void) ch_back_get();
        !           123:                new_pos = ch_tell();
        !           124:        }
        !           125:
        !           126:        return (new_pos);
        !           127: }
        !           128:
        !           129: /*
        !           130:  * Get the previous line.
        !           131:  * A "current" position is passed and a "new" position is returned.
        !           132:  * The current position is the position of the first character of
        !           133:  * a line.  The new position is the position of the first character
        !           134:  * of the PREVIOUS line.  The line obtained is the one starting at new_pos.
        !           135:  */
        !           136: off_t
        !           137: back_line(curr_pos)
        !           138:        off_t curr_pos;
        !           139: {
        !           140:        off_t new_pos, begin_new_pos;
        !           141:        int c;
        !           142:
        !           143:        if (curr_pos == NULL_POSITION || curr_pos <= (off_t)0 ||
        !           144:                ch_seek(curr_pos-1))
        !           145:                return (NULL_POSITION);
        !           146:
        !           147:        if (squeeze)
        !           148:        {
        !           149:                /*
        !           150:                 * Find out if the "current" line was blank.
        !           151:                 */
        !           152:                (void) ch_forw_get();   /* Skip the newline */
        !           153:                c = ch_forw_get();      /* First char of "current" line */
        !           154:                (void) ch_back_get();   /* Restore our position */
        !           155:                (void) ch_back_get();
        !           156:
        !           157:                if (c == '\n')
        !           158:                {
        !           159:                        /*
        !           160:                         * The "current" line was blank.
        !           161:                         * Skip over any preceeding blank lines,
        !           162:                         * since we skipped them in forw_line().
        !           163:                         */
        !           164:                        while ((c = ch_back_get()) == '\n')
        !           165:                                if (sigs)
        !           166:                                        return (NULL_POSITION);
        !           167:                        if (c == EOI)
        !           168:                                return (NULL_POSITION);
        !           169:                        (void) ch_forw_get();
        !           170:                }
        !           171:        }
        !           172:
        !           173:        /*
        !           174:         * Scan backwards until we hit the beginning of the line.
        !           175:         */
        !           176:        for (;;)
        !           177:        {
        !           178:                if (sigs)
        !           179:                        return (NULL_POSITION);
        !           180:                c = ch_back_get();
        !           181:                if (c == '\n')
        !           182:                {
        !           183:                        /*
        !           184:                         * This is the newline ending the previous line.
        !           185:                         * We have hit the beginning of the line.
        !           186:                         */
        !           187:                        new_pos = ch_tell() + 1;
        !           188:                        break;
        !           189:                }
        !           190:                if (c == EOI)
        !           191:                {
        !           192:                        /*
        !           193:                         * We have hit the beginning of the file.
        !           194:                         * This must be the first line in the file.
        !           195:                         * This must, of course, be the beginning of the line.
        !           196:                         */
        !           197:                        new_pos = ch_tell();
        !           198:                        break;
        !           199:                }
        !           200:        }
        !           201:
        !           202:        /*
        !           203:         * Now scan forwards from the beginning of this line.
        !           204:         * We keep discarding "printable lines" (based on screen width)
        !           205:         * until we reach the curr_pos.
        !           206:         *
        !           207:         * {{ This algorithm is pretty inefficient if the lines
        !           208:         *    are much longer than the screen width,
        !           209:         *    but I don't know of any better way. }}
        !           210:         */
        !           211:        if (ch_seek(new_pos))
        !           212:                return (NULL_POSITION);
        !           213:     loop:
        !           214:        begin_new_pos = new_pos;
        !           215:        prewind();
        !           216:
        !           217:        do
        !           218:        {
        !           219:                c = ch_forw_get();
        !           220:                if (c == EOI || sigs)
        !           221:                        return (NULL_POSITION);
        !           222:                new_pos++;
        !           223:                if (c == '\n')
        !           224:                        break;
        !           225:                if (pappend(c))
        !           226:                {
        !           227:                        /*
        !           228:                         * Got a full printable line, but we haven't
        !           229:                         * reached our curr_pos yet.  Discard the line
        !           230:                         * and start a new one.
        !           231:                         */
        !           232:                        (void) pappend('\0');
        !           233:                        (void) ch_back_get();
        !           234:                        new_pos--;
        !           235:                        goto loop;
        !           236:                }
        !           237:        } while (new_pos < curr_pos);
        !           238:
        !           239:        (void) pappend('\0');
        !           240:
        !           241:        return (begin_new_pos);
        !           242: }