1 #include "dynstring.h"
2 #include <errno.h>
3 #include <stdarg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <assert.h>
8
dyn_init(DYN_STRING * ds,int reserve_size)9 int dyn_init(DYN_STRING *ds,int reserve_size) // {{{
10 {
11 assert(ds);
12 assert(reserve_size>0);
13
14 ds->len=0;
15 ds->alloc=reserve_size;
16 ds->buf=malloc(ds->alloc+1);
17 if (!ds->buf) {
18 fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
19 assert(0);
20 ds->len=-1;
21 return -1;
22 }
23 return 0;
24 }
25 // }}}
26
dyn_free(DYN_STRING * ds)27 void dyn_free(DYN_STRING *ds) // {{{
28 {
29 assert(ds);
30
31 ds->len=-1;
32 ds->alloc=0;
33 free(ds->buf);
34 ds->buf=NULL;
35 }
36 // }}}
37
dyn_ensure(DYN_STRING * ds,int free_space)38 int dyn_ensure(DYN_STRING *ds,int free_space) // {{{
39 {
40 assert(ds);
41 assert(free_space);
42
43 if (ds->len<0) {
44 return -1;
45 }
46 if (ds->alloc - ds->len >= free_space) {
47 return 0; // done
48 }
49 ds->alloc+=free_space;
50 char *tmp=realloc(ds->buf,ds->alloc+1);
51 if (!tmp) {
52 ds->len=-1;
53 fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
54 assert(0);
55 return -1;
56 }
57 ds->buf=tmp;
58 return 0;
59 }
60 // }}}
61
dyn_vprintf(DYN_STRING * ds,const char * fmt,va_list ap)62 int dyn_vprintf(DYN_STRING *ds,const char *fmt,va_list ap) // {{{
63 {
64 assert(ds);
65
66 int need,len=strlen(fmt)+100;
67 va_list va;
68
69 if (dyn_ensure(ds,len)==-1) {
70 return -1;
71 }
72
73 while (1) {
74 va_copy(va,ap);
75 need=vsnprintf(ds->buf+ds->len,ds->alloc-ds->len+1,fmt,va);
76 va_end(va);
77 if (need==-1) {
78 len+=100;
79 } else if (need>=len) {
80 len=need;
81 } else {
82 ds->len+=need;
83 break;
84 }
85 if (dyn_ensure(ds,len)==-1) {
86 return -1;
87 }
88 }
89 return 0;
90 }
91 // }}}
92
dyn_printf(DYN_STRING * ds,const char * fmt,...)93 int dyn_printf(DYN_STRING *ds,const char *fmt,...) // {{{
94 {
95 va_list va;
96 int ret;
97
98 va_start(va,fmt);
99 ret=dyn_vprintf(ds,fmt,va);
100 va_end(va);
101
102 return ret;
103 }
104 // }}}
105
106