home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / GNU / LES177AS.ZIP / INPUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-04  |  5.3 KB  |  271 lines

  1. /*
  2.  * High level routines dealing with getting lines of input 
  3.  * from the file being viewed.
  4.  *
  5.  * When we speak of "lines" here, we mean PRINTABLE lines;
  6.  * lines processed with respect to the screen width.
  7.  * We use the term "raw line" to refer to lines simply
  8.  * delimited by newlines; not processed with respect to screen width.
  9.  */
  10.  
  11. #include "less.h"
  12.  
  13. extern int squeeze;
  14. extern int chopline;
  15. extern int sigs;
  16.  
  17. /*
  18.  * Get the next line.
  19.  * A "current" position is passed and a "new" position is returned.
  20.  * The current position is the position of the first character of
  21.  * a line.  The new position is the position of the first character
  22.  * of the NEXT line.  The line obtained is the line starting at curr_pos.
  23.  */
  24.     public POSITION
  25. forw_line(curr_pos)
  26.     POSITION curr_pos;
  27. {
  28.     POSITION new_pos;
  29.     register int c;
  30.     int blankline;
  31.     int endline;
  32.  
  33.     if (curr_pos == NULL_POSITION || ch_seek(curr_pos))
  34.     {
  35.         null_line();
  36.         return (NULL_POSITION);
  37.     }
  38.  
  39.     prewind();
  40.     plinenum(curr_pos);
  41.     (void) ch_seek(curr_pos);
  42.  
  43.     c = ch_forw_get();
  44.     if (c == EOI)
  45.     {
  46.         null_line();
  47.         return (NULL_POSITION);
  48.     }
  49.     blankline = (c == '\n' || c == '\r');
  50.  
  51.     for (;;)
  52.     {
  53.         if (sigs)
  54.         {
  55.             null_line();
  56.             return (NULL_POSITION);
  57.         }
  58.         if (c == '\n' || c == EOI)
  59.         {
  60.             /*
  61.              * End of the line.
  62.              */
  63.             new_pos = ch_tell();
  64.             endline = 1;
  65.             break;
  66.         }
  67.  
  68.         /*
  69.          * Append the char to the line and get the next char.
  70.          */
  71.         if (pappend(c))
  72.         {
  73.             /*
  74.              * The char won't fit in the line; the line
  75.              * is too long to print in the screen width.
  76.              * End the line here.
  77.              */
  78.             if (chopline)
  79.             {
  80.                 do
  81.                 {
  82.                     c = ch_forw_get();
  83.                 } while (c != '\n' && c != EOI);
  84.                 new_pos = ch_tell();
  85.                 endline = 1;
  86.             } else
  87.             {
  88.                 new_pos = ch_tell() - 1;
  89.                 endline = 0;
  90.             }
  91.             break;
  92.         }
  93.         c = ch_forw_get();
  94.     }
  95.     pdone(endline);
  96.  
  97.     if (squeeze && blankline)
  98.     {
  99.         /*
  100.          * This line is blank.
  101.          * Skip down to the last contiguous blank line
  102.          * and pretend it is the one which we are returning.
  103.          */
  104.         while ((c = ch_forw_get()) == '\n' || c == '\r')
  105.             if (sigs)
  106.             {
  107.                 null_line();
  108.                 return (NULL_POSITION);
  109.             }
  110.         if (c != EOI)
  111.             (void) ch_back_get();
  112.         new_pos = ch_tell();
  113.     }
  114.  
  115.     return (new_pos);
  116. }
  117.  
  118. /*
  119.  * Get the previous line.
  120.  * A "current" position is passed and a "new" position is returned.
  121.  * The current position is the position of the first character of
  122.  * a line.  The new position is the position of the first character
  123.  * of the PREVIOUS line.  The line obtained is the one starting at new_pos.
  124.  */
  125.     public POSITION
  126. back_line(curr_pos)
  127.     POSITION curr_pos;
  128. {
  129.     POSITION new_pos, begin_new_pos;
  130.     int c;
  131.     int endline;
  132.  
  133.     if (curr_pos == NULL_POSITION || curr_pos <= ch_zero() ||
  134.         ch_seek(curr_pos-1))
  135.     {
  136.         null_line();
  137.         return (NULL_POSITION);
  138.     }
  139.  
  140.     /*
  141.      * Scan backwards until we hit the beginning of the line.
  142.      */
  143.     for (;;)
  144.     {
  145.         if (sigs)
  146.         {
  147.             null_line();
  148.             return (NULL_POSITION);
  149.         }
  150.         c = ch_back_get();
  151.         if (c == '\n')
  152.         {
  153.             /*
  154.              * This is the newline ending the previous line.
  155.              * We have hit the beginning of the line.
  156.              */
  157.             new_pos = ch_tell() + 1;
  158.             break;
  159.         }
  160.         if (c == EOI)
  161.         {
  162.             /*
  163.              * We have hit the beginning of the file.
  164.              * This must be the first line in the file.
  165.              * This must, of course, be the beginning of the line.
  166.              */
  167.             new_pos = ch_tell();
  168.             break;
  169.         }
  170.     }
  171.  
  172.     if (squeeze && c != EOI)
  173.     {
  174.         /*
  175.          * Find out if the "new" line is blank.
  176.          */
  177.         (void) ch_forw_get();   /* Skip the newline */
  178.         c = ch_forw_get();      /* First char of "new" line */
  179.  
  180.         if (c == '\n' || c == '\r')
  181.         {
  182.             /*
  183.              * The "new" line is blank.
  184.              * Skip over any preceding blank lines,
  185.              * since we skipped them in forw_line().
  186.              */
  187.             while ((c = ch_back_get()) == '\n' || c == '\r')
  188.                 if (sigs)
  189.                 {
  190.                     null_line();
  191.                     return (NULL_POSITION);
  192.                 }
  193.             if (c != EOI)
  194.             {
  195.                 /*
  196.                  * We're near the end of a non-blank line.
  197.                  * Get to the beginning of the blank lines
  198.                  * that come after it.
  199.                  */
  200.                 (void) ch_forw_get();
  201.                 while (ch_forw_get() == '\r')
  202.                     if (sigs)
  203.                     {
  204.                         null_line();
  205.                         return (NULL_POSITION);
  206.                     }
  207.             }
  208.             new_pos = ch_tell();
  209.  
  210.         }
  211.     }
  212.  
  213.     /*
  214.      * Now scan forwards from the beginning of this line.
  215.      * We keep discarding "printable lines" (based on screen width)
  216.      * until we reach the curr_pos.
  217.      *
  218.      * {{ This algorithm is pretty inefficient if the lines
  219.      *    are much longer than the screen width, 
  220.      *    but I don't know of any better way. }}
  221.      */
  222.     if (ch_seek(new_pos))
  223.     {
  224.         null_line();
  225.         return (NULL_POSITION);
  226.     }
  227.     endline = 0;
  228.     loop:
  229.     begin_new_pos = new_pos;
  230.     prewind();
  231.     plinenum(new_pos);
  232.     (void) ch_seek(new_pos);
  233.  
  234.     do
  235.     {
  236.         c = ch_forw_get();
  237.         if (c == EOI || sigs)
  238.         {
  239.             null_line();
  240.             return (NULL_POSITION);
  241.         }
  242.         new_pos++;
  243.         if (c == '\n')
  244.         {
  245.             endline = 1;
  246.             break;
  247.         }
  248.         if (pappend(c))
  249.         {
  250.             /*
  251.              * Got a full printable line, but we haven't
  252.              * reached our curr_pos yet.  Discard the line
  253.              * and start a new one.
  254.              */
  255.             if (chopline)
  256.             {
  257.                 endline = 1;
  258.                 break;
  259.             }
  260.             pdone(0);
  261.             (void) ch_back_get();
  262.             new_pos--;
  263.             goto loop;
  264.         }
  265.     } while (new_pos < curr_pos);
  266.  
  267.     pdone(endline);
  268.  
  269.     return (begin_new_pos);
  270. }
  271.