diff options
Diffstat (limited to 'src/lib9/fmt/runevsmprint.c')
-rw-r--r-- | src/lib9/fmt/runevsmprint.c | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/src/lib9/fmt/runevsmprint.c b/src/lib9/fmt/runevsmprint.c index 988e5c02..d1b25f30 100644 --- a/src/lib9/fmt/runevsmprint.c +++ b/src/lib9/fmt/runevsmprint.c @@ -11,11 +11,64 @@ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ -#include <stdarg.h> +/* + * 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 "plan9.h" #include "fmt.h" #include "fmtdef.h" +#endif + +static int +runeFmtStrFlush(Fmt *f) +{ + Rune *s; + int n; + + if(f->start == nil) + return 0; + n = (int)f->farg; + n *= 2; + s = (Rune*)f->start; + f->start = realloc(s, sizeof(Rune)*n); + if(f->start == nil){ + f->farg = nil; + f->to = nil; + f->stop = nil; + free(s); + return 0; + } + f->farg = (void*)n; + f->to = (Rune*)f->start + ((Rune*)f->to - s); + f->stop = (Rune*)f->start + n - 1; + return 1; +} + +int +runefmtstrinit(Fmt *f) +{ + int n; + + memset(f, 0, sizeof *f); + f->runes = 1; + n = 32; + f->start = malloc(sizeof(Rune)*n); + if(f->start == nil) + return -1; + f->to = f->start; + f->stop = (Rune*)f->start + n - 1; + f->flush = runeFmtStrFlush; + f->farg = (void*)n; + f->nfmt = 0; + return 0; +} /* * print into an allocated string buffer @@ -28,11 +81,15 @@ runevsmprint(char *fmt, va_list args) if(runefmtstrinit(&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(f.start == nil) + return nil; + if(n < 0){ + free(f.start); return nil; + } *(Rune*)f.to = '\0'; return (Rune*)f.start; } |