tr: allow parsing macro arguments as a request
[neatroff.git] / sbuf.c
blobf03ddd61341cff0da1d11a7888c2b71fe852c553
1 /* variable length string buffer */
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "roff.h"
8 #define ALIGN(n, a) (((n) + (a) - 1) & ~((a) - 1))
9 #define SBUFSZ 512
11 static void sbuf_extend(struct sbuf *sbuf, int amount)
13 sbuf->sz = ALIGN(amount, SBUFSZ);
14 sbuf->s = mextend(sbuf->s, sbuf->n, sbuf->sz, sizeof(sbuf->s[0]));
17 void sbuf_init(struct sbuf *sbuf)
19 memset(sbuf, 0, sizeof(*sbuf));
20 sbuf_extend(sbuf, SBUFSZ);
23 void sbuf_add(struct sbuf *sbuf, int c)
25 if (sbuf->n + 2 >= sbuf->sz)
26 sbuf_extend(sbuf, sbuf->sz * 2);
27 sbuf->s[sbuf->n++] = c;
30 void sbuf_append(struct sbuf *sbuf, char *s)
32 int len = strlen(s);
33 if (sbuf->n + len + 1 >= sbuf->sz)
34 sbuf_extend(sbuf, sbuf->n + len + 1);
35 memcpy(sbuf->s + sbuf->n, s, len);
36 sbuf->n += len;
39 void sbuf_printf(struct sbuf *sbuf, char *s, ...)
41 char buf[ILNLEN];
42 va_list ap;
43 va_start(ap, s);
44 vsnprintf(buf, sizeof(buf), s, ap);
45 va_end(ap);
46 sbuf_append(sbuf, buf);
49 int sbuf_empty(struct sbuf *sbuf)
51 return !sbuf->n;
54 char *sbuf_buf(struct sbuf *sbuf)
56 sbuf->s[sbuf->n] = '\0';
57 return sbuf->s;
60 int sbuf_len(struct sbuf *sbuf)
62 return sbuf->n;
65 /* shorten the sbuf */
66 void sbuf_cut(struct sbuf *sbuf, int n)
68 if (sbuf->n > n)
69 sbuf->n = n;
72 void sbuf_done(struct sbuf *sbuf)
74 free(sbuf->s);
77 char *sbuf_out(struct sbuf *sbuf)
79 char *s = sbuf->s;
80 memset(sbuf, 0, sizeof(*sbuf));
81 return s;