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