175067f4fSPoul-Henning Kamp /*- 275067f4fSPoul-Henning Kamp * Copyright (c) 2005 Poul-Henning Kamp 375067f4fSPoul-Henning Kamp * Copyright (c) 1990, 1993 475067f4fSPoul-Henning Kamp * The Regents of the University of California. All rights reserved. 575067f4fSPoul-Henning Kamp * 675067f4fSPoul-Henning Kamp * This code is derived from software contributed to Berkeley by 775067f4fSPoul-Henning Kamp * Chris Torek. 875067f4fSPoul-Henning Kamp * 975067f4fSPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without 1075067f4fSPoul-Henning Kamp * modification, are permitted provided that the following conditions 1175067f4fSPoul-Henning Kamp * are met: 1275067f4fSPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright 1375067f4fSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer. 1475067f4fSPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright 1575067f4fSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the 1675067f4fSPoul-Henning Kamp * documentation and/or other materials provided with the distribution. 1775067f4fSPoul-Henning Kamp * 3. Neither the name of the University nor the names of its contributors 1875067f4fSPoul-Henning Kamp * may be used to endorse or promote products derived from this software 1975067f4fSPoul-Henning Kamp * without specific prior written permission. 2075067f4fSPoul-Henning Kamp * 2175067f4fSPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2275067f4fSPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2375067f4fSPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2475067f4fSPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2575067f4fSPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2675067f4fSPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2775067f4fSPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2875067f4fSPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2975067f4fSPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3075067f4fSPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3175067f4fSPoul-Henning Kamp * SUCH DAMAGE. 3275067f4fSPoul-Henning Kamp * 3375067f4fSPoul-Henning Kamp * $FreeBSD$ 3475067f4fSPoul-Henning Kamp */ 3575067f4fSPoul-Henning Kamp 36c17bf9a9SJohn Baldwin #include "namespace.h" 3775067f4fSPoul-Henning Kamp #include <err.h> 3875067f4fSPoul-Henning Kamp #include <sys/types.h> 3975067f4fSPoul-Henning Kamp #include <stdio.h> 4075067f4fSPoul-Henning Kamp #include <stddef.h> 4175067f4fSPoul-Henning Kamp #include <stdlib.h> 4275067f4fSPoul-Henning Kamp #include <locale.h> 4375067f4fSPoul-Henning Kamp #include <stdint.h> 4475067f4fSPoul-Henning Kamp #include <assert.h> 4575067f4fSPoul-Henning Kamp #include <stdarg.h> 4675067f4fSPoul-Henning Kamp #include <namespace.h> 4775067f4fSPoul-Henning Kamp #include <string.h> 4875067f4fSPoul-Henning Kamp #include <wchar.h> 49c17bf9a9SJohn Baldwin #include "un-namespace.h" 5075067f4fSPoul-Henning Kamp 511b0181dfSJohn Baldwin #include "local.h" 5275067f4fSPoul-Henning Kamp #include "printf.h" 5375067f4fSPoul-Henning Kamp #include "fvwrite.h" 5475067f4fSPoul-Henning Kamp 5575067f4fSPoul-Henning Kamp int __use_xprintf = -1; 5675067f4fSPoul-Henning Kamp 5775067f4fSPoul-Henning Kamp /* private stuff -----------------------------------------------------*/ 5875067f4fSPoul-Henning Kamp 5975067f4fSPoul-Henning Kamp union arg { 6075067f4fSPoul-Henning Kamp int intarg; 6175067f4fSPoul-Henning Kamp long longarg; 6275067f4fSPoul-Henning Kamp intmax_t intmaxarg; 6375067f4fSPoul-Henning Kamp #ifndef NO_FLOATING_POINT 6475067f4fSPoul-Henning Kamp double doublearg; 6575067f4fSPoul-Henning Kamp long double longdoublearg; 6675067f4fSPoul-Henning Kamp #endif 6775067f4fSPoul-Henning Kamp wint_t wintarg; 6875067f4fSPoul-Henning Kamp char *pchararg; 6975067f4fSPoul-Henning Kamp wchar_t *pwchararg; 7075067f4fSPoul-Henning Kamp void *pvoidarg; 7175067f4fSPoul-Henning Kamp }; 7275067f4fSPoul-Henning Kamp 7375067f4fSPoul-Henning Kamp /* 7475067f4fSPoul-Henning Kamp * Macros for converting digits to letters and vice versa 7575067f4fSPoul-Henning Kamp */ 7675067f4fSPoul-Henning Kamp #define to_digit(c) ((c) - '0') 7775067f4fSPoul-Henning Kamp #define is_digit(c) (((unsigned)to_digit(c)) <= 9) 7875067f4fSPoul-Henning Kamp 7975067f4fSPoul-Henning Kamp /* various globals ---------------------------------------------------*/ 8075067f4fSPoul-Henning Kamp 8175067f4fSPoul-Henning Kamp const char __lowercase_hex[17] = "0123456789abcdef?"; /*lint !e784 */ 8275067f4fSPoul-Henning Kamp const char __uppercase_hex[17] = "0123456789ABCDEF?"; /*lint !e784 */ 8375067f4fSPoul-Henning Kamp 8475067f4fSPoul-Henning Kamp #define PADSIZE 16 8575067f4fSPoul-Henning Kamp static char blanks[PADSIZE] = 8675067f4fSPoul-Henning Kamp {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 8775067f4fSPoul-Henning Kamp static char zeroes[PADSIZE] = 8875067f4fSPoul-Henning Kamp {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 8975067f4fSPoul-Henning Kamp 9075067f4fSPoul-Henning Kamp /* printing and padding functions ------------------------------------*/ 9175067f4fSPoul-Henning Kamp 9275067f4fSPoul-Henning Kamp #define NIOV 8 9375067f4fSPoul-Henning Kamp 9475067f4fSPoul-Henning Kamp struct __printf_io { 9575067f4fSPoul-Henning Kamp FILE *fp; 9675067f4fSPoul-Henning Kamp struct __suio uio; 9775067f4fSPoul-Henning Kamp struct __siov iov[NIOV]; 9875067f4fSPoul-Henning Kamp struct __siov *iovp; 9975067f4fSPoul-Henning Kamp }; 10075067f4fSPoul-Henning Kamp 10175067f4fSPoul-Henning Kamp static void 10275067f4fSPoul-Henning Kamp __printf_init(struct __printf_io *io) 10375067f4fSPoul-Henning Kamp { 10475067f4fSPoul-Henning Kamp 10575067f4fSPoul-Henning Kamp io->uio.uio_iov = io->iovp = &io->iov[0]; 10675067f4fSPoul-Henning Kamp io->uio.uio_resid = 0; 10775067f4fSPoul-Henning Kamp io->uio.uio_iovcnt = 0; 10875067f4fSPoul-Henning Kamp } 10975067f4fSPoul-Henning Kamp 11075067f4fSPoul-Henning Kamp void 11175067f4fSPoul-Henning Kamp __printf_flush(struct __printf_io *io) 11275067f4fSPoul-Henning Kamp { 11375067f4fSPoul-Henning Kamp 11475067f4fSPoul-Henning Kamp __sfvwrite(io->fp, &io->uio); 11575067f4fSPoul-Henning Kamp __printf_init(io); 11675067f4fSPoul-Henning Kamp } 11775067f4fSPoul-Henning Kamp 11875067f4fSPoul-Henning Kamp int 11975067f4fSPoul-Henning Kamp __printf_puts(struct __printf_io *io, const void *ptr, int len) 12075067f4fSPoul-Henning Kamp { 12175067f4fSPoul-Henning Kamp 12275067f4fSPoul-Henning Kamp 12375067f4fSPoul-Henning Kamp if (io->fp->_flags & __SERR) 12475067f4fSPoul-Henning Kamp return (0); 12575067f4fSPoul-Henning Kamp if (len == 0) 12675067f4fSPoul-Henning Kamp return (0); 12775067f4fSPoul-Henning Kamp io->iovp->iov_base = __DECONST(void *, ptr); 12875067f4fSPoul-Henning Kamp io->iovp->iov_len = len; 12975067f4fSPoul-Henning Kamp io->uio.uio_resid += len; 13075067f4fSPoul-Henning Kamp io->iovp++; 13175067f4fSPoul-Henning Kamp io->uio.uio_iovcnt++; 13275067f4fSPoul-Henning Kamp if (io->uio.uio_iovcnt >= NIOV) 13375067f4fSPoul-Henning Kamp __printf_flush(io); 13475067f4fSPoul-Henning Kamp return (len); 13575067f4fSPoul-Henning Kamp } 13675067f4fSPoul-Henning Kamp 13775067f4fSPoul-Henning Kamp int 13875067f4fSPoul-Henning Kamp __printf_pad(struct __printf_io *io, int howmany, int zero) 13975067f4fSPoul-Henning Kamp { 14075067f4fSPoul-Henning Kamp int n; 14175067f4fSPoul-Henning Kamp const char *with; 14275067f4fSPoul-Henning Kamp int ret = 0; 14375067f4fSPoul-Henning Kamp 14475067f4fSPoul-Henning Kamp if (zero) 14575067f4fSPoul-Henning Kamp with = zeroes; 14675067f4fSPoul-Henning Kamp else 14775067f4fSPoul-Henning Kamp with = blanks; 14875067f4fSPoul-Henning Kamp 14975067f4fSPoul-Henning Kamp if ((n = (howmany)) > 0) { 15075067f4fSPoul-Henning Kamp while (n > PADSIZE) { 15175067f4fSPoul-Henning Kamp ret += __printf_puts(io, with, PADSIZE); 15275067f4fSPoul-Henning Kamp n -= PADSIZE; 15375067f4fSPoul-Henning Kamp } 15475067f4fSPoul-Henning Kamp ret += __printf_puts(io, with, n); 15575067f4fSPoul-Henning Kamp } 15675067f4fSPoul-Henning Kamp return (ret); 15775067f4fSPoul-Henning Kamp } 15875067f4fSPoul-Henning Kamp 15975067f4fSPoul-Henning Kamp int 16075067f4fSPoul-Henning Kamp __printf_out(struct __printf_io *io, const struct printf_info *pi, const void *ptr, int len) 16175067f4fSPoul-Henning Kamp { 16275067f4fSPoul-Henning Kamp int ret = 0; 16375067f4fSPoul-Henning Kamp 16475067f4fSPoul-Henning Kamp if ((!pi->left) && pi->width > len) 16575067f4fSPoul-Henning Kamp ret += __printf_pad(io, pi->width - len, pi->pad == '0'); 16675067f4fSPoul-Henning Kamp ret += __printf_puts(io, ptr, len); 16775067f4fSPoul-Henning Kamp if (pi->left && pi->width > len) 16875067f4fSPoul-Henning Kamp ret += __printf_pad(io, pi->width - len, pi->pad == '0'); 16975067f4fSPoul-Henning Kamp return (ret); 17075067f4fSPoul-Henning Kamp } 17175067f4fSPoul-Henning Kamp 17275067f4fSPoul-Henning Kamp 17375067f4fSPoul-Henning Kamp /* percent handling -------------------------------------------------*/ 17475067f4fSPoul-Henning Kamp 17575067f4fSPoul-Henning Kamp static int 17675067f4fSPoul-Henning Kamp __printf_arginfo_pct(const struct printf_info *pi __unused, size_t n __unused, int *argt __unused) 17775067f4fSPoul-Henning Kamp { 17875067f4fSPoul-Henning Kamp 17975067f4fSPoul-Henning Kamp return (0); 18075067f4fSPoul-Henning Kamp } 18175067f4fSPoul-Henning Kamp 18275067f4fSPoul-Henning Kamp static int 18375067f4fSPoul-Henning Kamp __printf_render_pct(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg __unused) 18475067f4fSPoul-Henning Kamp { 18575067f4fSPoul-Henning Kamp 18675067f4fSPoul-Henning Kamp return (__printf_puts(io, "%", 1)); 18775067f4fSPoul-Henning Kamp } 18875067f4fSPoul-Henning Kamp 18975067f4fSPoul-Henning Kamp /* 'n' ---------------------------------------------------------------*/ 19075067f4fSPoul-Henning Kamp 19175067f4fSPoul-Henning Kamp static int 19275067f4fSPoul-Henning Kamp __printf_arginfo_n(const struct printf_info *pi, size_t n, int *argt) 19375067f4fSPoul-Henning Kamp { 19475067f4fSPoul-Henning Kamp 19575067f4fSPoul-Henning Kamp assert(n >= 1); 19675067f4fSPoul-Henning Kamp argt[0] = PA_POINTER; 19775067f4fSPoul-Henning Kamp return (1); 19875067f4fSPoul-Henning Kamp } 19975067f4fSPoul-Henning Kamp 20075067f4fSPoul-Henning Kamp /* 20175067f4fSPoul-Henning Kamp * This is a printf_render so that all output has been flushed before it 20275067f4fSPoul-Henning Kamp * gets called. 20375067f4fSPoul-Henning Kamp */ 20475067f4fSPoul-Henning Kamp 20575067f4fSPoul-Henning Kamp static int 20675067f4fSPoul-Henning Kamp __printf_render_n(FILE *io __unused, const struct printf_info *pi, const void *const *arg) 20775067f4fSPoul-Henning Kamp { 20875067f4fSPoul-Henning Kamp 20975067f4fSPoul-Henning Kamp if (pi->is_char) 21075067f4fSPoul-Henning Kamp **((signed char **)arg[0]) = (signed char)pi->sofar; 21175067f4fSPoul-Henning Kamp else if (pi->is_short) 21275067f4fSPoul-Henning Kamp **((short **)arg[0]) = (short)pi->sofar; 21375067f4fSPoul-Henning Kamp else if (pi->is_long) 21475067f4fSPoul-Henning Kamp **((long **)arg[0]) = pi->sofar; 21575067f4fSPoul-Henning Kamp else if (pi->is_long_double) 21675067f4fSPoul-Henning Kamp **((long long **)arg[0]) = pi->sofar; 21775067f4fSPoul-Henning Kamp else if (pi->is_intmax) 21875067f4fSPoul-Henning Kamp **((intmax_t **)arg[0]) = pi->sofar; 21975067f4fSPoul-Henning Kamp else if (pi->is_ptrdiff) 22075067f4fSPoul-Henning Kamp **((ptrdiff_t **)arg[0]) = pi->sofar; 22175067f4fSPoul-Henning Kamp else if (pi->is_quad) 22275067f4fSPoul-Henning Kamp **((quad_t **)arg[0]) = pi->sofar; 22375067f4fSPoul-Henning Kamp else if (pi->is_size) 22475067f4fSPoul-Henning Kamp **((size_t **)arg[0]) = pi->sofar; 22575067f4fSPoul-Henning Kamp else 22675067f4fSPoul-Henning Kamp **((int **)arg[0]) = pi->sofar; 22775067f4fSPoul-Henning Kamp 22875067f4fSPoul-Henning Kamp return (0); 22975067f4fSPoul-Henning Kamp } 23075067f4fSPoul-Henning Kamp 23175067f4fSPoul-Henning Kamp /* table -------------------------------------------------------------*/ 23275067f4fSPoul-Henning Kamp 23375067f4fSPoul-Henning Kamp /*lint -esym(785, printf_tbl) */ 23475067f4fSPoul-Henning Kamp static struct { 23575067f4fSPoul-Henning Kamp printf_arginfo_function *arginfo; 23675067f4fSPoul-Henning Kamp printf_function *gnurender; 23775067f4fSPoul-Henning Kamp printf_render *render; 23875067f4fSPoul-Henning Kamp } printf_tbl[256] = { 23975067f4fSPoul-Henning Kamp ['%'] = { __printf_arginfo_pct, NULL, __printf_render_pct }, 24075067f4fSPoul-Henning Kamp ['A'] = { __printf_arginfo_float, NULL, __printf_render_float }, 24175067f4fSPoul-Henning Kamp ['C'] = { __printf_arginfo_chr, NULL, __printf_render_chr }, 24275067f4fSPoul-Henning Kamp ['E'] = { __printf_arginfo_float, NULL, __printf_render_float }, 24375067f4fSPoul-Henning Kamp ['F'] = { __printf_arginfo_float, NULL, __printf_render_float }, 24475067f4fSPoul-Henning Kamp ['G'] = { __printf_arginfo_float, NULL, __printf_render_float }, 24575067f4fSPoul-Henning Kamp ['S'] = { __printf_arginfo_str, NULL, __printf_render_str }, 24675067f4fSPoul-Henning Kamp ['X'] = { __printf_arginfo_int, NULL, __printf_render_int }, 24775067f4fSPoul-Henning Kamp ['a'] = { __printf_arginfo_float, NULL, __printf_render_float }, 24875067f4fSPoul-Henning Kamp ['c'] = { __printf_arginfo_chr, NULL, __printf_render_chr }, 24975067f4fSPoul-Henning Kamp ['d'] = { __printf_arginfo_int, NULL, __printf_render_int }, 25075067f4fSPoul-Henning Kamp ['e'] = { __printf_arginfo_float, NULL, __printf_render_float }, 25175067f4fSPoul-Henning Kamp ['f'] = { __printf_arginfo_float, NULL, __printf_render_float }, 25275067f4fSPoul-Henning Kamp ['g'] = { __printf_arginfo_float, NULL, __printf_render_float }, 25375067f4fSPoul-Henning Kamp ['i'] = { __printf_arginfo_int, NULL, __printf_render_int }, 25475067f4fSPoul-Henning Kamp ['n'] = { __printf_arginfo_n, __printf_render_n, NULL }, 25575067f4fSPoul-Henning Kamp ['o'] = { __printf_arginfo_int, NULL, __printf_render_int }, 25675067f4fSPoul-Henning Kamp ['p'] = { __printf_arginfo_ptr, NULL, __printf_render_ptr }, 25775067f4fSPoul-Henning Kamp ['q'] = { __printf_arginfo_int, NULL, __printf_render_int }, 25875067f4fSPoul-Henning Kamp ['s'] = { __printf_arginfo_str, NULL, __printf_render_str }, 25975067f4fSPoul-Henning Kamp ['u'] = { __printf_arginfo_int, NULL, __printf_render_int }, 26075067f4fSPoul-Henning Kamp ['x'] = { __printf_arginfo_int, NULL, __printf_render_int }, 26175067f4fSPoul-Henning Kamp }; 26275067f4fSPoul-Henning Kamp 26375067f4fSPoul-Henning Kamp 26475067f4fSPoul-Henning Kamp static int 265525cd732SKonstantin Belousov __v2printf(FILE *fp, const char *fmt0, unsigned pct, va_list ap) 26675067f4fSPoul-Henning Kamp { 26775067f4fSPoul-Henning Kamp struct printf_info *pi, *pil; 26875067f4fSPoul-Henning Kamp const char *fmt; 26975067f4fSPoul-Henning Kamp int ch; 27075067f4fSPoul-Henning Kamp struct printf_info pia[pct + 10]; 27175067f4fSPoul-Henning Kamp int argt[pct + 10]; 27275067f4fSPoul-Henning Kamp union arg args[pct + 10]; 27375067f4fSPoul-Henning Kamp int nextarg; 27475067f4fSPoul-Henning Kamp int maxarg; 27575067f4fSPoul-Henning Kamp int ret = 0; 27675067f4fSPoul-Henning Kamp int n; 27775067f4fSPoul-Henning Kamp struct __printf_io io; 27875067f4fSPoul-Henning Kamp 27975067f4fSPoul-Henning Kamp __printf_init(&io); 28075067f4fSPoul-Henning Kamp io.fp = fp; 28175067f4fSPoul-Henning Kamp 28275067f4fSPoul-Henning Kamp fmt = fmt0; 28375067f4fSPoul-Henning Kamp maxarg = 0; 28475067f4fSPoul-Henning Kamp nextarg = 1; 28575067f4fSPoul-Henning Kamp memset(argt, 0, sizeof argt); 28675067f4fSPoul-Henning Kamp for (pi = pia; ; pi++) { 28775067f4fSPoul-Henning Kamp memset(pi, 0, sizeof *pi); 28875067f4fSPoul-Henning Kamp pil = pi; 28975067f4fSPoul-Henning Kamp if (*fmt == '\0') 29075067f4fSPoul-Henning Kamp break; 29175067f4fSPoul-Henning Kamp pil = pi + 1; 29275067f4fSPoul-Henning Kamp pi->prec = -1; 29375067f4fSPoul-Henning Kamp pi->pad = ' '; 29475067f4fSPoul-Henning Kamp pi->begin = pi->end = fmt; 29575067f4fSPoul-Henning Kamp while (*fmt != '\0' && *fmt != '%') 29675067f4fSPoul-Henning Kamp pi->end = ++fmt; 29775067f4fSPoul-Henning Kamp if (*fmt == '\0') 29875067f4fSPoul-Henning Kamp break; 29975067f4fSPoul-Henning Kamp fmt++; 30075067f4fSPoul-Henning Kamp for (;;) { 30175067f4fSPoul-Henning Kamp pi->spec = *fmt; 30275067f4fSPoul-Henning Kamp switch (pi->spec) { 30375067f4fSPoul-Henning Kamp case ' ': 30475067f4fSPoul-Henning Kamp /*- 30575067f4fSPoul-Henning Kamp * ``If the space and + flags both appear, the space 30675067f4fSPoul-Henning Kamp * flag will be ignored.'' 30775067f4fSPoul-Henning Kamp * -- ANSI X3J11 30875067f4fSPoul-Henning Kamp */ 30975067f4fSPoul-Henning Kamp if (pi->showsign == 0) 31075067f4fSPoul-Henning Kamp pi->showsign = ' '; 31175067f4fSPoul-Henning Kamp fmt++; 31275067f4fSPoul-Henning Kamp continue; 31375067f4fSPoul-Henning Kamp case '#': 31475067f4fSPoul-Henning Kamp pi->alt = 1; 31575067f4fSPoul-Henning Kamp fmt++; 31675067f4fSPoul-Henning Kamp continue; 31775067f4fSPoul-Henning Kamp case '.': 31875067f4fSPoul-Henning Kamp pi->prec = 0; 31975067f4fSPoul-Henning Kamp fmt++; 32075067f4fSPoul-Henning Kamp if (*fmt == '*') { 32175067f4fSPoul-Henning Kamp fmt++; 32275067f4fSPoul-Henning Kamp pi->get_prec = nextarg; 32375067f4fSPoul-Henning Kamp argt[nextarg++] = PA_INT; 32475067f4fSPoul-Henning Kamp continue; 32575067f4fSPoul-Henning Kamp } 32675067f4fSPoul-Henning Kamp while (*fmt != '\0' && is_digit(*fmt)) { 32775067f4fSPoul-Henning Kamp pi->prec *= 10; 32875067f4fSPoul-Henning Kamp pi->prec += to_digit(*fmt); 32975067f4fSPoul-Henning Kamp fmt++; 33075067f4fSPoul-Henning Kamp } 33175067f4fSPoul-Henning Kamp continue; 33275067f4fSPoul-Henning Kamp case '-': 33375067f4fSPoul-Henning Kamp pi->left = 1; 33475067f4fSPoul-Henning Kamp fmt++; 33575067f4fSPoul-Henning Kamp continue; 33675067f4fSPoul-Henning Kamp case '+': 33775067f4fSPoul-Henning Kamp pi->showsign = '+'; 33875067f4fSPoul-Henning Kamp fmt++; 33975067f4fSPoul-Henning Kamp continue; 34075067f4fSPoul-Henning Kamp case '*': 34175067f4fSPoul-Henning Kamp fmt++; 34275067f4fSPoul-Henning Kamp pi->get_width = nextarg; 34375067f4fSPoul-Henning Kamp argt[nextarg++] = PA_INT; 34475067f4fSPoul-Henning Kamp continue; 34575067f4fSPoul-Henning Kamp case '%': 34675067f4fSPoul-Henning Kamp fmt++; 34775067f4fSPoul-Henning Kamp break; 34875067f4fSPoul-Henning Kamp case '\'': 34975067f4fSPoul-Henning Kamp pi->group = 1; 35075067f4fSPoul-Henning Kamp fmt++; 35175067f4fSPoul-Henning Kamp continue; 35275067f4fSPoul-Henning Kamp case '0': 35375067f4fSPoul-Henning Kamp /*- 35475067f4fSPoul-Henning Kamp * ``Note that 0 is taken as a flag, not as the 35575067f4fSPoul-Henning Kamp * beginning of a field width.'' 35675067f4fSPoul-Henning Kamp * -- ANSI X3J11 35775067f4fSPoul-Henning Kamp */ 35875067f4fSPoul-Henning Kamp pi->pad = '0'; 35975067f4fSPoul-Henning Kamp fmt++; 36075067f4fSPoul-Henning Kamp continue; 36175067f4fSPoul-Henning Kamp case '1': case '2': case '3': 36275067f4fSPoul-Henning Kamp case '4': case '5': case '6': 36375067f4fSPoul-Henning Kamp case '7': case '8': case '9': 36475067f4fSPoul-Henning Kamp n = 0; 36575067f4fSPoul-Henning Kamp while (*fmt != '\0' && is_digit(*fmt)) { 36675067f4fSPoul-Henning Kamp n *= 10; 36775067f4fSPoul-Henning Kamp n += to_digit(*fmt); 36875067f4fSPoul-Henning Kamp fmt++; 36975067f4fSPoul-Henning Kamp } 37075067f4fSPoul-Henning Kamp if (*fmt == '$') { 37175067f4fSPoul-Henning Kamp if (nextarg > maxarg) 37275067f4fSPoul-Henning Kamp maxarg = nextarg; 37375067f4fSPoul-Henning Kamp nextarg = n; 37475067f4fSPoul-Henning Kamp fmt++; 37575067f4fSPoul-Henning Kamp } else 37675067f4fSPoul-Henning Kamp pi->width = n; 37775067f4fSPoul-Henning Kamp continue; 37875067f4fSPoul-Henning Kamp case 'D': 37975067f4fSPoul-Henning Kamp case 'O': 38075067f4fSPoul-Henning Kamp case 'U': 38175067f4fSPoul-Henning Kamp pi->spec += ('a' - 'A'); 38275067f4fSPoul-Henning Kamp pi->is_intmax = 0; 38375067f4fSPoul-Henning Kamp if (pi->is_long_double || pi->is_quad) { 38475067f4fSPoul-Henning Kamp pi->is_long = 0; 38575067f4fSPoul-Henning Kamp pi->is_long_double = 1; 38675067f4fSPoul-Henning Kamp } else { 38775067f4fSPoul-Henning Kamp pi->is_long = 1; 38875067f4fSPoul-Henning Kamp pi->is_long_double = 0; 38975067f4fSPoul-Henning Kamp } 39075067f4fSPoul-Henning Kamp fmt++; 39175067f4fSPoul-Henning Kamp break; 39275067f4fSPoul-Henning Kamp case 'j': 39375067f4fSPoul-Henning Kamp pi->is_intmax = 1; 39475067f4fSPoul-Henning Kamp fmt++; 39575067f4fSPoul-Henning Kamp continue; 39675067f4fSPoul-Henning Kamp case 'q': 39775067f4fSPoul-Henning Kamp pi->is_long = 0; 39875067f4fSPoul-Henning Kamp pi->is_quad = 1; 39975067f4fSPoul-Henning Kamp fmt++; 40075067f4fSPoul-Henning Kamp continue; 40175067f4fSPoul-Henning Kamp case 'L': 40275067f4fSPoul-Henning Kamp pi->is_long_double = 1; 40375067f4fSPoul-Henning Kamp fmt++; 40475067f4fSPoul-Henning Kamp continue; 40575067f4fSPoul-Henning Kamp case 'h': 40675067f4fSPoul-Henning Kamp fmt++; 40775067f4fSPoul-Henning Kamp if (*fmt == 'h') { 40875067f4fSPoul-Henning Kamp fmt++; 40975067f4fSPoul-Henning Kamp pi->is_char = 1; 41075067f4fSPoul-Henning Kamp } else { 41175067f4fSPoul-Henning Kamp pi->is_short = 1; 41275067f4fSPoul-Henning Kamp } 41375067f4fSPoul-Henning Kamp continue; 41475067f4fSPoul-Henning Kamp case 'l': 41575067f4fSPoul-Henning Kamp fmt++; 41675067f4fSPoul-Henning Kamp if (*fmt == 'l') { 41775067f4fSPoul-Henning Kamp fmt++; 41875067f4fSPoul-Henning Kamp pi->is_long_double = 1; 41975067f4fSPoul-Henning Kamp pi->is_quad = 0; 42075067f4fSPoul-Henning Kamp } else { 42175067f4fSPoul-Henning Kamp pi->is_quad = 0; 42275067f4fSPoul-Henning Kamp pi->is_long = 1; 42375067f4fSPoul-Henning Kamp } 42475067f4fSPoul-Henning Kamp continue; 42575067f4fSPoul-Henning Kamp case 't': 42675067f4fSPoul-Henning Kamp pi->is_ptrdiff = 1; 42775067f4fSPoul-Henning Kamp fmt++; 42875067f4fSPoul-Henning Kamp continue; 42975067f4fSPoul-Henning Kamp case 'z': 43075067f4fSPoul-Henning Kamp pi->is_size = 1; 43175067f4fSPoul-Henning Kamp fmt++; 43275067f4fSPoul-Henning Kamp continue; 43375067f4fSPoul-Henning Kamp default: 43475067f4fSPoul-Henning Kamp fmt++; 43575067f4fSPoul-Henning Kamp break; 43675067f4fSPoul-Henning Kamp } 43775067f4fSPoul-Henning Kamp if (printf_tbl[pi->spec].arginfo == NULL) 43875067f4fSPoul-Henning Kamp errx(1, "arginfo[%c] = NULL", pi->spec); 43975067f4fSPoul-Henning Kamp ch = printf_tbl[pi->spec].arginfo( 44075067f4fSPoul-Henning Kamp pi, __PRINTFMAXARG, &argt[nextarg]); 44175067f4fSPoul-Henning Kamp if (ch > 0) 44275067f4fSPoul-Henning Kamp pi->arg[0] = &args[nextarg]; 44375067f4fSPoul-Henning Kamp if (ch > 1) 44475067f4fSPoul-Henning Kamp pi->arg[1] = &args[nextarg + 1]; 44575067f4fSPoul-Henning Kamp nextarg += ch; 44675067f4fSPoul-Henning Kamp break; 44775067f4fSPoul-Henning Kamp } 44875067f4fSPoul-Henning Kamp } 44975067f4fSPoul-Henning Kamp if (nextarg > maxarg) 45075067f4fSPoul-Henning Kamp maxarg = nextarg; 45175067f4fSPoul-Henning Kamp #if 0 45275067f4fSPoul-Henning Kamp fprintf(stderr, "fmt0 <%s>\n", fmt0); 45375067f4fSPoul-Henning Kamp fprintf(stderr, "pil %p\n", pil); 45475067f4fSPoul-Henning Kamp #endif 45575067f4fSPoul-Henning Kamp for (ch = 1; ch < maxarg; ch++) { 45675067f4fSPoul-Henning Kamp #if 0 45775067f4fSPoul-Henning Kamp fprintf(stderr, "arg %d %x\n", ch, argt[ch]); 45875067f4fSPoul-Henning Kamp #endif 45975067f4fSPoul-Henning Kamp switch(argt[ch]) { 46075067f4fSPoul-Henning Kamp case PA_CHAR: 46175067f4fSPoul-Henning Kamp args[ch].intarg = (char)va_arg (ap, int); 46275067f4fSPoul-Henning Kamp break; 46375067f4fSPoul-Henning Kamp case PA_INT: 46475067f4fSPoul-Henning Kamp args[ch].intarg = va_arg (ap, int); 46575067f4fSPoul-Henning Kamp break; 46675067f4fSPoul-Henning Kamp case PA_INT | PA_FLAG_SHORT: 46775067f4fSPoul-Henning Kamp args[ch].intarg = (short)va_arg (ap, int); 46875067f4fSPoul-Henning Kamp break; 46975067f4fSPoul-Henning Kamp case PA_INT | PA_FLAG_LONG: 47075067f4fSPoul-Henning Kamp args[ch].longarg = va_arg (ap, long); 47175067f4fSPoul-Henning Kamp break; 47275067f4fSPoul-Henning Kamp case PA_INT | PA_FLAG_INTMAX: 47375067f4fSPoul-Henning Kamp args[ch].intmaxarg = va_arg (ap, intmax_t); 47475067f4fSPoul-Henning Kamp break; 47575067f4fSPoul-Henning Kamp case PA_INT | PA_FLAG_QUAD: 47675067f4fSPoul-Henning Kamp args[ch].intmaxarg = va_arg (ap, quad_t); 47775067f4fSPoul-Henning Kamp break; 47875067f4fSPoul-Henning Kamp case PA_INT | PA_FLAG_LONG_LONG: 47975067f4fSPoul-Henning Kamp args[ch].intmaxarg = va_arg (ap, long long); 48075067f4fSPoul-Henning Kamp break; 48175067f4fSPoul-Henning Kamp case PA_INT | PA_FLAG_SIZE: 48275067f4fSPoul-Henning Kamp args[ch].intmaxarg = va_arg (ap, size_t); 48375067f4fSPoul-Henning Kamp break; 48475067f4fSPoul-Henning Kamp case PA_INT | PA_FLAG_PTRDIFF: 48575067f4fSPoul-Henning Kamp args[ch].intmaxarg = va_arg (ap, ptrdiff_t); 48675067f4fSPoul-Henning Kamp break; 48775067f4fSPoul-Henning Kamp case PA_WCHAR: 48875067f4fSPoul-Henning Kamp args[ch].wintarg = va_arg (ap, wint_t); 48975067f4fSPoul-Henning Kamp break; 49075067f4fSPoul-Henning Kamp case PA_POINTER: 49175067f4fSPoul-Henning Kamp args[ch].pvoidarg = va_arg (ap, void *); 49275067f4fSPoul-Henning Kamp break; 49375067f4fSPoul-Henning Kamp case PA_STRING: 49475067f4fSPoul-Henning Kamp args[ch].pchararg = va_arg (ap, char *); 49575067f4fSPoul-Henning Kamp break; 49675067f4fSPoul-Henning Kamp case PA_WSTRING: 49775067f4fSPoul-Henning Kamp args[ch].pwchararg = va_arg (ap, wchar_t *); 49875067f4fSPoul-Henning Kamp break; 49975067f4fSPoul-Henning Kamp case PA_DOUBLE: 50075239a01SPoul-Henning Kamp #ifndef NO_FLOATING_POINT 50175067f4fSPoul-Henning Kamp args[ch].doublearg = va_arg (ap, double); 50275239a01SPoul-Henning Kamp #endif 50375067f4fSPoul-Henning Kamp break; 50475067f4fSPoul-Henning Kamp case PA_DOUBLE | PA_FLAG_LONG_DOUBLE: 50575239a01SPoul-Henning Kamp #ifndef NO_FLOATING_POINT 50675067f4fSPoul-Henning Kamp args[ch].longdoublearg = va_arg (ap, long double); 50775239a01SPoul-Henning Kamp #endif 50875067f4fSPoul-Henning Kamp break; 50975067f4fSPoul-Henning Kamp default: 51075067f4fSPoul-Henning Kamp errx(1, "argtype = %x (fmt = \"%s\")\n", 51175067f4fSPoul-Henning Kamp argt[ch], fmt0); 51275067f4fSPoul-Henning Kamp } 51375067f4fSPoul-Henning Kamp } 51475067f4fSPoul-Henning Kamp for (pi = pia; pi < pil; pi++) { 51575067f4fSPoul-Henning Kamp #if 0 51675067f4fSPoul-Henning Kamp fprintf(stderr, "pi %p", pi); 51775067f4fSPoul-Henning Kamp fprintf(stderr, " spec '%c'", pi->spec); 51875067f4fSPoul-Henning Kamp fprintf(stderr, " args %d", 51975067f4fSPoul-Henning Kamp ((uintptr_t)pi->arg[0] - (uintptr_t)args) / sizeof args[0]); 52075067f4fSPoul-Henning Kamp if (pi->width) fprintf(stderr, " width %d", pi->width); 52175067f4fSPoul-Henning Kamp if (pi->pad) fprintf(stderr, " pad 0x%x", pi->pad); 52275067f4fSPoul-Henning Kamp if (pi->left) fprintf(stderr, " left"); 52375067f4fSPoul-Henning Kamp if (pi->showsign) fprintf(stderr, " showsign"); 52475067f4fSPoul-Henning Kamp if (pi->prec != -1) fprintf(stderr, " prec %d", pi->prec); 52575067f4fSPoul-Henning Kamp if (pi->is_char) fprintf(stderr, " char"); 52675067f4fSPoul-Henning Kamp if (pi->is_short) fprintf(stderr, " short"); 52775067f4fSPoul-Henning Kamp if (pi->is_long) fprintf(stderr, " long"); 52875067f4fSPoul-Henning Kamp if (pi->is_long_double) fprintf(stderr, " long_double"); 52975067f4fSPoul-Henning Kamp fprintf(stderr, "\n"); 53075067f4fSPoul-Henning Kamp fprintf(stderr, "\t\"%.*s\"\n", pi->end - pi->begin, pi->begin); 53175067f4fSPoul-Henning Kamp #endif 53275067f4fSPoul-Henning Kamp if (pi->get_width) { 53375067f4fSPoul-Henning Kamp pi->width = args[pi->get_width].intarg; 53475067f4fSPoul-Henning Kamp /*- 53575067f4fSPoul-Henning Kamp * ``A negative field width argument is taken as a 53675067f4fSPoul-Henning Kamp * - flag followed by a positive field width.'' 53775067f4fSPoul-Henning Kamp * -- ANSI X3J11 53875067f4fSPoul-Henning Kamp * They don't exclude field widths read from args. 53975067f4fSPoul-Henning Kamp */ 54075067f4fSPoul-Henning Kamp if (pi->width < 0) { 54175067f4fSPoul-Henning Kamp pi->left = 1; 54275067f4fSPoul-Henning Kamp pi->width = -pi->width; 54375067f4fSPoul-Henning Kamp } 54475067f4fSPoul-Henning Kamp } 54575067f4fSPoul-Henning Kamp if (pi->get_prec) 54675067f4fSPoul-Henning Kamp pi->prec = args[pi->get_prec].intarg; 54775067f4fSPoul-Henning Kamp ret += __printf_puts(&io, pi->begin, pi->end - pi->begin); 54875067f4fSPoul-Henning Kamp if (printf_tbl[pi->spec].gnurender != NULL) { 54975067f4fSPoul-Henning Kamp __printf_flush(&io); 55075067f4fSPoul-Henning Kamp pi->sofar = ret; 55175067f4fSPoul-Henning Kamp ret += printf_tbl[pi->spec].gnurender( 55275067f4fSPoul-Henning Kamp fp, pi, (const void *)pi->arg); 55375067f4fSPoul-Henning Kamp } else if (printf_tbl[pi->spec].render != NULL) { 55475067f4fSPoul-Henning Kamp pi->sofar = ret; 55575067f4fSPoul-Henning Kamp n = printf_tbl[pi->spec].render( 55675067f4fSPoul-Henning Kamp &io, pi, (const void *)pi->arg); 55775067f4fSPoul-Henning Kamp if (n < 0) 55875067f4fSPoul-Henning Kamp io.fp->_flags |= __SERR; 55975067f4fSPoul-Henning Kamp else 56075067f4fSPoul-Henning Kamp ret += n; 56175067f4fSPoul-Henning Kamp } else if (pi->begin == pi->end) 56275067f4fSPoul-Henning Kamp errx(1, "render[%c] = NULL", *fmt); 56375067f4fSPoul-Henning Kamp } 56475067f4fSPoul-Henning Kamp __printf_flush(&io); 56575067f4fSPoul-Henning Kamp return (ret); 56675067f4fSPoul-Henning Kamp } 56775067f4fSPoul-Henning Kamp 56875067f4fSPoul-Henning Kamp extern int __fflush(FILE *fp); 56975067f4fSPoul-Henning Kamp 57075067f4fSPoul-Henning Kamp /* 57175067f4fSPoul-Henning Kamp * Helper function for `fprintf to unbuffered unix file': creates a 57275067f4fSPoul-Henning Kamp * temporary buffer. We only work on write-only files; this avoids 57375067f4fSPoul-Henning Kamp * worries about ungetc buffers and so forth. 57475067f4fSPoul-Henning Kamp */ 57575067f4fSPoul-Henning Kamp static int 57675067f4fSPoul-Henning Kamp __v3printf(FILE *fp, const char *fmt, int pct, va_list ap) 57775067f4fSPoul-Henning Kamp { 57875067f4fSPoul-Henning Kamp int ret; 5791b0181dfSJohn Baldwin FILE fake = FAKE_FILE; 58075067f4fSPoul-Henning Kamp unsigned char buf[BUFSIZ]; 58175067f4fSPoul-Henning Kamp 58275067f4fSPoul-Henning Kamp /* copy the important variables */ 58375067f4fSPoul-Henning Kamp fake._flags = fp->_flags & ~__SNBF; 58475067f4fSPoul-Henning Kamp fake._file = fp->_file; 58575067f4fSPoul-Henning Kamp fake._cookie = fp->_cookie; 58675067f4fSPoul-Henning Kamp fake._write = fp->_write; 5871e98f887SJohn Baldwin fake._orientation = fp->_orientation; 5881e98f887SJohn Baldwin fake._mbstate = fp->_mbstate; 58975067f4fSPoul-Henning Kamp 59075067f4fSPoul-Henning Kamp /* set up the buffer */ 59175067f4fSPoul-Henning Kamp fake._bf._base = fake._p = buf; 59275067f4fSPoul-Henning Kamp fake._bf._size = fake._w = sizeof(buf); 59375067f4fSPoul-Henning Kamp fake._lbfsize = 0; /* not actually used, but Just In Case */ 59475067f4fSPoul-Henning Kamp 59575067f4fSPoul-Henning Kamp /* do the work, then copy any error status */ 59675067f4fSPoul-Henning Kamp ret = __v2printf(&fake, fmt, pct, ap); 59775067f4fSPoul-Henning Kamp if (ret >= 0 && __fflush(&fake)) 59875067f4fSPoul-Henning Kamp ret = EOF; 59975067f4fSPoul-Henning Kamp if (fake._flags & __SERR) 60075067f4fSPoul-Henning Kamp fp->_flags |= __SERR; 60175067f4fSPoul-Henning Kamp return (ret); 60275067f4fSPoul-Henning Kamp } 60375067f4fSPoul-Henning Kamp 60475067f4fSPoul-Henning Kamp int 60575067f4fSPoul-Henning Kamp __xvprintf(FILE *fp, const char *fmt0, va_list ap) 60675067f4fSPoul-Henning Kamp { 60775067f4fSPoul-Henning Kamp unsigned u; 60875067f4fSPoul-Henning Kamp const char *p; 60975067f4fSPoul-Henning Kamp 61075067f4fSPoul-Henning Kamp /* Count number of '%' signs handling double '%' signs */ 61175067f4fSPoul-Henning Kamp for (p = fmt0, u = 0; *p; p++) { 61275067f4fSPoul-Henning Kamp if (*p != '%') 61375067f4fSPoul-Henning Kamp continue; 61475067f4fSPoul-Henning Kamp u++; 61575067f4fSPoul-Henning Kamp if (p[1] == '%') 61675067f4fSPoul-Henning Kamp p++; 61775067f4fSPoul-Henning Kamp } 61875067f4fSPoul-Henning Kamp 61975067f4fSPoul-Henning Kamp /* optimise fprintf(stderr) (and other unbuffered Unix files) */ 62075067f4fSPoul-Henning Kamp if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && 62175067f4fSPoul-Henning Kamp fp->_file >= 0) 62275067f4fSPoul-Henning Kamp return (__v3printf(fp, fmt0, u, ap)); 62375067f4fSPoul-Henning Kamp else 62475067f4fSPoul-Henning Kamp return (__v2printf(fp, fmt0, u, ap)); 62575067f4fSPoul-Henning Kamp } 62675067f4fSPoul-Henning Kamp 62775067f4fSPoul-Henning Kamp /* extending ---------------------------------------------------------*/ 62875067f4fSPoul-Henning Kamp 62975067f4fSPoul-Henning Kamp int 63075067f4fSPoul-Henning Kamp register_printf_function(int spec, printf_function *render, printf_arginfo_function *arginfo) 63175067f4fSPoul-Henning Kamp { 63275067f4fSPoul-Henning Kamp 63375067f4fSPoul-Henning Kamp if (spec > 255 || spec < 0) 63475067f4fSPoul-Henning Kamp return (-1); 63575067f4fSPoul-Henning Kamp printf_tbl[spec].gnurender = render; 63675067f4fSPoul-Henning Kamp printf_tbl[spec].arginfo = arginfo; 63775067f4fSPoul-Henning Kamp __use_xprintf = 1; 63875067f4fSPoul-Henning Kamp return (0); 63975067f4fSPoul-Henning Kamp } 64075067f4fSPoul-Henning Kamp 64175067f4fSPoul-Henning Kamp int 64275067f4fSPoul-Henning Kamp register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo) 64375067f4fSPoul-Henning Kamp { 64475067f4fSPoul-Henning Kamp 64575067f4fSPoul-Henning Kamp if (spec > 255 || spec < 0) 64675067f4fSPoul-Henning Kamp return (-1); 64775067f4fSPoul-Henning Kamp printf_tbl[spec].render = render; 64875067f4fSPoul-Henning Kamp printf_tbl[spec].arginfo = arginfo; 64975067f4fSPoul-Henning Kamp __use_xprintf = 1; 65075067f4fSPoul-Henning Kamp return (0); 65175067f4fSPoul-Henning Kamp } 65275067f4fSPoul-Henning Kamp 65375067f4fSPoul-Henning Kamp int 654*988a521bSPawel Jakub Dawidek register_printf_render_std(const char *specs) 65575067f4fSPoul-Henning Kamp { 65675067f4fSPoul-Henning Kamp 65775067f4fSPoul-Henning Kamp for (; *specs != '\0'; specs++) { 65875067f4fSPoul-Henning Kamp switch (*specs) { 65975067f4fSPoul-Henning Kamp case 'H': 66075067f4fSPoul-Henning Kamp register_printf_render(*specs, 66175067f4fSPoul-Henning Kamp __printf_render_hexdump, 66275067f4fSPoul-Henning Kamp __printf_arginfo_hexdump); 66375067f4fSPoul-Henning Kamp break; 6646dbacee2SPoul-Henning Kamp case 'M': 6656dbacee2SPoul-Henning Kamp register_printf_render(*specs, 6666dbacee2SPoul-Henning Kamp __printf_render_errno, 6676dbacee2SPoul-Henning Kamp __printf_arginfo_errno); 6686dbacee2SPoul-Henning Kamp break; 6696dbacee2SPoul-Henning Kamp case 'Q': 6706dbacee2SPoul-Henning Kamp register_printf_render(*specs, 6716dbacee2SPoul-Henning Kamp __printf_render_quote, 6726dbacee2SPoul-Henning Kamp __printf_arginfo_quote); 6736dbacee2SPoul-Henning Kamp break; 67475067f4fSPoul-Henning Kamp case 'T': 67575067f4fSPoul-Henning Kamp register_printf_render(*specs, 67675067f4fSPoul-Henning Kamp __printf_render_time, 67775067f4fSPoul-Henning Kamp __printf_arginfo_time); 67875067f4fSPoul-Henning Kamp break; 67975067f4fSPoul-Henning Kamp case 'V': 68075067f4fSPoul-Henning Kamp register_printf_render(*specs, 68175067f4fSPoul-Henning Kamp __printf_render_vis, 68275067f4fSPoul-Henning Kamp __printf_arginfo_vis); 68375067f4fSPoul-Henning Kamp break; 68475067f4fSPoul-Henning Kamp default: 68575067f4fSPoul-Henning Kamp return (-1); 68675067f4fSPoul-Henning Kamp } 68775067f4fSPoul-Henning Kamp } 68875067f4fSPoul-Henning Kamp return (0); 68975067f4fSPoul-Henning Kamp } 69075067f4fSPoul-Henning Kamp 691