12aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** @file
22aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Implementation of internals for printf and wprintf.
32aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
42aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
52aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    This program and the accompanying materials are licensed and made available
62aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    under the terms and conditions of the BSD License that accompanies this
72aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    distribution.  The full text of the license may be found at
82aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    http://opensource.org/licenses/bsd-license.
92aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Copyright (c) 1990, 1993
142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    The Regents of the University of California.  All rights reserved.
152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    This code is derived from software contributed to Berkeley by
172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Chris Torek.
182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Redistribution and use in source and binary forms, with or without
202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    modification, are permitted provided that the following conditions
212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    are met:
222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      - Redistributions of source code must retain the above copyright
232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        notice, this list of conditions and the following disclaimer.
242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      - Redistributions in binary form must reproduce the above copyright
252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        notice, this list of conditions and the following disclaimer in the
262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        documentation and/or other materials provided with the distribution.
272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      - Neither the name of the University nor the names of its contributors
282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        may be used to endorse or promote products derived from this software
292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        without specific prior written permission.
302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    POSSIBILITY OF SUCH DAMAGE.
422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    NetBSD: vfwprintf.c,v 1.9.2.1.4.1 2008/04/08 21:10:55 jdc Exp
442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    vfprintf.c  8.1 (Berkeley) 6/4/93
452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/
462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include  <LibConfig.h>
472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "namespace.h"
492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <sys/types.h>
502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <assert.h>
522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <ctype.h>
532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <limits.h>
542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <locale.h>
552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <stdarg.h>
562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <stddef.h>
572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <stdint.h>
582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <stdio.h>
592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <stdlib.h>
602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <string.h>
612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <errno.h>
622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <wchar.h>
632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <wctype.h>
642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "reentrant.h"
662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "local.h"
672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "extern.h"
682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "fvwrite.h"
692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef  _MSC_VER
712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  // Keep compiler quiet about conversions from larger to smaller types.
722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  #pragma warning ( disable : 4244 )
732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define MCHAR_T   char
772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define CHAR_T    wchar_t
782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define STRLEN(a) wcslen(a)
792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define MEMCHR(a, b, c) wmemchr(a, b, c)
802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define SCONV(a, b) __mbsconv(a, b)
812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define STRCONST(a) L ## a
822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define WDECL(a, b) a ## w ## b
832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define END_OF_FILE WEOF
842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define MULTI   0
852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define MCHAR_T   wchar_t
872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define CHAR_T    char
882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define STRLEN(a) strlen(a)
892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define MEMCHR(a, b, c) memchr(a, b, c)
902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define SCONV(a, b) __wcsconv(a, b)
912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define STRCONST(a) a
922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define WDECL(a, b) a ## b
932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define END_OF_FILE EOF
942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define MULTI   1
952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmunion arg {
982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int                 intarg;
992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  u_int               uintarg;
1002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  long                longarg;
1012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  unsigned long       ulongarg;
1022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  long long           longlongarg;
1032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  unsigned long long  ulonglongarg;
1042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ptrdiff_t           ptrdiffarg;
1052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  size_t              sizearg;
1062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  intmax_t            intmaxarg;
1072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uintmax_t           uintmaxarg;
1082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  void               *pvoidarg;
1092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char               *pchararg;
1102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  signed char        *pschararg;
1112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  short              *pshortarg;
1122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int                *pintarg;
1132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  long               *plongarg;
1142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  long long          *plonglongarg;
1152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ptrdiff_t          *pptrdiffarg;
1162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  size_t             *psizearg;
1172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  intmax_t           *pintmaxarg;
1182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
1192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  double              doublearg;
1202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  long double         longdoublearg;
1212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wint_t              wintarg;
1232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wchar_t            *pwchararg;
1242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm};
1252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
1272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Type ids for argument type table.
1282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
1292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmenum typeid {
1302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  T_UNUSED,   TP_SHORT,     T_INT,          T_U_INT,  TP_INT,
1312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  T_LONG,     T_U_LONG,     TP_LONG,        T_LLONG,  T_U_LLONG,
1322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  TP_LLONG,   T_PTRDIFFT,   TP_PTRDIFFT,    T_SIZET,  TP_SIZET,
1332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  T_INTMAXT,  T_UINTMAXT,   TP_INTMAXT,     TP_VOID,  TP_CHAR,
1342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  TP_SCHAR,   T_DOUBLE,     T_LONG_DOUBLE,  T_WINT,   TP_WCHAR
1352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm};
1362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int      __sbprintf(FILE *, const CHAR_T *, va_list);
1382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic CHAR_T  *__ujtoa(uintmax_t, CHAR_T *, int, int, const char *, int,
1392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                        char, const char *);
1402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic CHAR_T  *__ultoa(u_long, CHAR_T *, int, int, const char *, int,
1412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                        char, const char *);
1422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
1432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic CHAR_T  *__mbsconv(char *, int);
1442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic wint_t   __xfputwc(CHAR_T, FILE *);
1452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
1462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic char    *__wcsconv(wchar_t *, int);
1472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int      __sprint(FILE *, struct __suio *);
1482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int      __find_arguments(const CHAR_T *, va_list, union arg **);
1502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int      __grow_type_table(int, enum typeid **, int *);
1512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
1532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Helper function for `fprintf to unbuffered unix file': creates a
1542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * temporary buffer.  We only work on write-only files; this avoids
1552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * worries about ungetc buffers and so forth.
1562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
1572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int
1582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__sbprintf(FILE *fp, const CHAR_T *fmt, va_list ap)
1592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
1602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ret;
1612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  FILE fake;
1622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  struct __sfileext fakeext;
1632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  unsigned char buf[BUFSIZ];
1642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(fp != NULL);
1662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(fmt != NULL);
16753e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  if(fp == NULL) {
16853e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    errno = EINVAL;
16953e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    return (EOF);
17053e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  }
1712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _FILEEXT_SETUP(&fake, &fakeext);
1732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* copy the important variables */
1752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fake._flags   = fp->_flags & ~__SNBF;
1762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fake._file    = fp->_file;
1772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fake._cookie  = fp->_cookie;
1782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fake._write   = fp->_write;
1792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* set up the buffer */
1812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fake._bf._base  = fake._p = buf;
1822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fake._bf._size  = fake._w = sizeof(buf);
1832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fake._lbfsize   = 0;  /* not actually used, but Just In Case */
1842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* do the work, then copy any error status */
1862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ret = WDECL(__vf,printf_unlocked)(&fake, fmt, ap);
1872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (ret >= 0 && fflush(&fake))
1882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ret = END_OF_FILE;
1892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (fake._flags & __SERR)
1902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    fp->_flags |= __SERR;
1912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (ret);
1922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
1932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
1952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
1962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Like __fputwc, but handles fake string (__SSTR) files properly.
1972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * File must already be locked.
1982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
1992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic wint_t
2002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__xfputwc(wchar_t wc, FILE *fp)
2012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
2022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static const mbstate_t initial = { 0 };
2032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  mbstate_t mbs;
2042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char buf[MB_LEN_MAX];
2052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  struct __suio uio;
2062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  struct __siov iov;
2072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  size_t len;
2082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((fp->_flags & __SSTR) == 0)
2102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (__fputwc_unlock(wc, fp));
2112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  mbs = initial;
2132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
2142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    fp->_flags |= __SERR;
2152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (END_OF_FILE);
2162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
2172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_iov     = &iov;
2182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_resid   = (int)len;
2192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_iovcnt  = 1;
2202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  iov.iov_base    = buf;
2212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  iov.iov_len     = len;
2222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : END_OF_FILE);
2232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
2242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
2252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
2262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Flush out all the vectors defined by the given uio,
2272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * then reset it so that it can be reused.
2282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
2292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int
2302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__sprint(FILE *fp, struct __suio *uio)
2312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
2322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int err;
2332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(fp != NULL);
2352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(uio != NULL);
23653e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  if(fp == NULL) {
23753e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    errno = EINVAL;
23853e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    return (EOF);
23953e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  }
2402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (uio->uio_resid == 0) {
2422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    uio->uio_iovcnt = 0;
2432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (0);
2442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
2452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  err = __sfvwrite(fp, uio);
2462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio->uio_resid = 0;
2472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio->uio_iovcnt = 0;
2482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (err);
2492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
2502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
2512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
2532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Macros for converting digits to letters and vice versa
2542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
2552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define to_digit(c) ((c) - '0')
2562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define is_digit(c) ((unsigned)to_digit(c) <= 9)
2572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define to_char(n)  (CHAR_T)((n) + '0')
2582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
2602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Convert an unsigned long to ASCII for printf purposes, returning
2612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * a pointer to the first character of the string representation.
2622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Octal numbers can be forced to have a leading zero; hex numbers
2632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * use the given digits.
2642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
2652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic CHAR_T *
2662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__ultoa(u_long val, CHAR_T *endp, int base, int octzero, const char *xdigs,
2672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        int needgrp, char thousep, const char *grp)
2682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
2692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *cp = endp;
2702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  LONGN sval;
2712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ndig;
2722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
2742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Handle the three cases separately, in the hope of getting
2752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * better/faster code.
2762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
2772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  switch (base) {
2782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  case 10:
2792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (val < 10) { /* many numbers are 1 digit */
2802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(val);
2812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return (cp);
2822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ndig = 0;
2842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /*
2852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * On many machines, unsigned arithmetic is harder than
2862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * signed arithmetic, so we do at most one unsigned mod and
2872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * divide; this is sufficient to reduce the range of
2882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * the incoming value to where signed arithmetic works.
2892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     */
2902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (val > LONG_MAX) {
2912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(val % 10);
2922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ndig++;
2932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sval = (LONGN)(val / 10);
2942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } else
2952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sval = (LONGN)val;
2962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
2972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(sval % 10);
2982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ndig++;
2992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*
3002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * If (*grp == CHAR_MAX) then no more grouping
3012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * should be performed.
3022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
3032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (needgrp && ndig == *grp && *grp != CHAR_MAX
3042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          && sval > 9) {
3052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *--cp = thousep;
3062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ndig = 0;
3072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        /*
3082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * If (*(grp+1) == '\0') then we have to
3092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * use *grp character (last grouping rule)
3102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * for all next cases
3112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         */
3122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (*(grp+1) != '\0')
3132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          grp++;
3142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
3152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sval /= 10;
3162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } while (sval != 0);
3172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    break;
3182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  case 8:
3202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
3212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(val & 7);
3222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      val >>= 3;
3232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } while (val);
3242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (octzero && *cp != '0')
3252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = '0';
3262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    break;
3272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  case 16:
3292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
3302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = xdigs[(size_t)val & 15];
3312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      val >>= 4;
3322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } while (val);
3332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    break;
3342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  default:      /* oops */
3362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    abort();
3372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
3382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (cp);
3392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
3402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* Identical to __ultoa, but for intmax_t. */
3422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic CHAR_T *
3432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__ujtoa(uintmax_t val, CHAR_T *endp, int base, int octzero,
3442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        const char *xdigs, int needgrp, char thousep, const char *grp)
3452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
3462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *cp = endp;
3472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  intmax_t sval;
3482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ndig;
3492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* quick test for small values; __ultoa is typically much faster */
3512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* (perhaps instead we should run until small, then call __ultoa?) */
3522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (val <= ULONG_MAX)
3532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (__ultoa((u_long)val, endp, base, octzero, xdigs,
3542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        needgrp, thousep, grp));
3552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  switch (base) {
3562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  case 10:
3572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (val < 10) {
3582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(val % 10);
3592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return (cp);
3602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
3612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ndig = 0;
3622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (val > INTMAX_MAX) {
3632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(val % 10);
3642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ndig++;
3652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sval = val / 10;
3662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } else
3672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sval = val;
3682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
3692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(sval % 10);
3702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ndig++;
3712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*
3722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * If (*grp == CHAR_MAX) then no more grouping
3732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * should be performed.
3742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
3752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (needgrp && *grp != CHAR_MAX && ndig == *grp
3762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          && sval > 9) {
3772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *--cp = thousep;
3782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ndig = 0;
3792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        /*
3802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * If (*(grp+1) == '\0') then we have to
3812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * use *grp character (last grouping rule)
3822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * for all next cases
3832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         */
3842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (*(grp+1) != '\0')
3852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          grp++;
3862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
3872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sval /= 10;
3882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } while (sval != 0);
3892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    break;
3902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  case 8:
3922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
3932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = to_char(val & 7);
3942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      val >>= 3;
3952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } while (val);
3962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (octzero && *cp != '0')
3972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = '0';
3982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    break;
3992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  case 16:
4012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
4022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--cp = xdigs[(size_t)val & 15];
4032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      val >>= 4;
4042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } while (val);
4052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    break;
4062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  default:
4082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    abort();
4092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
4102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (cp);
4112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
4122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
4142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
4152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Convert a multibyte character string argument for the %s format to a wide
4162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * string representation. ``prec'' specifies the maximum number of bytes
4172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * to output. If ``prec'' is greater than or equal to zero, we can't assume
4182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * that the multibyte char. string ends in a null character.
4192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
4202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic wchar_t *
4212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__mbsconv(char *mbsarg, int prec)
4222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
4232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static const mbstate_t initial = { 0 };
4242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  mbstate_t mbs;
4252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wchar_t *convbuf, *wcp;
4262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  const char *p;
4272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  size_t insize, nchars, nconv;
4282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (mbsarg == NULL)
4302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (NULL);
4312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
4332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Supplied argument is a multibyte string; convert it to wide
4342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * characters first.
4352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
4362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (prec >= 0) {
4372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /*
4382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * String is not guaranteed to be NUL-terminated. Find the
4392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * number of characters to print.
4402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     */
4412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    p = mbsarg;
4422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    insize = nchars = nconv = 0;
4432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    mbs = initial;
4442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while (nchars != (size_t)prec) {
4452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      nconv = mbrlen(p, MB_CUR_MAX, &mbs);
4462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (nconv == 0 || nconv == (size_t)-1 ||
4472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          nconv == (size_t)-2)
4482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        break;
4492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      p += nconv;
4502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      nchars++;
4512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      insize += nconv;
4522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
4532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (nconv == (size_t)-1 || nconv == (size_t)-2)
4542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return (NULL);
4552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } else
4562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    insize = strlen(mbsarg);
4572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
4592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Allocate buffer for the result and perform the conversion,
4602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * converting at most `size' bytes of the input multibyte string to
4612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * wide characters for printing.
4622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
4632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  convbuf = malloc((insize + 1) * sizeof(*convbuf));
4642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (convbuf == NULL)
4652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (NULL);
4662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wcp = convbuf;
4672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  p = mbsarg;
4682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  mbs = initial;
4692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  nconv = 0;
4702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while (insize != 0) {
4712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    nconv = mbrtowc(wcp, p, insize, &mbs);
4722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
4732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
4742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    wcp++;
4752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    p += nconv;
4762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    insize -= nconv;
4772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
4782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (nconv == (size_t)-1 || nconv == (size_t)-2) {
4792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    free(convbuf);
4802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (NULL);
4812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
4822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  *wcp = L'\0';
4832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (convbuf);
4852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
4862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
4872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
4882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Convert a wide character string argument for the %ls format to a multibyte
4892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * string representation. If not -1, prec specifies the maximum number of
4902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * bytes to output, and also means that we can't assume that the wide char.
4912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * string ends is null-terminated.
4922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
4932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic char *
4942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__wcsconv(wchar_t *wcsarg, int prec)
4952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
4962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static const mbstate_t initial = { 0 };
4972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  mbstate_t mbs;
4982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char buf[MB_LEN_MAX];
4992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wchar_t *p;
5002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char *convbuf;
5012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  size_t clen, nbytes;
5022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* Allocate space for the maximum number of bytes we could output. */
5042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (prec < 0) {
5052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    p = wcsarg;
5062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    mbs = initial;
5072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
5082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (nbytes == (size_t)-1)
5092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return (NULL);
5102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } else {
5112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /*
5122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * Optimisation: if the output precision is small enough,
5132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * just allocate enough memory for the maximum instead of
5142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * scanning the string.
5152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     */
5162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (prec < 128)
5172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      nbytes = prec;
5182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else {
5192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      nbytes = 0;
5202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      p = wcsarg;
5212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      mbs = initial;
5222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      for (;;) {
5232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        clen = wcrtomb(buf, *p++, &mbs);
5242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (clen == 0 || clen == (size_t)-1 ||
5252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            nbytes + clen > (size_t)prec)
5262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          break;
5272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        nbytes += clen;
5282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
5292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
5302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
5312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((convbuf = malloc(nbytes + 1)) == NULL)
5322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (NULL);
5332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* Fill the output buffer. */
5352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  p = wcsarg;
5362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  mbs = initial;
5372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p,
5382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      nbytes, &mbs)) == (size_t)-1) {
5392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    free(convbuf);
5402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (NULL);
5412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
5422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  convbuf[nbytes] = '\0';
5432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (convbuf);
5442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
5452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
5482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * MT-safe version
5492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
5502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmint
5512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmWDECL(vf,printf)(FILE * __restrict fp, const CHAR_T * __restrict fmt0, va_list ap)
5522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
5532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ret;
5542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
55553e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  if(fp == NULL) {
55653e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    errno = EINVAL;
55753e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    return (EOF);
55853e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  }
5592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  FLOCKFILE(fp);
5602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ret = WDECL(__vf,printf_unlocked)(fp, fmt0, ap);
5612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  FUNLOCKFILE(fp);
5622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (ret);
5632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
5642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
5662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <float.h>
5682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <math.h>
5692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "floatio.h"
5702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define DEFPREC   6
5722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int exponent(CHAR_T *, int, int);
5742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef WIDE_DOUBLE
5752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic char *cvt(double, int, int, char *, int *, int, int *);
5762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* !NO_FLOATING_POINT */
5792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
5812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * The size of the buffer we use as scratch space for integer
5822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * conversions, among other things.  Technically, we would need the
5832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * most space for base 10 conversions with thousands' grouping
5842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * characters between each pair of digits.  100 bytes is a
5852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * conservative overestimate even for a 128-bit uintmax_t.
5862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
5872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define BUF 100
5882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define STATIC_ARG_TBL_SIZE 8           /* Size of static argument table. */
5902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
5922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Flags used during conversion.
5932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
5942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define ALT       0x001   /* alternate form */
5952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define LADJUST   0x004   /* left adjustment */
5962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define LONGDBL   0x008   /* long double */
5972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define LONGINT   0x010   /* long integer */
5982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define LLONGINT  0x020   /* long long integer */
5992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define SHORTINT  0x040   /* short integer */
6002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define ZEROPAD   0x080   /* zero (as opposed to blank) pad */
6012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define FPT       0x100   /* Floating point number */
6022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define GROUPING  0x200   /* use grouping ("'" flag) */
6032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          /* C99 additional size modifiers: */
6042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define SIZET     0x400   /* size_t */
6052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PTRDIFFT  0x800   /* ptrdiff_t */
6062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define INTMAXT   0x1000    /* intmax_t */
6072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define CHARINT   0x2000    /* print char using int format */
6082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
6092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
6102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Non-MT-safe version
6112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
6122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmint
6132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmWDECL(__vf,printf_unlocked)(FILE *fp, const CHAR_T *fmt0, va_list ap)
6142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
6152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *fmt;    /* format string */
6162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ch;     /* character from fmt */
6172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int n, n2;    /* handy integer (short term usage) */
6182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *cp;   /* handy char pointer (short term usage) */
6192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int flags;    /* flags as above */
6202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ret;    /* return value accumulator (number of items converted)*/
6212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int width;    /* width from format (%8d), or 0 */
6222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int prec;   /* precision from format; <0 for N/A */
6232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T sign;    /* sign prefix (' ', '+', '-', or \0) */
6242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char thousands_sep; /* locale specific thousands separator */
6252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  const char *grouping; /* locale specific numeric grouping rules */
6262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
6272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
6282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * We can decompose the printed representation of floating
6292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * point numbers into several parts, some of which may be empty:
6302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   *
6312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
6322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   *    A       B     ---C---      D       E   F
6332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   *
6342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * A: 'sign' holds this value if present; '\0' otherwise
6352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
6362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * C: cp points to the string MMMNNN.  Leading and trailing
6372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   *  zeros are not in the string and must be added.
6382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * D: expchar holds this character; '\0' if no exponent, e.g. %f
6392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * F: at least two digits for decimal, at least one digit for hex
6402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
6412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char *decimal_point;  /* locale specific decimal point */
6422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef WIDE_DOUBLE
6432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int signflag;   /* true if float is negative */
6442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  union {     /* floating point arguments %[aAeEfFgG] */
6452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    double dbl;
6462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    long double ldbl;
6472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } fparg;
6482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char *dtoaend;    /* pointer to end of converted digits */
6492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
6502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  double _double;   /* double precision arguments %[eEfgG] */
6512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char softsign;    /* temporary negative sign for floats */
6522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char *dtoaresult; /* buffer allocated by dtoa */
6542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int expt = 0;   /* integer value of exponent */
6552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char expchar;   /* exponent character: [eEpP\0] */
6562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int expsize;    /* character count for expstr */
6572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int lead;   /* sig figs before decimal or group sep */
6582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ndig;   /* actual number of digits returned by dtoa */
6592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
6602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int nseps;    /* number of group separators with ' */
6612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int nrepeats;   /* number of repeats of the last group */
6622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  u_long  ulval;    /* integer arguments %[diouxX] */
6642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uintmax_t ujval;  /* %j, %ll, %q, %t, %z integers */
6652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int base;   /* base for [diouxX] conversion */
6662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int dprec;    /* a copy of prec if [diouxX], 0 otherwise */
6672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int realsz;   /* field size expanded by dprec, sign, etc */
6682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int size;   /* size of converted field or string */
6692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int prsize;             /* max size of printed field */
6702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  const char *xdigs;  /* digits for %[xX] conversion */
6712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef NARROW
6722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define NIOV 8
6732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  struct __siov *iovp;  /* for PRINT macro */
6742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  struct __suio uio;  /* output information: summary */
6752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  struct __siov iov[NIOV];/* ... and individual io vectors */
6762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
6772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int n3;
6782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T buf[BUF];  /* buffer with space for digits of uintmax_t */
6802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T ox[2];   /* space for 0x hex-prefix */
6812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  union arg *argtable;  /* args, built due to positional arg */
6822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  union arg statargtable [STATIC_ARG_TBL_SIZE];
6832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int nextarg;    /* 1-based argument index */
6842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  va_list orgap;    /* original argument pointer */
6852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *convbuf;  /* multibyte to wide conversion result */
6862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
6872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
6882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Choose PADSIZE to trade efficiency vs. size.  If larger printf
6892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * fields occur frequently, increase PADSIZE and make the initialisers
6902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * below longer.
6912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
6922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PADSIZE 16    /* pad chunk size */
6932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static CHAR_T blanks[PADSIZE] =
6942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
6952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static CHAR_T zeroes[PADSIZE] =
6962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
6972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
6982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static const char xdigs_lower[17] = "0123456789abcdef";
6992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static const char xdigs_upper[17] = "0123456789ABCDEF";
7002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
7022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * BEWARE, these `goto error' on error, PRINT uses `n2' and
7032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * PAD uses `n'.
7042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
7052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
7062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PRINT(ptr, len) do {      \
7072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for (n3 = 0; n3 < (len); n3++)    \
7082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    __xfputwc((ptr)[n3], fp); \
7092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} while (/*CONSTCOND*/0)
7102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define FLUSH()
7112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
7122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PRINT(ptr, len) do { \
7132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  iovp->iov_base = __UNCONST(ptr); \
7142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  iovp->iov_len = (len); \
7152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_resid += (len); \
7162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  iovp++; \
7172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (++uio.uio_iovcnt >= NIOV) { \
7182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (__sprint(fp, &uio)) \
7192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto error; \
7202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    iovp = iov; \
7212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } \
7222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} while (/*CONSTCOND*/0)
7232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define FLUSH() do { \
7242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (uio.uio_resid && __sprint(fp, &uio)) \
7252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    goto error; \
7262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_iovcnt = 0; \
7272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  iovp = iov; \
7282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} while (/*CONSTCOND*/0)
7292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* NARROW */
7302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PAD(howmany, with)  do {    \
7322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((n = (howmany)) > 0) {    \
7332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while (n > PADSIZE) {   \
7342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PRINT(with, PADSIZE); \
7352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      n -= PADSIZE;   \
7362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }       \
7372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    PRINT(with, n);     \
7382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }         \
7392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} while (/*CONSTCOND*/0)
7402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PRINTANDPAD(p, ep, len, with) do {  \
7412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  n2 = (ep) - (p);            \
7422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (n2 > (len))       \
7432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    n2 = (len);     \
7442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (n2 > 0)       \
7452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    PRINT((p), n2);     \
7462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
7472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} while(/*CONSTCOND*/0)
7482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
7502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Get the argument indexed by nextarg.   If the argument table is
7512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * built, use it to get the argument.  If its not, get the next
7522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * argument (and arguments must be gotten sequentially).
7532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
7542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define GETARG(type) \
7552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ((/*CONSTCOND*/argtable != NULL) ? *((type*)(void*)(&argtable[nextarg++])) : \
7562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (nextarg++, va_arg(ap, type)))
7572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
7592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * To extend shorts properly, we need both signed and unsigned
7602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * argument extraction methods.
7612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
7622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define SARG() \
7632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ((long)(flags&LONGINT ? GETARG(long) : \
7642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&SHORTINT ? (short)GETARG(int) : \
7652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&CHARINT ? (signed char)GETARG(int) : \
7662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      GETARG(int)))
7672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define UARG() \
7692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ((u_long)(flags&LONGINT ? GETARG(u_long) : \
7702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
7712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
7722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (u_long)GETARG(u_int)))
7732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
7752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define SJARG() \
7772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (flags&INTMAXT ? GETARG(intmax_t) : \
7782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&SIZET ? (intmax_t)GETARG(size_t) : \
7792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
7802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (intmax_t)GETARG(long long))
7812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define UJARG() \
7832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (flags&INTMAXT ? GETARG(uintmax_t) : \
7842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&SIZET ? (uintmax_t)GETARG(size_t) : \
7852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
7862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (uintmax_t)GETARG(unsigned long long))
7872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
7892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Get * arguments, including the form *nn$.  Preserve the nextarg
7902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * that the argument can be gotten once the type is determined.
7912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
7922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define GETASTER(val) \
7932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  n2 = 0; \
7942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  cp = fmt; \
7952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while (is_digit(*cp)) { \
7962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    n2 = 10 * n2 + to_digit(*cp); \
7972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    cp++; \
7982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } \
7992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (*cp == '$') { \
8002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    int hold = nextarg; \
8012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (argtable == NULL) { \
8022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      argtable = statargtable; \
8032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (__find_arguments(fmt0, orgap, &argtable) == -1) \
8042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto oomem; \
8052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } \
8062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    nextarg = n2; \
8072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    val = GETARG (int); \
8082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    nextarg = hold; \
8092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    fmt = ++cp; \
8102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } else { \
8112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    val = GETARG (int); \
8122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
8132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(fp != NULL);
8152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(fmt0 != NULL);
81653e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  if(fp == NULL) {
81753e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    errno = EINVAL;
81853e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm    return (EOF);
81953e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm  }
8202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _SET_ORIENTATION(fp, -1);
8222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ndig = -1;  /* XXX gcc */
8242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  thousands_sep = '\0';
8262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  grouping = NULL;
8272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
8282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  decimal_point = localeconv()->decimal_point;
8292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  expsize = 0;    /* XXXGCC -Wuninitialized [sh3,m68000] */
8302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  convbuf = NULL;
8322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* sorry, f{w,}printf(read_only_file, L"") returns {W,}EOF, not 0 */
8332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (cantwrite(fp)) {
8342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    errno = EBADF;
8352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (END_OF_FILE);
8362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
8372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* optimise fprintf(stderr) (and other unbuffered Unix files) */
8392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
8402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      fp->_file >= 0)
8412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return (__sbprintf(fp, fmt0, ap));
8422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fmt = (CHAR_T *)__UNCONST(fmt0);
8442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  argtable = NULL;
8452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  nextarg = 1;
8462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  va_copy(orgap, ap);
8472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef NARROW
8482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_iov = iovp = iov;
8492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_resid = 0;
8502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  uio.uio_iovcnt = 0;
8512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ret = 0;
8532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
8552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Scan the format for conversions (`%' character).
8562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
8572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for (;;)
8582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  {
8592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    const CHAR_T *result;
8602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
8622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      continue;
8632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((n = (int)(fmt - cp)) != 0) {
8642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if ((unsigned)ret + n > INT_MAX) {
8652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ret = END_OF_FILE;
8662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto error;
8672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
8682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PRINT(cp, n);
8692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ret += n;
8702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
8712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (ch == '\0')
8722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto done;
8732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    fmt++;    /* skip over '%' */
8742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    flags = 0;
8762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    dprec = 0;
8772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    width = 0;
8782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    prec = -1;
8792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    sign = '\0';
8802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ox[1] = '\0';
8812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    expchar = '\0';
8822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    lead = 0;
8832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    nseps = nrepeats = 0;
8842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ulval = 0;
8852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ujval = 0;
8862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    xdigs = NULL;
8872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmrflag:    ch = *fmt++;
8892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmreswitch: switch (ch) {
8902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case ' ':
8912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*-
8922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * ``If the space and + flags both appear, the space
8932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * flag will be ignored.''
8942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *  -- ANSI X3J11
8952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
8962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (!sign)
8972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        sign = ' ';
8982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
8992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '#':
9002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= ALT;
9012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '*':
9032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*-
9042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * ``A negative field width argument is taken as a
9052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * - flag followed by a positive field width.''
9062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *  -- ANSI X3J11
9072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * They don't exclude field widths read from args.
9082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
9092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      GETASTER (width);
9102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (width >= 0)
9112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto rflag;
9122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      width = -width;
9132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /* FALLTHROUGH */
9142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '-':
9152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LADJUST;
9162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '+':
9182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sign = '+';
9192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '\'':
9212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= GROUPING;
9222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      thousands_sep = *(localeconv()->thousands_sep);
9232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      grouping = localeconv()->grouping;
9242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '.':
9262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if ((ch = *fmt++) == '*') {
9272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        GETASTER (prec);
9282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto rflag;
9292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
9302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      prec = 0;
9312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      while (is_digit(ch)) {
9322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        prec = 10 * prec + to_digit(ch);
9332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ch = *fmt++;
9342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
9352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto reswitch;
9362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '0':
9372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*-
9382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * ``Note that 0 is taken as a flag, not as the
9392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * beginning of a field width.''
9402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *  -- ANSI X3J11
9412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
9422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= ZEROPAD;
9432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '1': case '2': case '3': case '4':
9452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '5': case '6': case '7': case '8': case '9':
9462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      n = 0;
9472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      do {
9482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        n = 10 * n + to_digit(ch);
9492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ch = *fmt++;
9502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } while (is_digit(ch));
9512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (ch == '$') {
9522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        nextarg = n;
9532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (argtable == NULL) {
9542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          argtable = statargtable;
9552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (__find_arguments(fmt0, orgap,
9562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              &argtable) == -1)
9572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            goto oomem;
9582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
9592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto rflag;
9602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
9612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      width = n;
9622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto reswitch;
9632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
9642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'L':
9652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGDBL;
9662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
9682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'h':
9692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & SHORTINT) {
9702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags &= ~SHORTINT;
9712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= CHARINT;
9722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else
9732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= SHORTINT;
9742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'j':
9762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= INTMAXT;
9772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'l':
9792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGINT) {
9802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags &= ~LONGINT;
9812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= LLONGINT;
9822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else
9832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= LONGINT;
9842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'q':
9862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LLONGINT;  /* not necessarily */
9872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 't':
9892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= PTRDIFFT;
9902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'z':
9922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= SIZET;
9932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
9942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'C':
9952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
9962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
9972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'c':
9982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef NARROW
9992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGINT) {
10002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        static const mbstate_t initial = { 0 };
10012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        mbstate_t mbs;
10022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        size_t mbseqlen;
10032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
10042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        mbs = initial;
10052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        mbseqlen = wcrtomb(buf,
10065244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm            /* The compiler "knows" that wint_t may be smaller than an int so
10075244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm               it warns about it when used as the type argument to va_arg().
10085244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm               Since any type of parameter smaller than an int is promoted to an int on a
10095244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm               function call, we must call GETARG with type int instead of wint_t.
10105244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm            */
10115244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm            (wchar_t)GETARG(int), &mbs);
10122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (mbseqlen == (size_t)-1) {
10132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          fp->_flags |= __SERR;
10142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          goto error;
10152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
10162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        size = (int)mbseqlen;
10172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
10182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *buf = (char)(GETARG(int));
10192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        size = 1;
10202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
10212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
10222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGINT)
10235244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm        *buf = (wchar_t)GETARG(int);
10242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
10252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *buf = (wchar_t)btowc(GETARG(int));
10262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      size = 1;
10272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
10282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = buf;
10292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sign = '\0';
10302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
10312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'D':
10322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
10332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
10342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'd':
10352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'i':
10362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & INTMAX_SIZE) {
10372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ujval = SJARG();
10382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if ((intmax_t)ujval < 0) {
10392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          ujval = (uintmax_t)(-((intmax_t)ujval));
10402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          sign = '-';
10412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
10422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
10432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ulval = SARG();
10442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if ((long)ulval < 0) {
10452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          ulval = (u_long)(-((long)ulval));
10462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          sign = '-';
10472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
10482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
10492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      base = 10;
10502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto number;
10512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
10522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef WIDE_DOUBLE
10532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'a':
10542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'A':
10552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (ch == 'a') {
10562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ox[1] = 'x';
10572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        xdigs = xdigs_lower;
10582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        expchar = 'p';
10592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
10602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ox[1] = 'X';
10612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        xdigs = xdigs_upper;
10622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        expchar = 'P';
10632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
10642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGDBL) {
10652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        fparg.ldbl = GETARG(long double);
10662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        dtoaresult =
10672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            __hldtoa(fparg.ldbl, xdigs, prec,
10682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                &expt, &signflag, &dtoaend);
10692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
10702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        fparg.dbl = GETARG(double);
10712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        dtoaresult =
10722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            __hdtoa(fparg.dbl, xdigs, prec,
10732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                &expt, &signflag, &dtoaend);
10742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
10752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (dtoaresult == NULL)
10762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto oomem;
10772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
10782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (prec < 0)
10792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        prec = dtoaend - dtoaresult;
10802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (expt == INT_MAX)
10812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ox[1] = '\0';
10822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ndig = dtoaend - dtoaresult;
10832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (convbuf != NULL)
10842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        free(convbuf);
10852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
10862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = convbuf = __mbsconv(dtoaresult, -1);
10872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
10882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*XXX inefficient*/
10892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = convbuf = strdup(dtoaresult);
10902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
10912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (result == NULL)
10922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto oomem;
10932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      __freedtoa(dtoaresult);
10942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto fp_common;
10952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'e':
10962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'E':
10972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      expchar = ch;
1098d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      if (prec < 0)
1099d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        prec = DEFPREC;
11002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto fp_begin;
11012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'f':
11022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'F':
11032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      expchar = '\0';
11042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto fp_begin;
11052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'g':
11062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'G':
11072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      expchar = ch - ('g' - 'e');
11082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (prec == 0)
11092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        prec = 1;
11102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmfp_begin:
11112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (prec < 0)
11122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        prec = DEFPREC;
11132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGDBL) {
11142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        fparg.ldbl = GETARG(long double);
11152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        dtoaresult =
11162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
11172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            &expt, &signflag, &dtoaend);
11182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
11192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        fparg.dbl = GETARG(double);
11202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        dtoaresult =
11212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
11222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            &expt, &signflag, &dtoaend);
11232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (expt == 9999)
11242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          expt = INT_MAX;
11252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
11262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (dtoaresult == NULL)
11272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto oomem;
11282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ndig = dtoaend - dtoaresult;
11292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (convbuf != NULL)
11302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        free(convbuf);
11312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
11322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = convbuf = __mbsconv(dtoaresult, -1);
11332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
11342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*XXX inefficient*/
11352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = convbuf = strdup(dtoaresult);
11362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
11372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (result == NULL)
11382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto oomem;
11392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      __freedtoa(dtoaresult);
11402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmfp_common:
11412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (signflag)
11422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        sign = '-';
11432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (expt == INT_MAX) {  /* inf or nan */
11442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (*result == 'N') {
11452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = (ch >= 'a') ? STRCONST("nan") :
11462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              STRCONST("NAN");
11472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          sign = '\0';
11482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        } else
11492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = (ch >= 'a') ? STRCONST("inf") :
11502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              STRCONST("INF");
11512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        size = 3;
11522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        break;
11532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
11542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
11552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //case 'e':
11562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //case 'E':
11572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //case 'f':
11582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //case 'F':
11592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //case 'g':
11602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //case 'G':
11612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //  if (prec == -1) {
11622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //    prec = DEFPREC;
11632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //  } else if ((ch == 'g' || ch == 'G') && prec == 0) {
11642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //    prec = 1;
11652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    //  }
11662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'e':
11672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'E':
11682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      expchar = ch;
1169d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      if (prec < 0)
1170d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        prec = DEFPREC;
11712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto fp_begin;
11722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'f':
11732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'F':
11742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      expchar = '\0';
11752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto fp_begin;
11762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'g':
11772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'G':
11782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      expchar = ch - ('g' - 'e');
11792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (prec == 0)
11802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        prec = 1;
11812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmfp_begin:
11822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (prec < 0)
11832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        prec = DEFPREC;
11842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
11852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGDBL) {
11862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        _double = (double) GETARG(long double);
11872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
11882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        _double = GETARG(double);
11892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
11902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
11912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /* do this before tricky precision changes */
11922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (isinf(_double)) {
11932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (_double < 0)
11942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          sign = '-';
11952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (ch == 'E' || ch == 'F' || ch == 'G')
11962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = STRCONST("INF");
11972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        else
11982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = STRCONST("inf");
11992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        size = 3;
12002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        break;
12012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
12022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (isnan(_double)) {
12032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (ch == 'E' || ch == 'F' || ch == 'G')
12042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = STRCONST("NAN");
12052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        else
12062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = STRCONST("nan");
12072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        size = 3;
12082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        break;
12092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
12102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
12112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= FPT;
12122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      dtoaresult = cvt(_double, prec, flags, &softsign, &expt, ch, &ndig);
12132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (dtoaresult == NULL)
12142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto oomem;
12152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (convbuf != NULL)
12162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        free(convbuf);
12172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NARROW
12182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = convbuf = __mbsconv(dtoaresult, -1);
12192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
12202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*XXX inefficient*/
12212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = convbuf = strdup(dtoaresult);
12222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
12232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (result == NULL)
12242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto oomem;
12252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      __freedtoa(dtoaresult);
12262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (softsign)
12272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        sign = '-';
12282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
12292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= FPT;
12302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (ch == 'g' || ch == 'G') {
12312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (expt > -4 && expt <= prec) {
12322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          /* Make %[gG] smell like %[fF] */
12332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          expchar = '\0';
12342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (flags & ALT)
12352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            prec -= expt;
12362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          else
12372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            prec = ndig - expt;
12382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (prec < 0)
12392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            prec = 0;
12402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        } else {
12412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          /*
12422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm           * Make %[gG] smell like %[eE], but
12432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm           * trim trailing zeroes if no # flag.
1244d7ce700605e1af0e455e31ec11f19ff21d26b525darylm           *
1245d7ce700605e1af0e455e31ec11f19ff21d26b525darylm           * Note: The precision field used with [gG] is the number significant
1246d7ce700605e1af0e455e31ec11f19ff21d26b525darylm           * digits to print.  When converting to [eE] the digit before the
1247d7ce700605e1af0e455e31ec11f19ff21d26b525darylm           * decimal must not be included in the precision value.
12482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm           */
12492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (!(flags & ALT))
1250d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            prec = ndig - 1;
12512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
12522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
12532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (expchar) {
1254d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        dprec = prec; /* In some cases dprec will not be set.  Make sure it is set now */
12552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        expsize = exponent(expstr, expt - 1, expchar);
1256d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        size = expsize + prec + 1; /* Leading digit + exponent string + precision */
1257d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (prec >= 1 || flags & ALT)
1258d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          ++size; /* Decimal point is added to character count */
12592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
12602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        /* space for digits before decimal point */
12612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (expt > 0)
12622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          size = expt;
12632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        else  /* "0" */
12642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          size = 1;
12652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        /* space for decimal pt and following digits */
12662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (prec || flags & ALT)
12672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          size += prec + 1;
12682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (grouping && expt > 0) {
12692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          /* space for thousands' grouping */
12702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          nseps = nrepeats = 0;
12712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          lead = expt;
12722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          while (*grouping != CHAR_MAX) {
12732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            if (lead <= *grouping)
12742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              break;
12752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            lead -= *grouping;
12762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            if (*(grouping+1)) {
12772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              nseps++;
12782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              grouping++;
12792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            } else
12802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              nrepeats++;
12812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          }
12822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          size += nseps + nrepeats;
12832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        } else
12842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          lead = expt;
12852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
12862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
12872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* !NO_FLOATING_POINT */
12882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'n':
12892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*
12902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * Assignment-like behavior is specified if the
12912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * value overflows or is otherwise unrepresentable.
12922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * C99 says to use `signed char' for %hhn conversions.
12932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
12942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LLONGINT)
12952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(long long *) = ret;
12962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & SIZET)
12972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(ssize_t *) = (ssize_t)ret;
12982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & PTRDIFFT)
12992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(ptrdiff_t *) = ret;
13002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & INTMAXT)
13012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(intmax_t *) = ret;
13022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & LONGINT)
13032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(long *) = ret;
13042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & SHORTINT)
13052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(short *) = ret;
13062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & CHARINT)
13072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(signed char *) = ret;
13082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
13092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *GETARG(int *) = ret;
13102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      continue; /* no output */
13112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'O':
13122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
13132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
13142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'o':
13152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & INTMAX_SIZE)
13162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ujval = UJARG();
13172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
13182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ulval = UARG();
13192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      base = 8;
13202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto nosign;
13212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'p':
13222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*-
13232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * ``The argument shall be a pointer to void.  The
13242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * value of the pointer is converted to a sequence
13252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * of printable characters, in an implementation-
13262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * defined manner.''
13272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *  -- ANSI X3J11
13282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
1329d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      ujval = (uintmax_t) (UINTN) GETARG(void *);
13302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      base = 16;
13312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      xdigs = xdigs_lower;
13322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags = flags | INTMAXT;
13332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ox[1] = 'x';
13342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto nosign;
13352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'S':
13362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
13372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
13382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 's':
1339d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      if (((flags & LONGINT) ? 1:0) != MULTI) {
13402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if ((result = GETARG(CHAR_T *)) == NULL)
13412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = STRCONST("(null)");
13422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
13432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        MCHAR_T *mc;
13442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
13452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (convbuf != NULL)
13462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          free(convbuf);
13472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if ((mc = GETARG(MCHAR_T *)) == NULL)
13482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = STRCONST("(null)");
13492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        else {
13502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          convbuf = SCONV(mc, prec);
13512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (convbuf == NULL) {
13522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            fp->_flags |= __SERR;
13532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            goto error;
13542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          }
13552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = convbuf;
13562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
13572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
13582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
13592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (prec >= 0) {
13602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        /*
13612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * can't use STRLEN; can only look for the
13622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * NUL in the first `prec' characters, and
13632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         * STRLEN() will go further.
13642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         */
13652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        CHAR_T *p = MEMCHR(result, 0, (size_t)prec);
13662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
13672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (p != NULL) {
13682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          size = p - result;
13692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (size > prec)
13702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            size = prec;
13712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        } else
13722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          size = prec;
13732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else
13742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        size = (int)STRLEN(result);
13752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sign = '\0';
13762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
13772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'U':
13782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
13792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
13802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'u':
13812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & INTMAX_SIZE)
13822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ujval = UJARG();
13832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
13842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ulval = UARG();
13852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      base = 10;
13862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto nosign;
13872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'X':
13882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      xdigs = xdigs_upper;
13892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto hex;
13902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'x':
13912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      xdigs = xdigs_lower;
13922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmhex:
13932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & INTMAX_SIZE)
13942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ujval = UJARG();
13952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
13962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ulval = UARG();
13972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      base = 16;
13982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /* leading 0x/X only if non-zero */
13992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & ALT &&
14002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
14012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ox[1] = ch;
14022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags &= ~GROUPING;
14042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /* unsigned conversions */
14052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmnosign:     sign = '\0';
14062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*-
14072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * ``... diouXx conversions ... if a precision is
14082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * specified, the 0 flag will be ignored.''
14092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *  -- ANSI X3J11
14102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
14112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmnumber:     if ((dprec = prec) >= 0)
14122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags &= ~ZEROPAD;
14132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*-
14152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * ``The result of converting a zero value with an
14162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * explicit precision of zero is no characters.''
14172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *  -- ANSI X3J11
14182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *
14192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * ``The C Standard is clear enough as is.  The call
14202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       * printf("%#.0o", 0) should print 0.''
14212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       *  -- Defect Report #151
14222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm       */
14232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = cp = buf + BUF;
14242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & INTMAX_SIZE) {
14252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (ujval != 0 || prec != 0 ||
14262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            (flags & ALT && base == 8))
14272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        {
14282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = __ujtoa(ujval, cp, base,
14292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              flags & ALT, xdigs,
14302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              flags & GROUPING, thousands_sep,
14312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              grouping);
14322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
14332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {
14342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (ulval != 0 || prec != 0 ||
14352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            (flags & ALT && base == 8))
14362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result = __ultoa(ulval, cp, base,
14372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              flags & ALT, xdigs,
14382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              flags & GROUPING, thousands_sep,
14392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              grouping);
14402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
14412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      size = buf + BUF - result;
14422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (size > BUF) /* should never happen */
14432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        abort();
14442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
14452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    default:  /* "%?" prints ?, unless ? is NUL */
14462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (ch == '\0')
14472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto done;
14482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /* pretend it was %c with argument ch */
14492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *buf = ch;
14502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      result = buf;
14512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      size = 1;
14522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      sign = '\0';
14532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
14542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
14552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /*
14572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * All reasonable formats wind up here.  At this point, `result'
14582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * points to a string which (if not flags&LADJUST) should be
14592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * padded out to `width' places.  If flags&ZEROPAD, it should
14602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * first be prefixed by any sign or other prefix; otherwise,
14612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * it should be blank padded before the prefix is emitted.
14622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * After any left-hand padding and prefixing, emit zeroes
14632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * required by a decimal [diouxX] precision, then print the
14642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * string proper, then emit zeroes required by any leftover
14652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * floating precision; finally, if LADJUST, pad with blanks.
14662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     *
14672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * Compute actual size, so we know how much to pad.
14682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * size excludes decimal prec; realsz includes it.
14692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     */
14702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    realsz = dprec > size ? dprec : size;
14712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (sign)
14722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      realsz++;
14732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (ox[1])
14742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      realsz += 2;
14752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    prsize = width > realsz ? width : realsz;
14772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((unsigned)ret + prsize > INT_MAX) {
14782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ret = END_OF_FILE;
14792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto error;
14802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
14812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* right-adjusting blank padding */
14832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((flags & (LADJUST|ZEROPAD)) == 0)
14842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PAD(width - realsz, blanks);
14852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* prefix */
14872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (sign)
14882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PRINT(&sign, 1);
14892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (ox[1]) {  /* ox[1] is either x, X, or \0 */
14912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ox[0] = '0';
14922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PRINT(ox, 2);
14932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
14942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* right-adjusting zero padding */
14962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
14972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PAD(width - realsz, zeroes);
14982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
14992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* leading zeroes from decimal precision */
15002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    PAD(dprec - size, zeroes);
15012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
15022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* the string or number proper */
15032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
15042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((flags & FPT) == 0) {
15052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PRINT(result, size);
15062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } else {  /* glue together f_p fragments */
15072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (!expchar) { /* %[fF] or sufficiently short %[gG] */
15082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (expt <= 0) {
15092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          PRINT(zeroes, 1);
15102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (prec || flags & ALT)
15112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            PRINT(decimal_point, 1);
15122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          PAD(-expt, zeroes);
15132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          /* already handled initial 0's */
15142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          prec += expt;
15152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        } else {
15162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          PRINTANDPAD(result, convbuf + ndig,
15172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              lead, zeroes);
15182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          result += lead;
15192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (grouping) {
15202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            while (nseps>0 || nrepeats>0) {
15212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              if (nrepeats > 0)
15222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                nrepeats--;
15232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              else {
15242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                grouping--;
15252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                nseps--;
15262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              }
15272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              PRINT(&thousands_sep,
15282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                  1);
15292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              PRINTANDPAD(result,
15302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                  convbuf + ndig,
15312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm                  *grouping, zeroes);
15322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              result += *grouping;
15332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            }
15342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            if (result > convbuf + ndig)
15352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm              result = convbuf + ndig;
15362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          }
15372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          if (prec || flags & ALT) {
15382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            buf[0] = *decimal_point;
15392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            PRINT(buf, 1);
15402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          }
15412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
15422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        PRINTANDPAD(result, convbuf + ndig, prec,
15432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm            zeroes);
15442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else {  /* %[eE] or sufficiently long %[gG] */
1545d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (prec >= 1 || flags & ALT) {
15462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          buf[0] = *result++;
15472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          buf[1] = *decimal_point;
15482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          PRINT(buf, 2);
15492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          PRINT(result, ndig-1);
15502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          PAD(prec - ndig, zeroes);
15512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        } else  /* XeYYY */
15522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          PRINT(result, 1);
15532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        PRINT(expstr, expsize);
15542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
15552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
15562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
15572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    PRINT(result, size);
15582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
15592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* left-adjusting padding (always blank) */
15602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (flags & LADJUST)
15612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      PAD(width - realsz, blanks);
15622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
15632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* finally, adjust ret */
15642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ret += prsize;
15652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    FLUSH();
15662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
15672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmdone:
15682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  FLUSH();
15692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmerror:
15702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  va_end(orgap);
15712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (convbuf != NULL)
15722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    free(convbuf);
15732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (__sferror(fp))
15742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ret = END_OF_FILE;
15752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((argtable != NULL) && (argtable != statargtable))
15762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    free (argtable);
15772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (ret);
15782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /* NOTREACHED */
15792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmoomem:
15802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  errno = ENOMEM;
15812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ret = END_OF_FILE;
15822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  goto error;
15832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
15842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
15852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
15862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Find all arguments when a positional parameter is encountered.  Returns a
15872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * table, indexed by argument number, of pointers to each arguments.  The
15882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
15892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * It will be replaces with a malloc-ed one if it overflows.
15902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
15912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int
15922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__find_arguments(const CHAR_T *fmt0, va_list ap, union arg **argtable)
15932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
15942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *fmt;    /* format string */
15952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int ch;     /* character from fmt */
15962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int n, n2;    /* handy integer (short term usage) */
15972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *cp;   /* handy char pointer (short term usage) */
15982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int flags;    /* flags as above */
15992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  enum typeid *typetable; /* table of types */
16002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
16012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int tablesize;    /* current size of type table */
16022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int tablemax;   /* largest used index in table */
16032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int nextarg;    /* 1-based argument index */
16042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
16052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
16062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Add an argument type to the table, expanding if necessary.
16072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
16082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define ADDTYPE(type) \
16092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  do { \
16102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (nextarg >= tablesize) \
16112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (__grow_type_table(nextarg, &typetable, \
16122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          &tablesize) == -1) \
16132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        return -1; \
16142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (nextarg > tablemax) \
16152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      tablemax = nextarg; \
16162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    typetable[nextarg++] = type; \
16172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } while (/*CONSTCOND*/0)
16182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
16192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define ADDSARG() \
16202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  do { \
16212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (flags & INTMAXT)  \
16222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_INTMAXT); \
16232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & SIZET)  \
16242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_SIZET); \
16252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & PTRDIFFT) \
16262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_PTRDIFFT); \
16272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & LLONGINT) \
16282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_LLONG); \
16292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & LONGINT) \
16302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_LONG); \
16312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else \
16322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_INT); \
16332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } while (/*CONSTCOND*/0)
16342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
16352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define ADDUARG() \
16362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  do { \
16372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (flags & INTMAXT)  \
16382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_UINTMAXT); \
16392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & SIZET)  \
16402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_SIZET); \
16412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & PTRDIFFT) \
16422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_PTRDIFFT); \
16432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & LLONGINT) \
16442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_U_LLONG); \
16452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else if (flags & LONGINT) \
16462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_U_LONG); \
16472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else \
16482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(T_U_INT); \
16492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } while (/*CONSTCOND*/0)
16502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
16512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Add * arguments to the type array.
16522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
16532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define ADDASTER() \
16542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  n2 = 0; \
16552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  cp = fmt; \
16562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while (is_digit(*cp)) { \
16572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    n2 = 10 * n2 + to_digit(*cp); \
16582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    cp++; \
16592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } \
16602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (*cp == '$') { \
16612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    int hold = nextarg; \
16622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    nextarg = n2; \
16632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ADDTYPE(T_INT); \
16642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    nextarg = hold; \
16652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    fmt = ++cp; \
16662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } else { \
16672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ADDTYPE(T_INT); \
16682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
16692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  fmt = (CHAR_T *)__UNCONST(fmt0);
16702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  typetable = stattypetable;
16712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  tablesize = STATIC_ARG_TBL_SIZE;
16722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  tablemax = 0;
16732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  nextarg = 1;
16742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
16752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    typetable[n] = T_UNUSED;
16762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
16772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
16782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Scan the format for conversions (`%' character).
16792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
16802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for (;;) {
16812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
16822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /* void */;
16832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (ch == '\0')
16842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto done;
16852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    fmt++;    /* skip over '%' */
16862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
16872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    flags = 0;
16882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
16892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmrflag:    ch = *fmt++;
16902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmreswitch: switch (ch) {
16912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case ' ':
16922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '#':
16932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
16942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '*':
16952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDASTER ();
16962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
16972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '-':
16982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '+':
16992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '\'':
17002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '.':
17022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if ((ch = *fmt++) == '*') {
17032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDASTER ();
17042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto rflag;
17052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
17062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      while (is_digit(ch)) {
17072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ch = *fmt++;
17082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
17092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto reswitch;
17102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '0':
17112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '1': case '2': case '3': case '4':
17132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case '5': case '6': case '7': case '8': case '9':
17142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      n = 0;
17152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      do {
17162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        n = 10 * n + to_digit(ch);
17172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ch = *fmt++;
17182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } while (is_digit(ch));
17192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (ch == '$') {
17202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        nextarg = n;
17212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto rflag;
17222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
17232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto reswitch;
17242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
17252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'L':
17262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGDBL;
17272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
17292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'h':
17302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & SHORTINT) {
17312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags &= ~SHORTINT;
17322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= CHARINT;
17332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else
17342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= SHORTINT;
17352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'j':
17372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= INTMAXT;
17382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'l':
17402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGINT) {
17412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags &= ~LONGINT;
17422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= LLONGINT;
17432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      } else
17442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        flags |= LONGINT;
17452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'q':
17472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LLONGINT;  /* not necessarily */
17482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 't':
17502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= PTRDIFFT;
17512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'z':
17532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= SIZET;
17542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      goto rflag;
17552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'C':
17562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
17572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
17582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'c':
17592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGINT)
17602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(T_WINT);
17612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
17622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(T_INT);
17632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
17642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'D':
17652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
17662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
17672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'd':
17682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'i':
17692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDSARG();
17702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
17712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
17722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'a':
17732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'A':
17742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'e':
17752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'E':
17762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'f':
17772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'g':
17782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'G':
17792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGDBL)
17802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(T_LONG_DOUBLE);
17812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
17822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(T_DOUBLE);
17832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
17842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* !NO_FLOATING_POINT */
17852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'n':
17862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & INTMAXT)
17872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_INTMAXT);
17882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & PTRDIFFT)
17892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_PTRDIFFT);
17902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & SIZET)
17912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_SIZET);
17922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & LLONGINT)
17932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_LLONG);
17942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & LONGINT)
17952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_LONG);
17962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & SHORTINT)
17972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_SHORT);
17982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else if (flags & CHARINT)
17992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_SCHAR);
18002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
18012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_INT);
18022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      continue; /* no output */
18032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'O':
18042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
18052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
18062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'o':
18072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDUARG();
18082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'p':
18102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDTYPE(TP_VOID);
18112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'S':
18132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
18142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
18152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 's':
18162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (flags & LONGINT)
18172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_WCHAR);
18182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else
18192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        ADDTYPE(TP_CHAR);
18202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'U':
18222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      flags |= LONGINT;
18232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /*FALLTHROUGH*/
18242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'u':
18252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'X':
18262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    case 'x':
18272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ADDUARG();
18282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    default:  /* "%?" prints ?, unless ? is NUL */
18302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (ch == '\0')
18312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        goto done;
18322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
18342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
18352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmdone:
18362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  /*
18372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   * Build the argument table.
18382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm   */
18392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (tablemax >= STATIC_ARG_TBL_SIZE) {
18402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *argtable = (union arg *)
18412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        malloc (sizeof (union arg) * (tablemax + 1));
18422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (*argtable == NULL)
18432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return -1;
18442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
18452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
18462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (*argtable) [0].intarg = 0;
18472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for (n = 1; n <= tablemax; n++) {
18482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    switch (typetable [n]) {
18492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_UNUSED: /* whoops! */
18502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].intarg = va_arg (ap, int);
18512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_SCHAR:
18532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pschararg = va_arg (ap, signed char *);
18542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_SHORT:
18562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pshortarg = va_arg (ap, short *);
18572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_INT:
18592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].intarg = va_arg (ap, int);
18602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_U_INT:
18622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].uintarg = va_arg (ap, unsigned int);
18632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_INT:
18652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pintarg = va_arg (ap, int *);
18662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_LONG:
18682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].longarg = va_arg (ap, long);
18692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_U_LONG:
18712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].ulongarg = va_arg (ap, unsigned long);
18722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_LONG:
18742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].plongarg = va_arg (ap, long *);
18752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_LLONG:
18772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].longlongarg = va_arg (ap, long long);
18782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_U_LLONG:
18802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
18812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_LLONG:
18832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].plonglongarg = va_arg (ap, long long *);
18842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_PTRDIFFT:
18862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
18872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_PTRDIFFT:
18892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
18902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_SIZET:
18922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].sizearg = va_arg (ap, size_t);
18932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_SIZET:
18952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].psizearg = va_arg (ap, size_t *);
18962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
18972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_INTMAXT:
18982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
18992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_UINTMAXT:
19012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
19022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_INTMAXT:
19042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
19052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_DOUBLE:
19072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
19082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].doublearg = va_arg (ap, double);
19092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
19102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_LONG_DOUBLE:
19122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
19132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].longdoublearg = va_arg (ap, long double);
19142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
19152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_CHAR:
19172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pchararg = va_arg (ap, char *);
19182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_VOID:
19202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pvoidarg = va_arg (ap, void *);
19212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case T_WINT:
19235244f47e46709b22ecefcee8e52b6dc6170ed6c9darylm      (*argtable) [n].wintarg = va_arg (ap, int);
19242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        case TP_WCHAR:
19262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      (*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
19272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
19282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
19292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
19302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((typetable != NULL) && (typetable != stattypetable))
19322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    free (typetable);
19332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return 0;
19342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
19352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/*
19372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * Increase the size of the type table.
19382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */
19392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int
19402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
19412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
19422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  enum typeid *const oldtable = *typetable;
19432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  const int oldsize = *tablesize;
19442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  enum typeid *newtable;
19452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int n, newsize = oldsize * 2;
19462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (newsize < nextarg + 1)
19482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    newsize = nextarg + 1;
19492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (oldsize == STATIC_ARG_TBL_SIZE) {
19502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
19512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return -1;
19522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    memcpy(newtable, oldtable, oldsize * sizeof(enum typeid));
19532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } else {
19542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    newtable = realloc(oldtable, newsize * sizeof(enum typeid));
19552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (newtable == NULL) {
19562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      free(oldtable);
19572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return -1;
19582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
19592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
19602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for (n = oldsize; n < newsize; n++)
19612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    newtable[n] = T_UNUSED;
19622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  *typetable = newtable;
19642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  *tablesize = newsize;
19652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return 0;
19662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
19672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef NO_FLOATING_POINT
19702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef WIDE_DOUBLE
19712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic char *
19722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmcvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
19732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    int *length)
19742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
19752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int mode, dsgn;
19762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char *digits, *bp, *rve;
19772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(decpt != NULL);
19792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(length != NULL);
19802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  _DIAGASSERT(sign != NULL);
19812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (ch == 'f') {
19832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    mode = 3;   /* ndigits after the decimal point */
19842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } else {
19852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* To obtain ndigits after the decimal point for the 'e'
19862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * and 'E' formats, round to ndigits + 1 significant
19872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * figures.
19882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     */
19892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (ch == 'e' || ch == 'E') {
19902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ndigits++;
19912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
19922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    mode = 2;   /* ndigits significant digits */
19932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
19942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
19952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
19962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (digits == NULL)
19972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return NULL;
19982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (dsgn) {
19992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    value = -value;
20002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *sign = '-';
20012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  } else
20022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *sign = '\000';
20032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((ch != 'g' && ch != 'G') || flags & ALT) {  /* Print trailing zeros */
20042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    bp = digits + ndigits;
20052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (ch == 'f') {
20062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (*digits == '0' && value)
20072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *decpt = -ndigits + 1;
20082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      bp += *decpt;
20092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
20102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while (rve < bp)
20112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *rve++ = '0';
20122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
20132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  *length = rve - digits;
20142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return digits;
20152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
20162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
20172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
20182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int
20192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmexponent(CHAR_T *p0, int expo, int fmtch)
20202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
20212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T *p, *t;
20222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  CHAR_T expbuf[MAXEXPDIG];
20232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
20242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  p = p0;
20252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  *p++ = fmtch;
20262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (expo < 0) {
20272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    expo = -expo;
20282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *p++ = '-';
20292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
20302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else
20312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *p++ = '+';
20322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  t = expbuf + MAXEXPDIG;
20332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (expo > 9) {
20342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
20352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *--t = to_char(expo % 10);
20362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    } while ((expo /= 10) > 9);
20372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *--t = to_char(expo);
20382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
20392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
20402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else {
20412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /*
20422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * Exponents for decimal floating point conversions
20432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * (%[eEgG]) must be at least two characters long,
20442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * whereas exponents for hexadecimal conversions can
20452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     * be only one character long.
20462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm     */
20472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (fmtch == 'e' || fmtch == 'E')
20482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *p++ = '0';
20492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *p++ = to_char(expo);
20502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
20512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return (p - p0);
20522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}
20532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* !NO_FLOATING_POINT */
2054