• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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