home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / most-3.2 / part01 / buffer.c next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  9.1 KB  |  399 lines

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