1 /* Variable Length String Buffer */
8 #define MAX(a, b) ((a) < (b) ? (b) : (a))
9 #define ALIGN(n, a) (((n) + (a) - 1) & ~((a) - 1))
10 #define NEXTSZ(o, r) ALIGN(MAX((o) * 2, (o) + (r)), SBUFSZ)
15 char *s
; /* allocated buffer */
16 int s_n
; /* length of the string stored in s[] */
17 int s_sz
; /* size of memory allocated for s[] */
20 static void sbuf_extend(struct sbuf
*sbuf
, int newsz
)
24 sbuf
->s
= malloc(sbuf
->s_sz
);
26 memcpy(sbuf
->s
, s
, sbuf
->s_n
);
30 struct sbuf
*sbuf_make(void)
32 struct sbuf
*sb
= malloc(sizeof(*sb
));
33 memset(sb
, 0, sizeof(*sb
));
37 char *sbuf_buf(struct sbuf
*sb
)
41 sb
->s
[sb
->s_n
] = '\0';
45 char *sbuf_done(struct sbuf
*sb
)
47 char *s
= sbuf_buf(sb
);
52 void sbuf_free(struct sbuf
*sb
)
58 void sbuf_chr(struct sbuf
*sbuf
, int c
)
60 if (sbuf
->s_n
+ 2 >= sbuf
->s_sz
)
61 sbuf_extend(sbuf
, NEXTSZ(sbuf
->s_sz
, 1));
62 sbuf
->s
[sbuf
->s_n
++] = c
;
65 void sbuf_mem(struct sbuf
*sbuf
, char *s
, int len
)
67 if (sbuf
->s_n
+ len
+ 1 >= sbuf
->s_sz
)
68 sbuf_extend(sbuf
, NEXTSZ(sbuf
->s_sz
, len
+ 1));
69 memcpy(sbuf
->s
+ sbuf
->s_n
, s
, len
);
73 void sbuf_str(struct sbuf
*sbuf
, char *s
)
75 sbuf_mem(sbuf
, s
, strlen(s
));
78 int sbuf_len(struct sbuf
*sbuf
)
83 void sbuf_cut(struct sbuf
*sb
, int len
)
89 void sbuf_printf(struct sbuf
*sbuf
, char *s
, ...)
94 vsnprintf(buf
, sizeof(buf
), s
, ap
);