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