diff options
Diffstat (limited to 'src/lib9/fmt/vsmprint.c')
-rw-r--r-- | src/lib9/fmt/vsmprint.c | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/src/lib9/fmt/vsmprint.c b/src/lib9/fmt/vsmprint.c index 871531ee..b6cf187c 100644 --- a/src/lib9/fmt/vsmprint.c +++ b/src/lib9/fmt/vsmprint.c @@ -11,11 +11,64 @@ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ +/* + * Plan 9 port version must include libc.h in order to + * get Plan 9 debugging malloc, which sometimes returns + * different pointers than the standard malloc. + */ +#ifdef PLAN9PORT +#include <u.h> +#include <libc.h> +#else #include <stdlib.h> -#include <stdarg.h> #include "plan9.h" #include "fmt.h" #include "fmtdef.h" +#endif + +static int +fmtStrFlush(Fmt *f) +{ + char *s; + int n; + + if(f->start == nil) + return 0; + n = (int)f->farg; + n *= 2; + s = (char*)f->start; + f->start = realloc(s, n); + if(f->start == nil){ + f->farg = nil; + f->to = nil; + f->stop = nil; + free(s); + return 0; + } + f->farg = (void*)n; + f->to = (char*)f->start + ((char*)f->to - s); + f->stop = (char*)f->start + n - 1; + return 1; +} + +int +fmtstrinit(Fmt *f) +{ + int n; + + memset(f, 0, sizeof *f); + f->runes = 0; + n = 32; + f->start = malloc(n); + if(f->start == nil) + return -1; + f->to = f->start; + f->stop = (char*)f->start + n - 1; + f->flush = fmtStrFlush; + f->farg = (void*)n; + f->nfmt = 0; + return 0; +} /* * print into an allocated string buffer @@ -28,10 +81,12 @@ vsmprint(char *fmt, va_list args) if(fmtstrinit(&f) < 0) return nil; - va_copy(f.args,args); + VA_COPY(f.args,args); n = dofmt(&f, fmt); - va_end(f.args); - if(n < 0) + VA_END(f.args); + if(n < 0){ + free(f.start); return nil; + } return fmtstrflush(&f); } |