[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.2

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