/src/ntp-dev/libntp/xsbprintf.c
Line | Count | Source (jump to first uncovered line) |
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 |
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 | 0 | { |
39 | 0 | char *pbuf = (ppbuf) ? *ppbuf : NULL; |
40 | 0 | int rc = -1; |
41 | 0 | if (pbuf && (pend - pbuf > 0)) { |
42 | 0 | size_t blen = (size_t)(pend - pbuf); |
43 | 0 | rc = vsnprintf(pbuf, blen, pfmt, va); |
44 | 0 | if (rc > 0) { |
45 | 0 | if ((size_t)rc >= blen) |
46 | 0 | rc = 0; |
47 | 0 | pbuf += rc; |
48 | 0 | } |
49 | 0 | *pbuf = '\0'; /* fear of bad vsnprintf */ |
50 | 0 | *ppbuf = pbuf; |
51 | 0 | } else { |
52 | 0 | errno = EINVAL; |
53 | 0 | } |
54 | 0 | return rc; |
55 | 0 | } |
56 | | |
57 | | /* variadic wrapper around the buffer string formatter */ |
58 | | int |
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 | 0 | { |
66 | 0 | va_list va; |
67 | 0 | int rc; |
68 | | |
69 | 0 | va_start(va, pfmt); |
70 | 0 | rc = xvsbprintf(ppbuf, pend, pfmt, va); |
71 | 0 | va_end(va); |
72 | 0 | return rc; |
73 | 0 | } |
74 | | |
75 | | /* that's all folks! */ |