tr: escaped spaces inside macro arguments
[neatroff.git] / sbuf.c
blob041bfa82c66a897b5afd77b23c59909c16ebdbff
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 SBUF_SZ 512
10 static void sbuf_extend(struct sbuf *sbuf, int amount)
12 char *s = sbuf->s;
13 sbuf->sz = (MAX(1, amount) + SBUF_SZ - 1) & ~(SBUF_SZ - 1);
14 sbuf->s = xmalloc(sbuf->sz);
15 if (sbuf->n)
16 memcpy(sbuf->s, s, sbuf->n);
17 free(s);
20 void sbuf_init(struct sbuf *sbuf)
22 memset(sbuf, 0, sizeof(*sbuf));
23 sbuf_extend(sbuf, SBUF_SZ);
26 void sbuf_add(struct sbuf *sbuf, int c)
28 if (sbuf->n + 2 >= sbuf->sz)
29 sbuf_extend(sbuf, sbuf->sz * 2);
30 sbuf->s[sbuf->n++] = c;
33 void sbuf_append(struct sbuf *sbuf, char *s)
35 int len = strlen(s);
36 if (sbuf->n + len + 1 >= sbuf->sz)
37 sbuf_extend(sbuf, sbuf->n + len + 1);
38 memcpy(sbuf->s + sbuf->n, s, len);
39 sbuf->n += len;
42 void sbuf_printf(struct sbuf *sbuf, char *s, ...)
44 char buf[ILNLEN];
45 va_list ap;
46 va_start(ap, s);
47 vsprintf(buf, s, ap);
48 va_end(ap);
49 sbuf_append(sbuf, buf);
52 void sbuf_putnl(struct sbuf *sbuf)
54 if (sbuf->n && sbuf->s[sbuf->n - 1] != '\n')
55 sbuf_add(sbuf, '\n');
58 int sbuf_empty(struct sbuf *sbuf)
60 return !sbuf->n;
63 char *sbuf_buf(struct sbuf *sbuf)
65 sbuf->s[sbuf->n] = '\0';
66 return sbuf->s;
69 int sbuf_len(struct sbuf *sbuf)
71 return sbuf->n;
74 /* shorten the sbuf */
75 void sbuf_cut(struct sbuf *sbuf, int n)
77 if (sbuf->n > n)
78 sbuf->n = n;
81 void sbuf_done(struct sbuf *sbuf)
83 free(sbuf->s);