home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / vile-src.zip / vile-8.1 / tbuff.c < prev    next >
C/C++ Source or Header  |  1998-04-26  |  6KB  |  359 lines

  1. /*
  2.  *    tbuff.c
  3.  *
  4.  *    Manage dynamic temporary buffers.
  5.  *    Note that some temp-buffs are never freed, for speed
  6.  *
  7.  *    To do:    add 'tb_ins()' and 'tb_del()' to support cursor-level command
  8.  *        editing.
  9.  *
  10.  * $Header: /usr/build/vile/vile/RCS/tbuff.c,v 1.31 1998/04/26 13:57:45 tom Exp $
  11.  *
  12.  */
  13.  
  14. #include "estruct.h"
  15. #include "edef.h"
  16.  
  17. #define    NCHUNK    NLINE
  18.  
  19. /*******(testing)************************************************************/
  20. #if NO_LEAKS
  21. typedef    struct    _tb_list    {
  22.     struct    _tb_list    *link;
  23.     TBUFF            *buff;
  24.     } TB_LIST;
  25.  
  26. static    TB_LIST    *all_tbuffs;
  27.  
  28. #define    AllocatedBuffer(q)    tb_remember(q);
  29. #define    FreedBuffer(q)        tb_forget(q);
  30.  
  31. static
  32. void
  33. tb_remember(TBUFF *p)
  34. {
  35.     register TB_LIST *q = typealloc(TB_LIST);
  36.     q->buff = p;
  37.     q->link = all_tbuffs;
  38.     all_tbuffs = q;
  39. }
  40.  
  41. static
  42. void
  43. tb_forget(TBUFF *p)
  44. {
  45.     register TB_LIST *q, *r;
  46.  
  47.     for (q = all_tbuffs, r = 0; q != 0; r = q, q = q->link)
  48.         if (q->buff == p) {
  49.             if (r != 0)
  50.                 r->link = q->link;
  51.             else
  52.                 all_tbuffs = q->link;
  53.             free((char *)q);
  54.             break;
  55.         }
  56. }
  57.  
  58. void
  59. tb_leaks(void)
  60. {
  61.     while (all_tbuffs != 0) {
  62.         TBUFF    *q = all_tbuffs->buff;
  63.         FreedBuffer(q);
  64.         tb_free(&q);
  65.     }
  66. }
  67.  
  68. #else
  69. #define    AllocatedBuffer(q)
  70. #define    FreedBuffer(q)
  71. #endif
  72.  
  73. /*******(initialization)*****************************************************/
  74.  
  75. /*
  76.  * ensure that the given temp-buff has as much space as specified
  77.  */
  78. TBUFF *
  79. tb_alloc(TBUFF **p, ALLOC_T n)
  80. {
  81.     register TBUFF *q = *p;
  82.     if (q == 0) {
  83.         q = *p = typealloc(TBUFF);
  84.         q->tb_data = typeallocn(char, q->tb_size = n);
  85.         q->tb_used = 0;
  86.         q->tb_last = 0;
  87.         q->tb_endc = abortc;
  88.         q->tb_data[0] = 0;    /* appease Purify */
  89.         AllocatedBuffer(q)
  90.     } else if (n >= q->tb_size) {
  91.         q->tb_data = typereallocn(char, q->tb_data, q->tb_size = (n*2));
  92.     }
  93.     return q;
  94. }
  95.  
  96. /*
  97.  * (re)initialize a temp-buff
  98.  */
  99. TBUFF *
  100. tb_init(TBUFF **p, int c)
  101. {
  102.     register TBUFF *q = *p;
  103.     if (q == 0)
  104.         q = tb_alloc(p, NCHUNK);
  105.     q->tb_used = 0;
  106.     q->tb_last = 0;
  107.     q->tb_endc = c;        /* code to return if no-more-data */
  108.     return (*p = q);
  109. }
  110.  
  111. /*
  112.  * deallocate a temp-buff
  113.  */
  114. void
  115. tb_free(TBUFF **p)
  116. {
  117.     register TBUFF *q = *p;
  118.  
  119.     if (q != 0) {
  120.         FreedBuffer(q)
  121.         free(q->tb_data);
  122.         free((char *)q);
  123.     }
  124.     *p = 0;
  125. }
  126.  
  127. /*******(storage)************************************************************/
  128.  
  129. /*
  130.  * put a character c at the nth position of the temp-buff
  131.  */
  132. TBUFF *
  133. tb_put(TBUFF **p, ALLOC_T n, int c)
  134. {
  135.     register TBUFF *q;
  136.  
  137.     if ((q = tb_alloc(p, n+1)) != 0) {
  138.         q->tb_data[n] = (char)c;
  139.         q->tb_used = n+1;
  140.     }
  141.     return (*p = q);
  142. }
  143.  
  144. #if NEEDED
  145. /*
  146.  * stuff the nth character into the temp-buff -- assumes space already there
  147.  *  it's sort of the opposite of tb_peek
  148.  */
  149. void
  150. tb_stuff(TBUFF *p, int c)
  151. {
  152.     if (p->tb_last < p->tb_used)
  153.         p->tb_data[p->tb_last] = c;
  154.     else
  155.         p->tb_endc = c;
  156. }
  157. #endif
  158. /*
  159.  * append a character to the temp-buff
  160.  */
  161. TBUFF *
  162. tb_append(TBUFF **p, int c)
  163. {
  164.     register TBUFF *q = *p;
  165.     register ALLOC_T n = (q != 0) ? q->tb_used : 0;
  166.  
  167.     return tb_put(p, n, c);
  168. }
  169.  
  170. /*
  171.  * insert a character into the temp-buff
  172.  */
  173. TBUFF *
  174. tb_insert(TBUFF **p, ALLOC_T n, int c)
  175. {
  176.     register ALLOC_T m = tb_length(*p);
  177.     register TBUFF *q = tb_append(p, c);
  178.  
  179.     if (q != 0 && n < m) {
  180.         while (n < m) {
  181.             q->tb_data[m] = q->tb_data[m-1];
  182.             m--;
  183.         }
  184.         q->tb_data[m] = c;
  185.     }
  186.     return q;
  187. }
  188.  
  189. /*
  190.  * Copy one temp-buff to another
  191.  */
  192. TBUFF *
  193. tb_copy(TBUFF **d, TBUFF *s)
  194. {
  195.     register TBUFF *p;
  196.  
  197.     if (s != 0) {
  198.         if ((p = tb_init(d, s->tb_endc)) != 0)
  199.             p = tb_bappend(d, s->tb_data, s->tb_used);
  200.     } else
  201.         p = tb_init(d, abortc);
  202.     return p;
  203. }
  204.  
  205. /*
  206.  * append a binary data to the temp-buff
  207.  */
  208. TBUFF *
  209. tb_bappend(TBUFF **p, const char *s, ALLOC_T len)
  210. {
  211.     while ((len-- != 0) && tb_append(p, (int)(*s++)) != 0)
  212.         ;
  213.     return *p;
  214. }
  215. /*
  216.  * append a string to the temp-buff
  217.  */
  218. TBUFF *
  219. tb_sappend(TBUFF **p, const char *s)
  220. {
  221.     if (!s)
  222.         return *p;
  223.     while (*s && tb_append(p, (int)(*s++)) != 0)
  224.         ;
  225.     return *p;
  226. }
  227.  
  228. /*
  229.  * copy a string to the temp-buff, including a null
  230.  */
  231. TBUFF *
  232. tb_scopy(TBUFF **p, const char *s)
  233. {
  234.     (void) tb_init(p, EOS);
  235.     (void) tb_sappend(p, s);
  236.     return tb_append(p, EOS);
  237. }
  238.  
  239. /*
  240.  * Construct a TBUFF from a null-terminated string, omitting its null.
  241.  */
  242. TBUFF *
  243. tb_string(const char *s)
  244. {
  245.     TBUFF *p = 0;
  246.     (void) tb_init(&p, EOS);
  247.     return tb_bappend(&p, s, strlen(s));
  248. }
  249.  
  250. /*******(retrieval)************************************************************/
  251.  
  252. #if DISP_X11
  253. /*
  254.  * get the nth character from the temp-buff
  255.  */
  256. int
  257. tb_get(TBUFF *p, ALLOC_T n)
  258. {
  259.     register int    c = abortc;
  260.  
  261.     if (p != 0)
  262.         c = (n < p->tb_used) ? p->tb_data[n] : p->tb_endc;
  263.  
  264.     return char2int(c);
  265. }
  266. #endif
  267.  
  268. /*
  269.  * undo the last 'tb_put'
  270.  */
  271. void
  272. tb_unput(TBUFF *p)
  273. {
  274.     if (p != 0
  275.      && p->tb_used != 0)
  276.         p->tb_used -= 1;
  277. }
  278.  
  279. /*******(iterators)************************************************************/
  280.  
  281. #if NEEDED
  282. /*
  283.  * Reset the iteration-count
  284.  */
  285. void
  286. tb_first(TBUFF *p)
  287. {
  288.     if (p != 0)
  289.         p->tb_last = 0;
  290. }
  291. #endif
  292.  
  293. #if DISP_X11
  294. /*
  295.  * Returns true iff the iteration-count has not gone past the end of temp-buff.
  296.  */
  297. int
  298. tb_more(TBUFF *p)
  299. {
  300.     return (p != 0) ? (p->tb_last < p->tb_used) : FALSE;
  301. }
  302.  
  303. /*
  304.  * get the next character from the temp-buff
  305.  */
  306. int
  307. tb_next(TBUFF *p)
  308. {
  309.     if (p != 0)
  310.         return tb_get(p, p->tb_last++);
  311.     return abortc;
  312. }
  313. #endif
  314.  
  315. #if NEEDED
  316. /*
  317.  * undo a tb_next
  318.  */
  319. void
  320. tb_unnext(TBUFF *p)
  321. {
  322.     if (p == 0)
  323.         return;
  324.     if (p->tb_last > 0)
  325.         p->tb_last--;
  326. }
  327.  
  328. /*
  329.  * get the next character from the temp-buff w/o incrementing index
  330.  */
  331. int
  332. tb_peek(TBUFF *p)
  333. {
  334.     if (p != 0)
  335.         return tb_get(p, p->tb_last);
  336.     return abortc;
  337. }
  338. #endif  /* NEEDED */
  339.  
  340. /*******(bulk-data)************************************************************/
  341.  
  342. /*
  343.  * returns a pointer to data, assumes it is one long string
  344.  */
  345. char *
  346. tb_values(TBUFF *p)
  347. {
  348.     return (p != 0) ? p->tb_data : 0;
  349. }
  350.  
  351. /*
  352.  * returns the length of the data
  353.  */
  354. ALLOC_T
  355. tb_length(TBUFF *p)
  356. {
  357.     return (p != 0) ? p->tb_used : 0;
  358. }
  359.