11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* $OpenBSD: vfscanf.c,v 1.21 2006/01/13 21:33:28 millert Exp $ */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*- 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1990, 1993 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The Regents of the University of California. 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#include <ctype.h> 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <inttypes.h> 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdarg.h> 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stddef.h> 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "local.h" 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "floatio.h" 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define BUF 513 /* Maximum length of numeric string. */ 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flags used during conversion. 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LONG 0x00001 /* l: long or double */ 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LONGDBL 0x00002 /* L: long double; unimplemented */ 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SHORT 0x00004 /* h: short */ 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SHORTSHORT 0x00008 /* hh: 8 bit integer */ 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LLONG 0x00010 /* ll: long long (+ deprecated q: quad) */ 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define POINTER 0x00020 /* p: void * (as hex) */ 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SIZEINT 0x00040 /* z: (signed) size_t */ 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define MAXINT 0x00080 /* j: intmax_t */ 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PTRINT 0x00100 /* t: ptrdiff_t */ 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define NOSKIP 0x00200 /* [ or c: do not skip blanks */ 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SUPPRESS 0x00400 /* *: suppress assignment */ 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define UNSIGNED 0x00800 /* %[oupxX] conversions */ 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The following are used in numeric conversions only: 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point; 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral. 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SIGNOK 0x01000 /* +/- is (still) legal */ 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define HAVESIGN 0x02000 /* sign detected */ 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define NDIGITS 0x04000 /* no digits detected */ 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DPTOK 0x08000 /* (float) decimal point is still legal */ 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define EXPOK 0x10000 /* (float) exponent (e+3, etc) still legal */ 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PFXOK 0x08000 /* 0x prefix is (still) legal */ 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define NZDIGITS 0x10000 /* no zero digits detected */ 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Conversion types. 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CT_CHAR 0 /* %c conversion */ 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CT_CCL 1 /* %[...] conversion */ 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CT_STRING 2 /* %s conversion */ 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CT_INT 3 /* integer, i.e., strtoimax or strtoumax */ 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CT_FLOAT 4 /* floating, i.e., strtod */ 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define u_char unsigned char 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define u_long unsigned long 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic u_char *__sccl(char *, u_char *); 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if !defined(VFSCANF) 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define VFSCANF vfscanf 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * vfscanf 991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectVFSCANF(FILE *fp, const char *fmt0, __va_list ap) 1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *fmt = (u_char *)fmt0; 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int c; /* character from format, or conversion */ 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t width; /* field width, or 0 */ 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *p; /* points into all kinds of strings */ 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n; /* handy integer */ 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int flags; /* flags as defined above */ 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *p0; /* saves original value of p when necessary */ 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nassigned; /* number of fields assigned */ 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nread; /* number of characters consumed from fp */ 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int base; /* base argument to strtoimax/strtouimax */ 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char ccltab[256]; /* character class table for %[...] */ 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char buf[BUF]; /* buffer for numeric conversions */ 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* `basefix' is used to avoid `if' tests in the integer scanner */ 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static short basefix[17] = 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 120f582340a6a48588aa50da17e1620e8f91b146941Kenny Root FLOCKFILE(fp); 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _SET_ORIENTATION(fp, -1); 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nassigned = 0; 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread = 0; 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 0; /* XXX just to keep gcc happy */ 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (;;) { 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *fmt++; 128f582340a6a48588aa50da17e1620e8f91b146941Kenny Root if (c == 0) { 129f582340a6a48588aa50da17e1620e8f91b146941Kenny Root FUNLOCKFILE(fp); 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (nassigned); 131f582340a6a48588aa50da17e1620e8f91b146941Kenny Root } 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (isspace(c)) { 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((fp->_r > 0 || __srefill(fp) == 0) && 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project isspace(*fp->_p)) 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread++, fp->_r--, fp->_p++; 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (c != '%') 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto literal; 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = 0; 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags = 0; 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * switch on the format. continue if done; 1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * break once format type is derived. 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectagain: c = *fmt++; 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (c) { 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '%': 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectliteral: 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (fp->_r <= 0 && __srefill(fp)) 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto input_failure; 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*fp->_p != c) 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto match_failure; 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_r--, fp->_p++; 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread++; 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '*': 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SUPPRESS; 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'j': 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= MAXINT; 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'L': 165712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries flags |= 166712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries (*fmt == 'd') ? LLONG : 167712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries (*fmt == 'i') ? LLONG : 168712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries (*fmt == 'o') ? LLONG : 169712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries (*fmt == 'u') ? LLONG : 170712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries (*fmt == 'x') ? LLONG : 171712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries LONGDBL; 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'h': 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*fmt == 'h') { 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SHORTSHORT; 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SHORT; 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'l': 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*fmt == 'l') { 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LLONG; 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONG; 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'q': 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LLONG; /* deprecated */ 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 't': 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= PTRINT; 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'z': 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SIZEINT; 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '0': case '1': case '2': case '3': case '4': 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '5': case '6': case '7': case '8': case '9': 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = width * 10 + c - '0'; 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto again; 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Conversions. 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Those marked `compat' are for 4.[123]BSD compatibility. 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (According to ANSI, E and X formats are supposed 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * to the same as e and x. Sorry about that.) 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'D': /* compat */ 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONG; 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* FALLTHROUGH */ 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'd': 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_INT; 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 10; 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'i': 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_INT; 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 0; 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'O': /* compat */ 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONG; 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* FALLTHROUGH */ 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'o': 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_INT; 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= UNSIGNED; 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 8; 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'u': 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_INT; 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= UNSIGNED; 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 10; 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'X': 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'x': 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= PFXOK; /* enable 0x prefixing */ 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_INT; 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= UNSIGNED; 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 16; 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'E': 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'G': 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'e': 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'f': 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'g': 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_FLOAT; 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 's': 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_STRING; 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '[': 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt = __sccl(ccltab, fmt); 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= NOSKIP; 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_CCL; 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'c': 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= NOSKIP; 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_CHAR; 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'p': /* pointer format is like hex */ 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= POINTER | PFXOK; 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_INT; 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= UNSIGNED; 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 16; 2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'n': 2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & SUPPRESS) 2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & SHORTSHORT) 2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, __signed char *) = nread; 2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SHORT) 2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, short *) = nread; 2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & LONG) 2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, long *) = nread; 2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SIZEINT) 2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, ssize_t *) = nread; 2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & PTRINT) 2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, ptrdiff_t *) = nread; 2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & LLONG) 2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, long long *) = nread; 2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & MAXINT) 2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, intmax_t *) = nread; 2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, int *) = nread; 2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Disgusting backwards compatibility hacks. XXX 3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '\0': /* compat */ 304f582340a6a48588aa50da17e1620e8f91b146941Kenny Root FUNLOCKFILE(fp); 3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (EOF); 3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: /* compat */ 3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (isupper(c)) 3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= LONG; 3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = CT_INT; 3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 10; 3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * We have a conversion that requires input. 3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (fp->_r <= 0 && __srefill(fp)) 3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto input_failure; 3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Consume leading white space, except for formats 3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * that suppress this. 3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags & NOSKIP) == 0) { 3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (isspace(*fp->_p)) { 3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread++; 3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--fp->_r > 0) 3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_p++; 3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (__srefill(fp)) 3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto input_failure; 3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Note that there is at least one character in 3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the buffer, so conversions that do not set NOSKIP 3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ca no longer result in an input failure. 3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Do the conversion. 3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (c) { 3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case CT_CHAR: 3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* scan arbitrary characters (sets NOSKIP) */ 3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (width == 0) 3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = 1; 3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & SUPPRESS) { 3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t sum = 0; 3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (;;) { 3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((n = fp->_r) < (int)width) { 3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sum += n; 3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width -= n; 3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_p += n; 3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (__srefill(fp)) { 3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sum == 0) 3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto input_failure; 3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sum += width; 3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_r -= width; 3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_p += width; 3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread += sum; 3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t r = fread((void *)va_arg(ap, char *), 1, 3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width, fp); 3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (r == 0) 3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto input_failure; 3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread += r; 3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nassigned++; 3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case CT_CCL: 3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* scan a (nonempty) character class (sets NOSKIP) */ 3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (width == 0) 3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = (size_t)~0; /* `infinity' */ 3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* take only those things in the class */ 3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & SUPPRESS) { 3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 0; 3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (ccltab[*fp->_p]) { 3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++, fp->_r--, fp->_p++; 3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--width == 0) 3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (fp->_r <= 0 && __srefill(fp)) { 3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto input_failure; 3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto match_failure; 3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p0 = p = va_arg(ap, char *); 4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (ccltab[*fp->_p]) { 4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_r--; 4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = *fp->_p++; 4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--width == 0) 4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (fp->_r <= 0 && __srefill(fp)) { 4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (p == p0) 4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto input_failure; 4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = p - p0; 4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto match_failure; 4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p = '\0'; 4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nassigned++; 4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread += n; 4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case CT_STRING: 4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* like CCL, but zero-length string OK, & no NOSKIP */ 4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (width == 0) 4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = (size_t)~0; 4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & SUPPRESS) { 4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 0; 4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (!isspace(*fp->_p)) { 4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++, fp->_r--, fp->_p++; 4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--width == 0) 4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (fp->_r <= 0 && __srefill(fp)) 4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread += n; 4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p0 = p = va_arg(ap, char *); 4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (!isspace(*fp->_p)) { 4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_r--; 4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = *fp->_p++; 4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--width == 0) 4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (fp->_r <= 0 && __srefill(fp)) 4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p = '\0'; 4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread += p - p0; 4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nassigned++; 4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case CT_INT: 4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* scan an integer as if by strtoimax/strtoumax */ 4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef hardway 4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (width == 0 || width > sizeof(buf) - 1) 4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = sizeof(buf) - 1; 4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* size_t is unsigned, hence this optimisation */ 4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--width > sizeof(buf) - 2) 4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = sizeof(buf) - 2; 4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width++; 4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SIGNOK | NDIGITS | NZDIGITS; 4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (p = buf; width; width--) { 4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *fp->_p; 4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Switch on the character; `goto ok' 4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * if we accept it as a part of number. 4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (c) { 4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The digit 0 is always legal, but is 4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * special. For %i conversions, if no 4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * digits (zero or nonzero) have been 4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * scanned (only signs), we will have 4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * base==0. In that case, we should set 4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * it to 8 and enable 0x prefixing. 4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Also, if we have not scanned zero digits 4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * before this, do not turn off prefixing 4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (someone else will turn it off if we 4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * have scanned any nonzero digits). 4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '0': 4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (base == 0) { 4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 8; 4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= PFXOK; 4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & NZDIGITS) 4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~(SIGNOK|NZDIGITS|NDIGITS); 4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~(SIGNOK|PFXOK|NDIGITS); 4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto ok; 4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 1 through 7 always legal */ 4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '1': case '2': case '3': 4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '4': case '5': case '6': case '7': 4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = basefix[base]; 4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~(SIGNOK | PFXOK | NDIGITS); 4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto ok; 5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* digits 8 and 9 ok iff decimal or hex */ 5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '8': case '9': 5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = basefix[base]; 5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (base <= 8) 5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; /* not legal here */ 5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~(SIGNOK | PFXOK | NDIGITS); 5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto ok; 5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* letters ok iff hex */ 5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'A': case 'B': case 'C': 5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'D': case 'E': case 'F': 5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'a': case 'b': case 'c': 5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'd': case 'e': case 'f': 5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* no need to fix base here */ 5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (base <= 10) 5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; /* not legal here */ 5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~(SIGNOK | PFXOK | NDIGITS); 5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto ok; 5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* sign ok only as first character */ 5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '+': case '-': 5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & SIGNOK) { 5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~SIGNOK; 5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= HAVESIGN; 5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto ok; 5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * x ok iff flag still set and 2nd char (or 5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3rd char if we have a sign). 5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'x': case 'X': 5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags & PFXOK) && p == 5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project buf + 1 + !!(flags & HAVESIGN)) { 5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project base = 16; /* if %i */ 5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~PFXOK; 5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto ok; 5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 5441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If we got here, c is not a legal character 5451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * for a number. Stop accumulating digits. 5461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 5471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ok: 5491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * c is legal: store it and look at the next. 5511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 5521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = c; 5531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--fp->_r > 0) 5541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_p++; 5551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (__srefill(fp)) 5561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; /* EOF */ 5571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 5591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If we had only a sign, it is no good; push 5601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * back the sign. If the number ends in `x', 5611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * it was [sign] '0' 'x', so push back the x 5621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * and treat it as [sign] '0'. 5631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 5641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & NDIGITS) { 5651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (p > buf) 5661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) ungetc(*(u_char *)--p, fp); 5671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto match_failure; 5681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = ((u_char *)p)[-1]; 5701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (c == 'x' || c == 'X') { 5711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project --p; 5721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) ungetc(c, fp); 5731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags & SUPPRESS) == 0) { 5751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uintmax_t res; 5761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p = '\0'; 5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & UNSIGNED) 5791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res = strtoumax(buf, NULL, base); 5801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 5811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res = strtoimax(buf, NULL, base); 5821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & POINTER) 5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, void **) = 5841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void *)(uintptr_t)res; 5851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & MAXINT) 5861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, intmax_t *) = res; 5871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & LLONG) 5881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, long long *) = res; 5891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SIZEINT) 5901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, ssize_t *) = res; 5911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & PTRINT) 5921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, ptrdiff_t *) = res; 5931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & LONG) 5941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, long *) = res; 5951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SHORT) 5961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, short *) = res; 5971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & SHORTSHORT) 5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, __signed char *) = res; 5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 6001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, int *) = res; 6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nassigned++; 6021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread += p - buf; 6041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT 6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case CT_FLOAT: 6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* scan a floating point number as if by strtod */ 6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef hardway 6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (width == 0 || width > sizeof(buf) - 1) 6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = sizeof(buf) - 1; 6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* size_t is unsigned, hence this optimisation */ 6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--width > sizeof(buf) - 2) 6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width = sizeof(buf) - 2; 6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project width++; 6171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags |= SIGNOK | NDIGITS | DPTOK | EXPOK; 6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (p = buf; width; width--) { 6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *fp->_p; 6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code mimicks the integer conversion 6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * code, but is much simpler. 6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (c) { 6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '0': case '1': case '2': case '3': 6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '4': case '5': case '6': case '7': 6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '8': case '9': 6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~(SIGNOK | NDIGITS); 6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fok; 6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '+': case '-': 6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & SIGNOK) { 6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~SIGNOK; 6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fok; 6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '.': 6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & DPTOK) { 6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags &= ~(SIGNOK | DPTOK); 6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fok; 6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 'e': case 'E': 6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* no exponent without some digits */ 6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags&(NDIGITS|EXPOK)) == EXPOK) { 6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags = 6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (flags & ~(EXPOK|DPTOK)) | 6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project SIGNOK | NDIGITS; 6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fok; 6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fok: 6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p++ = c; 6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (--fp->_r > 0) 6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp->_p++; 6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (__srefill(fp)) 6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; /* EOF */ 6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If no digits, might be missing exponent digits 6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (just give back the exponent) or might be missing 6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * regular digits, but had sign and/or decimal point. 6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & NDIGITS) { 6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & EXPOK) { 6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* no digits at all */ 6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (p > buf) 6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ungetc(*(u_char *)--p, fp); 6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto match_failure; 6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* just a bad exponent (e and maybe sign) */ 6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *(u_char *)--p; 6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (c != 'e' && c != 'E') { 6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) ungetc(c, fp);/* sign */ 6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *(u_char *)--p; 6801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void) ungetc(c, fp); 6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((flags & SUPPRESS) == 0) { 6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project double res; 6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *p = '\0'; 6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res = strtod(buf, (char **) NULL); 6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (flags & LONGDBL) 6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, long double *) = res; 6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (flags & LONG) 6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, double *) = res; 6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *va_arg(ap, float *) = res; 6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nassigned++; 6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nread += p - buf; 6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */ 6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectinput_failure: 702f582340a6a48588aa50da17e1620e8f91b146941Kenny Root if (nassigned == 0) 703f582340a6a48588aa50da17e1620e8f91b146941Kenny Root nassigned = -1; 7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectmatch_failure: 705f582340a6a48588aa50da17e1620e8f91b146941Kenny Root FUNLOCKFILE(fp); 7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (nassigned); 7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Fill in the given table from the scanset at the given format 7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (just after `['). Return a pointer to the character past the 7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * closing `]'. The table has a 1 wherever characters should be 7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * considered part of the scanset. 7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic u_char * 7161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__sccl(char *tab, u_char *fmt) 7171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 7181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int c, n, v; 7191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* first `clear' the whole table */ 7211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *fmt++; /* first char hat => negated scanset */ 7221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (c == '^') { 7231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project v = 1; /* default => accept */ 7241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *fmt++; /* get new first char */ 7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project v = 0; /* default => reject */ 7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* should probably use memset here */ 7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (n = 0; n < 256; n++) 7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tab[n] = v; 7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (c == 0) 7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (fmt - 1);/* format ended before closing ] */ 7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Now set the entries corresponding to the actual scanset 7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * to the opposite of the above. 7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The first character may be ']' (or '-') without being special; 7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the last character may be '-'. 7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project v = 1 - v; 7411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (;;) { 7421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tab[c] = v; /* take character c */ 7431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdoswitch: 7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = *fmt++; /* and examine the next */ 7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (n) { 7461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 0: /* format ended too soon */ 7481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (fmt - 1); 7491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case '-': 7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * A scanset of the form 7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * [01+-] 7541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is defined as `the digit 0, the digit 1, 7551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the character +, the character -', but 7561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the effect of a scanset such as 7571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * [a-zA-Z0-9] 7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is implementation defined. The V7 Unix 7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * scanf treats `a-z' as `the letters a through 7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * z', but treats `a-a' as `the letter a, the 7611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * character -, and the letter a'. 7621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * For compatibility, the `-' is not considerd 7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * to define a range if the character following 7651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * it is either a close bracket (required by ANSI) 7661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * or is not numerically greater than the character 7671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * we just stored in the table (c). 7681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = *fmt; 7701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == ']' || n < c) { 7711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = '-'; 7721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; /* resume the for(;;) */ 7731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fmt++; 7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { /* fill in the range */ 7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tab[++c] = v; 7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (c < n); 7781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1 /* XXX another disgusting compatibility hack */ 7791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Alas, the V7 Unix scanf also treats formats 7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * such as [a-c-e] as `the letters a through e'. 7821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This too is permitted by the standard.... 7831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto doswitch; 7851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 7861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = *fmt++; 7871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (c == 0) 7881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (fmt - 1); 7891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (c == ']') 7901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (fmt); 7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ']': /* end of scanset */ 7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (fmt); 7961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: /* just another character */ 7981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project c = n; 7991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 8001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* NOTREACHED */ 8031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 804