11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* $OpenBSD: vfprintf.c,v 1.37 2006/01/13 17:56:18 millert Exp $ */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*- 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1990 The Regents of the University of California. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code is derived from software contributed to Berkeley by 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Chris Torek. 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * documentation and/or other materials provided with the distribution. 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * may be used to endorse or promote products derived from this software 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * without specific prior written permission. 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Actual printf innards. 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code is large and complicated... 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h> 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/mman.h> 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h> 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdarg.h> 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stddef.h> 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdint.h> 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "local.h" 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "fvwrite.h" 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void __find_arguments(const char *fmt0, va_list ap, va_list **argtable, 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t *argtablesiz); 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int __grow_type_table(unsigned char **typetable, int *tablesize); 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flush out all the vectors defined by the given uio, 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * then reset it so that it can be reused. 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__sprint(FILE *fp, struct __suio *uio) 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int err; 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (uio->uio_resid == 0) { 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio->uio_iovcnt = 0; 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project err = __sfvwrite(fp, uio); 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio->uio_resid = 0; 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio->uio_iovcnt = 0; 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (err); 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Helper function for `fprintf to unbuffered unix file': creates a 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * temporary buffer. We only work on write-only files; this avoids 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * worries about ungetc buffers and so forth. 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__sbprintf(FILE *fp, const char *fmt, va_list ap) 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ret; 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project FILE fake; 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct __sfileext fakeext; 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project unsigned char buf[BUFSIZ]; 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _FILEEXT_SETUP(&fake, &fakeext); 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* copy the important variables */ 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fake._flags = fp->_flags & ~__SNBF; 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fake._file = fp->_file; 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fake._cookie = fp->_cookie; 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fake._write = fp->_write; 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* set up the buffer */ 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fake._bf._base = fake._p = buf; 991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fake._bf._size = fake._w = sizeof(buf); 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fake._lbfsize = 0; /* not actually used, but Just In Case */ 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* do the work, then copy any error status */ 103f582340a6a48588aa50da17e1620e8f91b146941Kenny Root ret = __vfprintf(&fake, fmt, ap); 104f582340a6a48588aa50da17e1620e8f91b146941Kenny Root if (ret >= 0 && __sflush(&fake)) 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret = EOF; 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (fake._flags & __SERR) 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_flags |= __SERR; 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (ret); 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <locale.h> 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <math.h> 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "floatio.h" 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DEFPREC 6 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *cvt(double, int, int, char *, int *, int, int *); 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int exponent(char *, int, int); 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* no FLOATING_POINT */ 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define BUF 40 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */ 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC: do not link libm for only two rather simple functions */ 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int _my_isinf(double); 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int _my_isnan(double); 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Macros for converting digits to letters and vice versa 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define to_digit(c) ((c) - '0') 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define is_digit(c) ((unsigned)to_digit(c) <= 9) 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define to_char(n) ((n) + '0') 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flags used during conversion. 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ALT 0x0001 /* alternate form */ 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define HEXPREFIX 0x0002 /* add 0x or 0X prefix */ 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LADJUST 0x0004 /* left adjustment */ 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LONGDBL 0x0008 /* long double; unimplemented */ 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LONGINT 0x0010 /* long integer */ 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LLONGINT 0x0020 /* long long integer */ 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SHORTINT 0x0040 /* short integer */ 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ZEROPAD 0x0080 /* zero (as opposed to blank) pad */ 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define FPT 0x0100 /* Floating point number */ 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PTRINT 0x0200 /* (unsigned) ptrdiff_t */ 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SIZEINT 0x0400 /* (signed) size_t */ 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CHARINT 0x0800 /* 8 bit integer */ 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define MAXINT 0x1000 /* largest integer size (intmax_t) */ 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvfprintf(FILE *fp, const char *fmt0, __va_list ap) 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 161f582340a6a48588aa50da17e1620e8f91b146941Kenny Root int ret; 162f582340a6a48588aa50da17e1620e8f91b146941Kenny Root 163f582340a6a48588aa50da17e1620e8f91b146941Kenny Root FLOCKFILE(fp); 164f582340a6a48588aa50da17e1620e8f91b146941Kenny Root ret = __vfprintf(fp, fmt0, ap); 165f582340a6a48588aa50da17e1620e8f91b146941Kenny Root FUNLOCKFILE(fp); 166f582340a6a48588aa50da17e1620e8f91b146941Kenny Root return (ret); 167f582340a6a48588aa50da17e1620e8f91b146941Kenny Root} 168f582340a6a48588aa50da17e1620e8f91b146941Kenny Root 169f582340a6a48588aa50da17e1620e8f91b146941Kenny Rootint 170f582340a6a48588aa50da17e1620e8f91b146941Kenny Root__vfprintf(FILE *fp, const char *fmt0, __va_list ap) 171f582340a6a48588aa50da17e1620e8f91b146941Kenny Root{ 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *fmt; /* format string */ 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ch; /* character from fmt */ 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, m, n2; /* handy integers (short term usage) */ 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *cp; /* handy char pointer (short term usage) */ 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *cp_free = NULL; /* BIONIC: copy of cp to be freed after usage */ 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct __siov *iovp;/* for PRINT macro */ 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int flags; /* flags as above */ 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ret; /* return value accumulator */ 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int width; /* width from format (%8d), or 0 */ 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int prec; /* precision from format (%.3d), or -1 */ 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char sign; /* sign prefix (' ', '+', '-', or \0) */ 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project wchar_t wc; 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project void* ps; 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *decimal_point = "."; 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char softsign; /* temporary negative sign for floats */ 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project double _double = 0.; /* double precision arguments %[eEfgG] */ 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int expt; /* integer value of exponent */ 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int expsize = 0; /* character count for expstr */ 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ndig; /* actual number of digits returned by cvt */ 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char expstr[7]; /* buffer for exponent string */ 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uintmax_t _umax; /* integer arguments %[diouxX] */ 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */ 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int realsz; /* field size expanded by dprec */ 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int size; /* size of converted field or string */ 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char* xdigs = NULL; /* digits for [xX] conversion */ 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define NIOV 8 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct __suio uio; /* output information: summary */ 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct __siov iov[NIOV];/* ... and individual io vectors */ 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char ox[2]; /* space for 0x hex-prefix */ 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_list *argtable; /* args, built due to positional arg */ 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_list statargtable[STATIC_ARG_TBL_SIZE]; 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t argtablesiz; 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nextarg; /* 1-based argument index */ 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_list orgap; /* original argument pointer */ 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Choose PADSIZE to trade efficiency vs. size. If larger printf 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * fields occur frequently, increase PADSIZE and make the initialisers 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * below longer. 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PADSIZE 16 /* pad chunk size */ 2170946b1f6e9223a0a82306e40fc2b41ebddb1f7efGlenn Kasten static const char blanks[PADSIZE] = 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 2190946b1f6e9223a0a82306e40fc2b41ebddb1f7efGlenn Kasten static const char zeroes[PADSIZE] = 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BEWARE, these `goto error' on error, and PAD uses `n'. 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PRINT(ptr, len) do { \ 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iovp->iov_base = (ptr); \ 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iovp->iov_len = (len); \ 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio.uio_resid += (len); \ 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iovp++; \ 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (++uio.uio_iovcnt >= NIOV) { \ 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (__sprint(fp, &uio)) \ 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto error; \ 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iovp = iov; \ 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } \ 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} while (0) 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PAD(howmany, with) do { \ 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((n = (howmany)) > 0) { \ 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (n > PADSIZE) { \ 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(with, PADSIZE); \ 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n -= PADSIZE; \ 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } \ 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(with, n); \ 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } \ 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} while (0) 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define FLUSH() do { \ 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (uio.uio_resid && __sprint(fp, &uio)) \ 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto error; \ 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio.uio_iovcnt = 0; \ 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iovp = iov; \ 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} while (0) 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * To extend shorts properly, we need both signed and unsigned 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * argument extraction methods. 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SARG() \ 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((intmax_t)(flags&MAXINT ? GETARG(intmax_t) : \ 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&LLONGINT ? GETARG(long long) : \ 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&LONGINT ? GETARG(long) : \ 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&PTRINT ? GETARG(ptrdiff_t) : \ 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&SIZEINT ? GETARG(ssize_t) : \ 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&SHORTINT ? (short)GETARG(int) : \ 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&CHARINT ? (__signed char)GETARG(int) : \ 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project GETARG(int))) 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define UARG() \ 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \ 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&LLONGINT ? GETARG(unsigned long long) : \ 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&LONGINT ? GETARG(unsigned long) : \ 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&PTRINT ? (uintptr_t)GETARG(ptrdiff_t) : /* XXX */ \ 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&SIZEINT ? GETARG(size_t) : \ 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&SHORTINT ? (unsigned short)GETARG(int) : \ 2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags&CHARINT ? (unsigned char)GETARG(int) : \ 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project GETARG(unsigned int))) 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Get * arguments, including the form *nn$. Preserve the nextarg 2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * that the argument can be gotten once the type is determined. 2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define GETASTER(val) \ 2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n2 = 0; \ 2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = fmt; \ 2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (is_digit(*cp)) { \ 2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n2 = 10 * n2 + to_digit(*cp); \ 2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp++; \ 2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } \ 2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*cp == '$') { \ 2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int hold = nextarg; \ 2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (argtable == NULL) { \ 2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argtable = statargtable; \ 2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __find_arguments(fmt0, orgap, &argtable, &argtablesiz); \ 2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } \ 2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = n2; \ 2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project val = GETARG(int); \ 2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = hold; \ 2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt = ++cp; \ 2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { \ 2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project val = GETARG(int); \ 2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project* Get the argument indexed by nextarg. If the argument table is 3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project* built, use it to get the argument. If its not, get the next 3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project* argument (and arguments must be gotten sequentially). 3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define GETARG(type) \ 3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (((argtable != NULL) ? (void)(ap = argtable[nextarg]) : (void)0), \ 3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg++, va_arg(ap, type)) 3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _SET_ORIENTATION(fp, -1); 3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ 3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cantwrite(fp)) { 3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EBADF; 3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (EOF); 3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* optimise fprintf(stderr) (and other unbuffered Unix files) */ 3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && 3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_file >= 0) 3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (__sbprintf(fp, fmt0, ap)); 3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt = (char *)fmt0; 3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argtable = NULL; 3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = 1; 3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_copy(orgap, ap); 3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio.uio_iov = iovp = iov; 3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio.uio_resid = 0; 3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uio.uio_iovcnt = 0; 3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret = 0; 3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memset(&ps, 0, sizeof(ps)); 3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Scan the format for conversions (`%' character). 3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (;;) { 3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = fmt; 3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1 /* BIONIC */ 3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = -1; 3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ( (wc = *fmt) != 0 ) { 3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (wc == '%') { 3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((n = mbrtowc(&wc, fmt, MB_CUR_MAX, &ps)) > 0) { 3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt += n; 3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (wc == '%') { 3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt--; 3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((m = fmt - cp) != 0) { 3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, m); 3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret += m; 3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) 3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; /* skip over '%' */ 3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags = 0; 3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dprec = 0; 3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = 0; 3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project prec = -1; 3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '\0'; 3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectrflag: ch = *fmt++; 3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectreswitch: switch (ch) { 3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ' ': 3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``If the space and + flags both appear, the space 3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * flag will be ignored.'' 3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -- ANSI X3J11 3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!sign) 3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = ' '; 3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '#': 3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= ALT; 3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '*': 3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``A negative field width argument is taken as a 3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - flag followed by a positive field width.'' 3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -- ANSI X3J11 3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * They don't exclude field widths read from args. 3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project GETASTER(width); 3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (width >= 0) 3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = -width; 3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* FALLTHROUGH */ 3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '-': 3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LADJUST; 3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '+': 3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '+'; 3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '.': 4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((ch = *fmt++) == '*') { 4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project GETASTER(n); 4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project prec = n < 0 ? -1 : n; 4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 0; 4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (is_digit(ch)) { 4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 10 * n + to_digit(ch); 4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = *fmt++; 4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == '$') { 4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = n; 4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (argtable == NULL) { 4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argtable = statargtable; 4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __find_arguments(fmt0, orgap, 4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project &argtable, &argtablesiz); 4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project prec = n < 0 ? -1 : n; 4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto reswitch; 4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '0': 4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``Note that 0 is taken as a flag, not as the 4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * beginning of a field width.'' 4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -- ANSI X3J11 4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= ZEROPAD; 4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '1': case '2': case '3': case '4': 4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '5': case '6': case '7': case '8': case '9': 4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 0; 4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 10 * n + to_digit(ch); 4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = *fmt++; 4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (is_digit(ch)); 4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == '$') { 4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = n; 4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (argtable == NULL) { 4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argtable = statargtable; 4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __find_arguments(fmt0, orgap, 4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project &argtable, &argtablesiz); 4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = n; 4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto reswitch; 4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'L': 4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGDBL; 4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'h': 4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SHORTINT; 4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'j': 4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= MAXINT; 4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'l': 4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*fmt == 'l') { 4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LLONGINT; 4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'q': 4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LLONGINT; 4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 't': 4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= PTRINT; 4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'z': 4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SIZEINT; 4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'c': 4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *(cp = buf) = GETARG(int); 4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = 1; 4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '\0'; 4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'D': 4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'd': 4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'i': 4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax = SARG(); 4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((intmax_t)_umax < 0) { 4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax = -_umax; 4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '-'; 4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = DEC; 4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto number; 4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'e': 4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'E': 4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'f': 4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'g': 4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'G': 4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (prec == -1) { 5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project prec = DEFPREC; 5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if ((ch == 'g' || ch == 'G') && prec == 0) { 5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project prec = 1; 5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & LONGDBL) { 5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _double = (double) GETARG(long double); 5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _double = GETARG(double); 5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* do this before tricky precision changes */ 5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (_my_isinf(_double)) { 5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (_double < 0) 5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '-'; 5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = "Inf"; 5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = 3; 5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (_my_isnan(_double)) { 5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = "NaN"; 5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = 3; 5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= FPT; 5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = cvt(_double, prec, flags, &softsign, 5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project &expt, ch, &ndig); 5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp_free = cp; 5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == 'g' || ch == 'G') { 5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (expt <= -4 || expt > prec) 5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = (ch == 'g') ? 'e' : 'E'; 5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = 'g'; 5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch <= 'e') { /* 'e' or 'E' fmt */ 5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project --expt; 5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project expsize = exponent(expstr, expt, ch); 5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = expsize + ndig; 5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ndig > 1 || flags & ALT) 5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ++size; 5411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if (ch == 'f') { /* f fmt */ 5421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (expt > 0) { 5431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = expt; 5441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (prec || flags & ALT) 5451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size += prec + 1; 5461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else /* "0.X" */ 5471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = prec + 2; 5481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if (expt >= ndig) { /* fixed g fmt */ 5491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = expt; 5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & ALT) 5511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ++size; 5521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 5531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = ndig + (expt > 0 ? 5541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1 : 2 - expt); 5551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (softsign) 5571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '-'; 5581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */ 5601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* the Android security team suggests removing support for %n 5611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * since it has no real practical value, and could lead to 5621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * running malicious code (for really bugy programs that 5631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * send to printf() user-generated formatting strings). 5641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 5651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 0 5661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'n': 5671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & LLONGINT) 5681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(long long *) = ret; 5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & LONGINT) 5701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(long *) = ret; 5711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SHORTINT) 5721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(short *) = ret; 5731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & CHARINT) 5741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(__signed char *) = ret; 5751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & PTRINT) 5761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(ptrdiff_t *) = ret; 5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SIZEINT) 5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(ssize_t *) = ret; 5791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & MAXINT) 5801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(intmax_t *) = ret; 5811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 5821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *GETARG(int *) = ret; 5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; /* no output */ 5841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 5851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'O': 5861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 5871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 5881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'o': 5891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax = UARG(); 5901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = OCT; 5911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto nosign; 5921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'p': 5931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 5941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``The argument shall be a pointer to void. The 5951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * value of the pointer is converted to a sequence 5961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * of printable characters, in an implementation- 5971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * defined manner.'' 5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -- ANSI X3J11 5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* NOSTRICT */ 6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax = (u_long)GETARG(void *); 6021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = HEX; 6031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project xdigs = "0123456789abcdef"; 6041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= HEXPREFIX; 6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = 'x'; 6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto nosign; 6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 's': 6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((cp = GETARG(char *)) == NULL) 6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = "(null)"; 6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (prec >= 0) { 6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * can't use strlen; can only look for the 6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * NUL in the first `prec' characters, and 6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * strlen() will go further. 6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *p = memchr(cp, 0, prec); 6171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (p != NULL) { 6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = p - cp; 6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (size > prec) 6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = prec; 6221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = prec; 6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = strlen(cp); 6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '\0'; 6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'U': 6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'u': 6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax = UARG(); 6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = DEC; 6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto nosign; 6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'X': 6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project xdigs = "0123456789ABCDEF"; 6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto hex; 6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'x': 6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project xdigs = "0123456789abcdef"; 6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecthex: _umax = UARG(); 6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = HEX; 6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* leading 0x/X only if non-zero */ 6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & ALT && _umax != 0) 6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= HEXPREFIX; 6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* unsigned conversions */ 6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectnosign: sign = '\0'; 6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``... diouXx conversions ... if a precision is 6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * specified, the 0 flag will be ignored.'' 6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -- ANSI X3J11 6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectnumber: if ((dprec = prec) >= 0) 6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~ZEROPAD; 6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``The result of converting a zero value with an 6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * explicit precision of zero is no characters.'' 6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -- ANSI X3J11 6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = buf + BUF; 6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (_umax != 0 || prec != 0) { 6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Unsigned mod is hard, and unsigned mod 6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * by a constant is easier than that by 6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * a variable; hence this switch. 6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (base) { 6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case OCT: 6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *--cp = to_char(_umax & 7); 6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax >>= 3; 6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (_umax); 6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* handle octal leading 0 */ 6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & ALT && *cp != '0') 6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *--cp = '0'; 6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case DEC: 6801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* many numbers are 1 digit */ 6811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (_umax >= 10) { 6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *--cp = to_char(_umax % 10); 6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax /= 10; 6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *--cp = to_char(_umax); 6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case HEX: 6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *--cp = xdigs[_umax & 15]; 6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _umax >>= 4; 6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (_umax); 6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = "bug in vfprintf: bad base"; 6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = strlen(cp); 6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto skipsize; 6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = buf + BUF - cp; 7021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project skipsize: 7031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: /* "%?" prints ?, unless ? is NUL */ 7051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == '\0') 7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* pretend it was %c with argument ch */ 7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = buf; 7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *cp = ch; 7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size = 1; 7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sign = '\0'; 7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All reasonable formats wind up here. At this point, `cp' 7171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * points to a string which (if not flags&LADJUST) should be 7181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * padded out to `width' places. If flags&ZEROPAD, it should 7191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * first be prefixed by any sign or other prefix; otherwise, 7201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * it should be blank padded before the prefix is emitted. 7211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * After any left-hand padding and prefixing, emit zeroes 7221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * required by a decimal [diouxX] precision, then print the 7231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * string proper, then emit zeroes required by any leftover 7241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * floating precision; finally, if LADJUST, pad with blanks. 7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Compute actual size, so we know how much to pad. 7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * size excludes decimal prec; realsz includes it. 7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project realsz = dprec > size ? dprec : size; 7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sign) 7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project realsz++; 7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & HEXPREFIX) 7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project realsz+= 2; 7341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* right-adjusting blank padding */ 7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags & (LADJUST|ZEROPAD)) == 0) 7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(width - realsz, blanks); 7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* prefix */ 7401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sign) { 7411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(&sign, 1); 7421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if (flags & HEXPREFIX) { 7431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ox[0] = '0'; 7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ox[1] = ch; 7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(ox, 2); 7461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* right-adjusting zero padding */ 7491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(width - realsz, zeroes); 7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* leading zeroes from decimal precision */ 7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(dprec - size, zeroes); 7541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* the string or number proper */ 7561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 7571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags & FPT) == 0) { 7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, size); 7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { /* glue together f_p fragments */ 7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch >= 'f') { /* 'f' or 'g' */ 7611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (_double == 0) { 7621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* kludge for __dtoa irregularity */ 7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT("0", 1); 7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (expt < ndig || (flags & ALT) != 0) { 7651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(decimal_point, 1); 7661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(ndig - 1, zeroes); 7671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if (expt <= 0) { 7691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT("0", 1); 7701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(decimal_point, 1); 7711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(-expt, zeroes); 7721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, ndig); 7731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if (expt >= ndig) { 7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, ndig); 7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(expt - ndig, zeroes); 7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & ALT) 7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(".", 1); 7781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 7791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, expt); 7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += expt; 7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(".", 1); 7821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, ndig-expt); 7831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { /* 'e' or 'E' */ 7851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ndig > 1 || flags & ALT) { 7861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ox[0] = *cp++; 7871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ox[1] = '.'; 7881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(ox, 2); 7891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (_double) { 7901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, ndig-1); 7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else /* 0.[0..] */ 7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* __dtoa irregularity */ 7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(ndig - 1, zeroes); 7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else /* XeYYY */ 7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, 1); 7961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(expstr, expsize); 7971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 8001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PRINT(cp, size); 8011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 8021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* left-adjusting padding (always blank) */ 8031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & LADJUST) 8041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PAD(width - realsz, blanks); 8051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* finally, adjust ret */ 8071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret += width > realsz ? width : realsz; 8081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project FLUSH(); /* copy out the I/O vectors */ 8101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1 /* BIONIC: remove memory leak when printing doubles */ 8111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp_free) { 8121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project free(cp_free); 8131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp_free = NULL; 8141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 8161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdone: 8181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project FLUSH(); 8191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecterror: 8201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1 /* BIONIC: remove memory leak when printing doubles */ 8211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp_free) { 8221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project free(cp_free); 8231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp_free = NULL; 8241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 8261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (argtable != NULL && argtable != statargtable) { 8271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project munmap(argtable, argtablesiz); 8281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argtable = NULL; 8291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (__sferror(fp) ? EOF : ret); 8311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* NOTREACHED */ 8321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 8331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 8351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Type ids for argument type table. 8361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_UNUSED 0 8381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_SHORT 1 8391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_SHORT 2 8401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_SHORT 3 8411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_INT 4 8421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_INT 5 8431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_INT 6 8441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_LONG 7 8451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_LONG 8 8461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_LONG 9 8471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_LLONG 10 8481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_LLONG 11 8491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_LLONG 12 8501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_DOUBLE 13 8511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_LONG_DOUBLE 14 8521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_CHAR 15 8531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_VOID 16 8541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_PTRINT 17 8551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_PTRINT 18 8561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_SIZEINT 19 8571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_SSIZEINT 20 8581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_SSIZEINT 21 8591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_MAXINT 22 8601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_MAXUINT 23 8611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_MAXINT 24 8621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 8641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Find all arguments when a positional parameter is encountered. Returns a 8651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * table, indexed by argument number, of pointers to each arguments. The 8661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. 8671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * It will be replaced with a mmap-ed one if it overflows (malloc cannot be 8681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * used since we are attempting to make snprintf thread safe, and alloca is 8691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * problematic since we have nested functions..) 8701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void 8721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__find_arguments(const char *fmt0, va_list ap, va_list **argtable, 8731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t *argtablesiz) 8741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 8751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *fmt; /* format string */ 8761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ch; /* character from fmt */ 8771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, n2; /* handy integer (short term usage) */ 8781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *cp; /* handy char pointer (short term usage) */ 8791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int flags; /* flags as above */ 8801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project unsigned char *typetable; /* table of types */ 8811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project unsigned char stattypetable[STATIC_ARG_TBL_SIZE]; 8821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int tablesize; /* current size of type table */ 8831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int tablemax; /* largest used index in table */ 8841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nextarg; /* 1-based argument index */ 8851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project wchar_t wc; 8861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project void* ps; 8871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Add an argument type to the table, expanding if necessary. 8901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ADDTYPE(type) \ 8921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((nextarg >= tablesize) ? \ 8931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __grow_type_table(&typetable, &tablesize) : 0, \ 8941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (nextarg > tablemax) ? tablemax = nextarg : 0, \ 8951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project typetable[nextarg++] = type) 8961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ADDSARG() \ 8981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&MAXINT) ? ADDTYPE(T_MAXINT) : \ 8991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \ 9001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&SIZEINT) ? ADDTYPE(T_SSIZEINT) : \ 9011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ 9021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&LONGINT) ? ADDTYPE(T_LONG) : \ 9031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : ADDTYPE(T_INT))))))) 9041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ADDUARG() \ 9061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&MAXINT) ? ADDTYPE(T_MAXUINT) : \ 9071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \ 9081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&SIZEINT) ? ADDTYPE(T_SIZEINT) : \ 9091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ 9101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : \ 9111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : ADDTYPE(T_U_INT))))))) 9121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Add * arguments to the type array. 9151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ADDASTER() \ 9171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n2 = 0; \ 9181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = fmt; \ 9191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (is_digit(*cp)) { \ 9201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n2 = 10 * n2 + to_digit(*cp); \ 9211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp++; \ 9221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } \ 9231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*cp == '$') { \ 9241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int hold = nextarg; \ 9251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = n2; \ 9261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(T_INT); \ 9271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = hold; \ 9281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt = ++cp; \ 9291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { \ 9301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(T_INT); \ 9311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt = (char *)fmt0; 9331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project typetable = stattypetable; 9341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tablesize = STATIC_ARG_TBL_SIZE; 9351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tablemax = 0; 9361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = 1; 9371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memset(typetable, T_UNUSED, STATIC_ARG_TBL_SIZE); 9381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memset(&ps, 0, sizeof(ps)); 9391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Scan the format for conversions (`%' character). 9421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (;;) { 9441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = fmt; 9451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1 /* BIONIC */ 9461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = -1; 9471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((wc = *fmt) != 0) { 9481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (wc == '%') { 9491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 9501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 9511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 9531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 9551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((n = mbrtowc(&wc, fmt, MB_CUR_MAX, &ps)) > 0) { 9561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt += n; 9571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (wc == '%') { 9581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt--; 9591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 9601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 9631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) 9641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 9651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; /* skip over '%' */ 9661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags = 0; 9681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectrflag: ch = *fmt++; 9701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectreswitch: switch (ch) { 9711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ' ': 9721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '#': 9731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 9741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '*': 9751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDASTER(); 9761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 9771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '-': 9781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '+': 9791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 9801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '.': 9811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((ch = *fmt++) == '*') { 9821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDASTER(); 9831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 9841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (is_digit(ch)) { 9861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = *fmt++; 9871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto reswitch; 9891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '0': 9901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 9911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '1': case '2': case '3': case '4': 9921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '5': case '6': case '7': case '8': case '9': 9931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 0; 9941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 9951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 10 * n + to_digit(ch); 9961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = *fmt++; 9971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (is_digit(ch)); 9981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == '$') { 9991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nextarg = n; 10001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 10011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto reswitch; 10031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 10041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'L': 10051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGDBL; 10061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 10071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 10081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'h': 10091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*fmt == 'h') { 10101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 10111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= CHARINT; 10121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 10131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SHORTINT; 10141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 10161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'l': 10171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*fmt == 'l') { 10181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 10191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LLONGINT; 10201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 10211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 10221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 10241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'q': 10251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LLONGINT; 10261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 10271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 't': 10281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= PTRINT; 10291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 10301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'z': 10311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SIZEINT; 10321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto rflag; 10331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'c': 10341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(T_INT); 10351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'D': 10371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 10381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 10391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'd': 10401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'i': 10411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDSARG(); 10421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 10441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'e': 10451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'E': 10461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'f': 10471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'g': 10481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'G': 10491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & LONGDBL) 10501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(T_LONG_DOUBLE); 10511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 10521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(T_DOUBLE); 10531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */ 10551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'n': 10561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & LLONGINT) 10571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_LLONG); 10581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & LONGINT) 10591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_LONG); 10601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SHORTINT) 10611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_SHORT); 10621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & PTRINT) 10631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_PTRINT); 10641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SIZEINT) 10651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_SSIZEINT); 10661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & MAXINT) 10671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_MAXINT); 10681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 10691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_INT); 10701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; /* no output */ 10711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'O': 10721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 10731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 10741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'o': 10751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDUARG(); 10761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'p': 10781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_VOID); 10791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 's': 10811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDTYPE(TP_CHAR); 10821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'U': 10841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONGINT; 10851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 10861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'u': 10871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'X': 10881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'x': 10891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ADDUARG(); 10901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: /* "%?" prints ?, unless ? is NUL */ 10921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == '\0') 10931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 10941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 10951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdone: 10981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 10991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Build the argument table. 11001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 11011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tablemax >= STATIC_ARG_TBL_SIZE) { 11021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *argtablesiz = sizeof (va_list) * (tablemax + 1); 11031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *argtable = (va_list *)mmap(NULL, *argtablesiz, 11041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project PROT_WRITE|PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0); 11051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 11071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 0 11081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* XXX is this required? */ 11091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (*argtable) [0] = NULL; 11101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 11111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (n = 1; n <= tablemax; n++) { 11121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_copy((*argtable)[n], ap); 11131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (typetable[n]) { 11141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_UNUSED: 11151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, int); 11161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_SHORT: 11181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, int); 11191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_U_SHORT: 11211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, int); 11221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_SHORT: 11241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, short *); 11251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_INT: 11271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, int); 11281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_U_INT: 11301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, unsigned int); 11311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_INT: 11331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, int *); 11341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_LONG: 11361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, long); 11371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_U_LONG: 11391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, unsigned long); 11401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_LONG: 11421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, long *); 11431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_LLONG: 11451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, long long); 11461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_U_LLONG: 11481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, unsigned long long); 11491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_LLONG: 11511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, long long *); 11521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_DOUBLE: 11541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, double); 11551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_LONG_DOUBLE: 11571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, long double); 11581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_CHAR: 11601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, char *); 11611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_VOID: 11631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, void *); 11641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_PTRINT: 11661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, ptrdiff_t); 11671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_PTRINT: 11691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, ptrdiff_t *); 11701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_SIZEINT: 11721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, size_t); 11731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case T_SSIZEINT: 11751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, ssize_t); 11761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_SSIZEINT: 11781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, ssize_t *); 11791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case TP_MAXINT: 11811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) va_arg(ap, intmax_t *); 11821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 11831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 11861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (typetable != NULL && typetable != stattypetable) { 11871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project munmap(typetable, *argtablesiz); 11881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project typetable = NULL; 11891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 11911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 11921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 11931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Increase the size of the type table. 11941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 11951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 11961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__grow_type_table(unsigned char **typetable, int *tablesize) 11971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 11981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project unsigned char *oldtable = *typetable; 11991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int newsize = *tablesize * 2; 12001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*tablesize == STATIC_ARG_TBL_SIZE) { 12021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *typetable = (unsigned char *)mmap(NULL, 12031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sizeof (unsigned char) * newsize, PROT_WRITE|PROT_READ, 12041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project MAP_ANON|MAP_PRIVATE, -1, 0); 12051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* XXX unchecked */ 12061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memcpy( *typetable, oldtable, *tablesize); 12071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 12081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project unsigned char *new = (unsigned char *)mmap(NULL, 12091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sizeof (unsigned char) * newsize, PROT_WRITE|PROT_READ, 12101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project MAP_ANON|MAP_PRIVATE, -1, 0); 12111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memmove(new, *typetable, *tablesize); 12121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project munmap(*typetable, *tablesize); 12131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *typetable = new; 12141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* XXX unchecked */ 12151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memset(*typetable + *tablesize, T_UNUSED, (newsize - *tablesize)); 12171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *tablesize = newsize; 12191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return(0); 12201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 12241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char *__dtoa(double, int, int, int *, int *, char **); 12261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char * 12281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectcvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch, 12291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int *length) 12301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 12311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int mode, dsgn; 12321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *digits, *bp, *rve; 12331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == 'f') { 12351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mode = 3; /* ndigits after the decimal point */ 12361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 12371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* To obtain ndigits after the decimal point for the 'e' 12381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * and 'E' formats, round to ndigits + 1 significant 12391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * figures. 12401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == 'e' || ch == 'E') { 12421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ndigits++; 12431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mode = 2; /* ndigits significant digits */ 12451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (value < 0) { 12481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project value = -value; 12491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *sign = '-'; 12501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 12511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *sign = '\000'; 12521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); 12531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */ 12541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bp = digits + ndigits; 12551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == 'f') { 12561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*digits == '0' && value) 12571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *decpt = -ndigits + 1; 12581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bp += *decpt; 12591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (value == 0) /* kludge for __dtoa irregularity */ 12611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rve = bp; 12621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (rve < bp) 12631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *rve++ = '0'; 12641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *length = rve - digits; 12661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (digits); 12671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 12701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectexponent(char *p0, int exp, int fmtch) 12711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 12721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *p, *t; 12731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char expbuf[MAXEXP]; 12741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p = p0; 12761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = fmtch; 12771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (exp < 0) { 12781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project exp = -exp; 12791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = '-'; 12801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 12821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = '+'; 12831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = expbuf + MAXEXP; 12841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (exp > 9) { 12851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 12861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *--t = to_char(exp % 10); 12871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while ((exp /= 10) > 9); 12881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *--t = to_char(exp); 12891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (; t < expbuf + MAXEXP; *p++ = *t++); 12901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else { 12921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = '0'; 12931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = to_char(exp); 12941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (p - p0); 12961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC */ 13001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <machine/ieee.h> 13011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union { 13021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project double d; 13031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct ieee_double i; 13041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} ieee_u; 13051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 13071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_my_isinf (double value) 13081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 13091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ieee_u u; 13101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.d = value; 13121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (u.i.dbl_exp == 2047 && u.i.dbl_frach == 0 && u.i.dbl_fracl == 0); 13131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 13161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_my_isnan (double value) 13171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 13181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ieee_u u; 13191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.d = value; 13211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (u.i.dbl_exp == 2047 && (u.i.dbl_frach != 0 || u.i.dbl_fracl != 0)); 13221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */ 1324