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