1 #include <u.h> 2 #include <libc.h> 3 #include "fmtdef.h" 4 5 static int fmtStrFlush(Fmt * f)6fmtStrFlush(Fmt *f) 7 { 8 char *s; 9 int n; 10 11 if(f->start == nil) 12 return 0; 13 n = (int)(uintptr)f->farg; 14 n *= 2; 15 s = f->start; 16 f->start = realloc(s, n); 17 if(f->start == nil){ 18 f->farg = nil; 19 f->to = nil; 20 f->stop = nil; 21 free(s); 22 return 0; 23 } 24 f->farg = (void*)n; 25 f->to = (char*)f->start + ((char*)f->to - s); 26 f->stop = (char*)f->start + n - 1; 27 return 1; 28 } 29 30 int fmtstrinit(Fmt * f)31fmtstrinit(Fmt *f) 32 { 33 int n; 34 35 memset(f, 0, sizeof *f); 36 f->runes = 0; 37 n = 32; 38 f->start = malloc(n); 39 if(f->start == nil) 40 return -1; 41 setmalloctag(f->start, getcallerpc(&f)); 42 f->to = f->start; 43 f->stop = (char*)f->start + n - 1; 44 f->flush = fmtStrFlush; 45 f->farg = (void*)n; 46 f->nfmt = 0; 47 return 0; 48 } 49 50 /* 51 * print into an allocated string buffer 52 */ 53 char* vsmprint(char * fmt,va_list args)54vsmprint(char *fmt, va_list args) 55 { 56 Fmt f; 57 int n; 58 59 if(fmtstrinit(&f) < 0) 60 return nil; 61 f.args = args; 62 n = dofmt(&f, fmt); 63 if(f.start == nil) /* realloc failed? */ 64 return nil; 65 if(n < 0){ 66 free(f.start); 67 return nil; 68 } 69 setmalloctag(f.start, getcallerpc(&fmt)); 70 *(char*)f.to = '\0'; 71 return f.start; 72 } 73