home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / less_332.lzh / less_332 / jump.c < prev    next >
Text File  |  1998-03-03  |  7KB  |  293 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994,1995,1996  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.     pos = percent_pos(len, percent);
  137.     if (pos >= len)
  138.         pos = len-1;
  139.  
  140.     jump_line_loc(pos, jump_sline);
  141. }
  142.  
  143. /*
  144.  * Jump to a specified position in the file.
  145.  * Like jump_loc, but the position need not be 
  146.  * the first character in a line.
  147.  */
  148.     public void
  149. jump_line_loc(pos, sline)
  150.     POSITION pos;
  151.     int sline;
  152. {
  153.     int c;
  154.  
  155.     if (ch_seek(pos) == 0)
  156.     {
  157.         /*
  158.          * Back up to the beginning of the line.
  159.          */
  160.         while ((c = ch_back_get()) != '\n' && c != EOI)
  161.             ;
  162.         if (c == '\n')
  163.             (void) ch_forw_get();
  164.         pos = ch_tell();
  165.     }
  166.     jump_loc(pos, sline);
  167. }
  168.  
  169. /*
  170.  * Jump to a specified position in the file.
  171.  * The position must be the first character in a line.
  172.  * Place the target line on a specified line on the screen.
  173.  */
  174.     public void
  175. jump_loc(pos, sline)
  176.     POSITION pos;
  177.     int sline;
  178. {
  179.     register int nline;
  180.     POSITION tpos;
  181.     POSITION bpos;
  182.  
  183.     /*
  184.      * Normalize sline.
  185.      */
  186.     sline = adjsline(sline);
  187.  
  188.     if ((nline = onscreen(pos)) >= 0)
  189.     {
  190.         /*
  191.          * The line is currently displayed.  
  192.          * Just scroll there.
  193.          */
  194.         nline -= sline;
  195.         if (nline > 0)
  196.             forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
  197.         else
  198.             back(-nline, position(TOP), 1, 0);
  199.         return;
  200.     }
  201.  
  202.     /*
  203.      * Line is not on screen.
  204.      * Seek to the desired location.
  205.      */
  206.     if (ch_seek(pos))
  207.     {
  208.         error("Cannot seek to that file position", NULL_PARG);
  209.         return;
  210.     }
  211.  
  212.     /*
  213.      * See if the desired line is before or after 
  214.      * the currently displayed screen.
  215.      */
  216.     tpos = position(TOP);
  217.     bpos = position(BOTTOM_PLUS_ONE);
  218.     if (tpos == NULL_POSITION || pos >= tpos)
  219.     {
  220.         /*
  221.          * The desired line is after the current screen.
  222.          * Move back in the file far enough so that we can
  223.          * call forw() and put the desired line at the 
  224.          * sline-th line on the screen.
  225.          */
  226.         for (nline = 0;  nline < sline;  nline++)
  227.         {
  228.             if (bpos != NULL_POSITION && pos <= bpos)
  229.             {
  230.                 /*
  231.                  * Surprise!  The desired line is
  232.                  * close enough to the current screen
  233.                  * that we can just scroll there after all.
  234.                  */
  235.                 forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
  236.                 return;
  237.             }
  238.             pos = back_line(pos);
  239.             if (pos == NULL_POSITION)
  240.             {
  241.                 /*
  242.                  * Oops.  Ran into the beginning of the file.
  243.                  * Exit the loop here and rely on forw()
  244.                  * below to draw the required number of
  245.                  * blank lines at the top of the screen.
  246.                  */
  247.                 break;
  248.             }
  249.         }
  250.         lastmark();
  251.         hit_eof = 0;
  252.         squished = 0;
  253.         screen_trashed = 0;
  254.         forw(sc_height-1, pos, 1, 0, sline-nline);
  255.     } else
  256.     {
  257.         /*
  258.          * The desired line is before the current screen.
  259.          * Move forward in the file far enough so that we
  260.          * can call back() and put the desired line at the 
  261.          * sline-th line on the screen.
  262.          */
  263.         for (nline = sline;  nline < sc_height - 1;  nline++)
  264.         {
  265.             pos = forw_line(pos);
  266.             if (pos == NULL_POSITION)
  267.             {
  268.                 /*
  269.                  * Ran into end of file.
  270.                  * This shouldn't normally happen, 
  271.                  * but may if there is some kind of read error.
  272.                  */
  273.                 break;
  274.             }
  275.             if (pos >= tpos)
  276.             {
  277.                 /* 
  278.                  * Surprise!  The desired line is
  279.                  * close enough to the current screen
  280.                  * that we can just scroll there after all.
  281.                  */
  282.                 back(nline+1, tpos, 1, 0);
  283.                 return;
  284.             }
  285.         }
  286.         lastmark();
  287.         clear();
  288.         screen_trashed = 0;
  289.         add_back_pos(pos);
  290.         back(sc_height-1, pos, 1, 0);
  291.     }
  292. }
  293.