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)
13 char *s
; /* allocated buffer */
14 int s_n
; /* length of the string stored in s[] */
15 int s_sz
; /* size of memory allocated for s[] */
18 static void sbuf_extend(struct sbuf
*sbuf
, int newsz
)
22 sbuf
->s
= malloc(sbuf
->s_sz
);
24 memcpy(sbuf
->s
, s
, sbuf
->s_n
);
28 struct sbuf
*sbuf_make(void)
30 struct sbuf
*sb
= malloc(sizeof(*sb
));
31 memset(sb
, 0, sizeof(*sb
));
35 char *sbuf_buf(struct sbuf
*sb
)
39 sb
->s
[sb
->s_n
] = '\0';
43 char *sbuf_done(struct sbuf
*sb
)
45 char *s
= sbuf_buf(sb
);
50 void sbuf_free(struct sbuf
*sb
)
56 void sbuf_chr(struct sbuf
*sbuf
, int c
)
58 if (sbuf
->s_n
+ 2 >= sbuf
->s_sz
)
59 sbuf_extend(sbuf
, NEXTSZ(sbuf
->s_sz
, 1));
60 sbuf
->s
[sbuf
->s_n
++] = c
;
63 void sbuf_mem(struct sbuf
*sbuf
, char *s
, int len
)
65 if (sbuf
->s_n
+ len
+ 1 >= sbuf
->s_sz
)
66 sbuf_extend(sbuf
, NEXTSZ(sbuf
->s_sz
, len
+ 1));
67 memcpy(sbuf
->s
+ sbuf
->s_n
, s
, len
);
71 void sbuf_str(struct sbuf
*sbuf
, char *s
)
73 sbuf_mem(sbuf
, s
, strlen(s
));
76 int sbuf_len(struct sbuf
*sbuf
)
81 void sbuf_cut(struct sbuf
*sb
, int len
)
87 void sbuf_printf(struct sbuf
*sbuf
, char *s
, ...)
92 vsnprintf(buf
, sizeof(buf
), s
, ap
);