home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / vile-src.zip / vile-8.1 / itbuff.c < prev    next >
C/C++ Source or Header  |  1998-04-28  |  6KB  |  399 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 'itb_ins()' and 'itb_del()' to support cursor-level command
  8.  *        editing.
  9.  *
  10.  * $Header: /usr/build/vile/vile/RCS/itbuff.c,v 1.12 1998/04/28 10:17:09 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    _itb_list    {
  22.     struct    _itb_list    *link;
  23.     ITBUFF            *buff;
  24.     } ITB_LIST;
  25.  
  26. static    ITB_LIST    *all_tbuffs;
  27.  
  28. #define    AllocatedBuffer(q)    itb_remember(q);
  29. #define    FreedBuffer(q)        itb_forget(q);
  30.  
  31. static void
  32. itb_remember(ITBUFF *p)
  33. {
  34.     register ITB_LIST *q = typealloc(ITB_LIST);
  35.     q->buff = p;
  36.     q->link = all_tbuffs;
  37.     all_tbuffs = q;
  38. }
  39.  
  40. static void
  41. itb_forget(ITBUFF *p)
  42. {
  43.     register ITB_LIST *q, *r;
  44.  
  45.     for (q = all_tbuffs, r = 0; q != 0; r = q, q = q->link)
  46.         if (q->buff == p) {
  47.             if (r != 0)
  48.                 r->link = q->link;
  49.             else
  50.                 all_tbuffs = q->link;
  51.             free((char *)q);
  52.             break;
  53.         }
  54. }
  55.  
  56. void
  57. itb_leaks(void)
  58. {
  59.     while (all_tbuffs != 0) {
  60.         ITBUFF    *q = all_tbuffs->buff;
  61.         FreedBuffer(q);
  62.         itb_free(&q);
  63.     }
  64. }
  65.  
  66. #else
  67. #define    AllocatedBuffer(q)
  68. #define    FreedBuffer(q)
  69. #endif
  70.  
  71. /*******(initialization)*****************************************************/
  72.  
  73. /*
  74.  * ensure that the given temp-buff has as much space as specified
  75.  */
  76. ITBUFF *
  77. itb_alloc(ITBUFF **p, ALLOC_T n)
  78. {
  79.     register ITBUFF *q = *p;
  80.     if (q == 0) {
  81.         q = *p = typealloc(ITBUFF);
  82.         q->itb_data = typeallocn(int, q->itb_size = n);
  83.         q->itb_used = 0;
  84.         q->itb_last = 0;
  85.         q->itb_endc = abortc;
  86.         AllocatedBuffer(q)
  87.     } else if (n >= q->itb_size) {
  88.         q->itb_data = typereallocn(int, q->itb_data,
  89.                         q->itb_size = (n*2));
  90.     }
  91.     return q;
  92. }
  93.  
  94. /*
  95.  * (re)initialize a temp-buff
  96.  */
  97. ITBUFF *
  98. itb_init(ITBUFF **p, int c)
  99. {
  100.     register ITBUFF *q = *p;
  101.     if (q == 0)
  102.         q = itb_alloc(p, NCHUNK);
  103.     q->itb_used = 0;
  104.     q->itb_last = 0;
  105.     q->itb_endc = c;    /* code to return if no-more-data */
  106.     return (*p = q);
  107. }
  108.  
  109. /*
  110.  * deallocate a temp-buff
  111.  */
  112. void
  113. itb_free(ITBUFF **p)
  114. {
  115.     register ITBUFF *q = *p;
  116.  
  117.     if (q != 0) {
  118.         FreedBuffer(q)
  119.         free((char *)(q->itb_data));
  120.         free((char *)q);
  121.     }
  122.     *p = 0;
  123. }
  124.  
  125. /*******(storage)************************************************************/
  126.  
  127. /*
  128.  * put a character c at the nth position of the temp-buff.  make it the last.
  129.  */
  130. static ITBUFF *
  131. itb_put(ITBUFF **p, ALLOC_T n, int c)
  132. {
  133.     register ITBUFF *q;
  134.  
  135.     if ((q = itb_alloc(p, n+1)) != 0) {
  136.         q->itb_data[n] = c;
  137.         q->itb_used = n+1;
  138.     }
  139.     return q;
  140. }
  141.  
  142. /*
  143.  * stuff the nth character into the temp-buff -- assumes space already there
  144.  *  it's sort of the opposite of itb_peek
  145.  */
  146. void
  147. itb_stuff(ITBUFF *p, int c)
  148. {
  149.     if (p->itb_last < p->itb_used)
  150.         p->itb_data[p->itb_last] = c;
  151.     else
  152.         p->itb_endc = c;
  153. }
  154. /*
  155.  * append a character to the temp-buff
  156.  */
  157. ITBUFF *
  158. itb_append(ITBUFF **p, int c)
  159. {
  160.     register ITBUFF *q = *p;
  161.     register ALLOC_T n = (q != 0) ? q->itb_used : 0;
  162.  
  163.     return itb_put(p, n, c);
  164. }
  165.  
  166. /*
  167.  * Copy one temp-buff to another
  168.  */
  169. ITBUFF *
  170. itb_copy(ITBUFF **d, ITBUFF *s)
  171. {
  172.     ITBUFF *p;
  173.  
  174.     if (s != 0) {
  175.         if ((p = itb_init(d, s->itb_endc)) != 0) {
  176.             int    *ptr = s->itb_data;
  177.             ALLOC_T len = s->itb_used;
  178.             while ((len-- != 0) && itb_append(&p, *ptr++) != 0)
  179.                 ;
  180.         }
  181.     } else
  182.         p = itb_init(d, abortc);
  183.     return p;
  184. }
  185.  
  186. /*
  187.  * append a binary data to the temp-buff
  188.  */
  189. ITBUFF *
  190. itb_bappend(ITBUFF **p, const char *s, ALLOC_T len)
  191. {
  192.     while ((len-- != 0) && itb_append(p, (int)(*s++)) != 0)
  193.         ;
  194.     return *p;
  195. }
  196.  
  197. #if NEEDED
  198. /*
  199.  * append a string to the temp-buff
  200.  */
  201. ITBUFF *
  202. itb_sappend( ITBUFF **p, const char *s)
  203. {
  204.     if (!s)
  205.         return *p;
  206.     while (*s && itb_append(p, (int)(*s++)) != 0)
  207.         ;
  208.     return *p;
  209. }
  210.  
  211. void
  212. itb_delete(ITBUFF *p, ALLOC_T cnt)
  213. {
  214.     int *from, *to, *used;
  215.  
  216.     to = &p->itb_data[p->itb_last];
  217.     from = to + cnt;
  218.  
  219.     used = &p->itb_data[p->itb_used];
  220.  
  221.     if (from >= used) {
  222.         p->itb_used = p->itb_last;
  223.         return;
  224.     }
  225.  
  226.     while (from < used) {
  227.         *to++ = *from++;
  228.     }
  229.  
  230.     p->itb_used -= cnt;
  231.  
  232. }
  233.  
  234. ITBUFF *
  235. itb_insert(ITBUFF **p, int c)
  236. {
  237.     register ITBUFF *q = *p;
  238.     int *last, *to;
  239.  
  240.     /* force enough room for another character */
  241.     itb_put(p, q->itb_used, 0 /* any value */ );
  242.  
  243.     /* copy up */
  244.     to = &q->itb_data[q->itb_used-1];
  245.     last = &q->itb_data[q->itb_last];
  246.     while (to > last) {
  247.         *to = *(to-1);
  248.         to--;
  249.     }
  250.  
  251.     /* put in the new one */
  252.     itb_stuff(q, c);
  253.  
  254.     return *p;
  255. }
  256. #endif  /* NEEDED */
  257.  
  258.  
  259. /*******(retrieval)************************************************************/
  260.  
  261. /*
  262.  * get the nth character from the temp-buff
  263.  */
  264. int
  265. itb_get(ITBUFF *p, ALLOC_T n)
  266. {
  267.     register int    c = abortc;
  268.  
  269.     if (p != 0)
  270.         c = (n < p->itb_used) ? p->itb_data[n] : p->itb_endc;
  271.  
  272.     return c;
  273. }
  274.  
  275. #if NEEDED
  276. /*
  277.  * undo the last 'itb_put'
  278.  */
  279. void
  280. itb_unput(ITBUFF *p)
  281. {
  282.     if (p != 0
  283.      && p->itb_used != 0)
  284.         p->itb_used -= 1;
  285. }
  286. #endif
  287.  
  288. /*******(iterators)************************************************************/
  289.  
  290. /*
  291.  * Reset the iteration-count
  292.  */
  293. static
  294. ALLOC_T
  295. itb_seek(ITBUFF *p, ALLOC_T seekto, int whence)
  296. {
  297.     ALLOC_T olast;
  298.  
  299.     if (p == 0)
  300.         return 0;
  301.  
  302.     olast = p->itb_last;
  303.  
  304.     if (whence == 0)
  305.         p->itb_last = seekto;
  306.     else if (whence == 1)
  307.         p->itb_last += seekto;
  308.     else if (whence == 2)
  309.         p->itb_last = p->itb_used - seekto;
  310.     return olast;
  311. }
  312.  
  313. void
  314. itb_first(ITBUFF *p)
  315. {
  316.     (void)itb_seek(p, 0, 0);
  317. }
  318.  
  319. /*
  320.  * Returns true iff the iteration-count has not gone past the end of temp-buff.
  321.  */
  322. int
  323. itb_more(ITBUFF *p)
  324. {
  325.     return (p != 0) ? (p->itb_last < p->itb_used) : FALSE;
  326. }
  327.  
  328. /*
  329.  * get the next character from the temp-buff
  330.  */
  331. int
  332. itb_next(ITBUFF *p)
  333. {
  334.     if (p != 0)
  335.         return itb_get(p, p->itb_last++);
  336.     return abortc;
  337. }
  338.  
  339. /*
  340.  * get the last character from the temp-buff, and shorten
  341.  * (opposite of itb_append)
  342.  */
  343. int
  344. itb_last(ITBUFF *p)
  345. {
  346.     int c;
  347.     if (p != 0 && p->itb_used > 0) {
  348.         c = itb_get(p, p->itb_used-1);
  349.         p->itb_used--;
  350.         return c;
  351.     }
  352.     return abortc;
  353. }
  354.  
  355. #if NEEDED
  356. /*
  357.  * undo a itb_next
  358.  */
  359. void
  360. itb_unnext(ITBUFF *p)
  361. {
  362.     if (p == 0)
  363.         return;
  364.     if (p->itb_last > 0)
  365.         p->itb_last--;
  366. }
  367. #endif
  368.  
  369. /*
  370.  * get the next character from the temp-buff w/o incrementing index
  371.  */
  372. int
  373. itb_peek(ITBUFF *p)
  374. {
  375.     if (p != 0)
  376.         return itb_get(p, p->itb_last);
  377.     return abortc;
  378. }
  379.  
  380. /*******(bulk-data)************************************************************/
  381.  
  382. /*
  383.  * returns a pointer to data, assumes it is one long string
  384.  */
  385. int *
  386. itb_values(ITBUFF *p)
  387. {
  388.     return (p != 0) ? p->itb_data : 0;
  389. }
  390.  
  391. /*
  392.  * returns the length of the data
  393.  */
  394. ALLOC_T
  395. itb_length(ITBUFF *p)
  396. {
  397.     return (p != 0) ? p->itb_used : 0;
  398. }
  399.