]> mj.ucw.cz Git - libucw.git/blob - lib/mempool-fmt.c
Well, a simple variant of stk_conv.
[libucw.git] / lib / mempool-fmt.c
1 /*
2  *      UCW Library -- Memory Pools (Formatting)
3  *
4  *      (c) 2005 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/mempool.h"
12
13 #include <alloca.h>
14 #include <stdio.h>
15 #include <string.h>
16
17 char *
18 mp_vprintf(struct mempool *p, char *fmt, va_list args)
19 {
20   char *ret = p->free;
21   int free = p->last - p->free;
22   if (!free)
23     {
24       ret = mp_alloc(p, 1);
25       free = p->last - p->free;
26     }
27   va_list args2;
28   va_copy(args2, args);
29   int cnt = vsnprintf(ret, free, fmt, args2);
30   va_end(args2);
31   if (cnt < 0)
32     {
33       /* Our C library doesn't support C99 return value of vsnprintf, so we need to iterate */
34       uns len = 128;
35       char *buf;
36       do
37         {
38           len *= 2;
39           buf = alloca(len);
40           va_copy(args2, args);
41           cnt = vsnprintf(buf, len, fmt, args2);
42           va_end(args2);
43         }
44       while (cnt < 0);
45       ret = mp_alloc(p, cnt+1);
46       memcpy(ret, buf, cnt+1);
47     }
48   else if (cnt < free)
49     p->free += cnt + 1;
50   else
51     {
52       ret = mp_alloc(p, cnt+1);
53       va_copy(args2, args);
54       int cnt2 = vsnprintf(ret, cnt+1, fmt, args2);
55       va_end(args2);
56       ASSERT(cnt2 == cnt);
57     }
58   return ret;
59 }
60
61 char *
62 mp_printf(struct mempool *p, char *fmt, ...)
63 {
64   va_list args;
65   va_start(args, fmt);
66   char *res = mp_vprintf(p, fmt, args);
67   va_end(args);
68   return res;
69 }
70
71 #ifdef TEST
72
73 int main(void)
74 {
75   struct mempool *mp = mp_new(64);
76   char *x = mp_printf(mp, "<Hello, %s!>", "World");
77   fputs(x, stdout);
78   x = mp_printf(mp, "<Hello, %50s!>\n", "World");
79   fputs(x, stdout);
80   return 0;
81 }
82
83 #endif