runevsmprint.c (1542B) download
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
21static int
22runeFmtStrFlush(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
44int 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 */
65Rune* 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}