home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / most423.zip / buffer.c < prev    next >
C/C++ Source or Header  |  1994-01-28  |  10KB  |  455 lines

  1. #include <stdio.h>
  2. #ifndef VMS
  3. /* #include <malloc.h> */
  4. #endif
  5. #include <stdlib.h>
  6.  
  7. #include "buffer.h"
  8. #include "externs.h"
  9. #include "display.h"
  10. #include "line.h"
  11. #include "file.h"
  12.  
  13. int MOST_W_OPT = 0;
  14.  
  15. unsigned char *BEG;             /* beginning of current buffer */
  16. unsigned char *EOB;             /* end of current buffer */
  17. unsigned char MINI_BUF[132];
  18.  
  19. Buffer *BUF;
  20.  
  21. extern int SQUEEZE_LINES;
  22. int NUM_LINES;
  23. int ACTUAL_LINES;
  24.  
  25. unsigned char *C_POS;
  26. int C_LINE;
  27.  
  28. unsigned char *beg_of_line1()
  29. {
  30.     unsigned char *pos;
  31.     
  32.     if (C_POS == BEG) return BEG;
  33.  
  34.     pos = C_POS;
  35.     if (pos == EOB) pos--;
  36.  
  37.     if ((*pos != '\n') && (*(pos-1) == '\n')) return(pos);
  38.     
  39.     if ((*pos == '\n') && (pos == BEG)) return(BEG);
  40.     /* suppose BEG[] is "....\nabcde\n\n\n\n\n..." and we are somwhere in
  41.        the middle of the \n's.  Then we want to return the 2nd \n if the
  42.        SQUEEZE is on otherwise just return where we are. */
  43.     if ((*pos-- == '\n') && (*pos == '\n'))
  44.       {
  45.           if (SQUEEZE_LINES)
  46.             {
  47.                 /* if we are between '\n's then skip past all of them. */
  48.                 while ((pos > BEG) && (*pos == '\n')) pos--;
  49.                 if ((pos == BEG) && (*pos == '\n')) return (BEG);
  50.                 pos++;
  51.             }
  52.           return (++pos);
  53.       }      
  54.     
  55.     while((pos > BEG) && (*pos != '\n')) pos--;
  56.     if (pos != BEG) pos++;
  57.     else if ((pos == BEG) && (*pos == '\n')) pos++;
  58.     return pos;
  59. }
  60.  
  61. unsigned char *beg_of_line()
  62. {
  63.     unsigned char *b;
  64.     int d,n;
  65.     
  66.     if (!MOST_W_OPT) return beg_of_line1();
  67.     b = beg_of_line1();
  68.     d = C_POS - b;
  69.     n = d / (SCREEN_WIDTH - 1);
  70.     return(b +  (int) (n * (SCREEN_WIDTH - 1)));
  71. }
  72.  
  73. /* does not move point */
  74. unsigned char *end_of_line1()
  75. {
  76.    register unsigned char *pos, *pmax = EOB;
  77.    int n, n2;
  78.  
  79.     pos = C_POS;
  80.     if (pos >= EOB)  return(EOB);
  81.     /*     if ((pos == BEG) && (*pos == '\n')) return (BEG); */
  82.     
  83.     /* find the first '\n' */
  84.     if (*pos != '\n')
  85.       {
  86.      n = pmax - pos;
  87.      n2 = n % 8;
  88.      pmax = pos + (n - 8);
  89.     
  90.      while(pos <= pmax)
  91.        {
  92.          if ((*pos++ == '\n')
  93.          || (*pos++ == '\n')
  94.          || (*pos++ == '\n')
  95.          || (*pos++ == '\n')
  96.          || (*pos++ == '\n')
  97.          || (*pos++ == '\n')
  98.          || (*pos++ == '\n')
  99.          || (*pos++ == '\n'))
  100.         {
  101.            return(pos - 1);
  102.         }
  103.        }
  104.      pmax = pos + n2;
  105.      while ((pos < pmax) && (*pos != '\n')) pos++;
  106.      return(pos);
  107.       }
  108.    
  109.     if (!SQUEEZE_LINES) return (pos);
  110.  
  111.     /* if BEG = "....abc\n\n\n\n\ndef..." then we are at some first \n.  We
  112.        want to return the last '\n' unless we wre at the first '\n'. */
  113.  
  114.     if ((pos > BEG) && ( pos--, *pos++ != '\n')) return (pos); 
  115.     
  116.     while ((pos < EOB) && (*pos == '\n')) pos++;
  117.     if (pos-- == EOB) return (pos);
  118.     if (pos < BEG) pos = BEG;
  119.     return pos;
  120. }
  121.  
  122. unsigned char *end_of_line()
  123. {
  124.     unsigned char *b, *e;
  125.     int n;
  126.     
  127.     if (!MOST_W_OPT) return end_of_line1();
  128.  
  129.     b = beg_of_line();
  130.     e = end_of_line1();
  131.     n = (e - b) / (SCREEN_WIDTH - 1);
  132.     if (n) return(b + (SCREEN_WIDTH - 1));
  133.     return (e);
  134. }
  135.  
  136. int forward_line(int save)
  137. {
  138.     int m, ok;
  139.    register int n = save;
  140.    unsigned char *p;
  141.    unsigned char *pmax;
  142.    pmax = EOB - 1;
  143.     if (n > 0) 
  144.       {
  145.           if (MOST_B_OPT)
  146.             {
  147.                 m = (EOB - C_POS)/16;
  148.                 if (n > m) n = m;
  149.                 C_POS += n * 16;
  150.                 C_LINE += n;
  151.                 return n;
  152.             }
  153.           else while (n--)
  154.             {
  155.            C_POS = end_of_line();
  156.                 /* next step handles newline at the EOB */
  157.            if (C_POS >= pmax)
  158.          {
  159.             if ((C_POS > pmax) || (*C_POS == '\n')) return (save - n - 1);
  160.          }
  161.            
  162.                 C_LINE++;
  163.                 C_POS++;
  164.                 if (MOST_S_OPT)
  165.                   {
  166.                       p = C_POS;
  167.                       ok = 1;
  168.                       while ((*p <= ' ') && ok)
  169.                         {
  170.                if (*p != '\n') p++;
  171.                if (p > pmax) break;
  172.                             if ((*p == '\n') || (apparant_distance(p) >= MOST_S_OPT))
  173.                               {
  174.                                   ok = 0;
  175.                                   C_LINE--;
  176.                                   n++;
  177.                               }
  178.                         }
  179.                   } /* MOST_S_OPT */
  180.             }
  181.       }
  182.     else
  183.       {
  184.           if (MOST_B_OPT)
  185.             {
  186.                 m = (BEG - C_POS)/16;
  187.                 if (n < m) n = m;
  188.                 C_POS += n * 16;
  189.                 C_LINE += n;
  190.                 return n;
  191.             }
  192.           else while (n++)
  193.             {
  194.                 C_POS = beg_of_line();
  195.                 if (C_POS == BEG) return (n - save - 1);
  196.                 C_POS--;
  197.                 C_LINE--;
  198.                 if (MOST_S_OPT)
  199.                   {
  200.                       C_POS = beg_of_line();
  201.                       p = C_POS;
  202.                       ok = 1;
  203.                       while ((*p <= ' ') && ok)
  204.                         {
  205.                             if (*p != '\n') p++;
  206.                             if (p >= EOB) break;
  207.                             if ((*p == '\n') || (apparant_distance(p) >= MOST_S_OPT))
  208.                               {
  209.                                   ok = 0;
  210.                                   C_LINE++;
  211.                                   n--;
  212.                               }
  213.                         }
  214.                   } /* MOST_S_OPT */
  215.             }
  216.       }
  217.     return(save);
  218. }
  219.  
  220. int count_lines(unsigned char *beg, unsigned char *end)
  221. {
  222.     int save_line = C_LINE, n;
  223.     unsigned char *save_beg = beg, *save_eob = EOB, *save_pos = C_POS;
  224.    int dn = 1000;
  225.  
  226.     if (MOST_B_OPT) return(1 + (int)(end - beg) / 16);
  227.     BEG = C_POS = beg;
  228.     EOB = end;
  229.     n = 1;
  230.     while((dn = forward_line(dn)) != 0) n += dn;
  231.     if (*end ==  '\n') n--;
  232.     if (!n) n = 1;
  233.     C_POS = save_pos;
  234.     EOB = save_eob;
  235.     BEG = save_beg;
  236.     C_LINE = save_line;
  237.     return(n);
  238. }
  239.  
  240. void goto_line(int line)
  241. {
  242.    int dif_c, dif_b,dif_t;
  243.  
  244.    if (line < 1) line = 1;
  245.    read_to_line(line);
  246.    if (line > NUM_LINES) line = NUM_LINES;
  247.  
  248.     if (MOST_B_OPT)
  249.       {
  250.           C_POS = BEG + (16 * (line - 1));
  251.           C_LINE = line;
  252.           return;
  253.       }
  254.     
  255.     dif_c = line - C_LINE;
  256.     dif_b = line - NUM_LINES;
  257.     dif_t = line - 1;
  258.  
  259.     /* 4 possibilites */
  260.     if (dif_c <= 0)
  261.       {
  262.           if (dif_t < -dif_c) /* go from top */
  263.             {
  264.                 C_LINE = 1;
  265.                 C_POS = BEG;
  266.                 (void) forward_line(dif_t);
  267.             }
  268.           else  /* from curr back */
  269.             {
  270.                 (void) forward_line(dif_c);
  271.             }
  272.       }
  273.     else if (dif_c > 0)
  274.       {
  275.           if ((dif_c + dif_b) < 0) /* go from curr */
  276.             {
  277.                 (void) forward_line(dif_c);
  278.             }
  279.           else
  280.             {
  281.                 C_LINE = NUM_LINES;
  282.                 C_POS = EOB;
  283.                 (void) forward_line(dif_b);
  284.             }
  285.       }
  286. }       
  287.  
  288. /* return line the point is on without the final '\n's
  289.     unless beg = end in which case we take care of it later ...
  290.  
  291.     returns 1 if the line should be wrapped */
  292. int extract_line(unsigned char **beg, unsigned char **end)
  293. {
  294.     *beg = beg_of_line();
  295.     *end = end_of_line();
  296.     if (**end != '\n') return(1);
  297.     while ((*end > BEG) && (**end == '\n')) *end = *end - 1;
  298.     return(0);
  299. }    
  300.  
  301. int what_line(unsigned char *pos)
  302. {
  303.     
  304.     unsigned char *save_pos;
  305.     int save_line, dir;
  306.     register int dif_c, dif_b,dif_t;
  307.     int ret;
  308.  
  309.     if (MOST_B_OPT)
  310.       {
  311.           return (1 + (pos - BEG)/16);
  312.       }
  313.     
  314.         
  315.     save_pos = C_POS;
  316.     save_line = C_LINE;
  317.     
  318.     dif_c = pos - C_POS;
  319.     dif_b = pos - EOB;
  320.     dif_t = pos - BEG;
  321.  
  322.     /* 4 possibilites */
  323.     if (dif_c <= 0)
  324.       {
  325.           if (dif_t < -dif_c) /* go from top */
  326.             {
  327.                 C_LINE = 1;
  328.                 C_POS = BEG;
  329.                 dir = 1;
  330.             }
  331.           else  /* from curr back */
  332.             {
  333.                 dir = -1;
  334.             }
  335.       }
  336.     else if (dif_c > 0)
  337.       {
  338.           if ((dif_c + dif_b) < 0) /* go from curr */
  339.             {
  340.                 dir = 1;
  341.             }
  342.           else
  343.             {
  344.                 C_LINE = NUM_LINES;
  345.                 C_POS = EOB;
  346.                 dir = -1;
  347.             }
  348.       }
  349.     if (dir == 1)
  350.       {
  351.           while(C_POS = end_of_line(), C_POS < pos)
  352.             {
  353.                 C_POS++;
  354.                 C_LINE++;
  355.             }
  356.       }
  357.     else
  358.       {
  359.           while(C_POS = beg_of_line(), pos < C_POS)
  360.             {
  361.                 C_LINE--;
  362.                 C_POS--;
  363.             }
  364.       }
  365.  
  366.     ret = C_LINE;
  367.     C_POS = save_pos;
  368.     C_LINE = save_line;
  369.     return(ret);
  370. }
  371.  
  372. /* given a buffer position, find the line and column */
  373. void find_row_column(unsigned char *pos, int *r, int *c)
  374. {
  375.     unsigned char *beg, *save_pos;
  376.     int save_line;
  377.  
  378.  
  379.     if (pos <= BEG)
  380.       {
  381.           *r = 1;
  382.           *c = 1;
  383.           return;
  384.       }
  385.  
  386.     save_line = C_LINE;
  387.     save_pos = C_POS;
  388.     *r = what_line(pos);
  389.     
  390.     if (MOST_B_OPT)
  391.       {
  392.           *c = (int) (pos - BEG) - *r * 16 + 1;
  393.           return;
  394.       }
  395.     C_LINE = *r;
  396.     C_POS = pos;
  397.     
  398.     /* Now we have found the line it is on so.... */
  399.     beg = beg_of_line();
  400.     *c = 1;
  401.     while (beg++ < pos) *c = *c + 1;
  402.     C_LINE = save_line;
  403.     C_POS = save_pos;
  404. }       
  405.  
  406. Buffer *switch_to_buffer(Buffer *new)
  407. {
  408.     Buffer *old;
  409.     old = BUF;
  410.     BUF = new;
  411.     BEG = BUF->beg;
  412.     EOB = BUF->end;
  413.     return(old);
  414. }
  415. /*
  416. void delete_buffer(Buffer *old)
  417. {
  418.    if (BUF->fd != -1) close(BUF->fd);
  419.     (void) free(BUF);
  420.     BUF = old;
  421.     BEG = BUF->beg;
  422.     EOB = BUF->end;
  423. }
  424. */
  425. Buffer *create_buffer(char *file)
  426. {
  427.     Buffer *buf;
  428.  
  429.     buf = (Buffer *) MALLOC(sizeof(Buffer));
  430.     strcpy(buf->file,file);
  431.     return(buf);
  432. }
  433.  
  434. unsigned char *most_malloc(unsigned int n)
  435. {
  436.    unsigned char *b = (unsigned char *) malloc(n);
  437.    if (b == NULL) 
  438.      {
  439.     exit_error("malloc: Memory Allocation Error.");
  440.      }
  441.    return b;
  442. }
  443.  
  444. unsigned char *most_realloc(unsigned char *p, unsigned int n)
  445. {
  446.    unsigned char *b = (unsigned char *) realloc(p, n);
  447.    if (b == NULL) 
  448.      {
  449.     exit_error("malloc: Memory Allocation Error.");
  450.      }
  451.    return b;
  452. }
  453.  
  454.      
  455.