]> mj.ucw.cz Git - libucw.git/blob - lib/mempool-fmt.c
Added printf-like function with output to mempool.
[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   int cnt = vsnprintf(ret, free, fmt, args);
28   if (cnt < 0)
29     {
30       /* Our C library doesn't support C99 return value of vsnprintf, so we need to iterate */
31       uns len = 128;
32       char *buf;
33       do
34         {
35           len *= 2;
36           buf = alloca(len);
37           cnt = vsnprintf(buf, len, fmt, args);
38         }
39       while (cnt < 0);
40       ret = mp_alloc(p, cnt+1);
41       memcpy(ret, buf, cnt+1);
42     }
43   else if (cnt < free)
44     p->free += cnt + 1;
45   else
46     {
47       ret = mp_alloc(p, cnt+1);
48       int cnt2 = vsnprintf(ret, cnt+1, fmt, args);
49       ASSERT(cnt2 == cnt);
50     }
51   return ret;
52 }
53
54 char *
55 mp_printf(struct mempool *p, char *fmt, ...)
56 {
57   va_list args;
58   va_start(args, fmt);
59   char *res = mp_vprintf(p, fmt, args);
60   va_end(args);
61   return res;
62 }
63
64 #ifdef TEST
65
66 int main(void)
67 {
68   struct mempool *mp = mp_new(64);
69   char *x = mp_printf(mp, "Hello, %s!\n", "World");
70   fputs(x, stdout);
71   x = mp_printf(mp, "Hello, %100s!\n", "World");
72   fputs(x, stdout);
73   return 0;
74 }
75
76 #endif