]> mj.ucw.cz Git - libucw.git/blob - lib/ff-printf.c
Another thing about the C standard I didn't know: passing a va_list to
[libucw.git] / lib / ff-printf.c
1 /*
2  *      UCW Library -- Printf on Fastbuf Streams
3  *
4  *      (c) 2002 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/fastbuf.h"
12
13 #include <alloca.h>
14
15 int
16 vbprintf(struct fastbuf *b, char *msg, va_list args)
17 {
18   byte *buf;
19   int len, r;
20   va_list args2;
21
22   len = bdirect_write_prepare(b, &buf);
23   if (len >= 16)
24     {
25       va_copy(args2, args);
26       r = vsnprintf(buf, len, msg, args2);
27       if (r < 0)
28         len = 256;
29       else if (r < len)
30         {
31           bdirect_write_commit(b, buf+r);
32           return r;
33         }
34       else
35         len = r+1;
36     }
37   else
38     len = 256;
39
40   while (1)
41     {
42       buf = alloca(len);
43       va_copy(args2, args);
44       r = vsnprintf(buf, len, msg, args2);
45       if (r < 0)
46         len += len;
47       else if (r < len)
48         {
49           bwrite(b, buf, r);
50           return r;
51         }
52       else
53         len = r+1;
54     }
55 }
56
57 int
58 bprintf(struct fastbuf *b, char *msg, ...)
59 {
60   va_list args;
61   int res;
62
63   va_start(args, msg);
64   res = vbprintf(b, msg, args);
65   va_end(args);
66   return res;
67 }
68
69 #ifdef TEST
70
71 int main(void)
72 {
73   struct fastbuf *b = bfdopen_shared(1, 65536);
74   for (int i=0; i<10000; i++)
75     bprintf(b, "13=%d str=<%s> msg=%m\n", 13, "str");
76   bclose(b);
77   return 0;
78 }
79
80 #endif