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

Annotation of src/usr.bin/less/jump.c, Revision 1.1

1.1     ! etheisen    1: /*
        !             2:  * Copyright (c) 1984,1985,1989,1994,1995  Mark Nudelman
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice in the documentation and/or other materials provided with
        !            12:  *    the distribution.
        !            13:  *
        !            14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
        !            15:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            16:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            17:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
        !            18:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            19:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
        !            20:  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
        !            21:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        !            22:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
        !            23:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
        !            24:  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            25:  */
        !            26:
        !            27:
        !            28: /*
        !            29:  * Routines which jump to a new location in the file.
        !            30:  */
        !            31:
        !            32: #include "less.h"
        !            33: #include "position.h"
        !            34:
        !            35: extern int hit_eof;
        !            36: extern int jump_sline;
        !            37: extern int squished;
        !            38: extern int screen_trashed;
        !            39: extern int sc_width, sc_height;
        !            40:
        !            41: /*
        !            42:  * Jump to the end of the file.
        !            43:  */
        !            44:        public void
        !            45: jump_forw()
        !            46: {
        !            47:        POSITION pos;
        !            48:
        !            49:        if (ch_end_seek())
        !            50:        {
        !            51:                error("Cannot seek to end of file", NULL_PARG);
        !            52:                return;
        !            53:        }
        !            54:        /*
        !            55:         * Position the last line in the file at the last screen line.
        !            56:         * Go back one line from the end of the file
        !            57:         * to get to the beginning of the last line.
        !            58:         */
        !            59:        pos = back_line(ch_tell());
        !            60:        if (pos == NULL_POSITION)
        !            61:                jump_loc((POSITION)0, sc_height-1);
        !            62:        else
        !            63:                jump_loc(pos, sc_height-1);
        !            64: }
        !            65:
        !            66: /*
        !            67:  * Jump to line n in the file.
        !            68:  */
        !            69:        public void
        !            70: jump_back(n)
        !            71:        int n;
        !            72: {
        !            73:        POSITION pos;
        !            74:        PARG parg;
        !            75:
        !            76:        /*
        !            77:         * Find the position of the specified line.
        !            78:         * If we can seek there, just jump to it.
        !            79:         * If we can't seek, but we're trying to go to line number 1,
        !            80:         * use ch_beg_seek() to get as close as we can.
        !            81:         */
        !            82:        pos = find_pos(n);
        !            83:        if (pos != NULL_POSITION && ch_seek(pos) == 0)
        !            84:        {
        !            85:                jump_loc(pos, jump_sline);
        !            86:        } else if (n <= 1 && ch_beg_seek() == 0)
        !            87:        {
        !            88:                jump_loc(ch_tell(), jump_sline);
        !            89:                error("Cannot seek to beginning of file", NULL_PARG);
        !            90:        } else
        !            91:        {
        !            92:                parg.p_int = n;
        !            93:                error("Cannot seek to line number %d", &parg);
        !            94:        }
        !            95: }
        !            96:
        !            97: /*
        !            98:  * Repaint the screen.
        !            99:  */
        !           100:        public void
        !           101: repaint()
        !           102: {
        !           103:        struct scrpos scrpos;
        !           104:        /*
        !           105:         * Start at the line currently at the top of the screen
        !           106:         * and redisplay the screen.
        !           107:         */
        !           108:        get_scrpos(&scrpos);
        !           109:        pos_clear();
        !           110:        jump_loc(scrpos.pos, scrpos.ln);
        !           111: }
        !           112:
        !           113: /*
        !           114:  * Jump to a specified percentage into the file.
        !           115:  */
        !           116:        public void
        !           117: jump_percent(percent)
        !           118:        int percent;
        !           119: {
        !           120:        POSITION pos, len;
        !           121:
        !           122:        /*
        !           123:         * Determine the position in the file
        !           124:         * (the specified percentage of the file's length).
        !           125:         */
        !           126:        if ((len = ch_length()) == NULL_POSITION)
        !           127:        {
        !           128:                ierror("Determining length of file", NULL_PARG);
        !           129:                ch_end_seek();
        !           130:        }
        !           131:        if ((len = ch_length()) == NULL_POSITION)
        !           132:        {
        !           133:                error("Don't know length of file", NULL_PARG);
        !           134:                return;
        !           135:        }
        !           136:        /*
        !           137:         * {{ This calculation may overflow! }}
        !           138:         */
        !           139:        pos = (percent * len) / 100;
        !           140:        if (pos >= len)
        !           141:                pos = len-1;
        !           142:
        !           143:        jump_line_loc(pos, jump_sline);
        !           144: }
        !           145:
        !           146: /*
        !           147:  * Jump to a specified position in the file.
        !           148:  * Like jump_loc, but the position need not be
        !           149:  * the first character in a line.
        !           150:  */
        !           151:        public void
        !           152: jump_line_loc(pos, sline)
        !           153:        POSITION pos;
        !           154:        int sline;
        !           155: {
        !           156:        int c;
        !           157:
        !           158:        if (ch_seek(pos) == 0)
        !           159:        {
        !           160:                /*
        !           161:                 * Back up to the beginning of the line.
        !           162:                 */
        !           163:                while ((c = ch_back_get()) != '\n' && c != EOI)
        !           164:                        ;
        !           165:                if (c == '\n')
        !           166:                        (void) ch_forw_get();
        !           167:                pos = ch_tell();
        !           168:        }
        !           169:        jump_loc(pos, sline);
        !           170: }
        !           171:
        !           172: /*
        !           173:  * Jump to a specified position in the file.
        !           174:  * The position must be the first character in a line.
        !           175:  * Place the target line on a specified line on the screen.
        !           176:  */
        !           177:        public void
        !           178: jump_loc(pos, sline)
        !           179:        POSITION pos;
        !           180:        int sline;
        !           181: {
        !           182:        register int nline;
        !           183:        POSITION tpos;
        !           184:        POSITION bpos;
        !           185:
        !           186:        /*
        !           187:         * Normalize sline.
        !           188:         */
        !           189:        sline = adjsline(sline);
        !           190:
        !           191:        if ((nline = onscreen(pos)) >= 0)
        !           192:        {
        !           193:                /*
        !           194:                 * The line is currently displayed.
        !           195:                 * Just scroll there.
        !           196:                 */
        !           197:                nline -= sline;
        !           198:                if (nline > 0)
        !           199:                        forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
        !           200:                else
        !           201:                        back(-nline, position(TOP), 1, 0);
        !           202:                return;
        !           203:        }
        !           204:
        !           205:        /*
        !           206:         * Line is not on screen.
        !           207:         * Seek to the desired location.
        !           208:         */
        !           209:        if (ch_seek(pos))
        !           210:        {
        !           211:                error("Cannot seek to that file position", NULL_PARG);
        !           212:                return;
        !           213:        }
        !           214:
        !           215:        /*
        !           216:         * See if the desired line is before or after
        !           217:         * the currently displayed screen.
        !           218:         */
        !           219:        tpos = position(TOP);
        !           220:        bpos = position(BOTTOM_PLUS_ONE);
        !           221:        if (tpos == NULL_POSITION || pos >= tpos)
        !           222:        {
        !           223:                /*
        !           224:                 * The desired line is after the current screen.
        !           225:                 * Move back in the file far enough so that we can
        !           226:                 * call forw() and put the desired line at the
        !           227:                 * sline-th line on the screen.
        !           228:                 */
        !           229:                for (nline = 0;  nline < sline;  nline++)
        !           230:                {
        !           231:                        if (bpos != NULL_POSITION && pos <= bpos)
        !           232:                        {
        !           233:                                /*
        !           234:                                 * Surprise!  The desired line is
        !           235:                                 * close enough to the current screen
        !           236:                                 * that we can just scroll there after all.
        !           237:                                 */
        !           238:                                forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
        !           239:                                return;
        !           240:                        }
        !           241:                        pos = back_line(pos);
        !           242:                        if (pos == NULL_POSITION)
        !           243:                        {
        !           244:                                /*
        !           245:                                 * Oops.  Ran into the beginning of the file.
        !           246:                                 * Exit the loop here and rely on forw()
        !           247:                                 * below to draw the required number of
        !           248:                                 * blank lines at the top of the screen.
        !           249:                                 */
        !           250:                                break;
        !           251:                        }
        !           252:                }
        !           253:                lastmark();
        !           254:                hit_eof = 0;
        !           255:                squished = 0;
        !           256:                screen_trashed = 0;
        !           257:                forw(sc_height-1, pos, 1, 0, sline-nline);
        !           258:        } else
        !           259:        {
        !           260:                /*
        !           261:                 * The desired line is before the current screen.
        !           262:                 * Move forward in the file far enough so that we
        !           263:                 * can call back() and put the desired line at the
        !           264:                 * sline-th line on the screen.
        !           265:                 */
        !           266:                for (nline = sline;  nline < sc_height - 1;  nline++)
        !           267:                {
        !           268:                        pos = forw_line(pos);
        !           269:                        if (pos == NULL_POSITION)
        !           270:                        {
        !           271:                                /*
        !           272:                                 * Ran into end of file.
        !           273:                                 * This shouldn't normally happen,
        !           274:                                 * but may if there is some kind of read error.
        !           275:                                 */
        !           276:                                break;
        !           277:                        }
        !           278:                        if (pos >= tpos)
        !           279:                        {
        !           280:                                /*
        !           281:                                 * Surprise!  The desired line is
        !           282:                                 * close enough to the current screen
        !           283:                                 * that we can just scroll there after all.
        !           284:                                 */
        !           285:                                back(nline+1, tpos, 1, 0);
        !           286:                                return;
        !           287:                        }
        !           288:                }
        !           289:                lastmark();
        !           290:                clear();
        !           291:                screen_trashed = 0;
        !           292:                add_back_pos(pos);
        !           293:                back(sc_height-1, pos, 1, 0);
        !           294:        }
        !           295: }