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