home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 036 / less232.zip / JUMP.C < prev    next >
C/C++ Source or Header  |  1994-08-17  |  6KB  |  291 lines

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