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 { 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 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