1 /* 2 * The authors of this software are Rob Pike and Ken Thompson. 3 * Copyright (c) 2002 by Lucent Technologies. 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose without fee is hereby granted, provided that this entire notice 6 * is included in all copies of any software which is or includes a copy 7 * or modification of this software and in all copies of the supporting 8 * documentation for such software. 9 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 10 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE 11 * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 12 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 13 */ 14 #include <u.h> 15 #include <libc.h> 16 #include "fmtdef.h" 17 18 static int 19 runeFmtStrFlush(Fmt *f) 20 { 21 Rune *s; 22 int n; 23 24 if(f->start == nil) 25 return 0; 26 n = (uintptr)f->farg; 27 n *= 2; 28 s = (Rune*)f->start; 29 f->start = realloc(s, sizeof(Rune)*n); 30 if(f->start == nil){ 31 f->farg = nil; 32 f->to = nil; 33 f->stop = nil; 34 free(s); 35 return 0; 36 } 37 f->farg = (void*)(uintptr)n; 38 f->to = (Rune*)f->start + ((Rune*)f->to - s); 39 f->stop = (Rune*)f->start + n - 1; 40 return 1; 41 } 42 43 int 44 runefmtstrinit(Fmt *f) 45 { 46 int n; 47 48 memset(f, 0, sizeof *f); 49 f->runes = 1; 50 n = 32; 51 f->start = malloc(sizeof(Rune)*n); 52 if(f->start == nil) 53 return -1; 54 f->to = f->start; 55 f->stop = (Rune*)f->start + n - 1; 56 f->flush = runeFmtStrFlush; 57 f->farg = (void*)(uintptr)n; 58 f->nfmt = 0; 59 return 0; 60 } 61 62 /* 63 * print into an allocated string buffer 64 */ 65 Rune* 66 runevsmprint(char *fmt, va_list args) 67 { 68 Fmt f; 69 int n; 70 71 if(runefmtstrinit(&f) < 0) 72 return nil; 73 VA_COPY(f.args,args); 74 n = dofmt(&f, fmt); 75 VA_END(f.args); 76 if(f.start == nil) 77 return nil; 78 if(n < 0){ 79 free(f.start); 80 return nil; 81 } 82 *(Rune*)f.to = '\0'; 83 return (Rune*)f.start; 84 } 85