1 /*
2 * xsbprintf.c - string buffer formatting helpers
3 *
4 * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
5 * The contents of 'html/copyright.html' apply.
6 */
7
8 #include <config.h>
9 #include <sys/types.h>
10
11 #include "ntp_stdlib.h"
12
13 /* eXtended Varlist String Buffer printf
14 *
15 * Formats via 'vsnprintf' into a string buffer, with some semantic
16 * specialties:
17 *
18 * - The start of the buffer pointer is updated according to the number
19 * of characters written.
20 * - If the buffer is insufficient to format the number of charactes,
21 * the partial result will be be discarded, and zero is returned to
22 * indicate nothing was written to the buffer.
23 * - On successful formatting, the return code is the return value of
24 * the inner call to 'vsnprintf()'.
25 * - If there is any error, the state of the buffer will not be
26 * changed. (Bytes in the buffer might be smashed, but the buffer
27 * position does not change, and the NUL marker stays in place at the
28 * current buffer position.)
29 * - If '(*ppbuf - pend) <= 0' (or ppbuf is NULL), fail with EINVAL.
30 */
31 int
xvsbprintf(char ** ppbuf,char * const pend,char const * pfmt,va_list va)32 xvsbprintf(
33 char **ppbuf, /* pointer to buffer pointer (I/O) */
34 char * const pend, /* buffer end (I) */
35 char const *pfmt, /* printf-like format string */
36 va_list va /* formatting args for above */
37 )
38 {
39 char *pbuf = (ppbuf) ? *ppbuf : NULL;
40 int rc = -1;
41 if (pbuf && (pend - pbuf > 0)) {
42 size_t blen = (size_t)(pend - pbuf);
43 rc = vsnprintf(pbuf, blen, pfmt, va);
44 if (rc > 0) {
45 if ((size_t)rc >= blen)
46 rc = 0;
47 pbuf += rc;
48 }
49 *pbuf = '\0'; /* fear of bad vsnprintf */
50 *ppbuf = pbuf;
51 } else {
52 errno = EINVAL;
53 }
54 return rc;
55 }
56
57 /* variadic wrapper around the buffer string formatter */
58 int
xsbprintf(char ** ppbuf,char * const pend,char const * pfmt,...)59 xsbprintf(
60 char **ppbuf, /* pointer to buffer pointer (I/O) */
61 char * const pend, /* buffer end (I) */
62 char const *pfmt, /* printf-like format string */
63 ... /* formatting args for above */
64 )
65 {
66 va_list va;
67 int rc;
68
69 va_start(va, pfmt);
70 rc = xvsbprintf(ppbuf, pend, pfmt, va);
71 va_end(va);
72 return rc;
73 }
74
75 /* that's all folks! */
76