69bd8e9da2
These files were segregated because they were lacking a little cleanup. Unfortunately that means this change has to do some of the cleanup, but that's probably for the best. Test: treehugger Change-Id: I2dd33504787fc3313995de99e0745a0df22915b3
115 lines
4.7 KiB
C
115 lines
4.7 KiB
C
/* $OpenBSD: vfscanf.c,v 1.31 2014/03/19 05:17:01 guenther Exp $ */
|
|
/*-
|
|
* Copyright (c) 1990, 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to Berkeley by
|
|
* Chris Torek.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <inttypes.h>
|
|
#include <limits.h>
|
|
#include <locale.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/param.h>
|
|
#include <wctype.h>
|
|
#include "local.h"
|
|
|
|
#include <platform/bionic/macros.h>
|
|
#include <private/bionic_fortify.h>
|
|
#include <private/bionic_mbstate.h>
|
|
|
|
#define BUF 513 /* Maximum length of numeric string. */
|
|
|
|
// Flags used during conversion.
|
|
// Size/type:
|
|
#define LONG 0x00001 // l: long or double
|
|
#define LONGDBL 0x00002 // L: long double
|
|
#define SHORT 0x00004 // h: short
|
|
#define SHORTSHORT 0x00008 // hh: 8 bit integer
|
|
#define LLONG 0x00010 // ll: long long (+ deprecated q: quad)
|
|
#define POINTER 0x00020 // p: void* (as hex)
|
|
#define SIZEINT 0x00040 // z: (signed) size_t
|
|
#define MAXINT 0x00080 // j: intmax_t
|
|
#define PTRINT 0x00100 // t: ptrdiff_t
|
|
#define NOSKIP 0x00200 // [ or c: do not skip blanks
|
|
// Modifiers:
|
|
#define SUPPRESS 0x00400 // *: suppress assignment
|
|
#define UNSIGNED 0x00800 // %[oupxX] conversions
|
|
#define ALLOCATE 0x01000 // m: allocate a char*
|
|
// Internal use during integer parsing:
|
|
#define SIGNOK 0x02000 // +/- is (still) legal
|
|
#define HAVESIGN 0x04000 // Sign detected
|
|
#define NDIGITS 0x08000 // No digits detected
|
|
#define PFXOK 0x10000 // "0x" prefix is (still) legal
|
|
#define PFBOK 0x20000 // "0b" prefix is (still) legal
|
|
#define NZDIGITS 0x40000 // No zero digits detected
|
|
|
|
// Conversion types.
|
|
#define CT_CHAR 0 // %c conversion
|
|
#define CT_CCL 1 // %[...] conversion
|
|
#define CT_STRING 2 // %s conversion
|
|
#define CT_INT 3 // Integer: strtoimax/strtoumax
|
|
#define CT_FLOAT 4 // Float: strtod
|
|
|
|
#define to_digit(c) static_cast<int>((c) - '0')
|
|
#define is_digit(c) (static_cast<unsigned>(to_digit(c)) <= 9)
|
|
|
|
// Append a digit to a value and check for overflow.
|
|
#define APPEND_DIGIT(val, dig) \
|
|
do { \
|
|
if ((val) > INT_MAX / 10) \
|
|
errno = ENOMEM; \
|
|
else { \
|
|
(val) *= 10; \
|
|
if ((val) > INT_MAX - to_digit((dig))) \
|
|
errno = ENOMEM; \
|
|
else \
|
|
(val) += to_digit((dig)); \
|
|
} \
|
|
} while (0)
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunused-function"
|
|
// Trasnlate a fixed size integer argument for the %w/%wf format to a
|
|
// flag representation. Supported sizes are 8, 16, 32, and 64 so far.
|
|
// See details in bionic/libc/include/stdint.h
|
|
static int w_to_flag(int size, bool fast) {
|
|
static constexpr int fast_size = sizeof(void*) == 8 ? LLONG : 0;
|
|
if (size == 8) return SHORTSHORT;
|
|
if (size == 16) return fast ? fast_size : SHORT;
|
|
if (size == 32) return fast ? fast_size : 0;
|
|
if (size == 64) return LLONG;
|
|
__fortify_fatal("%%w%s%d is unsupported", fast ? "f" : "", size);
|
|
}
|
|
|
|
#pragma clang diagnostic pop
|