kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

cbuf.c (1821B)


      1 /* Heap-backed growable byte buffer used by the C target for per-function
      2  * declarations and body text. The TU writer is bytewise but CG hands us
      3  * declarations and body emission interleaved; we accumulate both and flush
      4  * at func_end. */
      5 
      6 #include "arch/c_target/c_emit.h"
      7 #include "core/heap.h"
      8 
      9 enum { CBUF_MIN_CAP = 256 };
     10 
     11 void cbuf_init(CBuf* b, Heap* h) {
     12   b->heap = h;
     13   b->data = NULL;
     14   b->len = 0;
     15   b->cap = 0;
     16 }
     17 
     18 void cbuf_fini(CBuf* b) {
     19   if (b->data) b->heap->free(b->heap, b->data, b->cap);
     20   b->data = NULL;
     21   b->len = 0;
     22   b->cap = 0;
     23 }
     24 
     25 void cbuf_reset(CBuf* b) { b->len = 0; }
     26 
     27 static void cbuf_grow(CBuf* b, size_t want) {
     28   size_t newcap = b->cap ? b->cap : CBUF_MIN_CAP;
     29   while (newcap < want) newcap *= 2;
     30   u8* nd = (u8*)b->heap->realloc(b->heap, b->data, b->cap, newcap, 1);
     31   if (!nd) {
     32     /* Out of memory; truncate silently. Caller writer will produce
     33      * partial output but no UB. */
     34     return;
     35   }
     36   b->data = nd;
     37   b->cap = newcap;
     38 }
     39 
     40 void cbuf_putc(CBuf* b, char c) {
     41   if (b->len + 1 > b->cap) cbuf_grow(b, b->len + 1);
     42   if (b->len < b->cap) b->data[b->len++] = (u8)c;
     43 }
     44 
     45 void cbuf_puts(CBuf* b, const char* s) {
     46   while (*s) cbuf_putc(b, *s++);
     47 }
     48 
     49 void cbuf_putn(CBuf* b, const char* s, size_t n) {
     50   if (b->len + n > b->cap) cbuf_grow(b, b->len + n);
     51   for (size_t i = 0; i < n && b->len < b->cap; ++i)
     52     b->data[b->len++] = (u8)s[i];
     53 }
     54 
     55 void cbuf_put_u64(CBuf* b, u64 v) {
     56   char tmp[24];
     57   size_t n = 0;
     58   if (v == 0) {
     59     cbuf_putc(b, '0');
     60     return;
     61   }
     62   while (v) {
     63     tmp[n++] = (char)('0' + (v % 10));
     64     v /= 10;
     65   }
     66   while (n--) cbuf_putc(b, tmp[n]);
     67 }
     68 
     69 void cbuf_put_i64(CBuf* b, i64 v) {
     70   u64 u;
     71   if (v < 0) {
     72     cbuf_putc(b, '-');
     73     /* careful with INT64_MIN */
     74     u = (u64)(-(v + 1)) + 1u;
     75   } else {
     76     u = (u64)v;
     77   }
     78   cbuf_put_u64(b, u);
     79 }