Cleaned up some of the comments ... removed vestiges of last year's doxygen experiment
[citadel.git] / webcit / snprintf.c
1 /*
2  * $Id$
3  */
4
5 /**
6  *  Replacements for snprintf() and vsnprintf()
7  *
8  * Use it only if you have the "spare" cycles needed to effectively
9  * do every snprintf operation twice! Why is that? Because everything
10  * is first vfprintf()'d to /dev/null to determine the number of bytes.
11  * Perhaps a bit slow for demanding applications on slow machines,
12  * no problem for a fast machine with some spare cycles.
13  *
14  * You don't have a /dev/null? Every Linux contains one for free!
15  *
16  * Because the format string is never even looked at, all current and
17  * possible future printf-conversions should be handled just fine.
18  *
19  * Written July 1997 by Sten Gunterberg (gunterberg@ergon.ch)
20  */
21
22 #include "webcit.h"
23 #include "webserver.h"
24
25 /**
26  *  is it needed????
27  *  fmt the formatstring?
28  *  argp how many params?
29  */
30 static int needed(const char *fmt, va_list argp)
31 {
32         static FILE *sink = NULL;
33
34         /**
35          * ok, there's a small race here that could result in the sink being
36          * opened more than once if we're threaded, but I'd rather ignore it than
37          * spend cycles synchronizing :-) */
38
39         if (sink == NULL) {
40                 if ((sink = fopen("/dev/null", "w")) == NULL) {
41                         perror("/dev/null");
42                         exit(1);
43                 }
44         }
45         return vfprintf(sink, fmt, argp);
46 }
47
48 /**
49  *  vsnprintf wrapper
50  *  buf the output charbuffer
51  *  max maximal size of the buffer
52  *  fmt the formatstring (see man printf)
53  *  argp the variable argument list 
54  */
55 int vsnprintf(char *buf, size_t max, const char *fmt, va_list argp)
56 {
57         char *p;
58         int size;
59
60         if ((p = malloc(needed(fmt, argp) + 1)) == NULL) {
61                 lprintf(1, "vsnprintf: malloc failed, aborting\n");
62                 abort();
63         }
64         if ((size = vsprintf(p, fmt, argp)) >= max)
65                 size = -1;
66
67         strncpy(buf, p, max);
68         buf[max - 1] = 0;
69         free(p);
70         return size;
71 }
72
73 /**
74  *  snprintf wrapper
75  *  buf the output charbuffer
76  *  max maximal size of the buffer
77  *  fmt the formatstring (see man printf)
78  *  ... the variable argument list 
79  */
80 int snprintf(char *buf, size_t max, const char *fmt,...)
81 {
82         va_list argp;
83         int bytes;
84
85         va_start(argp, fmt);
86         bytes = vsnprintf(buf, max, fmt, argp);
87         va_end(argp);
88
89         return bytes;
90 }
91
92