runevsmprint.c (1542B)
1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */ 2 /* 3 * Plan 9 port version must include libc.h in order to 4 * get Plan 9 debugging malloc, which sometimes returns 5 * different pointers than the standard malloc. 6 */ 7 #ifdef PLAN9PORT 8 # include "fmtdef.h" 9 10 # include <libc.h> 11 # include <u.h> 12 #else 13 # include "fmt.h" 14 # include "fmtdef.h" 15 # include "plan9.h" 16 17 # include <stdlib.h> 18 # include <string.h> 19 #endif 20 21 static int 22 runeFmtStrFlush(Fmt* f) { 23 Rune* s; 24 int n; 25 26 if (f->start == nil) 27 return 0; 28 n = (uintptr) f->farg; 29 n *= 2; 30 s = (Rune*) f->start; 31 f->start = realloc(s, sizeof(Rune) * n); 32 if (f->start == nil) { 33 f->farg = nil; 34 f->to = nil; 35 f->stop = nil; 36 return 0; 37 } 38 f->farg = (void*) (uintptr) n; 39 f->to = (Rune*) f->start + ((Rune*) f->to - s); 40 f->stop = (Rune*) f->start + n - 1; 41 return 1; 42 } 43 44 int runefmtstrinit(Fmt* f) { 45 int n; 46 47 memset(f, 0, sizeof *f); 48 f->runes = 1; 49 n = 32; 50 f->start = malloc(sizeof(Rune) * n); 51 if (f->start == nil) 52 return -1; 53 f->to = f->start; 54 f->stop = (Rune*) f->start + n - 1; 55 f->flush = runeFmtStrFlush; 56 f->farg = (void*) (uintptr) n; 57 f->nfmt = 0; 58 fmtlocaleinit(f, nil, nil, nil); 59 return 0; 60 } 61 62 /* 63 * print into an allocated string buffer 64 */ 65 Rune* runevsmprint(char* fmt, va_list args) { 66 Fmt f; 67 int n; 68 69 if (runefmtstrinit(&f) < 0) 70 return nil; 71 VA_COPY(f.args, args); 72 n = dofmt(&f, fmt); 73 VA_END(f.args); 74 if (f.start == nil) 75 return nil; 76 if (n < 0) { 77 free(f.start); 78 return nil; 79 } 80 *(Rune*) f.to = '\0'; 81 return (Rune*) f.start; 82 }