Blob


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 /*
15 * Plan 9 port version must include libc.h in order to
16 * get Plan 9 debugging malloc, which sometimes returns
17 * different pointers than the standard malloc.
18 */
19 #ifdef PLAN9PORT
20 #include <u.h>
21 #include <libc.h>
22 #include "fmtdef.h"
23 #else
24 #include <stdlib.h>
25 #include <string.h>
26 #include "plan9.h"
27 #include "fmt.h"
28 #include "fmtdef.h"
29 #endif
31 static int
32 fmtStrFlush(Fmt *f)
33 {
34 char *s;
35 int n;
37 if(f->start == nil)
38 return 0;
39 n = (int)f->farg;
40 n *= 2;
41 s = (char*)f->start;
42 f->start = realloc(s, n);
43 if(f->start == nil){
44 f->farg = nil;
45 f->to = nil;
46 f->stop = nil;
47 free(s);
48 return 0;
49 }
50 f->farg = (void*)n;
51 f->to = (char*)f->start + ((char*)f->to - s);
52 f->stop = (char*)f->start + n - 1;
53 return 1;
54 }
56 int
57 fmtstrinit(Fmt *f)
58 {
59 int n;
61 memset(f, 0, sizeof *f);
62 f->runes = 0;
63 n = 32;
64 f->start = malloc(n);
65 if(f->start == nil)
66 return -1;
67 f->to = f->start;
68 f->stop = (char*)f->start + n - 1;
69 f->flush = fmtStrFlush;
70 f->farg = (void*)n;
71 f->nfmt = 0;
72 return 0;
73 }
75 /*
76 * print into an allocated string buffer
77 */
78 char*
79 vsmprint(char *fmt, va_list args)
80 {
81 Fmt f;
82 int n;
84 if(fmtstrinit(&f) < 0)
85 return nil;
86 VA_COPY(f.args,args);
87 n = dofmt(&f, fmt);
88 VA_END(f.args);
89 if(n < 0){
90 free(f.start);
91 return nil;
92 }
93 return fmtstrflush(&f);
94 }