1 #include <u.h> 2 #include <libc.h> 3 #include "fmtdef.h" 4 5 static int runeFmtStrFlush(Fmt * f)6runeFmtStrFlush(Fmt *f) 7 { 8 Rune *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, sizeof(Rune)*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 = (Rune*)f->start + ((Rune*)f->to - s); 26 f->stop = (Rune*)f->start + n - 1; 27 return 1; 28 } 29 30 int runefmtstrinit(Fmt * f)31runefmtstrinit(Fmt *f) 32 { 33 int n; 34 35 memset(f, 0, sizeof *f); 36 f->runes = 1; 37 n = 32; 38 f->start = malloc(sizeof(Rune)*n); 39 if(f->start == nil) 40 return -1; 41 setmalloctag(f->start, getcallerpc(&f)); 42 f->to = f->start; 43 f->stop = (Rune*)f->start + n - 1; 44 f->flush = runeFmtStrFlush; 45 f->farg = (void*)n; 46 f->nfmt = 0; 47 return 0; 48 } 49 50 /* 51 * print into an allocated string buffer 52 */ 53 Rune* runevsmprint(char * fmt,va_list args)54runevsmprint(char *fmt, va_list args) 55 { 56 Fmt f; 57 int n; 58 59 if(runefmtstrinit(&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 *(Rune*)f.to = '\0'; 71 return f.start; 72 } 73