4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implementation of scanf internals for <stdio.h>.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials are licensed and made available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync under the terms and conditions of the BSD License that accompanies this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 1990, 1993
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Regents of the University of California. All rights reserved.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code is derived from software contributed to Berkeley by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Chris Torek.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Redistribution and use in source and binary forms, with or without
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync modification, are permitted provided that the following conditions
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are met:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Redistributions of source code must retain the above copyright
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync notice, this list of conditions and the following disclaimer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Redistributions in binary form must reproduce the above copyright
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync notice, this list of conditions and the following disclaimer in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync documentation and/or other materials provided with the distribution.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Neither the name of the University nor the names of its contributors
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync may be used to endorse or promote products derived from this software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync without specific prior written permission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync POSSIBILITY OF SUCH DAMAGE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetBSD: vfscanf.c,v 1.37.4.1 2007/05/07 19:49:08 pavel Exp
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.41 2007/01/09 00:28:07 imp Exp
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync vfscanf.c 8.1 (Berkeley) 6/4/93
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <LibConfig.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "namespace.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <assert.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <ctype.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <errno.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <inttypes.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <stdio.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <stdlib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <stddef.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <stdarg.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <string.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <sys/types.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <wchar.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <wctype.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "reentrant.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "local.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_FLOATING_POINT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <locale.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Provide an external name for vfscanf. Note, EFI uses the normal
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * namespace.h method; stdio routines explicitly use the internal name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * __svfscanf.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef __weak_alias
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync__weak_alias(vfscanf,__svfscanf)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define BUF 513 /* Maximum length of numeric string. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Flags used during conversion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define LONG 0x0001 /* l: long or double */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define LONGDBL 0x0002 /* L: long double */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define SHORT 0x0004 /* h: short */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define SUPPRESS 0x0008 /* *: suppress assignment */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define POINTER 0x0010 /* p: void * (as hex) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define NOSKIP 0x0020 /* [ or c: do not skip blanks */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define LONGLONG 0x0400 /* ll: long long (+ deprecated q: quad) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define INTMAXT 0x0800 /* j: intmax_t */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define PTRDIFFT 0x1000 /* t: ptrdiff_t */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define SIZET 0x2000 /* z: size_t */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define SHORTSHORT 0x4000 /* hh: char */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define UNSIGNED 0x8000 /* %[oupxX] conversions */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The following are used in integral conversions only:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * SIGNOK, NDIGITS, PFXOK, and NZDIGITS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define SIGNOK 0x00040 /* +/- is (still) legal */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define NDIGITS 0x00080 /* no digits detected */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define PFXOK 0x00100 /* 0x prefix is (still) legal */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define NZDIGITS 0x00200 /* no zero digits detected */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define HAVESIGN 0x10000 /* sign detected */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Conversion types.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define CT_CHAR 0 /* %c conversion */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define CT_CCL 1 /* %[...] conversion */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define CT_STRING 2 /* %s conversion */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define CT_INT 3 /* %[dioupxX] conversion */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define CT_FLOAT 4 /* %[efgEFG] conversion */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic const u_char *__sccl(char *, const u_char *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_FLOATING_POINT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static int parsefloat(FILE *, char *, char *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint __scanfdebug = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define __collate_load_error /*CONSTCOND*/0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync__collate_range_cmp(int c1, int c2)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static char s1[2], s2[2];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s1[0] = (char)c1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s2[0] = (char)c2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return strcoll(s1, s2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * __svfscanf - MT-safe version
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync__svfscanf(FILE *fp, char const *fmt0, va_list ap)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if(fp == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (EOF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FLOCKFILE(fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ret = __svfscanf_unlocked(fp, fmt0, ap);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FUNLOCKFILE(fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (ret);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * __svfscanf_unlocked - non-MT-safe version of __svfscanf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync__svfscanf_unlocked(FILE *fp, const char *fmt0, va_list ap)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync const u_char *fmt = (const u_char *)fmt0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int c; /* character from format, or conversion */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t width; /* field width, or 0 */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char *p; /* points into all kinds of strings */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t n; /* handy size_t */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int flags; /* flags as defined above */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char *p0; /* saves original value of p when necessary */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int nassigned; /* number of fields assigned */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int nconversions; /* number of conversions */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int nread; /* number of characters consumed from fp */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int base; /* base argument to conversion function */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char ccltab[256]; /* character class table for %[...] */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char buf[BUF]; /* buffer for numeric and mb conversions */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wchar_t *wcp; /* handy wide character pointer */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t nconv; /* length of multibyte sequence converted */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static const mbstate_t initial = { 0 };
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mbstate_t mbs;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* `basefix' is used to avoid `if' tests in the integer scanner */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static const short basefix[17] =
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync _DIAGASSERT(fp != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync _DIAGASSERT(fmt0 != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if(fp == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (EOF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync _SET_ORIENTATION(fp, -1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a( %d, \"%a\", ...)\n", __func__, fp->_file, fmt0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconversions = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (;;) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = (unsigned char)*fmt++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (nassigned);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (isspace(c)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((fp->_r > 0 || __srefill(fp) == 0) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync isspace(*fp->_p))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread++, fp->_r--, fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c != '%')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto literal;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * switch on the format. continue if done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * break once format type is derived.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncagain: c = *fmt++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (c) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '%':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncliteral:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*fp->_p != c)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto match_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_r--, fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '*':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= SUPPRESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'j':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= INTMAXT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'l':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & LONG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~LONG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= LONGLONG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= LONG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'q':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= LONGLONG; /* not quite */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 't':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= PTRDIFFT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'z':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= SIZET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'L':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= LONGDBL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'h':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & SHORT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~SHORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= SHORTSHORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= SHORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '0': case '1': case '2': case '3': case '4':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '5': case '6': case '7': case '8': case '9':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = width * 10 + c - '0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto again;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Conversions.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'd':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_INT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 10;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'i':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_INT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'o':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_INT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= UNSIGNED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 8;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'u':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_INT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= UNSIGNED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 10;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'X':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'x':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= PFXOK; /* enable 0x prefixing */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_INT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= UNSIGNED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 16;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_FLOATING_POINT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'A': case 'E': case 'F': case 'G':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'a': case 'e': case 'f': case 'g':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_FLOAT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'S':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= LONG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* FALLTHROUGH */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 's':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_STRING;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '[':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fmt = __sccl(ccltab, fmt);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= NOSKIP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_CCL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'C':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= LONG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* FALLTHROUGH */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'c':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= NOSKIP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_CHAR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'p': /* pointer format is like hex */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= POINTER | PFXOK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = CT_INT; /* assumes sizeof(uintmax_t) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= UNSIGNED; /* >= sizeof(uintptr_t) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 16;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'n':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconversions++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & SUPPRESS) /* ??? */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & SHORTSHORT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, char *) = (char)nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & SHORT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, short *) = (short)nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & LONG)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, long *) = nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & LONGLONG)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, long long *) = nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & INTMAXT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, intmax_t *) = nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & SIZET)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, size_t *) = nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & PTRDIFFT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, ptrdiff_t *) = nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, int *) = nread;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto match_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Disgusting backwards compatibility hack. XXX
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '\0': /* compat */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (EOF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * We have a conversion that requires input.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Consume leading white space, except for formats
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * that suppress this.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((flags & NOSKIP) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (isspace(*fp->_p)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--fp->_r > 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (__srefill(fp))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Note that there is at least one character in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * the buffer, so conversions that do not set NOSKIP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * ca no longer result in an input failure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Do the conversion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (c) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CT_CHAR:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* scan arbitrary characters (sets NOSKIP) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (width == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & LONG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((flags & SUPPRESS) == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp = va_arg(ap, wchar_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (width != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == MB_CUR_MAX) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buf[n++] = *fp->_p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_r--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mbs = initial;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconv = mbrtowc(wcp, buf, n, &mbs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv == (size_t)-1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv == 0 && !(flags & SUPPRESS))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *wcp = L'\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv != (size_t)-2) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(flags & SUPPRESS))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(flags & SUPPRESS))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (flags & SUPPRESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t sum = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (;;) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((n = fp->_r) < width) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sum += n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width -= n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p += n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (__srefill(fp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (sum == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sum += width;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_r -= (int)width;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p += width;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)sum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t r = fread(va_arg(ap, char *), 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width, fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (r == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)r;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconversions++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CT_CCL:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* scan a (nonempty) character class (sets NOSKIP) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (width == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = (size_t)~0; /* `infinity' */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* take only those things in the class */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & LONG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wchar_t twc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int nchars;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((flags & SUPPRESS) == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp = va_arg(ap, wchar_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp = &twc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nchars = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (width != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == MB_CUR_MAX) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buf[n++] = *fp->_p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_r--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mbs = initial;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconv = mbrtowc(wcp, buf, n, &mbs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv == (size_t)-1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *wcp = L'\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv != (size_t)-2) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (wctob(*wcp) != EOF &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync !ccltab[wctob(*wcp)]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (n != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (void)ungetc(buf[n],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(flags & SUPPRESS))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nchars++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = nchars;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto match_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(flags & SUPPRESS)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *wcp = L'\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (flags & SUPPRESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (ccltab[*fp->_p]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n++, fp->_r--, fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--width == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto match_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync p0 = p = va_arg(ap, char *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (ccltab[*fp->_p]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_r--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *p++ = *fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--width == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (p == p0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = p - p0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto match_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *p = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconversions++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CT_STRING:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* like CCL, but zero-length string OK, & no NOSKIP */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (width == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = (size_t)~0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & LONG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wchar_t twc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((flags & SUPPRESS) == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp = va_arg(ap, wchar_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp = &twc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!isspace(*fp->_p) && width != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == MB_CUR_MAX) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buf[n++] = *fp->_p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_r--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mbs = initial;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconv = mbrtowc(wcp, buf, n, &mbs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv == (size_t)-1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *wcp = L'\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nconv != (size_t)-2) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (iswspace(*wcp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (n != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (void)ungetc(buf[n],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(flags & SUPPRESS))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wcp++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_flags |= __SERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto input_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(flags & SUPPRESS)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *wcp = L'\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (flags & SUPPRESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!isspace(*fp->_p)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n++, fp->_r--, fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--width == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync p0 = p = va_arg(ap, char *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!isspace(*fp->_p)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_r--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *p++ = *fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--width == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (fp->_r <= 0 && __srefill(fp))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *p = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)(p - p0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconversions++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CT_INT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* scan an integer as if by the conversion function */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef hardway
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (width == 0 || width > sizeof(buf) - 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = sizeof(buf) - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* size_t is unsigned, hence this optimisation */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--width > sizeof(buf) - 2)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = sizeof(buf) - 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= SIGNOK | NDIGITS | NZDIGITS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (p = buf; width; width--) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *fp->_p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Switch on the character; `goto ok'
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * if we accept it as a part of number.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (c) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The digit 0 is always legal, but is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * special. For %i conversions, if no
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * digits (zero or nonzero) have been
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * scanned (only signs), we will have
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * base==0. In that case, we should set
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * it to 8 and enable 0x prefixing.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Also, if we have not scanned zero digits
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * before this, do not turn off prefixing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (someone else will turn it off if we
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * have scanned any nonzero digits).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '0':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (base == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 8;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= PFXOK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & NZDIGITS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~(SIGNOK|PFXOK|NDIGITS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ok;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* 1 through 7 always legal */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '1': case '2': case '3':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '4': case '5': case '6': case '7':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = basefix[base];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~(SIGNOK | PFXOK | NDIGITS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ok;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* digits 8 and 9 ok iff decimal or hex */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '8': case '9':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = basefix[base];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (base <= 8)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break; /* not legal here */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~(SIGNOK | PFXOK | NDIGITS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ok;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* letters ok iff hex */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'A': case 'B': case 'C':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'D': case 'E': case 'F':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'a': case 'b': case 'c':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'd': case 'e': case 'f':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* no need to fix base here */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (base <= 10)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break; /* not legal here */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~(SIGNOK | PFXOK | NDIGITS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ok;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* sign ok only as first character */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '+': case '-':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & SIGNOK) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~SIGNOK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags |= HAVESIGN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ok;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * x ok iff flag still set & 2nd char (or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * 3rd char if we have a sign).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'x': case 'X':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & PFXOK && p ==
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buf + 1 + !!(flags & HAVESIGN)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync base = 16; /* if %i */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync flags &= ~PFXOK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ok;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * If we got here, c is not a legal character
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * for a number. Stop accumulating digits.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ok:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * c is legal: store it and look at the next.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *p++ = (char)c;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--fp->_r > 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (__srefill(fp))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break; /* EOF */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * If we had only a sign, it is no good; push
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * back the sign. If the number ends in `x',
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * it was [sign] '0' 'x', so push back the x
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * and treat it as [sign] '0'.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & NDIGITS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (p > buf)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (void)ungetc(*(u_char *)--p, fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto match_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = ((u_char *)p)[-1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == 'x' || c == 'X') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync --p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (void)ungetc(c, fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((flags & SUPPRESS) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //uintmax_t res;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Use a union to get around the truncation warnings.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync union {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync uintmax_t umax;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync intmax_t imax;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync void *vp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ptrdiff_t pdt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t sz;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync long long ll;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync long lo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int in;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync short hw;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char ch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } res;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *p = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((flags & UNSIGNED) == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync res.imax = strtoimax(buf, (char **)NULL, base);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync res.umax = strtoumax(buf, (char **)NULL, base);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & POINTER)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, void **) = res.vp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //(void *)((uintptr_t)res);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & SHORTSHORT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, char *) = res.ch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & SHORT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, short *) = res.hw;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & LONG)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, long *) = res.lo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & LONGLONG)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, long long *) = res.ll;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & INTMAXT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, intmax_t *) = res.imax;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & PTRDIFFT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, ptrdiff_t *) = res.pdt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //(ptrdiff_t)res;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (flags & SIZET)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, size_t *) = res.sz;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, int *) = res.in;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)(p - buf);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconversions++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_FLOATING_POINT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CT_FLOAT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* scan a floating point number as if by strtod */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (width == 0 || width > sizeof(buf) - 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync width = sizeof(buf) - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((width = parsefloat(fp, buf, buf + width)) == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto match_failure;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((flags & SUPPRESS) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (flags & LONGDBL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync long double **mp = (long double **)ap;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync long double res = strtold(buf, &p);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *(*mp) = res;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ap += sizeof(long double *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*???*/ //*va_arg(ap, long double *) = res;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (flags & LONG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync double res = strtod(buf, &p);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, double *) = res;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync float res = strtof(buf, &p);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *va_arg(ap, float *) = res;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (__scanfdebug && p - buf != (ptrdiff_t)width)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync abort();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nassigned++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nread += (int)width;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nconversions++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* !NO_FLOATING_POINT */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncinput_failure:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//Print(L"%a: %d\n", __func__, __LINE__);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (nconversions != 0 ? nassigned : EOF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncmatch_failure:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (nassigned);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Fill in the given table from the scanset at the given format
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (just after `['). Return a pointer to the character past the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * closing `]'. The table has a 1 wherever characters should be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * considered part of the scanset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic const u_char *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync__sccl(char *tab, const u_char *fmt)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int c, n, v, i;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync _DIAGASSERT(tab != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync _DIAGASSERT(fmt != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* first `clear' the whole table */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *fmt++; /* first char hat => negated scanset */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == '^') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync v = 1; /* default => accept */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *fmt++; /* get new first char */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync v = 0; /* default => reject */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* XXX: Will not work if sizeof(tab*) > sizeof(char) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (void)memset(tab, v, 256);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (fmt - 1);/* format ended before closing ] */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Now set the entries corresponding to the actual scanset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * to the opposite of the above.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The first character may be ']' (or '-') without being special;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * the last character may be '-'.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync v = 1 - v;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (;;) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync tab[c] = (char)v; /* take character c */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdoswitch:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = *fmt++; /* and examine the next */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (n) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 0: /* format ended too soon */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (fmt - 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '-':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * A scanset of the form
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * [01+-]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * is defined as `the digit 0, the digit 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * the character +, the character -', but
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * the effect of a scanset such as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * [a-zA-Z0-9]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * is implementation defined. The V7 Unix
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * scanf treats `a-z' as `the letters a through
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * z', but treats `a-a' as `the letter a, the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * character -, and the letter a'.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * For compatibility, the `-' is not considerd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * to define a range if the character following
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * it is either a close bracket (required by ANSI)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * or is not numerically greater than the character
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * we just stored in the table (c).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync n = *fmt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n == ']' || (__collate_load_error ? n < c :
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync __collate_range_cmp(n, c) < 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = '-';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break; /* resume the for(;;) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fmt++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* fill in the range */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (__collate_load_error) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync tab[++c] = (char)v;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (c < n);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (i = 0; i < 256; i ++)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (__collate_range_cmp(c, i) < 0 &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync __collate_range_cmp(i, n) <= 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync tab[i] = (char)v;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if 1 /* XXX another disgusting compatibility hack */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Alas, the V7 Unix scanf also treats formats
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * such as [a-c-e] as `the letters a through e'.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This too is permitted by the standard....
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto doswitch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *fmt++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (fmt - 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == ']')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (fmt);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ']': /* end of scanset */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (fmt);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default: /* just another character */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* NOTREACHED */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_FLOATING_POINT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncparsefloat(FILE *fp, char *buf, char *end)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char *commit, *p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int infnanpos = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync enum {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } state = S_START;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync unsigned char c;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char decpt = *localeconv()->decimal_point;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync _Bool gotmantdig = 0, ishex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if(fp == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (EOF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * We set commit = p whenever the string we have read so far
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * constitutes a valid representation of a floating point
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * number by itself. At some point, the parse will complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * or fail, and we will ungetc() back to the last commit point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * To ensure that the file offset gets updated properly, it is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * always necessary to read at least one character that doesn't
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * match; thus, we can't short-circuit "infinity" or "nan(...)".
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = buf - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (p = buf; p < end; ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *fp->_p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncreswitch:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (state) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_START:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_GOTSIGN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == '-' || c == '+')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto reswitch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_GOTSIGN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (c) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '0':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_MAYBEHEX;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'I':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'i':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_INF;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'N':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'n':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_NAN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_DIGITS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto reswitch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_INF:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (infnanpos > 6 ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (c != "nfinity"[infnanpos] &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c != "NFINITY"[infnanpos]))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (infnanpos == 1 || infnanpos == 6)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = p; /* inf or infinity */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync infnanpos++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_NAN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (infnanpos) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case -1: /* XXX kludge to deal with nan(...) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 0:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c != 'A' && c != 'a')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 1:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c != 'N' && c != 'n')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 2:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c != '(')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == ')') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync infnanpos = -2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (!isalnum(c) && c != '_')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync infnanpos++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_MAYBEHEX:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_DIGITS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == 'X' || c == 'x') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ishex = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else { /* we saw a '0', but no 'x' */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gotmantdig = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto reswitch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_DIGITS:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ishex && isxdigit(c)) || isdigit(c))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gotmantdig = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_FRAC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c != decpt)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto reswitch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (gotmantdig)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_FRAC:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((c == 'E' || c == 'e') && !ishex) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((c == 'P' || c == 'p') && ishex)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!gotmantdig)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_EXP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if ((ishex && isxdigit(c)) || isdigit(c)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gotmantdig = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_EXP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync state = S_EXPDIGITS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == '-' || c == '+')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto reswitch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case S_EXPDIGITS:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (isdigit(c))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync commit = p;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto parsedone;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync abort();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *p++ = c;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (--fp->_r > 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fp->_p++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (__srefill(fp))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break; /* EOF */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncparsedone:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (commit < --p)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (void)ungetc(*(u_char *)p, fp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *++commit = '\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (int)(commit - buf);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif