66// returned value is always at least 1 greater than argument
77#define ROUND_ALLOC (a ) (((a) & ((~0) - 7)) + 8)
88
9- void vstr_init (vstr_t * vstr ) {
10- vstr -> alloc = 32 ;
9+ void vstr_init (vstr_t * vstr , int alloc ) {
10+ vstr -> alloc = alloc ;
1111 vstr -> len = 0 ;
1212 vstr -> buf = m_new (char , vstr -> alloc );
1313 if (vstr -> buf == NULL ) {
@@ -28,7 +28,16 @@ vstr_t *vstr_new(void) {
2828 if (vstr == NULL ) {
2929 return NULL ;
3030 }
31- vstr_init (vstr );
31+ vstr_init (vstr , 32 );
32+ return vstr ;
33+ }
34+
35+ vstr_t * vstr_new_size (int alloc ) {
36+ vstr_t * vstr = m_new (vstr_t , 1 );
37+ if (vstr == NULL ) {
38+ return NULL ;
39+ }
40+ vstr_init (vstr , alloc );
3241 return vstr ;
3342}
3443
@@ -63,6 +72,36 @@ int vstr_len(vstr_t *vstr) {
6372 return vstr -> len ;
6473}
6574
75+ // Extend vstr strictly to by requested size, return pointer to newly added chunk
76+ char * vstr_extend (vstr_t * vstr , int size ) {
77+ char * new_buf = m_renew (char , vstr -> buf , vstr -> alloc , vstr -> alloc + size );
78+ if (new_buf == NULL ) {
79+ vstr -> had_error = true;
80+ return NULL ;
81+ }
82+ char * p = new_buf + vstr -> alloc ;
83+ vstr -> alloc += size ;
84+ vstr -> buf = new_buf ;
85+ return p ;
86+ }
87+
88+ // Shrink vstr to be given size
89+ bool vstr_set_size (vstr_t * vstr , int size ) {
90+ char * new_buf = m_renew (char , vstr -> buf , vstr -> alloc , size );
91+ if (new_buf == NULL ) {
92+ vstr -> had_error = true;
93+ return false;
94+ }
95+ vstr -> buf = new_buf ;
96+ vstr -> alloc = vstr -> len = size ;
97+ return true;
98+ }
99+
100+ // Shrink vstr allocation to its actual length
101+ bool vstr_shrink (vstr_t * vstr ) {
102+ return vstr_set_size (vstr , vstr -> len );
103+ }
104+
66105bool vstr_ensure_extra (vstr_t * vstr , int size ) {
67106 if (vstr -> len + size + 1 > vstr -> alloc ) {
68107 int new_alloc = ROUND_ALLOC ((vstr -> len + size + 1 ) * 2 );
0 commit comments