1 /* variable length string buffer */
9 #define ALIGN(n, a) (((n) + (a) - 1) & ~((a) - 1))
10 #define NEXTSZ(o, r) ALIGN(MAX((o) * 2, (o) + (r)), SBUFSZ)
11 #define MAX(a, b) ((a) < (b) ? (b) : (a))
14 char *s
; /* allocated buffer */
15 int s_n
; /* length of the string stored in s[] */
16 int s_sz
; /* size of memory allocated for s[] */
19 static void sbuf_extend(struct sbuf
*sbuf
, int newsz
)
23 sbuf
->s
= malloc(sbuf
->s_sz
);
25 memcpy(sbuf
->s
, s
, sbuf
->s_n
);
29 struct sbuf
*sbuf_make(void)
31 struct sbuf
*sb
= malloc(sizeof(*sb
));
32 memset(sb
, 0, sizeof(*sb
));
36 char *sbuf_buf(struct sbuf
*sb
)
40 sb
->s
[sb
->s_n
] = '\0';
44 char *sbuf_done(struct sbuf
*sb
)
46 char *s
= sbuf_buf(sb
);
51 void sbuf_free(struct sbuf
*sb
)
57 void sbuf_chr(struct sbuf
*sbuf
, int c
)
59 if (sbuf
->s_n
+ 2 >= sbuf
->s_sz
)
60 sbuf_extend(sbuf
, NEXTSZ(sbuf
->s_sz
, 1));
61 sbuf
->s
[sbuf
->s_n
++] = c
;
64 void sbuf_mem(struct sbuf
*sbuf
, char *s
, int len
)
66 if (sbuf
->s_n
+ len
+ 1 >= sbuf
->s_sz
)
67 sbuf_extend(sbuf
, NEXTSZ(sbuf
->s_sz
, len
+ 1));
68 memcpy(sbuf
->s
+ sbuf
->s_n
, s
, len
);
72 void sbuf_str(struct sbuf
*sbuf
, char *s
)
74 sbuf_mem(sbuf
, s
, strlen(s
));
77 int sbuf_len(struct sbuf
*sbuf
)
82 void sbuf_cut(struct sbuf
*sb
, int len
)
88 void sbuf_printf(struct sbuf
*sbuf
, char *s
, ...)
93 vsnprintf(buf
, sizeof(buf
), s
, ap
);