/*++ /* NAME /* vbuf_print 3 /* SUMMARY /* formatted print to generic buffer /* SYNOPSIS /* #include <stdarg.h> /* #include <vbuf_print.h> /* /* VBUF *vbuf_print(bp, format, ap) /* VBUF *bp; /* const char *format; /* va_list ap; /* DESCRIPTION /* vbuf_print() appends data to the named buffer according to its /* \fIformat\fR argument. It understands the s, c, d, u, o, x, X, p, e, /* f and g format types, the l modifier, field width and precision, /* sign, and padding with zeros or spaces. /* /* In addition, vbuf_print() recognizes the %m format specifier /* and expands it to the error message corresponding to the current /* value of the global \fIerrno\fR variable. /* REENTRANCY /* .ad /* .fi /* vbuf_print() allocates a static buffer. After completion /* of the first vbuf_print() call, this buffer is safe for /* reentrant vbuf_print() calls by (asynchronous) terminating /* signal handlers or by (synchronous) terminating error /* handlers. vbuf_print() initialization typically happens /* upon the first formatted output to a VSTRING or VSTREAM. /* /* However, it is up to the caller to ensure that the destination /* VSTREAM or VSTRING buffer is protected against reentrant usage. /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /* /* Wietse Venema /* Google, Inc. /* 111 8th Avenue /* New York, NY 10011, USA /* /* Wietse Venema /* porcupine.org
/*--*/
/* *Helpermacros...Notethatthereisnoneedtochecktheresultfrom *VSTRING_SPACE()becausethatalwayssucceedsorneverreturns.
*/ #ifndef NO_SNPRINTF #define VBUF_SNPRINTF(bp, sz, fmt, arg) do { \
ssize_t _ret; \ if (VBUF_SPACE((bp), (sz)) != 0) \ return (bp); \
_ret = snprintf((char *) (bp)->ptr, (bp)->cnt, (fmt), (arg)); \ if (_ret < 0) \
msg_panic("%s: output error for '%s'", myname, mystrdup(fmt)); \ if (_ret >= (bp)->cnt) \
msg_panic("%s: output for '%s' exceeds space %ld", \
myname, mystrdup(fmt), (long) (bp)->cnt); \
VBUF_SKIP(bp); \
} while (0) #else #define VBUF_SNPRINTF(bp, sz, fmt, arg) do { \ if (VBUF_SPACE((bp), (sz)) != 0) \ return (bp); \
sprintf((char *) (bp)->ptr, (fmt), (arg)); \
VBUF_SKIP(bp); \
} while (0) #endif
#define VBUF_SKIP(bp) do { \ while ((bp)->cnt > 0 && *(bp)->ptr) \
(bp)->ptr++, (bp)->cnt--; \
} while (0)
#define VSTRING_ADDNUM(vp, n) do { \
VBUF_SNPRINTF(&(vp)->vbuf, INT_SPACE, "%d", n); \
} while (0)
#define VBUF_STRCAT(bp, s) do { \ unsignedchar *_cp = (unsignedchar *) (s); \ int _ch; \ while ((_ch = *_cp++) != 0) \
VBUF_PUT((bp), _ch); \
} while (0)
/* vbuf_print - format string, vsprintf-like interface */
VBUF *vbuf_print(VBUF *bp, constchar *format, va_list ap)
{ constchar *myname = "vbuf_print"; static VSTRING *fmt; /* format specifier */ unsignedchar *cp; int width; /* width and numerical precision */ int prec; /* are signed for overflow defense */ unsigned long_flag; /* long long, or long integer */ unsigned intmax_flag; /* intmax_t */ int ch; char *s; int saved_errno = errno; /* VBUF_SPACE() may clobber it */
/* *Assumethatformatstringsareshort.
*/ if (fmt == 0)
fmt = vstring_alloc(INT_SPACE);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.