diff options
author | eberlein <eberlein@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2008-01-15 21:45:22 +0000 |
---|---|---|
committer | eberlein <eberlein@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2008-01-15 21:45:22 +0000 |
commit | 87bb0ced5731f8d1b67cfd6d85d305abfae1bdab (patch) | |
tree | f340b0b12b1c73ba3aacfe1cac327fcbe47abbb7 | |
parent | f50e4435755c253328b1edc723365553c2cbd6ad (diff) |
2008-01-15 Pete Eberlein <eberlein@us.ibm.com>
* stdlib/stdlib.h: Merged DFP code.
* wcsmbs/wchar.h: Merged DFP code.
* configure.in: Added --enable-decimal-float option.
* math/math.h: Merged DFP code.
* math/fenv.h: Merged DFP code.
* math/bits/mathcalls.h: Merged DFP code.
* config.h.in: Added __STDC_DEC_FP__ define.
* stdio-common/printf.h: Merged DFP code.
* stdio-common/vfprintf.c: Merged DFP code.
* stdio-common/vfscanf.c: Merged DFP code.
* stdio-common/printf-parse.h: Merged DFP code.
* configure: Regenerated.
* dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions: Changed to GLIBC_2.6.
* dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions: Changed to GLIBC_2.6.
* dfp/sysdeps/soft-dfp/Versions: Changed to GLIBC_2.6.
* dfp/sysdeps/dfp/stdlib/stdlib.h: Deleted file.
* dfp/sysdeps/dfp/stdio-common/vfprintf.c: Deleted file.
* dfp/sysdeps/dfp/stdio-common/printf-parse.h: Deleted file.
* dfp/sysdeps/dfp/stdio-common/vfscanf.c: Deleted file.
* dfp/sysdeps/dfp/stdio-common/printf.h: Deleted file.
* dfp/sysdeps/dfp/Versions: Changed to GLIBC_2.6
* dfp/sysdeps/dfp/math/math.h: Deleted file.
* dfp/sysdeps/dfp/math/bits: Deleted file.
* dfp/sysdeps/dfp/math/bits/mathcalls.h: Deleted file.
* dfp/sysdeps/dfp/math/fenv.h: Deleted file.
* dfp/sysdeps/dfp/wcsmbs/wchar.h: Deleted file.
* dfp/Versions.def: Changed to GLIBC_2.6.
* dfp/Versions: Changed to GLIBC_2.6.
* dfp/Makefile: No longer build libdecnumber.so, instead only libdfp.so.
git-svn-id: svn://svn.eglibc.org/branches/libdfp@4902 7b3dc134-2b1b-0410-93df-9e9f96275f8d
28 files changed, 560 insertions, 8619 deletions
diff --git a/libc/config.h.in b/libc/config.h.in index b5abb1018..c198618f1 100644 --- a/libc/config.h.in +++ b/libc/config.h.in @@ -189,6 +189,9 @@ /* Define if __stack_chk_guard canary should be randomized at program startup. */ #undef ENABLE_STACKGUARD_RANDOMIZE +/* Define if decimal floating point support is desired. */ +#undef __STDC_DEC_FP__ + /* */ diff --git a/libc/configure b/libc/configure index c6854d5f1..e4d8a3eab 100755 --- a/libc/configure +++ b/libc/configure @@ -313,7 +313,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR NM OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH_SHELL libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_cc_with_libunwind libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie libc_cv_hashstyle fno_unit_at_a_time libc_cv_ssp libc_cv_gnu89_inline libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_libcap have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings libc_cv_cc_with_decimal_float build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR NM OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH_SHELL libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_cc_with_libunwind libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie libc_cv_hashstyle fno_unit_at_a_time libc_cv_ssp libc_cv_gnu89_inline libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_libcap have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -905,6 +905,7 @@ Optional Packages: default] --with-tls enable support for TLS --without-__thread do not use TLS features even when supporting them + --decimal-float enable support for decimal floating point. --with-cpu=CPU select code for CPU variant Some influential environment variables: @@ -1692,6 +1693,45 @@ if test "${enable_all_warnings+set}" = set; then fi; + +# Check whether --with-decimal-float or --without-decimal-float was given. +if test "${with_decimal_float+set}" = set; then + withval="$with_decimal_float" + usedfp=$withval +else + usedfp=yes +fi; +if test "$usedfp" != no; then +# Check to make sure the compiler supports decimal floating point. +echo "$as_me:$LINENO: checking for decimal-float-support in compiler" >&5 +echo $ECHO_N "checking for decimal-float-support in compiler... $ECHO_C" >&6 +if test "${libc_cv_cc_with_decimal_float+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat > conftest.c <<EOF +int main (void) { _Decimal32 d32; d32 = 1.0D; return 0; } +EOF + if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static -o conftest \ + conftest.c -v 2>&1 >/dev/null | grep -q " --enable-decimal-float "; +then + libc_cv_cc_with_decimal_float=yes + else + libc_cv_cc_with_decimal_float=no + fi + rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_cc_with_decimal_float" >&5 +echo "${ECHO_T}$libc_cv_cc_with_decimal_float" >&6 + +if test $libc_cv_cc_with_decimal_float = yes; then + cat >> confdefs.h <<\EOF +#define __STDC_DEC_FP__ 200704L +EOF +fi +fi + + # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 @@ -8464,6 +8504,7 @@ s,@oldest_abi@,$oldest_abi,;t t s,@bindnow@,$bindnow,;t t s,@force_install@,$force_install,;t t s,@all_warnings@,$all_warnings,;t t +s,@libc_cv_cc_with_decimal_float@,$libc_cv_cc_with_decimal_float,;t t s,@build@,$build,;t t s,@build_cpu@,$build_cpu,;t t s,@build_vendor@,$build_vendor,;t t diff --git a/libc/configure.in b/libc/configure.in index e6cf65a87..1a1921c77 100644 --- a/libc/configure.in +++ b/libc/configure.in @@ -254,6 +254,35 @@ AC_ARG_ENABLE([all-warnings], []) AC_SUBST(all_warnings) +AC_ARG_WITH([decimal-float], + AC_HELP_STRING([--decimal-float], + [enable support for decimal floating point.]), + [usedfp=$withval], + [usedfp=yes]) +if test "$usedfp" != no; then +# Check to make sure the compiler supports decimal floating point. +AC_CACHE_CHECK(for decimal-float-support in compiler, + libc_cv_cc_with_decimal_float, [ + cat > conftest.c <<EOF +int main (void) { _Decimal32 d32; d32 = 1.0D; return 0; } +EOF + if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static -o conftest \ + conftest.c -v 2>&1 >/dev/null | grep -q " --enable-decimal-float "; +then + libc_cv_cc_with_decimal_float=yes + else + libc_cv_cc_with_decimal_float=no + fi + rm -f conftest*]) +AC_SUBST(libc_cv_cc_with_decimal_float) +if test $libc_cv_cc_with_decimal_float = yes; then + cat >> confdefs.h <<\EOF +#define __STDC_DEC_FP__ 200704L +EOF +fi +fi + + AC_CANONICAL_HOST # The way shlib-versions is used to generate soversions.mk uses a diff --git a/libc/dfp/Makefile b/libc/dfp/Makefile index 8d987cf5c..3a33d9dc8 100644 --- a/libc/dfp/Makefile +++ b/libc/dfp/Makefile @@ -4,8 +4,8 @@ headers := bits/dfpfenv.h bits/dfpcalls.h # Build the -ldfp and -libdecnumber libraries. -#extra-libs := libdfp -extra-libs := libdfp libdecnumber +extra-libs := libdfp +#extra-libs := libdfp libdecnumber extra-libs-others := $(extra-libs) # install-lib-ldscripts := libdfp.so @@ -15,16 +15,17 @@ vpath %.h libdecnumber:libdecnumber/dpd # Some symbols need to be in libdfp.so as well as libc. -libdfp-shared = fmt_d32 fmt_d64 fmt_d128 dfptypeconv decode-decimal +libdfp-shared = fmt_d32 fmt_d64 fmt_d128 dfptypeconv decode-decimal \ + decNumber decimal32 decimal64 decimal128 decContext # The libdecnumber printing functions need to be in libc.so as well as # libdecnumber. -libdecnumber-shared = decNumber decimal32 decimal64 decimal128 decContext +#libdecnumber-shared = decNumber decimal32 decimal64 decimal128 decContext include ../Makeconfig # libDecNumber contains some functionality which isn't needed in libc. -libdecnumber-routines := $(libdecnumber-shared) decNumberMath +#libdecnumber-routines := $(libdecnumber-shared) decNumberMath # These get added to libdfp. Anything in $(libdfp-shared) gets # added to libc.so as well because they're the printf helpers. @@ -98,11 +99,12 @@ libdfp-routines := $(libdfp-shared) \ fmodd32 fmodd64 fmodd128 \ hypotd32 hypotd64 hypotd128 \ fmad32 fmad64 fmad128 \ - mapround fe_decround + mapround fe_decround \ + decNumberMath # Some of these functions are picked up out of the dfp/sysdeps/dfp directory # due to the sysdeps/unix/sysv/linux/Implies sydeps/dfp/Subdirs chain. -routines = $(libdecnumber-shared:%=libc_%) $(libdfp-shared:%=libc_%) \ +routines = $(libdfp-shared:%=libc_%) \ decroundtls strtod32 strtod64 strtod128 \ wcstod32 wcstod64 wcstod128 printf_dfp printf_dfphex @@ -198,10 +200,10 @@ include $(o-iterator) # Required to get libdfp linked against the test cases. ifeq ($(build-shared),yes) -$(addprefix $(objpfx),$(tests)): $(objpfx)libdfp.so$(libdfp.so-version) $(objpfx)libdecnumber.so$(libdecnumber.so-version) +$(addprefix $(objpfx),$(tests)): $(objpfx)libdfp.so$(libdfp.so-version) endif # libc is required for libdfp in order to query the rounding mode when # invoking dfp functions because we need the TLS functions. # We current link libm.so because we need _LIB_VERSION. -$(objpfx)libdfp.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a $(common-objpfx)dfp/libdecnumber.so $(common-objpfx)math/libm.so +$(objpfx)libdfp.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a $(common-objpfx)math/libm.so diff --git a/libc/dfp/Versions b/libc/dfp/Versions index 2e702b529..112937259 100644 --- a/libc/dfp/Versions +++ b/libc/dfp/Versions @@ -1,5 +1,5 @@ libdfp { - GLIBC_2.5 { + GLIBC_2.6 { # functions potentially used in other libraries fe_dec_getround; fe_dec_setround; @@ -220,66 +220,11 @@ libdfp { __isnand32; __isnand64; __isnand128; - }; -} -libc { - GLIBC_2.5 { - __decrm_location; - strtod32; - strtod64; - strtod128; - wcstod32; - wcstod64; - wcstod128; - }; -} -libdecnumber { - GLIBC_2.5 { -# ___decNumberFromString; -# ___decNumberToString; -# ___decNumberToEngString; -# ___decNumberAbs; -# ___decNumberAdd; -# ___decNumberCompare; -# ___decNumberCompareTotal; -# ___decNumberDivide; -# ___decNumberDivideInteger; -# ___decNumberExp; -# ___decNumberFromInt32; -# ___decNumberFromUInt32; -# ___decNumberLn; -# ___decNumberLog10; -# ___decNumberMax; -# ___decNumberMin; -# ___decNumberMinus; -# ___decNumberMultiply; -# ___decNumberNormalize; -# ___decNumberPlus; -# ___decNumberPower; -# ___decNumberQuantize; -# ___decNumberRemainder; -# ___decNumberRemainderNear; -# ___decNumberRescale; -# ___decNumberSameQuantum; -# ___decNumberScaleB; -# ___decNumberSquareRoot; -# ___decNumberSubtract; -# ___decNumberToIntegralValue; -# ___decNumberCopy; -# ___decNumberTrim; -# ___decNumberVersion; -# ___decNumberZero; -# ___decContextDefault; -# ___decContextSetStatus; -# ___decContextStatusToString; -# ___decContextSetStatusFromString; -# ___decNumberLog10; -# ___decNumberLn; -# ___decNumberExp; -# ___decNumberSquareRoot; -# ___decNumberMin; -# ___decNumberMax; +# }; +#} +#libdecnumber { +# GLIBC_2.6 { # From decContext.c ___decContextClearStatus; @@ -390,3 +335,15 @@ libdecnumber { ___decimal32ToNumber; }; } +libc { + GLIBC_2.6 { + __decrm_location; + strtod32; + strtod64; + strtod128; + wcstod32; + wcstod64; + wcstod128; + }; +} + diff --git a/libc/dfp/Versions.def b/libc/dfp/Versions.def index 2613299e7..0b62d7e96 100644 --- a/libc/dfp/Versions.def +++ b/libc/dfp/Versions.def @@ -1,6 +1,6 @@ libdfp { - GLIBC_2.5 -} -libdecnumber { - GLIBC_2.5 + GLIBC_2.6 } +#libdecnumber { +# GLIBC_2.6 +#} diff --git a/libc/dfp/sysdeps/dfp/Versions b/libc/dfp/sysdeps/dfp/Versions index 1c6b288cc..0f979b01d 100644 --- a/libc/dfp/sysdeps/dfp/Versions +++ b/libc/dfp/sysdeps/dfp/Versions @@ -1,5 +1,5 @@ libc { - GLIBC_2.5 { + GLIBC_2.6 { # functions used in other libraries __printf_dfp; }; diff --git a/libc/dfp/sysdeps/dfp/math/bits/mathcalls.h b/libc/dfp/sysdeps/dfp/math/bits/mathcalls.h deleted file mode 100644 index b787695de..000000000 --- a/libc/dfp/sysdeps/dfp/math/bits/mathcalls.h +++ /dev/null @@ -1,367 +0,0 @@ -/* Prototype declarations for math functions; helper file for <math.h>. - Copyright (C) 1996-2002, 2003, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* NOTE: Because of the special way this file is used by <math.h>, this - file must NOT be protected from multiple inclusion as header files - usually are. - - This file provides prototype declarations for the math functions. - Most functions are declared using the macro: - - __MATHCALL (NAME,[_r], (ARGS...)); - - This means there is a function `NAME' returning `double' and a function - `NAMEf' returning `float'. Each place `_Mdouble_' appears in the - prototype, that is actually `double' in the prototype for `NAME' and - `float' in the prototype for `NAMEf'. Reentrant variant functions are - called `NAME_r' and `NAMEf_r'. - - Functions returning other types like `int' are declared using the macro: - - __MATHDECL (TYPE, NAME,[_r], (ARGS...)); - - This is just like __MATHCALL but for a function returning `TYPE' - instead of `_Mdouble_'. In all of these cases, there is still - both a `NAME' and a `NAMEf' that takes `float' arguments. - - Note that there must be no whitespace before the argument passed for - NAME, to make token pasting work with -traditional. */ - -#ifndef _MATH_H -# error "Never include <bits/mathcalls.h> directly; include <math.h> instead." -#endif - - -/* Trigonometric functions. */ - -_Mdouble_BEGIN_NAMESPACE -/* Arc cosine of X. */ -__MATHCALL (acos,, (_Mdouble_ __x)); -/* Arc sine of X. */ -__MATHCALL (asin,, (_Mdouble_ __x)); -/* Arc tangent of X. */ -__MATHCALL (atan,, (_Mdouble_ __x)); -/* Arc tangent of Y/X. */ -__MATHCALL (atan2,, (_Mdouble_ __y, _Mdouble_ __x)); - -/* Cosine of X. */ -__MATHCALL (cos,, (_Mdouble_ __x)); -/* Sine of X. */ -__MATHCALL (sin,, (_Mdouble_ __x)); -/* Tangent of X. */ -__MATHCALL (tan,, (_Mdouble_ __x)); - -/* Hyperbolic functions. */ - -/* Hyperbolic cosine of X. */ -__MATHCALL (cosh,, (_Mdouble_ __x)); -/* Hyperbolic sine of X. */ -__MATHCALL (sinh,, (_Mdouble_ __x)); -/* Hyperbolic tangent of X. */ -__MATHCALL (tanh,, (_Mdouble_ __x)); -_Mdouble_END_NAMESPACE - -#ifdef __USE_GNU -/* Cosine and sine of X. */ -__MATHDECL (void,sincos,, - (_Mdouble_ __x, _Mdouble_ *__sinx, _Mdouble_ *__cosx)); -#endif - -#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Hyperbolic arc cosine of X. */ -__MATHCALL (acosh,, (_Mdouble_ __x)); -/* Hyperbolic arc sine of X. */ -__MATHCALL (asinh,, (_Mdouble_ __x)); -/* Hyperbolic arc tangent of X. */ -__MATHCALL (atanh,, (_Mdouble_ __x)); -__END_NAMESPACE_C99 -#endif - -/* Exponential and logarithmic functions. */ - -_Mdouble_BEGIN_NAMESPACE -/* Exponential function of X. */ -__MATHCALL (exp,, (_Mdouble_ __x)); - -/* Break VALUE into a normalized fraction and an integral power of 2. */ -__MATHCALL (frexp,, (_Mdouble_ __x, int *__exponent)); - -/* X times (two to the EXP power). */ -__MATHCALL (ldexp,, (_Mdouble_ __x, int __exponent)); - -/* Natural logarithm of X. */ -__MATHCALL (log,, (_Mdouble_ __x)); - -/* Base-ten logarithm of X. */ -__MATHCALL (log10,, (_Mdouble_ __x)); - -/* Break VALUE into integral and fractional parts. */ -__MATHCALL (modf,, (_Mdouble_ __x, _Mdouble_ *__iptr)); -_Mdouble_END_NAMESPACE - -#ifdef __USE_GNU -/* A function missing in all standards: compute exponent to base ten. */ -__MATHCALL (exp10,, (_Mdouble_ __x)); -/* Another name occasionally used. */ -__MATHCALL (pow10,, (_Mdouble_ __x)); -#endif - -#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Return exp(X) - 1. */ -__MATHCALL (expm1,, (_Mdouble_ __x)); - -/* Return log(1 + X). */ -__MATHCALL (log1p,, (_Mdouble_ __x)); - -/* Return the base 2 signed integral exponent of X. */ -__MATHCALL (logb,, (_Mdouble_ __x)); -__END_NAMESPACE_C99 -#endif - -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Compute base-2 exponential of X. */ -__MATHCALL (exp2,, (_Mdouble_ __x)); - -/* Compute base-2 logarithm of X. */ -__MATHCALL (log2,, (_Mdouble_ __x)); -__END_NAMESPACE_C99 -#endif - - -/* Power functions. */ - -_Mdouble_BEGIN_NAMESPACE -/* Return X to the Y power. */ -__MATHCALL (pow,, (_Mdouble_ __x, _Mdouble_ __y)); - -/* Return the square root of X. */ -__MATHCALL (sqrt,, (_Mdouble_ __x)); -_Mdouble_END_NAMESPACE - -#if defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Return `sqrt(X*X + Y*Y)'. */ -__MATHCALL (hypot,, (_Mdouble_ __x, _Mdouble_ __y)); -__END_NAMESPACE_C99 -#endif - -#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Return the cube root of X. */ -__MATHCALL (cbrt,, (_Mdouble_ __x)); -__END_NAMESPACE_C99 -#endif - - -/* Nearest integer, absolute value, and remainder functions. */ - -_Mdouble_BEGIN_NAMESPACE -/* Smallest integral value not less than X. */ -__MATHCALLX (ceil,, (_Mdouble_ __x), (__const__)); - -/* Absolute value of X. */ -__MATHCALLX (fabs,, (_Mdouble_ __x), (__const__)); - -/* Largest integer not greater than X. */ -__MATHCALLX (floor,, (_Mdouble_ __x), (__const__)); - -/* Floating-point modulo remainder of X/Y. */ -__MATHCALL (fmod,, (_Mdouble_ __x, _Mdouble_ __y)); - - -/* Return 0 if VALUE is finite or NaN, +1 if it - is +Infinity, -1 if it is -Infinity. */ -__MATHDECL_1 (int,__isinf,, (_Mdouble_ __value)) __attribute__ ((__const__)); - -/* Return nonzero if VALUE is finite and not NaN. */ -__MATHDECL_1 (int,__finite,, (_Mdouble_ __value)) __attribute__ ((__const__)); -_Mdouble_END_NAMESPACE - -#ifdef __USE_MISC -/* Return 0 if VALUE is finite or NaN, +1 if it - is +Infinity, -1 if it is -Infinity. */ -__MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__ ((__const__)); - -/* Return nonzero if VALUE is finite and not NaN. */ -__MATHDECL_1 (int,finite,, (_Mdouble_ __value)) __attribute__ ((__const__)); - -/* Return the remainder of X/Y. */ -__MATHCALL (drem,, (_Mdouble_ __x, _Mdouble_ __y)); - - -/* Return the fractional part of X after dividing out `ilogb (X)'. */ -__MATHCALL (significand,, (_Mdouble_ __x)); -#endif /* Use misc. */ - -#if defined __USE_MISC || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Return X with its signed changed to Y's. */ -__MATHCALLX (copysign,, (_Mdouble_ __x, _Mdouble_ __y), (__const__)); -__END_NAMESPACE_C99 -#endif - -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Return representation of NaN for double type. */ -__MATHCALLX (nan,, (__const char *__tagb), (__const__)); -__END_NAMESPACE_C99 -#endif - - -/* Return nonzero if VALUE is not a number. */ -__MATHDECL_1 (int,__isnan,, (_Mdouble_ __value)) __attribute__ ((__const__)); - -#if defined __USE_MISC || defined __USE_XOPEN -/* Return nonzero if VALUE is not a number. */ -__MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__)); - -/* Bessel functions. */ -__MATHCALL (j0,, (_Mdouble_)); -__MATHCALL (j1,, (_Mdouble_)); -__MATHCALL (jn,, (int, _Mdouble_)); -__MATHCALL (y0,, (_Mdouble_)); -__MATHCALL (y1,, (_Mdouble_)); -__MATHCALL (yn,, (int, _Mdouble_)); -#endif - - -#if defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Error and gamma functions. */ -__MATHCALL (erf,, (_Mdouble_)); -__MATHCALL (erfc,, (_Mdouble_)); -__MATHCALL (lgamma,, (_Mdouble_)); -__END_NAMESPACE_C99 -#endif - -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* True gamma function. */ -__MATHCALL (tgamma,, (_Mdouble_)); -__END_NAMESPACE_C99 -#endif - -#if defined __USE_MISC || defined __USE_XOPEN -/* Obsolete alias for `lgamma'. */ -__MATHCALL (gamma,, (_Mdouble_)); -#endif - -#ifdef __USE_MISC -/* Reentrant version of lgamma. This function uses the global variable - `signgam'. The reentrant version instead takes a pointer and stores - the value through it. */ -__MATHCALL (lgamma,_r, (_Mdouble_, int *__signgamp)); -#endif - - -#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Return the integer nearest X in the direction of the - prevailing rounding mode. */ -__MATHCALL (rint,, (_Mdouble_ __x)); - -/* Return X + epsilon if X < Y, X - epsilon if X > Y. */ -__MATHCALLX (nextafter,, (_Mdouble_ __x, _Mdouble_ __y), (__const__)); -# if defined __STDC_WANT_DEC_FP__ && __USE_DEC_FP_NEXTTOWARD__ -__MATHCALLX (nexttoward,, (_Mdouble_ __x, _Decimal128 __y), (__const__)); -# elif defined __USE_ISOC99 && !defined __LDBL_COMPAT -__MATHCALLX (nexttoward,, (_Mdouble_ __x, long double __y), (__const__)); -# endif - -/* Return the remainder of integer divison X / Y with infinite precision. */ -__MATHCALL (remainder,, (_Mdouble_ __x, _Mdouble_ __y)); - -# if defined __USE_MISC || defined __USE_ISOC99 -/* Return X times (2 to the Nth power). */ -__MATHCALL (scalbn,, (_Mdouble_ __x, int __n)); -# endif - -/* Return the binary exponent of X, which must be nonzero. */ -__MATHDECL (int,ilogb,, (_Mdouble_ __x)); -#endif - -#ifdef __USE_ISOC99 -/* Return X times (2 to the Nth power). */ -__MATHCALL (scalbln,, (_Mdouble_ __x, long int __n)); - -/* Round X to integral value in floating-point format using current - rounding direction, but do not raise inexact exception. */ -__MATHCALL (nearbyint,, (_Mdouble_ __x)); - -/* Round X to nearest integral value, rounding halfway cases away from - zero. */ -__MATHCALLX (round,, (_Mdouble_ __x), (__const__)); - -/* Round X to the integral value in floating-point format nearest but - not larger in magnitude. */ -__MATHCALLX (trunc,, (_Mdouble_ __x), (__const__)); - -/* Compute remainder of X and Y and put in *QUO a value with sign of x/y - and magnitude congruent `mod 2^n' to the magnitude of the integral - quotient x/y, with n >= 3. */ -__MATHCALL (remquo,, (_Mdouble_ __x, _Mdouble_ __y, int *__quo)); - - -/* Conversion functions. */ - -/* Round X to nearest integral value according to current rounding - direction. */ -__MATHDECL (long int,lrint,, (_Mdouble_ __x)); -__MATHDECL (long long int,llrint,, (_Mdouble_ __x)); - -/* Round X to nearest integral value, rounding halfway cases away from - zero. */ -__MATHDECL (long int,lround,, (_Mdouble_ __x)); -__MATHDECL (long long int,llround,, (_Mdouble_ __x)); - - -/* Return positive difference between X and Y. */ -__MATHCALL (fdim,, (_Mdouble_ __x, _Mdouble_ __y)); - -/* Return maximum numeric value from X and Y. */ -__MATHCALL (fmax,, (_Mdouble_ __x, _Mdouble_ __y)); - -/* Return minimum numeric value from X and Y. */ -__MATHCALL (fmin,, (_Mdouble_ __x, _Mdouble_ __y)); - - -/* Classify given number. */ -__MATHDECL_1 (int, __fpclassify,, (_Mdouble_ __value)) - __attribute__ ((__const__)); - -/* Test for negative number. */ -__MATHDECL_1 (int, __signbit,, (_Mdouble_ __value)) - __attribute__ ((__const__)); - - -/* Multiply-add function computed as a ternary operation. */ -__MATHCALL (fma,, (_Mdouble_ __x, _Mdouble_ __y, _Mdouble_ __z)); -#endif /* Use ISO C99. */ - -#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 -__END_NAMESPACE_C99 -#endif - -#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED -/* Return X times (2 to the Nth power). */ -__MATHCALL (scalb,, (_Mdouble_ __x, _Mdouble_ __n)); -#endif diff --git a/libc/dfp/sysdeps/dfp/math/fenv.h b/libc/dfp/sysdeps/dfp/math/fenv.h deleted file mode 100644 index 5e48ea4a5..000000000 --- a/libc/dfp/sysdeps/dfp/math/fenv.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * ISO C99 7.6: Floating-point environment <fenv.h> - */ - -#ifndef _FENV_H -#define _FENV_H 1 - -#include <features.h> - -/* Get the architecture dependend definitions. The following definitions - are expected to be done: - - fenv_t type for object representing an entire floating-point - environment - - FE_DFL_ENV macro of type pointer to fenv_t to be used as the argument - to functions taking an argument of type fenv_t; in this - case the default environment will be used - - fexcept_t type for object representing the floating-point exception - flags including status associated with the flags - - The following macros are defined iff the implementation supports this - kind of exception. - FE_INEXACT inexact result - FE_DIVBYZERO division by zero - FE_UNDERFLOW result not representable due to underflow - FE_OVERFLOW result not representable due to overflow - FE_INVALID invalid operation - - FE_ALL_EXCEPT bitwise OR of all supported exceptions - - The next macros are defined iff the appropriate rounding mode is - supported by the implementation. - FE_TONEAREST round to nearest - FE_UPWARD round toward +Inf - FE_DOWNWARD round toward -Inf - FE_TOWARDZERO round toward 0 -*/ -#include <bits/fenv.h> - -#ifdef __STDC_WANT_DEC_FP__ -# include <bits/dfpfenv.h> -#endif - -__BEGIN_DECLS - -/* Floating-point exception handling. */ - -/* Clear the supported exceptions represented by EXCEPTS. */ -extern int feclearexcept (int __excepts) __THROW; - -/* Store implementation-defined representation of the exception flags - indicated by EXCEPTS in the object pointed to by FLAGP. */ -extern int fegetexceptflag (fexcept_t *__flagp, int __excepts) __THROW; - -/* Raise the supported exceptions represented by EXCEPTS. */ -extern int feraiseexcept (int __excepts) __THROW; - -/* Set complete status for exceptions indicated by EXCEPTS according to - the representation in the object pointed to by FLAGP. */ -extern int fesetexceptflag (__const fexcept_t *__flagp, int __excepts) __THROW; - -/* Determine which of subset of the exceptions specified by EXCEPTS are - currently set. */ -extern int fetestexcept (int __excepts) __THROW; - - -/* Rounding control. */ - -/* Get current rounding direction. */ -extern int fegetround (void) __THROW; - -/* Establish the rounding direction represented by ROUND. */ -extern int fesetround (int __rounding_direction) __THROW; - - -/* Floating-point environment. */ - -/* Store the current floating-point environment in the object pointed - to by ENVP. */ -extern int fegetenv (fenv_t *__envp) __THROW; - -/* Save the current environment in the object pointed to by ENVP, clear - exception flags and install a non-stop mode (if available) for all - exceptions. */ -extern int feholdexcept (fenv_t *__envp) __THROW; - -/* Establish the floating-point environment represented by the object - pointed to by ENVP. */ -extern int fesetenv (__const fenv_t *__envp) __THROW; - -/* Save current exceptions in temporary storage, install environment - represented by object pointed to by ENVP and raise exceptions - according to saved exceptions. */ -extern int feupdateenv (__const fenv_t *__envp) __THROW; - - -/* Include optimization. */ -#ifdef __OPTIMIZE__ -# include <bits/fenvinline.h> -#endif - -#ifdef __USE_GNU - -/* Enable individual exceptions. Will not enable more exceptions than - EXCEPTS specifies. Returns the previous enabled exceptions if all - exceptions are successfully set, otherwise returns -1. */ -extern int feenableexcept (int __excepts) __THROW; - -/* Disable individual exceptions. Will not disable more exceptions than - EXCEPTS specifies. Returns the previous enabled exceptions if all - exceptions are successfully disabled, otherwise returns -1. */ -extern int fedisableexcept (int __excepts) __THROW; - -/* Return enabled exceptions. */ -extern int fegetexcept (void) __THROW; -#endif - -__END_DECLS - -#endif /* fenv.h */ diff --git a/libc/dfp/sysdeps/dfp/math/math.h b/libc/dfp/sysdeps/dfp/math/math.h deleted file mode 100644 index d6d3651b3..000000000 --- a/libc/dfp/sysdeps/dfp/math/math.h +++ /dev/null @@ -1,645 +0,0 @@ -/* Declarations for math functions. - Copyright (C) 1991-1993, 1995-1999, 2001, 2002, 2004, 2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * ISO C99 Standard: 7.12 Mathematics <math.h> - */ - -#ifndef _MATH_H -#define _MATH_H 1 - -#include <features.h> - -__BEGIN_DECLS - -/* Get machine-dependent HUGE_VAL value (returned on overflow). - On all IEEE754 machines, this is +Infinity. */ -#include <bits/huge_val.h> -#ifdef __USE_ISOC99 -# include <bits/huge_valf.h> -# include <bits/huge_vall.h> - -/* Get machine-dependent INFINITY value. */ -# include <bits/inf.h> - -/* Get machine-dependent NAN value (returned for some domain errors). */ -# include <bits/nan.h> -#endif /* __USE_ISOC99 */ - -/* Get general and ISO C99 specific information. */ -#include <bits/mathdef.h> - -/* The file <bits/mathcalls.h> contains the prototypes for all the - actual math functions. These macros are used for those prototypes, - so we can easily declare each function as both `name' and `__name', - and can declare the float versions `namef' and `__namef'. */ - -#define __MATHCALL(function,suffix, args) \ - __MATHDECL (_Mdouble_,function,suffix, args) -#define __MATHDECL(type, function,suffix, args) \ - __MATHDECL_1(type, function,suffix, args); \ - __MATHDECL_1(type, __CONCAT(__,function),suffix, args) -#define __MATHCALLX(function,suffix, args, attrib) \ - __MATHDECLX (_Mdouble_,function,suffix, args, attrib) -#define __MATHDECLX(type, function,suffix, args, attrib) \ - __MATHDECL_1(type, function,suffix, args) __attribute__ (attrib); \ - __MATHDECL_1(type, __CONCAT(__,function),suffix, args) __attribute__ (attrib) -#define __MATHDECL_1(type, function,suffix, args) \ - extern type __MATH_PRECNAME(function,suffix) args __THROW - -#ifdef __USE_DEC_FP_NEXTTOWARD__ -#undef __USE_DEC_FP_NEXTTOWARD__ -#endif - -#define _Mdouble_ double -#define __MATH_PRECNAME(name,r) __CONCAT(name,r) -# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_STD -# define _Mdouble_END_NAMESPACE __END_NAMESPACE_STD -#include <bits/mathcalls.h> -#undef _Mdouble_ -#undef _Mdouble_BEGIN_NAMESPACE -#undef _Mdouble_END_NAMESPACE -#undef __MATH_PRECNAME - -/* Decimal-Floating point support is outlined in ISO proposed C-specification - WG14 N1176 and IEEE 754r. */ -#ifdef __STDC_WANT_DEC_FP__ -#define DEC_INFINITY __builtin_infd32() -#define DEC_NAN (0.0DF * DEC_INFINITY) -# define HUGE_VAL_D64 __builtin_infd64() -/*# define DEC_INFINITY (9999999.E96DF + 1.E96df) -#define DEC_NAN (0.0DF * DEC_INFINITY) -# define HUGE_VAL_D64 (9.999999999999999E384DD + 1.E384dd) */ -# define HUGE_VAL_D32 HUGE_VAL_D64 -# define HUGE_VAL_D128 HUGE_VAL_D64 - -/* this causes the nexttoward mathcall to get a _Decimal128 second parameter - * rather than a long double one. */ -#define __USE_DEC_FP_NEXTTOWARD__ 1 - -#define __dfp_compatible(X) ((_Decimal128)(__typeof__(X))1.E-50DL == 1.E-50DL) - -/* For _Decimal32 */ -# ifndef _M_Decimal32_ -# define _M_Decimal32_ _Decimal32 -# endif -# define _Mdouble_ _M_Decimal32_ -# ifdef __STDC__ -# define __MATH_PRECNAME(name,r) name##d32##r -# else -# define __MATH_PRECNAME(name,r) name/**/d32/**/r -# endif -# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 -# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 -# include <bits/mathcalls.h> -# include <bits/dfpcalls.h> -# undef _Mdouble_ -# undef _Mdouble_BEGIN_NAMESPACE -# undef _Mdouble_END_NAMESPACE -# undef __MATH_PRECNAME - -/* For _Decimal64 */ -# ifndef _M_Decimal64_ -# define _M_Decimal64_ _Decimal64 -# endif -# define _Mdouble_ _M_Decimal64_ -# ifdef __STDC__ -# define __MATH_PRECNAME(name,r) name##d64##r -# else -# define __MATH_PRECNAME(name,r) name/**/d64/**/r -# endif -# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 -# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 -# include <bits/mathcalls.h> -# include <bits/dfpcalls.h> -# undef _Mdouble_ -# undef _Mdouble_BEGIN_NAMESPACE -# undef _Mdouble_END_NAMESPACE -# undef __MATH_PRECNAME - -/* For _Decimal128 */ -# ifndef _M_Decimal128_ -# define _M_Decimal128_ _Decimal128 -# endif -# define _Mdouble_ _M_Decimal128_ -# ifdef __STDC__ -# define __MATH_PRECNAME(name,r) name##d128##r -# else -# define __MATH_PRECNAME(name,r) name/**/d128/**/r -# endif -# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 -# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 -# include <bits/mathcalls.h> -# include <bits/dfpcalls.h> -# undef _Mdouble_ -# undef _Mdouble_BEGIN_NAMESPACE -# undef _Mdouble_END_NAMESPACE -# undef __MATH_PRECNAME - -#endif /* __STDC_WANT_DEC_FP__ */ - -#ifdef __USE_DEC_FP_NEXTTOWARD__ -#undef __USE_DEC_FP_NEXTTOWARD__ -#endif - -#if defined __USE_MISC || defined __USE_ISOC99 - - -/* Include the file of declarations again, this time using `float' - instead of `double' and appending f to each function name. */ - -# ifndef _Mfloat_ -# define _Mfloat_ float -# endif -# define _Mdouble_ _Mfloat_ -# ifdef __STDC__ -# define __MATH_PRECNAME(name,r) name##f##r -# else -# define __MATH_PRECNAME(name,r) name/**/f/**/r -# endif -# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 -# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 -# include <bits/mathcalls.h> -# undef _Mdouble_ -# undef _Mdouble_BEGIN_NAMESPACE -# undef _Mdouble_END_NAMESPACE -# undef __MATH_PRECNAME - -# if (__STDC__ - 0 || __GNUC__ - 0) \ - && (!defined __NO_LONG_DOUBLE_MATH || defined __LDBL_COMPAT) -# ifdef __LDBL_COMPAT - -# ifdef __USE_ISOC99 -extern float __nldbl_nexttowardf (float __x, long double __y) - __THROW __attribute__ ((__const__)); -# ifdef __REDIRECT_NTH -extern float __REDIRECT_NTH (nexttowardf, (float __x, long double __y), - __nldbl_nexttowardf) - __attribute__ ((__const__)); -extern double __REDIRECT_NTH (nexttoward, (double __x, long double __y), - nextafter) __attribute__ ((__const__)); -extern long double __REDIRECT_NTH (nexttowardl, - (long double __x, long double __y), - nextafter) __attribute__ ((__const__)); -# endif -# endif - -/* Include the file of declarations again, this time using `long double' - instead of `double' and appending l to each function name. */ - -# undef __MATHDECL_1 -# define __MATHDECL_2(type, function,suffix, args, alias) \ - extern type __REDIRECT_NTH(__MATH_PRECNAME(function,suffix), \ - args, alias) -# define __MATHDECL_1(type, function,suffix, args) \ - __MATHDECL_2(type, function,suffix, args, __CONCAT(function,suffix)) -# endif - -# ifndef _Mlong_double_ -# define _Mlong_double_ long double -# endif -# define _Mdouble_ _Mlong_double_ -# ifdef __STDC__ -# define __MATH_PRECNAME(name,r) name##l##r -# else -# define __MATH_PRECNAME(name,r) name/**/l/**/r -# endif -# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 -# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 -# include <bits/mathcalls.h> -# undef _Mdouble_ -# undef _Mdouble_BEGIN_NAMESPACE -# undef _Mdouble_END_NAMESPACE -# undef __MATH_PRECNAME - -# endif /* __STDC__ || __GNUC__ */ - -#endif /* Use misc or ISO C99. */ -#undef __MATHDECL_1 -#undef __MATHDECL -#undef __MATHCALL - - -#if defined __USE_MISC || defined __USE_XOPEN -/* This variable is used by `gamma' and `lgamma'. */ -extern int signgam; -#endif - - -/* ISO C99 defines some generic macros which work on any data type. */ -#ifdef __USE_ISOC99 - -/* Get the architecture specific values describing the floating-point - evaluation. The following symbols will get defined: - - float_t floating-point type at least as wide as `float' used - to evaluate `float' expressions - double_t floating-point type at least as wide as `double' used - to evaluate `double' expressions - - FLT_EVAL_METHOD - Defined to - 0 if `float_t' is `float' and `double_t' is `double' - 1 if `float_t' and `double_t' are `double' - 2 if `float_t' and `double_t' are `long double' - else `float_t' and `double_t' are unspecified - - INFINITY representation of the infinity value of type `float' - - FP_FAST_FMA - FP_FAST_FMAF - FP_FAST_FMAL - If defined it indicates that the `fma' function - generally executes about as fast as a multiply and an add. - This macro is defined only iff the `fma' function is - implemented directly with a hardware multiply-add instructions. - - FP_ILOGB0 Expands to a value returned by `ilogb (0.0)'. - FP_ILOGBNAN Expands to a value returned by `ilogb (NAN)'. - - DECIMAL_DIG Number of decimal digits supported by conversion between - decimal and all internal floating-point formats. - -*/ - -/* All decimal and binary floating-point numbers can be put in one of these - categories. */ -enum - { - FP_NAN, -# define FP_NAN FP_NAN - FP_INFINITE, -# define FP_INFINITE FP_INFINITE - FP_ZERO, -# define FP_ZERO FP_ZERO - FP_SUBNORMAL, -# define FP_SUBNORMAL FP_SUBNORMAL - FP_NORMAL -# define FP_NORMAL FP_NORMAL - }; - -/* Return number of classification appropriate for X. */ -# ifdef __NO_LONG_DOUBLE_MATH -# define ____fpclassify(x) \ - (sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassify (x)) -# else -# define ____fpclassify(x) \ - (sizeof (x) == sizeof (float) \ - ? __fpclassifyf (x) \ - : sizeof (x) == sizeof (double) \ - ? __fpclassify (x) : __fpclassifyl (x)) -# endif - -# ifdef __STDC_WANT_DEC_FP__ -# define fpclassify(x) \ - ( \ - (!__dfp_compatible(x)? (____fpclassify(x)) : \ - (sizeof (x) == sizeof (_Decimal128)? __fpclassifyd128(x): \ - (sizeof (x) == sizeof (_Decimal64)? __fpclassifyd64(x): \ - __fpclassifyd32(x) \ - ) \ - ) \ - ) \ - ) -# else -# define fpclassify(x) ____fpclassify(x) -# endif - -/* Return nonzero value if sign of X is negative. */ -# ifdef __NO_LONG_DOUBLE_MATH -# define ____signbit(x) \ - (sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x)) -# else -# define ____signbit(x) \ - (sizeof (x) == sizeof (float) \ - ? __signbitf (x) \ - : sizeof (x) == sizeof (double) \ - ? __signbit (x) : __signbitl (x)) -# endif - -# ifdef __STDC_WANT_DEC_FP__ -# define signbit(x) \ - ( \ - (!__dfp_compatible(x)? (____signbit(x)) : \ - (sizeof (x) == sizeof (_Decimal128)? __signbitd128(x): \ - (sizeof (x) == sizeof (_Decimal64)? __signbitd64(x): \ - __signbitd32(x) \ - ) \ - ) \ - ) \ - ) -# else -# define signbit(x) ____signbit(x) -# endif - -/* Return nonzero value if X is not +-Inf or NaN. */ -# ifdef __NO_LONG_DOUBLE_MATH -# define ____isfinite(x) \ - (sizeof (x) == sizeof (float) ? __finitef (x) : __finite (x)) -# else -# define ____isfinite(x) \ - (sizeof (x) == sizeof (float) \ - ? __finitef (x) \ - : sizeof (x) == sizeof (double) \ - ? __finite (x) : __finitel (x)) -# endif - -# ifdef __STDC_WANT_DEC_FP__ -# define isfinite(x) \ - ( \ - (!__dfp_compatible(x)? (____isfinite(x)) : \ - (sizeof (x) == sizeof (_Decimal128)? __finited128(x): \ - (sizeof (x) == sizeof (_Decimal64)? __finited64(x): \ - __finited32(x) \ - ) \ - ) \ - ) \ - ) -# else -# define isfinite(x) ____isfinite(x) -# endif - -/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ -# define isnormal(x) (fpclassify (x) == FP_NORMAL) - -/* Return nonzero value if X is a NaN. We could use `fpclassify' but - we already have this functions `__isnan' and it is faster. */ -# ifdef __NO_LONG_DOUBLE_MATH -# define ____isnan(x) \ - (sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x)) -# else -# define ____isnan(x) \ - (sizeof (x) == sizeof (float) \ - ? __isnanf (x) \ - : sizeof (x) == sizeof (double) \ - ? __isnan (x) : __isnanl (x)) -# endif - -# ifdef __STDC_WANT_DEC_FP__ -# define isnan(x) \ - (!__dfp_compatible(x) \ - ? (____isnan(x)) \ - : (sizeof (x) == sizeof (_Decimal128) \ - ? __isnand128(x) \ - : (sizeof (x) == sizeof (_Decimal64) \ - ? __isnand64(x) \ - : __isnand32(x))) \ - ) -# else -# define isnan(x) ____isnan(x) -# endif - -/* Return nonzero value is X is positive or negative infinity. */ -# ifdef __NO_LONG_DOUBLE_MATH -# define _____isinf(x) \ - (sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x)) -# else -# define ____isinf(x) \ - (sizeof (x) == sizeof (float) \ - ? __isinff (x) \ - : sizeof (x) == sizeof (double) \ - ? __isinf (x) : __isinfl (x)) -# endif - -# ifdef __STDC_WANT_DEC_FP__ -# define isinf(x) \ - ( \ - (!__dfp_compatible(x)? (____isinf(x)) : \ - (sizeof (x) == sizeof (_Decimal128)? __isinfd128(x): \ - (sizeof (x) == sizeof (_Decimal64)? __isinfd64(x): \ - __isinfd32(x) \ - ) \ - ) \ - ) \ - ) -# else -# define isinf(x) ____isinf(x) -# endif - -/* Bitmasks for the math_errhandling macro. */ -# define MATH_ERRNO 1 /* errno set by math functions. */ -# define MATH_ERREXCEPT 2 /* Exceptions raised by math functions. */ - -#endif /* Use ISO C99. */ - -#ifdef __USE_MISC -/* Support for various different standard error handling behaviors. */ -typedef enum -{ - _IEEE_ = -1, /* According to IEEE 754/IEEE 854. */ - _SVID_, /* According to System V, release 4. */ - _XOPEN_, /* Nowadays also Unix98. */ - _POSIX_, - _ISOC_ /* Actually this is ISO C99. */ -} _LIB_VERSION_TYPE; - -/* This variable can be changed at run-time to any of the values above to - affect floating point error handling behavior (it may also be necessary - to change the hardware FPU exception settings). */ -extern _LIB_VERSION_TYPE _LIB_VERSION; -#endif - - -#ifdef __USE_SVID -/* In SVID error handling, `matherr' is called with this description - of the exceptional condition. - - We have a problem when using C++ since `exception' is a reserved - name in C++. */ -# ifdef __cplusplus -struct __exception -# else -struct exception -# endif - { - int type; - char *name; - double arg1; - double arg2; - double retval; - }; - -# ifdef __cplusplus -extern int matherr (struct __exception *__exc) throw (); -# else -extern int matherr (struct exception *__exc); -# endif - -# define X_TLOSS 1.41484755040568800000e+16 - -/* Types of exceptions in the `type' field. */ -# define DOMAIN 1 -# define SING 2 -# define OVERFLOW 3 -# define UNDERFLOW 4 -# define TLOSS 5 -# define PLOSS 6 - -/* SVID mode specifies returning this large value instead of infinity. */ -# define HUGE 3.40282347e+38F - -#else /* !SVID */ - -# ifdef __USE_XOPEN -/* X/Open wants another strange constant. */ -# define MAXFLOAT 3.40282347e+38F -# endif - -#endif /* SVID */ - - -/* Some useful constants. */ -#if defined __USE_BSD || defined __USE_XOPEN -# define M_E 2.7182818284590452354 /* e */ -# define M_LOG2E 1.4426950408889634074 /* log_2 e */ -# define M_LOG10E 0.43429448190325182765 /* log_10 e */ -# define M_LN2 0.69314718055994530942 /* log_e 2 */ -# define M_LN10 2.30258509299404568402 /* log_e 10 */ -# define M_PI 3.14159265358979323846 /* pi */ -# define M_PI_2 1.57079632679489661923 /* pi/2 */ -# define M_PI_4 0.78539816339744830962 /* pi/4 */ -# define M_1_PI 0.31830988618379067154 /* 1/pi */ -# define M_2_PI 0.63661977236758134308 /* 2/pi */ -# define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ -# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -# define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ -#endif - -/* The above constants are not adequate for computation using `long double's. - Therefore we provide as an extension constants with similar names as a - GNU extension. Provide enough digits for the 128-bit IEEE quad. */ -#ifdef __USE_GNU -# define M_El 2.7182818284590452353602874713526625L /* e */ -# define M_LOG2El 1.4426950408889634073599246810018921L /* log_2 e */ -# define M_LOG10El 0.4342944819032518276511289189166051L /* log_10 e */ -# define M_LN2l 0.6931471805599453094172321214581766L /* log_e 2 */ -# define M_LN10l 2.3025850929940456840179914546843642L /* log_e 10 */ -# define M_PIl 3.1415926535897932384626433832795029L /* pi */ -# define M_PI_2l 1.5707963267948966192313216916397514L /* pi/2 */ -# define M_PI_4l 0.7853981633974483096156608458198757L /* pi/4 */ -# define M_1_PIl 0.3183098861837906715377675267450287L /* 1/pi */ -# define M_2_PIl 0.6366197723675813430755350534900574L /* 2/pi */ -# define M_2_SQRTPIl 1.1283791670955125738961589031215452L /* 2/sqrt(pi) */ -# define M_SQRT2l 1.4142135623730950488016887242096981L /* sqrt(2) */ -# define M_SQRT1_2l 0.7071067811865475244008443621048490L /* 1/sqrt(2) */ -#endif - -/* Some useful constants for DFP support (with the DL specifier). Proper - * truncation to DD and DF will be handled by libdfp. */ -#ifdef __STDC_WANT_DEC_FP__ -# define M_Edl 2.7182818284590452353602874713526625DL /* e */ -# define M_LOG2Edl 1.4426950408889634073599246810018921DL /* log_2 e */ -# define M_LOG10Edl 0.4342944819032518276511289189166051DL /* log_10 e */ -# define M_LN2dl 0.6931471805599453094172321214581766DL /* log_e 2 */ -# define M_LN10dl 2.3025850929940456840179914546843642DL /* log_e 10 */ -# define M_PIdl 3.1415926535897932384626433832795029DL /* pi */ -# define M_PI_2dl 1.5707963267948966192313216916397514DL /* pi/2 */ -# define M_PI_4dl 0.7853981633974483096156608458198757DL /* pi/4 */ -# define M_1_PIdl 0.3183098861837906715377675267450287DL /* 1/pi */ -# define M_2_PIdl 0.6366197723675813430755350534900574DL /* 2/pi */ -# define M_2_SQRTPIdl 1.1283791670955125738961589031215452DL /* 2/sqrt(pi) */ -# define M_SQRT2dl 1.4142135623730950488016887242096981DL /* sqrt(2) */ -# define M_SQRT1_2dl 0.7071067811865475244008443621048490DL /* 1/sqrt(2) */ -#endif /* __STDC_WANT_DEC_FP__ */ - -/* When compiling in strict ISO C compatible mode we must not use the - inline functions since they, among other things, do not set the - `errno' variable correctly. */ -#if defined __STRICT_ANSI__ && !defined __NO_MATH_INLINES -# define __NO_MATH_INLINES 1 -#endif - -#if defined __USE_ISOC99 && __GNUC_PREREQ(2,97) -/* ISO C99 defines some macros to compare number while taking care for - unordered numbers. Many FPUs provide special instructions to support - these operations. Generic support in GCC for these as builtins went - in before 3.0.0, but not all cpus added their patterns. We define - versions that use the builtins here, and <bits/mathinline.h> will - undef/redefine as appropriate for the specific GCC version in use. */ -# define isgreater(x, y) __builtin_isgreater(x, y) -# define isgreaterequal(x, y) __builtin_isgreaterequal(x, y) -# define isless(x, y) __builtin_isless(x, y) -# define islessequal(x, y) __builtin_islessequal(x, y) -# define islessgreater(x, y) __builtin_islessgreater(x, y) -# define isunordered(u, v) __builtin_isunordered(u, v) -#endif - -/* Get machine-dependent inline versions (if there are any). */ -#ifdef __USE_EXTERN_INLINES -# include <bits/mathinline.h> -#endif - -#ifdef __USE_ISOC99 -/* If we've still got undefined comparison macros, provide defaults. */ - -/* Return nonzero value if X is greater than Y. */ -# ifndef isgreater -# define isgreater(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered (__x, __y) && __x > __y; })) -# endif - -/* Return nonzero value if X is greater than or equal to Y. */ -# ifndef isgreaterequal -# define isgreaterequal(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered (__x, __y) && __x >= __y; })) -# endif - -/* Return nonzero value if X is less than Y. */ -# ifndef isless -# define isless(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered (__x, __y) && __x < __y; })) -# endif - -/* Return nonzero value if X is less than or equal to Y. */ -# ifndef islessequal -# define islessequal(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered (__x, __y) && __x <= __y; })) -# endif - -/* Return nonzero value if either X is less than Y or Y is less than X. */ -# ifndef islessgreater -# define islessgreater(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered (__x, __y) && (__x < __y || __y < __x); })) -# endif - -/* Return nonzero value if arguments are unordered. */ -# ifndef isunordered -# define isunordered(u, v) \ - (__extension__ \ - ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \ - fpclassify (__u) == FP_NAN || fpclassify (__v) == FP_NAN; })) -# endif - -#endif - -__END_DECLS - - -#endif /* math.h */ diff --git a/libc/dfp/sysdeps/dfp/stdio-common/printf-parse.h b/libc/dfp/sysdeps/dfp/stdio-common/printf-parse.h deleted file mode 100644 index f76ba8db9..000000000 --- a/libc/dfp/sysdeps/dfp/stdio-common/printf-parse.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Internal header for parsing printf format strings. - Copyright (C) 1995-1999, 2000, 2002, 2003, 2007 - Free Software Foundation, Inc. - This file is part of th GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <printf.h> -#include <stdint.h> -#include <stddef.h> -#include <string.h> -#include <wchar.h> - - -struct printf_spec - { - /* Information parsed from the format spec. */ - struct printf_info info; - - /* Pointers into the format string for the end of this format - spec and the next (or to the end of the string if no more). */ - const UCHAR_T *end_of_fmt, *next_fmt; - - /* Position of arguments for precision and width, or -1 if `info' has - the constant value. */ - int prec_arg, width_arg; - - int data_arg; /* Position of data argument. */ - int data_arg_type; /* Type of first argument. */ - /* Number of arguments consumed by this format specifier. */ - size_t ndata_args; - }; - - -/* The various kinds off arguments that can be passed to printf. */ -union printf_arg - { - wchar_t pa_wchar; - int pa_int; - long int pa_long_int; - long long int pa_long_long_int; - unsigned int pa_u_int; - unsigned long int pa_u_long_int; - unsigned long long int pa_u_long_long_int; - double pa_double; - long double pa_long_double; - const char *pa_string; - const wchar_t *pa_wstring; - void *pa_pointer; - _Decimal128 pa_decimal128; - _Decimal64 pa_decimal64; - _Decimal32 pa_decimal32; - }; - - -#ifndef DONT_NEED_READ_INT -/* Read a simple integer from a string and update the string pointer. - It is assumed that the first character is a digit. */ -static unsigned int -read_int (const UCHAR_T * *pstr) -{ - unsigned int retval = **pstr - L_('0'); - - while (ISDIGIT (*++(*pstr))) - { - retval *= 10; - retval += **pstr - L_('0'); - } - - return retval; -} -#endif - - -/* These are defined in reg-printf.c. */ -extern printf_arginfo_function **__printf_arginfo_table attribute_hidden; -extern printf_function **__printf_function_table attribute_hidden; - - -/* Find the next spec in FORMAT, or the end of the string. Returns - a pointer into FORMAT, to a '%' or a '\0'. */ -__extern_always_inline const unsigned char * -__find_specmb (const unsigned char *format) -{ - return (const unsigned char *) __strchrnul ((const char *) format, '%'); -} - -__extern_always_inline const unsigned int * -__find_specwc (const unsigned int *format) -{ - return (const unsigned int *) __wcschrnul ((const wchar_t *) format, L'%'); -} - - -/* FORMAT must point to a '%' at the beginning of a spec. Fills in *SPEC - with the parsed details. POSN is the number of arguments already - consumed. At most MAXTYPES - POSN types are filled in TYPES. Return - the number of args consumed by this spec; *MAX_REF_ARG is updated so it - remains the highest argument index used. */ -extern size_t __parse_one_specmb (const unsigned char *format, size_t posn, - struct printf_spec *spec, - size_t *max_ref_arg) attribute_hidden; - -extern size_t __parse_one_specwc (const unsigned int *format, size_t posn, - struct printf_spec *spec, - size_t *max_ref_arg) attribute_hidden; diff --git a/libc/dfp/sysdeps/dfp/stdio-common/printf.h b/libc/dfp/sysdeps/dfp/stdio-common/printf.h deleted file mode 100644 index e1013fb5b..000000000 --- a/libc/dfp/sysdeps/dfp/stdio-common/printf.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright (C) 1991-1993,1995-1999,2000,2001,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _PRINTF_H - -#define _PRINTF_H 1 -#include <features.h> - -__BEGIN_DECLS - -#define __need_FILE -#include <stdio.h> -#define __need_size_t -#define __need_wchar_t -#include <stddef.h> - - -struct printf_info -{ - int prec; /* Precision. */ - int width; /* Width. */ - wchar_t spec; /* Format letter. */ - unsigned int is_long_double:1;/* L flag. */ - unsigned int is_short:1; /* h flag. */ - unsigned int is_long:1; /* l flag. */ - unsigned int alt:1; /* # flag. */ - unsigned int space:1; /* Space flag. */ - unsigned int left:1; /* - flag. */ - unsigned int showsign:1; /* + flag. */ - unsigned int group:1; /* ' flag. */ - unsigned int extra:1; /* For special use. */ - unsigned int is_char:1; /* hh flag. */ - unsigned int wide:1; /* Nonzero for wide character streams. */ - unsigned int i18n:1; /* I flag. */ - unsigned int is_decimal:1; /* H/D/DD flags. */ - wchar_t pad; /* Padding character. */ -}; - - -/* Type of a printf specifier-handler function. - STREAM is the FILE on which to write output. - INFO gives information about the format specification. - ARGS is a vector of pointers to the argument data; - the number of pointers will be the number returned - by the associated arginfo function for the same INFO. - - The function should return the number of characters written, - or -1 for errors. */ - -typedef int printf_function (FILE *__stream, - __const struct printf_info *__info, - __const void *__const *__args); - -/* Type of a printf specifier-arginfo function. - INFO gives information about the format specification. - N, ARGTYPES, and return value are as for parse_printf_format. */ - -typedef int printf_arginfo_function (__const struct printf_info *__info, - size_t __n, int *__argtypes); - - -/* Register FUNC to be called to format SPEC specifiers; ARGINFO must be - specified to determine how many arguments a SPEC conversion requires and - what their types are. */ - -extern int register_printf_function (int __spec, printf_function __func, - printf_arginfo_function __arginfo); - - -/* Parse FMT, and fill in N elements of ARGTYPES with the - types needed for the conversions FMT specifies. Returns - the number of arguments required by FMT. - - The ARGINFO function registered with a user-defined format is passed a - `struct printf_info' describing the format spec being parsed. A width - or precision of INT_MIN means a `*' was used to indicate that the - width/precision will come from an arg. The function should fill in the - array it is passed with the types of the arguments it wants, and return - the number of arguments it wants. */ - -extern size_t parse_printf_format (__const char *__restrict __fmt, size_t __n, - int *__restrict __argtypes) __THROW; - - -/* Codes returned by `parse_printf_format' for basic types. - - These values cover all the standard format specifications. - Users can add new values after PA_LAST for their own types. */ - -enum -{ /* C type: */ - PA_INT, /* int */ - PA_CHAR, /* int, cast to char */ - PA_WCHAR, /* wide char */ - PA_STRING, /* const char *, a '\0'-terminated string */ - PA_WSTRING, /* const wchar_t *, wide character string */ - PA_POINTER, /* void * */ - PA_FLOAT, /* float */ - PA_DOUBLE, /* double */ - PA_DECIMAL, /* _Decimal* types */ - PA_LAST -}; - -/* Flag bits that can be set in a type returned by `parse_printf_format'. */ -#define PA_FLAG_MASK 0xff00 -#define PA_FLAG_LONG_LONG (1 << 8) -#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG -#define PA_FLAG_LONG (1 << 9) -#define PA_FLAG_SHORT (1 << 10) -#define PA_FLAG_PTR (1 << 11) - - - -/* Function which can be registered as `printf'-handlers. */ - -/* Print floating point value using using abbreviations for the orders - of magnitude used for numbers ('k' for kilo, 'm' for mega etc). If - the format specifier is a uppercase character powers of 1000 are - used. Otherwise powers of 1024. */ -extern int printf_size (FILE *__restrict __fp, - __const struct printf_info *__info, - __const void *__const *__restrict __args) __THROW; - -/* This is the appropriate argument information function for `printf_size'. */ -extern int printf_size_info (__const struct printf_info *__restrict - __info, size_t __n, int *__restrict __argtypes) - __THROW; - -#ifdef __LDBL_COMPAT -# include <bits/printf-ldbl.h> -#endif - -__END_DECLS - -#endif /* printf.h */ diff --git a/libc/dfp/sysdeps/dfp/stdio-common/vfprintf.c b/libc/dfp/sysdeps/dfp/stdio-common/vfprintf.c deleted file mode 100644 index 0ea10a05b..000000000 --- a/libc/dfp/sysdeps/dfp/stdio-common/vfprintf.c +++ /dev/null @@ -1,2305 +0,0 @@ -/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <ctype.h> -#include <limits.h> -#include <printf.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <wchar.h> -#include <bits/libc-lock.h> -#include <sys/param.h> -#include "_itoa.h" -#include <locale/localeinfo.h> -#include <stdio.h> -#include <printf_dfp.h> - -/* This code is shared between the standard stdio implementation found - in GNU C library and the libio implementation originally found in - GNU libg++. - - Beside this it is also shared between the normal and wide character - implementation as defined in ISO/IEC 9899:1990/Amendment 1:1995. */ - - -#include <libioP.h> -#define FILE _IO_FILE -#undef va_list -#define va_list _IO_va_list -#undef BUFSIZ -#define BUFSIZ _IO_BUFSIZ -#define ARGCHECK(S, Format) \ - do \ - { \ - /* Check file argument for consistence. */ \ - CHECK_FILE (S, -1); \ - if (S->_flags & _IO_NO_WRITES) \ - { \ - __set_errno (EBADF); \ - return -1; \ - } \ - if (Format == NULL) \ - { \ - MAYBE_SET_EINVAL; \ - return -1; \ - } \ - } while (0) -#define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED) - -#ifndef COMPILE_WPRINTF -# define vfprintf _IO_vfprintf_internal -# define CHAR_T char -# define UCHAR_T unsigned char -# define INT_T int -# define L_(Str) Str -# define ISDIGIT(Ch) ((unsigned int) ((Ch) - '0') < 10) -# define STR_LEN(Str) strlen (Str) - -# define PUT(F, S, N) _IO_sputn ((F), (S), (N)) -# define PAD(Padchar) \ - if (width > 0) \ - done += INTUSE(_IO_padn) (s, (Padchar), width) -# define PUTC(C, F) _IO_putc_unlocked (C, F) -# define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\ - return -1 -#else -# define vfprintf _IO_vfwprintf -# define CHAR_T wchar_t -/* This is a hack!!! There should be a type uwchar_t. */ -# define UCHAR_T unsigned int /* uwchar_t */ -# define INT_T wint_t -# define L_(Str) L##Str -# define ISDIGIT(Ch) ((unsigned int) ((Ch) - L'0') < 10) -# define STR_LEN(Str) __wcslen (Str) - -# include "_itowa.h" - -# define PUT(F, S, N) _IO_sputn ((F), (S), (N)) -# define PAD(Padchar) \ - if (width > 0) \ - done += _IO_wpadn (s, (Padchar), width) -# define PUTC(C, F) _IO_putwc_unlocked (C, F) -# define ORIENT if (_IO_fwide (s, 1) != 1) return -1 - -# undef _itoa -# define _itoa(Val, Buf, Base, Case) _itowa (Val, Buf, Base, Case) -# define _itoa_word(Val, Buf, Base, Case) _itowa_word (Val, Buf, Base, Case) -# undef EOF -# define EOF WEOF -#endif - -#include "_i18n_number.h" - -/* Include the shared code for parsing the format string. */ -/*#include "printf-parse.h" */ -#include <printf-parse.h> - - -#define outchar(Ch) \ - do \ - { \ - register const INT_T outc = (Ch); \ - if (PUTC (outc, s) == EOF) \ - { \ - done = -1; \ - goto all_done; \ - } \ - else \ - ++done; \ - } \ - while (0) - -#define outstring(String, Len) \ - do \ - { \ - if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len)) \ - { \ - done = -1; \ - goto all_done; \ - } \ - done += (Len); \ - } \ - while (0) - -/* For handling long_double and longlong we use the same flag. If - `long' and `long long' are effectively the same type define it to - zero. */ -#if LONG_MAX == LONG_LONG_MAX -# define is_longlong 0 -#else -# define is_longlong is_long_double -#endif - -/* If `long' and `int' is effectively the same type we don't have to - handle `long separately. */ -#if INT_MAX == LONG_MAX -# define is_long_num 0 -#else -# define is_long_num is_long -#endif - - -/* Global variables. */ -static const CHAR_T null[] = L_("(null)"); - - -/* Helper function to provide temporary buffering for unbuffered streams. */ -static int buffered_vfprintf (FILE *stream, const CHAR_T *fmt, va_list) - __THROW __attribute__ ((noinline)) internal_function; - -/* Handle unknown format specifier. */ -static int printf_unknown (FILE *, const struct printf_info *, - const void *const *) __THROW; - -/* Group digits of number string. */ -#ifdef COMPILE_WPRINTF -static CHAR_T *group_number (CHAR_T *, CHAR_T *, const char *, wchar_t) - __THROW internal_function; -#else -static CHAR_T *group_number (CHAR_T *, CHAR_T *, const char *, const char *) - __THROW internal_function; -#endif - - -/* The function itself. */ -int -vfprintf (FILE *s, const CHAR_T *format, va_list ap) -{ - /* The character used as thousands separator. */ -#ifdef COMPILE_WPRINTF - wchar_t thousands_sep = L'\0'; -#else - const char *thousands_sep = NULL; -#endif - - /* The string describing the size of groups of digits. */ - const char *grouping; - - /* Place to accumulate the result. */ - int done; - - /* Current character in format string. */ - const UCHAR_T *f; - - /* End of leading constant string. */ - const UCHAR_T *lead_str_end; - - /* Points to next format specifier. */ - const UCHAR_T *end_of_spec; - - /* Buffer intermediate results. */ - CHAR_T work_buffer[1000]; - CHAR_T *workstart = NULL; - CHAR_T *workend; - - /* We have to save the original argument pointer. */ - va_list ap_save; - - /* Count number of specifiers we already processed. */ - int nspecs_done; - - /* For the %m format we may need the current `errno' value. */ - int save_errno = errno; - - /* 1 if format is in read-only memory, -1 if it is in writable memory, - 0 if unknown. */ - int readonly_format = 0; - - /* This table maps a character into a number representing a - class. In each step there is a destination label for each - class. */ - static const int jump_table[] = - { - /* ' ' */ 1, 0, 0, /* '#' */ 4, - 0, /* '%' */ 14, 0, /* '\''*/ 6, - 0, 0, /* '*' */ 7, /* '+' */ 2, - 0, /* '-' */ 3, /* '.' */ 9, 0, - /* '0' */ 5, /* '1' */ 8, /* '2' */ 8, /* '3' */ 8, - /* '4' */ 8, /* '5' */ 8, /* '6' */ 8, /* '7' */ 8, - /* '8' */ 8, /* '9' */ 8, 0, 0, - 0, 0, 0, 0, - 0, /* 'A' */ 26, 0, /* 'C' */ 25, - /* 'D' */ 31, /* 'E' */ 19, /* F */ 19, /* 'G' */ 19, - /* 'H' */ 30, /* 'I' */ 29, 0, 0, - /* 'L' */ 12, 0, 0, 0, - 0, 0, 0, /* 'S' */ 21, - 0, 0, 0, 0, - /* 'X' */ 18, 0, /* 'Z' */ 13, 0, - 0, 0, 0, 0, - 0, /* 'a' */ 26, 0, /* 'c' */ 20, - /* 'd' */ 15, /* 'e' */ 19, /* 'f' */ 19, /* 'g' */ 19, - /* 'h' */ 10, /* 'i' */ 15, /* 'j' */ 28, 0, - /* 'l' */ 11, /* 'm' */ 24, /* 'n' */ 23, /* 'o' */ 17, - /* 'p' */ 22, /* 'q' */ 12, 0, /* 's' */ 21, - /* 't' */ 27, /* 'u' */ 16, 0, 0, - /* 'x' */ 18, 0, /* 'z' */ 13 - }; - -#define NOT_IN_JUMP_RANGE(Ch) ((Ch) < L_(' ') || (Ch) > L_('z')) -#define CHAR_CLASS(Ch) (jump_table[(INT_T) (Ch) - L_(' ')]) -#ifdef SHARED - /* 'int' is enough and it saves some space on 64 bit systems. */ -# define JUMP_TABLE_TYPE const int -# define JUMP(ChExpr, table) \ - do \ - { \ - int offset; \ - void *__unbounded ptr; \ - spec = (ChExpr); \ - offset = NOT_IN_JUMP_RANGE (spec) ? REF (form_unknown) \ - : table[CHAR_CLASS (spec)]; \ - ptr = &&do_form_unknown + offset; \ - goto *ptr; \ - } \ - while (0) -#else -# define JUMP_TABLE_TYPE const void *const -# define JUMP(ChExpr, table) \ - do \ - { \ - const void *__unbounded ptr; \ - spec = (ChExpr); \ - ptr = NOT_IN_JUMP_RANGE (spec) ? REF (form_unknown) \ - : table[CHAR_CLASS (spec)]; \ - goto *ptr; \ - } \ - while (0) -#endif - -#define STEP0_3_TABLE \ - /* Step 0: at the beginning. */ \ - static JUMP_TABLE_TYPE step0_jumps[32] = \ - { \ - REF (form_unknown), \ - REF (flag_space), /* for ' ' */ \ - REF (flag_plus), /* for '+' */ \ - REF (flag_minus), /* for '-' */ \ - REF (flag_hash), /* for '<hash>' */ \ - REF (flag_zero), /* for '0' */ \ - REF (flag_quote), /* for '\'' */ \ - REF (width_asterics), /* for '*' */ \ - REF (width), /* for '1'...'9' */ \ - REF (precision), /* for '.' */ \ - REF (mod_half), /* for 'h' */ \ - REF (mod_long), /* for 'l' */ \ - REF (mod_longlong), /* for 'L', 'q' */ \ - REF (mod_size_t), /* for 'z', 'Z' */ \ - REF (form_percent), /* for '%' */ \ - REF (form_integer), /* for 'd', 'i' */ \ - REF (form_unsigned), /* for 'u' */ \ - REF (form_octal), /* for 'o' */ \ - REF (form_hexa), /* for 'X', 'x' */ \ - REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ - REF (form_character), /* for 'c' */ \ - REF (form_string), /* for 's', 'S' */ \ - REF (form_pointer), /* for 'p' */ \ - REF (form_number), /* for 'n' */ \ - REF (form_strerror), /* for 'm' */ \ - REF (form_wcharacter), /* for 'C' */ \ - REF (form_floathex), /* for 'A', 'a' */ \ - REF (mod_ptrdiff_t), /* for 't' */ \ - REF (mod_intmax_t), /* for 'j' */ \ - REF (flag_i18n), /* for 'I' */ \ - REF (mod_decimal_half), /* for 'H' */ \ - REF (mod_decimal) /* for 'D' */ \ - }; \ - /* Step 1: after processing width. */ \ - static JUMP_TABLE_TYPE step1_jumps[32] = \ - { \ - REF (form_unknown), \ - REF (form_unknown), /* for ' ' */ \ - REF (form_unknown), /* for '+' */ \ - REF (form_unknown), /* for '-' */ \ - REF (form_unknown), /* for '<hash>' */ \ - REF (form_unknown), /* for '0' */ \ - REF (form_unknown), /* for '\'' */ \ - REF (form_unknown), /* for '*' */ \ - REF (form_unknown), /* for '1'...'9' */ \ - REF (precision), /* for '.' */ \ - REF (mod_half), /* for 'h' */ \ - REF (mod_long), /* for 'l' */ \ - REF (mod_longlong), /* for 'L', 'q' */ \ - REF (mod_size_t), /* for 'z', 'Z' */ \ - REF (form_percent), /* for '%' */ \ - REF (form_integer), /* for 'd', 'i' */ \ - REF (form_unsigned), /* for 'u' */ \ - REF (form_octal), /* for 'o' */ \ - REF (form_hexa), /* for 'X', 'x' */ \ - REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ - REF (form_character), /* for 'c' */ \ - REF (form_string), /* for 's', 'S' */ \ - REF (form_pointer), /* for 'p' */ \ - REF (form_number), /* for 'n' */ \ - REF (form_strerror), /* for 'm' */ \ - REF (form_wcharacter), /* for 'C' */ \ - REF (form_floathex), /* for 'A', 'a' */ \ - REF (mod_ptrdiff_t), /* for 't' */ \ - REF (mod_intmax_t), /* for 'j' */ \ - REF (form_unknown), /* for 'I' */ \ - REF (mod_decimal_half), /* for 'H' */ \ - REF (mod_decimal) /* for 'D' */ \ - }; \ - /* Step 2: after processing precision. */ \ - static JUMP_TABLE_TYPE step2_jumps[32] = \ - { \ - REF (form_unknown), \ - REF (form_unknown), /* for ' ' */ \ - REF (form_unknown), /* for '+' */ \ - REF (form_unknown), /* for '-' */ \ - REF (form_unknown), /* for '<hash>' */ \ - REF (form_unknown), /* for '0' */ \ - REF (form_unknown), /* for '\'' */ \ - REF (form_unknown), /* for '*' */ \ - REF (form_unknown), /* for '1'...'9' */ \ - REF (form_unknown), /* for '.' */ \ - REF (mod_half), /* for 'h' */ \ - REF (mod_long), /* for 'l' */ \ - REF (mod_longlong), /* for 'L', 'q' */ \ - REF (mod_size_t), /* for 'z', 'Z' */ \ - REF (form_percent), /* for '%' */ \ - REF (form_integer), /* for 'd', 'i' */ \ - REF (form_unsigned), /* for 'u' */ \ - REF (form_octal), /* for 'o' */ \ - REF (form_hexa), /* for 'X', 'x' */ \ - REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ - REF (form_character), /* for 'c' */ \ - REF (form_string), /* for 's', 'S' */ \ - REF (form_pointer), /* for 'p' */ \ - REF (form_number), /* for 'n' */ \ - REF (form_strerror), /* for 'm' */ \ - REF (form_wcharacter), /* for 'C' */ \ - REF (form_floathex), /* for 'A', 'a' */ \ - REF (mod_ptrdiff_t), /* for 't' */ \ - REF (mod_intmax_t), /* for 'j' */ \ - REF (form_unknown), /* for 'I' */ \ - REF (mod_decimal_half), /* for 'H' */ \ - REF (mod_decimal) /* for 'D' */ \ - }; \ - /* Step 3a: after processing first 'h' modifier. */ \ - static JUMP_TABLE_TYPE step3a_jumps[32] = \ - { \ - REF (form_unknown), \ - REF (form_unknown), /* for ' ' */ \ - REF (form_unknown), /* for '+' */ \ - REF (form_unknown), /* for '-' */ \ - REF (form_unknown), /* for '<hash>' */ \ - REF (form_unknown), /* for '0' */ \ - REF (form_unknown), /* for '\'' */ \ - REF (form_unknown), /* for '*' */ \ - REF (form_unknown), /* for '1'...'9' */ \ - REF (form_unknown), /* for '.' */ \ - REF (mod_halfhalf), /* for 'h' */ \ - REF (form_unknown), /* for 'l' */ \ - REF (form_unknown), /* for 'L', 'q' */ \ - REF (form_unknown), /* for 'z', 'Z' */ \ - REF (form_percent), /* for '%' */ \ - REF (form_integer), /* for 'd', 'i' */ \ - REF (form_unsigned), /* for 'u' */ \ - REF (form_octal), /* for 'o' */ \ - REF (form_hexa), /* for 'X', 'x' */ \ - REF (form_unknown), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ - REF (form_unknown), /* for 'c' */ \ - REF (form_unknown), /* for 's', 'S' */ \ - REF (form_unknown), /* for 'p' */ \ - REF (form_number), /* for 'n' */ \ - REF (form_unknown), /* for 'm' */ \ - REF (form_unknown), /* for 'C' */ \ - REF (form_unknown), /* for 'A', 'a' */ \ - REF (form_unknown), /* for 't' */ \ - REF (form_unknown), /* for 'j' */ \ - REF (form_unknown), /* for 'I' */ \ - REF (form_unknown), /* for 'H' */ \ - REF (form_unknown) /* for 'D' */ \ - }; \ - /* Step 3b: after processing first 'l' modifier. */ \ - static JUMP_TABLE_TYPE step3b_jumps[32] = \ - { \ - REF (form_unknown), \ - REF (form_unknown), /* for ' ' */ \ - REF (form_unknown), /* for '+' */ \ - REF (form_unknown), /* for '-' */ \ - REF (form_unknown), /* for '<hash>' */ \ - REF (form_unknown), /* for '0' */ \ - REF (form_unknown), /* for '\'' */ \ - REF (form_unknown), /* for '*' */ \ - REF (form_unknown), /* for '1'...'9' */ \ - REF (form_unknown), /* for '.' */ \ - REF (form_unknown), /* for 'h' */ \ - REF (mod_longlong), /* for 'l' */ \ - REF (form_unknown), /* for 'L', 'q' */ \ - REF (form_unknown), /* for 'z', 'Z' */ \ - REF (form_percent), /* for '%' */ \ - REF (form_integer), /* for 'd', 'i' */ \ - REF (form_unsigned), /* for 'u' */ \ - REF (form_octal), /* for 'o' */ \ - REF (form_hexa), /* for 'X', 'x' */ \ - REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ - REF (form_character), /* for 'c' */ \ - REF (form_string), /* for 's', 'S' */ \ - REF (form_pointer), /* for 'p' */ \ - REF (form_number), /* for 'n' */ \ - REF (form_strerror), /* for 'm' */ \ - REF (form_wcharacter), /* for 'C' */ \ - REF (form_floathex), /* for 'A', 'a' */ \ - REF (form_unknown), /* for 't' */ \ - REF (form_unknown), /* for 'j' */ \ - REF (form_unknown), /* for 'I' */ \ - REF (form_unknown), /* for 'H' */ \ - REF (form_unknown) /* for 'D' */ \ - }; \ - /* Some format codes should not be allowed for decimal-float. */ \ - /* Step 3c: after processing first 'D' modifier. */ \ - static JUMP_TABLE_TYPE step3c_jumps[32] = \ - { \ - REF (form_unknown), \ - REF (form_unknown), /* for ' ' */ \ - REF (form_unknown), /* for '+' */ \ - REF (form_unknown), /* for '-' */ \ - REF (form_unknown), /* for '<hash>' */ \ - REF (form_unknown), /* for '0' */ \ - REF (form_unknown), /* for '\'' */ \ - REF (form_unknown), /* for '*' */ \ - REF (form_unknown), /* for '1'...'9' */ \ - REF (form_unknown), /* for '.' */ \ - REF (form_unknown), /* for 'h' */ \ - REF (form_unknown), /* for 'l' */ \ - REF (form_unknown), /* for 'L', 'q' */ \ - REF (form_unknown), /* for 'z', 'Z' */ \ - REF (form_percent), /* for '%' */ \ - REF (form_integer), /* for 'd', 'i' */ \ - REF (form_unsigned), /* for 'u' */ \ - REF (form_octal), /* for 'o' */ \ - REF (form_hexa), /* for 'X', 'x' */ \ - REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ - REF (form_character), /* for 'c' */ \ - REF (form_string), /* for 's', 'S' */ \ - REF (form_pointer), /* for 'p' */ \ - REF (form_number), /* for 'n' */ \ - REF (form_strerror), /* for 'm' */ \ - REF (form_wcharacter), /* for 'C' */ \ - REF (form_floathex), /* for 'A', 'a' */ \ - REF (form_unknown), /* for 't' */ \ - REF (form_unknown), /* for 'j' */ \ - REF (form_unknown), /* for 'I' */ \ - REF (form_unknown), /* for 'H' */ \ - REF (mod_decimal_long) /* for 'D' */ \ - } - -#define STEP4_TABLE \ - /* Step 4: processing format specifier. */ \ - static JUMP_TABLE_TYPE step4_jumps[32] = \ - { \ - REF (form_unknown), \ - REF (form_unknown), /* for ' ' */ \ - REF (form_unknown), /* for '+' */ \ - REF (form_unknown), /* for '-' */ \ - REF (form_unknown), /* for '<hash>' */ \ - REF (form_unknown), /* for '0' */ \ - REF (form_unknown), /* for '\'' */ \ - REF (form_unknown), /* for '*' */ \ - REF (form_unknown), /* for '1'...'9' */ \ - REF (form_unknown), /* for '.' */ \ - REF (form_unknown), /* for 'h' */ \ - REF (form_unknown), /* for 'l' */ \ - REF (form_unknown), /* for 'L', 'q' */ \ - REF (form_unknown), /* for 'z', 'Z' */ \ - REF (form_percent), /* for '%' */ \ - REF (form_integer), /* for 'd', 'i' */ \ - REF (form_unsigned), /* for 'u' */ \ - REF (form_octal), /* for 'o' */ \ - REF (form_hexa), /* for 'X', 'x' */ \ - REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ - REF (form_character), /* for 'c' */ \ - REF (form_string), /* for 's', 'S' */ \ - REF (form_pointer), /* for 'p' */ \ - REF (form_number), /* for 'n' */ \ - REF (form_strerror), /* for 'm' */ \ - REF (form_wcharacter), /* for 'C' */ \ - REF (form_floathex), /* for 'A', 'a' */ \ - REF (form_unknown), /* for 't' */ \ - REF (form_unknown), /* for 'j' */ \ - REF (form_unknown), /* for 'I' */ \ - REF (form_unknown), /* for 'H' */ \ - REF (form_unknown) /* for 'D' */ \ - } - - -#define process_arg(fspec) \ - /* Start real work. We know about all flags and modifiers and \ - now process the wanted format specifier. */ \ - LABEL (form_percent): \ - /* Write a literal "%". */ \ - outchar (L_('%')); \ - break; \ - \ - LABEL (form_integer): \ - /* Signed decimal integer. */ \ - base = 10; \ - \ - if (is_longlong) \ - { \ - long long int signed_number; \ - \ - if (fspec == NULL) \ - signed_number = va_arg (ap, long long int); \ - else \ - signed_number = args_value[fspec->data_arg].pa_long_long_int; \ - \ - is_negative = signed_number < 0; \ - number.longlong = is_negative ? (- signed_number) : signed_number; \ - \ - goto LABEL (longlong_number); \ - } \ - else \ - { \ - long int signed_number; \ - \ - if (fspec == NULL) \ - { \ - if (is_long_num) \ - signed_number = va_arg (ap, long int); \ - else if (is_char) \ - signed_number = (signed char) va_arg (ap, unsigned int); \ - else if (!is_short) \ - signed_number = va_arg (ap, int); \ - else \ - signed_number = (short int) va_arg (ap, unsigned int); \ - } \ - else \ - if (is_long_num) \ - signed_number = args_value[fspec->data_arg].pa_long_int; \ - else if (is_char) \ - signed_number = (signed char) \ - args_value[fspec->data_arg].pa_u_int; \ - else if (!is_short) \ - signed_number = args_value[fspec->data_arg].pa_int; \ - else \ - signed_number = (short int) \ - args_value[fspec->data_arg].pa_u_int; \ - \ - is_negative = signed_number < 0; \ - number.word = is_negative ? (- signed_number) : signed_number; \ - \ - goto LABEL (number); \ - } \ - /* NOTREACHED */ \ - \ - LABEL (form_unsigned): \ - /* Unsigned decimal integer. */ \ - base = 10; \ - goto LABEL (unsigned_number); \ - /* NOTREACHED */ \ - \ - LABEL (form_octal): \ - /* Unsigned octal integer. */ \ - base = 8; \ - goto LABEL (unsigned_number); \ - /* NOTREACHED */ \ - \ - LABEL (form_hexa): \ - /* Unsigned hexadecimal integer. */ \ - base = 16; \ - \ - LABEL (unsigned_number): /* Unsigned number of base BASE. */ \ - \ - /* ISO specifies the `+' and ` ' flags only for signed \ - conversions. */ \ - is_negative = 0; \ - showsign = 0; \ - space = 0; \ - \ - if (is_longlong) \ - { \ - if (fspec == NULL) \ - number.longlong = va_arg (ap, unsigned long long int); \ - else \ - number.longlong = args_value[fspec->data_arg].pa_u_long_long_int; \ - \ - LABEL (longlong_number): \ - if (prec < 0) \ - /* Supply a default precision if none was given. */ \ - prec = 1; \ - else \ - /* We have to take care for the '0' flag. If a precision \ - is given it must be ignored. */ \ - pad = L_(' '); \ - \ - /* If the precision is 0 and the number is 0 nothing has to \ - be written for the number, except for the 'o' format in \ - alternate form. */ \ - if (prec == 0 && number.longlong == 0) \ - { \ - string = workend; \ - if (base == 8 && alt) \ - *--string = L_('0'); \ - } \ - else \ - { \ - /* Put the number in WORK. */ \ - string = _itoa (number.longlong, workend, base, \ - spec == L_('X')); \ - if (group && grouping) \ - string = group_number (string, workend, grouping, \ - thousands_sep); \ - \ - if (use_outdigits && base == 10) \ - string = _i18n_number_rewrite (string, workend); \ - } \ - /* Simplify further test for num != 0. */ \ - number.word = number.longlong != 0; \ - } \ - else \ - { \ - if (fspec == NULL) \ - { \ - if (is_long_num) \ - number.word = va_arg (ap, unsigned long int); \ - else if (is_char) \ - number.word = (unsigned char) va_arg (ap, unsigned int); \ - else if (!is_short) \ - number.word = va_arg (ap, unsigned int); \ - else \ - number.word = (unsigned short int) va_arg (ap, unsigned int); \ - } \ - else \ - if (is_long_num) \ - number.word = args_value[fspec->data_arg].pa_u_long_int; \ - else if (is_char) \ - number.word = (unsigned char) \ - args_value[fspec->data_arg].pa_u_int; \ - else if (!is_short) \ - number.word = args_value[fspec->data_arg].pa_u_int; \ - else \ - number.word = (unsigned short int) \ - args_value[fspec->data_arg].pa_u_int; \ - \ - LABEL (number): \ - if (prec < 0) \ - /* Supply a default precision if none was given. */ \ - prec = 1; \ - else \ - /* We have to take care for the '0' flag. If a precision \ - is given it must be ignored. */ \ - pad = L_(' '); \ - \ - /* If the precision is 0 and the number is 0 nothing has to \ - be written for the number, except for the 'o' format in \ - alternate form. */ \ - if (prec == 0 && number.word == 0) \ - { \ - string = workend; \ - if (base == 8 && alt) \ - *--string = L_('0'); \ - } \ - else \ - { \ - /* Put the number in WORK. */ \ - string = _itoa_word (number.word, workend, base, \ - spec == L_('X')); \ - if (group && grouping) \ - string = group_number (string, workend, grouping, \ - thousands_sep); \ - \ - if (use_outdigits && base == 10) \ - string = _i18n_number_rewrite (string, workend); \ - } \ - } \ - \ - if (prec <= workend - string && number.word != 0 && alt && base == 8) \ - /* Add octal marker. */ \ - *--string = L_('0'); \ - \ - prec = MAX (0, prec - (workend - string)); \ - \ - if (!left) \ - { \ - width -= workend - string + prec; \ - \ - if (number.word != 0 && alt && base == 16) \ - /* Account for 0X hex marker. */ \ - width -= 2; \ - \ - if (is_negative || showsign || space) \ - --width; \ - \ - if (pad == L_(' ')) \ - { \ - PAD (L_(' ')); \ - width = 0; \ - } \ - \ - if (is_negative) \ - outchar (L_('-')); \ - else if (showsign) \ - outchar (L_('+')); \ - else if (space) \ - outchar (L_(' ')); \ - \ - if (number.word != 0 && alt && base == 16) \ - { \ - outchar (L_('0')); \ - outchar (spec); \ - } \ - \ - width += prec; \ - PAD (L_('0')); \ - \ - outstring (string, workend - string); \ - \ - break; \ - } \ - else \ - { \ - if (is_negative) \ - { \ - outchar (L_('-')); \ - --width; \ - } \ - else if (showsign) \ - { \ - outchar (L_('+')); \ - --width; \ - } \ - else if (space) \ - { \ - outchar (L_(' ')); \ - --width; \ - } \ - \ - if (number.word != 0 && alt && base == 16) \ - { \ - outchar (L_('0')); \ - outchar (spec); \ - width -= 2; \ - } \ - \ - width -= workend - string + prec; \ - \ - if (prec > 0) \ - { \ - int temp = width; \ - width = prec; \ - PAD (L_('0'));; \ - width = temp; \ - } \ - \ - outstring (string, workend - string); \ - \ - PAD (L_(' ')); \ - break; \ - } \ - \ - LABEL (form_float): \ - { \ - /* Floating-point number. This is handled by printf_fp.c */ \ - /* or printf_dfp.c */ \ - const void *ptr; \ - int function_done; \ - \ - if (fspec == NULL) \ - { \ - if (__ldbl_is_dbl) \ - is_long_double = 0; \ - \ - struct printf_info info = { .prec = prec, \ - .width = width, \ - .spec = spec, \ - .is_long_double = is_long_double, \ - .is_short = is_short, \ - .is_long = is_long, \ - .alt = alt, \ - .space = space, \ - .left = left, \ - .showsign = showsign, \ - .group = group, \ - .pad = pad, \ - .extra = 0, \ - .i18n = use_outdigits, \ - .is_decimal = is_decimal, \ - .wide = sizeof (CHAR_T) != 1 }; \ - \ - if (is_long_double && !is_decimal) \ - the_arg.pa_long_double = va_arg (ap, long double); \ - else if (is_long_double && is_decimal) \ - the_arg.pa_decimal128 = va_arg (ap, _Decimal128); \ - else if (is_short && is_decimal) \ - /* The specification indicates that _Decimal32 should */ \ - /* NOT be promoted to _Decimal64 for DFP types. */ \ - the_arg.pa_decimal32 = va_arg (ap, _Decimal32); \ - else if (is_decimal && !is_long_double && !is_short) \ - the_arg.pa_decimal64 = va_arg (ap, _Decimal64); \ - else \ - the_arg.pa_double = va_arg (ap, double); \ - ptr = (const void *) &the_arg; \ - \ - if (is_decimal) \ - function_done = __printf_dfp (s, &info, &ptr); \ - else \ - function_done = __printf_fp (s, &info, &ptr); \ - } \ - else \ - { \ - ptr = (const void *) &args_value[fspec->data_arg]; \ - if (__ldbl_is_dbl) \ - { \ - fspec->data_arg_type = PA_DOUBLE; \ - fspec->info.is_long_double = 0; \ - } \ - \ - function_done = __printf_fp (s, &fspec->info, &ptr); \ - } \ - \ - if (function_done < 0) \ - { \ - /* Error in print handler. */ \ - done = -1; \ - goto all_done; \ - } \ - \ - done += function_done; \ - } \ - break; \ - \ - LABEL (form_floathex): \ - { \ - /* Floating point number printed as hexadecimal number. */ \ - const void *ptr; \ - int function_done; \ - \ - if (fspec == NULL) \ - { \ - if (__ldbl_is_dbl) \ - is_long_double = 0; \ - \ - struct printf_info info = { .prec = prec, \ - .width = width, \ - .spec = spec, \ - .is_long_double = is_long_double, \ - .is_short = is_short, \ - .is_long = is_long, \ - .alt = alt, \ - .space = space, \ - .left = left, \ - .showsign = showsign, \ - .group = group, \ - .pad = pad, \ - .extra = 0, \ - .is_decimal = is_decimal, \ - .wide = sizeof (CHAR_T) != 1 }; \ - \ - if (is_long_double && !is_decimal) \ - the_arg.pa_long_double = va_arg (ap, long double); \ - else if (is_long_double && is_decimal) \ - the_arg.pa_decimal128 = va_arg (ap, _Decimal128); \ - else if (is_short && is_decimal) \ - the_arg.pa_decimal32 = va_arg (ap, _Decimal32); \ - else if (is_decimal && !is_long_double && !is_short) \ - the_arg.pa_decimal64 = va_arg (ap, _Decimal64); \ - else \ - the_arg.pa_double = va_arg (ap, double); \ - ptr = (const void *) &the_arg; \ - \ - if (is_decimal) \ - function_done = __printf_dfphex (s, &info, &ptr); \ - else \ - function_done = __printf_fphex (s, &info, &ptr); \ - } \ - else \ - { \ - ptr = (const void *) &args_value[fspec->data_arg]; \ - if (__ldbl_is_dbl) \ - fspec->info.is_long_double = 0; \ - \ - /* FIX ME */ \ - if (is_decimal) \ - function_done = __printf_dfphex (s, &fspec->info, &ptr); \ - else \ - function_done = __printf_fphex (s, &fspec->info, &ptr); \ - } \ - \ - if (function_done < 0) \ - { \ - /* Error in print handler. */ \ - done = -1; \ - goto all_done; \ - } \ - \ - done += function_done; \ - } \ - break; \ - \ - LABEL (form_pointer): \ - /* Generic pointer. */ \ - { \ - const void *ptr; \ - if (fspec == NULL) \ - ptr = va_arg (ap, void *); \ - else \ - ptr = args_value[fspec->data_arg].pa_pointer; \ - if (ptr != NULL) \ - { \ - /* If the pointer is not NULL, write it as a %#x spec. */ \ - base = 16; \ - number.word = (unsigned long int) ptr; \ - is_negative = 0; \ - alt = 1; \ - group = 0; \ - spec = L_('x'); \ - goto LABEL (number); \ - } \ - else \ - { \ - /* Write "(nil)" for a nil pointer. */ \ - string = (CHAR_T *) L_("(nil)"); \ - /* Make sure the full string "(nil)" is printed. */ \ - if (prec < 5) \ - prec = 5; \ - is_long = 0; /* This is no wide-char string. */ \ - goto LABEL (print_string); \ - } \ - } \ - /* NOTREACHED */ \ - \ - LABEL (form_number): \ - if (s->_flags2 & _IO_FLAGS2_FORTIFY) \ - { \ - if (! readonly_format) \ - { \ - extern int __readonly_area (const void *, size_t) \ - attribute_hidden; \ - readonly_format \ - = __readonly_area (format, ((STR_LEN (format) + 1) \ - * sizeof (CHAR_T))); \ - } \ - if (readonly_format < 0) \ - __libc_fatal ("*** %n in writable segment detected ***\n"); \ - } \ - /* Answer the count of characters written. */ \ - if (fspec == NULL) \ - { \ - if (is_longlong) \ - *(long long int *) va_arg (ap, void *) = done; \ - else if (is_long_num) \ - *(long int *) va_arg (ap, void *) = done; \ - else if (is_char) \ - *(char *) va_arg (ap, void *) = done; \ - else if (!is_short) \ - *(int *) va_arg (ap, void *) = done; \ - else \ - *(short int *) va_arg (ap, void *) = done; \ - } \ - else \ - if (is_longlong) \ - *(long long int *) args_value[fspec->data_arg].pa_pointer = done; \ - else if (is_long_num) \ - *(long int *) args_value[fspec->data_arg].pa_pointer = done; \ - else if (is_char) \ - *(char *) args_value[fspec->data_arg].pa_pointer = done; \ - else if (!is_short) \ - *(int *) args_value[fspec->data_arg].pa_pointer = done; \ - else \ - *(short int *) args_value[fspec->data_arg].pa_pointer = done; \ - break; \ - \ - LABEL (form_strerror): \ - /* Print description of error ERRNO. */ \ - string = \ - (CHAR_T *) __strerror_r (save_errno, (char *) work_buffer, \ - sizeof work_buffer); \ - is_long = 0; /* This is no wide-char string. */ \ - goto LABEL (print_string) - -#ifdef COMPILE_WPRINTF -# define process_string_arg(fspec) \ - LABEL (form_character): \ - /* Character. */ \ - if (is_long) \ - goto LABEL (form_wcharacter); \ - --width; /* Account for the character itself. */ \ - if (!left) \ - PAD (L' '); \ - if (fspec == NULL) \ - outchar (__btowc ((unsigned char) va_arg (ap, int))); /* Promoted. */ \ - else \ - outchar (__btowc ((unsigned char) \ - args_value[fspec->data_arg].pa_int)); \ - if (left) \ - PAD (L' '); \ - break; \ - \ - LABEL (form_wcharacter): \ - { \ - /* Wide character. */ \ - --width; \ - if (!left) \ - PAD (L' '); \ - if (fspec == NULL) \ - outchar (va_arg (ap, wchar_t)); \ - else \ - outchar (args_value[fspec->data_arg].pa_wchar); \ - if (left) \ - PAD (L' '); \ - } \ - break; \ - \ - LABEL (form_string): \ - { \ - size_t len; \ - int string_malloced; \ - \ - /* The string argument could in fact be `char *' or `wchar_t *'. \ - But this should not make a difference here. */ \ - if (fspec == NULL) \ - string = (CHAR_T *) va_arg (ap, const wchar_t *); \ - else \ - string = (CHAR_T *) args_value[fspec->data_arg].pa_wstring; \ - \ - /* Entry point for printing other strings. */ \ - LABEL (print_string): \ - \ - string_malloced = 0; \ - if (string == NULL) \ - { \ - /* Write "(null)" if there's space. */ \ - if (prec == -1 \ - || prec >= (int) (sizeof (null) / sizeof (null[0])) - 1) \ - { \ - string = (CHAR_T *) null; \ - len = (sizeof (null) / sizeof (null[0])) - 1; \ - } \ - else \ - { \ - string = (CHAR_T *) L""; \ - len = 0; \ - } \ - } \ - else if (!is_long && spec != L_('S')) \ - { \ - /* This is complicated. We have to transform the multibyte \ - string into a wide character string. */ \ - const char *mbs = (const char *) string; \ - mbstate_t mbstate; \ - \ - len = prec != -1 ? __strnlen (mbs, (size_t) prec) : strlen (mbs); \ - \ - /* Allocate dynamically an array which definitely is long \ - enough for the wide character version. Each byte in the \ - multi-byte string can produce at most one wide character. */ \ - if (__libc_use_alloca (len * sizeof (wchar_t))) \ - string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \ - else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \ - == NULL) \ - { \ - done = -1; \ - goto all_done; \ - } \ - else \ - string_malloced = 1; \ - \ - memset (&mbstate, '\0', sizeof (mbstate_t)); \ - len = __mbsrtowcs (string, &mbs, len, &mbstate); \ - if (len == (size_t) -1) \ - { \ - /* Illegal multibyte character. */ \ - done = -1; \ - goto all_done; \ - } \ - } \ - else \ - { \ - if (prec != -1) \ - /* Search for the end of the string, but don't search past \ - the length specified by the precision. */ \ - len = __wcsnlen (string, prec); \ - else \ - len = __wcslen (string); \ - } \ - \ - if ((width -= len) < 0) \ - { \ - outstring (string, len); \ - break; \ - } \ - \ - if (!left) \ - PAD (L' '); \ - outstring (string, len); \ - if (left) \ - PAD (L' '); \ - if (__builtin_expect (string_malloced, 0)) \ - free (string); \ - } \ - break; -#else -# define process_string_arg(fspec) \ - LABEL (form_character): \ - /* Character. */ \ - if (is_long) \ - goto LABEL (form_wcharacter); \ - --width; /* Account for the character itself. */ \ - if (!left) \ - PAD (' '); \ - if (fspec == NULL) \ - outchar ((unsigned char) va_arg (ap, int)); /* Promoted. */ \ - else \ - outchar ((unsigned char) args_value[fspec->data_arg].pa_int); \ - if (left) \ - PAD (' '); \ - break; \ - \ - LABEL (form_wcharacter): \ - { \ - /* Wide character. */ \ - char buf[MB_CUR_MAX]; \ - mbstate_t mbstate; \ - size_t len; \ - \ - memset (&mbstate, '\0', sizeof (mbstate_t)); \ - len = __wcrtomb (buf, (fspec == NULL ? va_arg (ap, wchar_t) \ - : args_value[fspec->data_arg].pa_wchar), \ - &mbstate); \ - if (len == (size_t) -1) \ - { \ - /* Something went wron gduring the conversion. Bail out. */ \ - done = -1; \ - goto all_done; \ - } \ - width -= len; \ - if (!left) \ - PAD (' '); \ - outstring (buf, len); \ - if (left) \ - PAD (' '); \ - } \ - break; \ - \ - LABEL (form_string): \ - { \ - size_t len; \ - int string_malloced; \ - \ - /* The string argument could in fact be `char *' or `wchar_t *'. \ - But this should not make a difference here. */ \ - if (fspec == NULL) \ - string = (char *) va_arg (ap, const char *); \ - else \ - string = (char *) args_value[fspec->data_arg].pa_string; \ - \ - /* Entry point for printing other strings. */ \ - LABEL (print_string): \ - \ - string_malloced = 0; \ - if (string == NULL) \ - { \ - /* Write "(null)" if there's space. */ \ - if (prec == -1 || prec >= (int) sizeof (null) - 1) \ - { \ - string = (char *) null; \ - len = sizeof (null) - 1; \ - } \ - else \ - { \ - string = (char *) ""; \ - len = 0; \ - } \ - } \ - else if (!is_long && spec != L_('S')) \ - { \ - if (prec != -1) \ - { \ - /* Search for the end of the string, but don't search past \ - the length (in bytes) specified by the precision. Also \ - don't use incomplete characters. */ \ - if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX) == 1) \ - len = __strnlen (string, prec); \ - else \ - { \ - /* In case we have a multibyte character set the \ - situation is more complicated. We must not copy \ - bytes at the end which form an incomplete character. */\ - size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\ - wchar_t ignore[ignore_size]; \ - const char *str2 = string; \ - const char *strend = string + prec; \ - if (strend < string) \ - strend = (const char *) UINTPTR_MAX; \ - \ - mbstate_t ps; \ - memset (&ps, '\0', sizeof (ps)); \ - \ - while (str2 != NULL && str2 < strend) \ - if (__mbsnrtowcs (ignore, &str2, strend - str2, \ - ignore_size, &ps) == (size_t) -1) \ - { \ - done = -1; \ - goto all_done; \ - } \ - \ - if (str2 == NULL) \ - len = strlen (string); \ - else \ - len = str2 - string - (ps.__count & 7); \ - } \ - } \ - else \ - len = strlen (string); \ - } \ - else \ - { \ - const wchar_t *s2 = (const wchar_t *) string; \ - mbstate_t mbstate; \ - \ - memset (&mbstate, '\0', sizeof (mbstate_t)); \ - \ - if (prec >= 0) \ - { \ - /* The string `s2' might not be NUL terminated. */ \ - if (__libc_use_alloca (prec)) \ - string = (char *) alloca (prec); \ - else if ((string = (char *) malloc (prec)) == NULL) \ - { \ - done = -1; \ - goto all_done; \ - } \ - else \ - string_malloced = 1; \ - len = __wcsrtombs (string, &s2, prec, &mbstate); \ - } \ - else \ - { \ - len = __wcsrtombs (NULL, &s2, 0, &mbstate); \ - if (len != (size_t) -1) \ - { \ - assert (__mbsinit (&mbstate)); \ - s2 = (const wchar_t *) string; \ - if (__libc_use_alloca (len + 1)) \ - string = (char *) alloca (len + 1); \ - else if ((string = (char *) malloc (len + 1)) == NULL) \ - { \ - done = -1; \ - goto all_done; \ - } \ - else \ - string_malloced = 1; \ - (void) __wcsrtombs (string, &s2, len + 1, &mbstate); \ - } \ - } \ - \ - if (len == (size_t) -1) \ - { \ - /* Illegal wide-character string. */ \ - done = -1; \ - goto all_done; \ - } \ - } \ - \ - if ((width -= len) < 0) \ - { \ - outstring (string, len); \ - break; \ - } \ - \ - if (!left) \ - PAD (' '); \ - outstring (string, len); \ - if (left) \ - PAD (' '); \ - if (__builtin_expect (string_malloced, 0)) \ - free (string); \ - } \ - break; -#endif - - /* Orient the stream. */ -#ifdef ORIENT - ORIENT; -#endif - - /* Sanity check of arguments. */ - ARGCHECK (s, format); - -#ifdef ORIENT - /* Check for correct orientation. */ - if (_IO_vtable_offset (s) == 0 && - _IO_fwide (s, sizeof (CHAR_T) == 1 ? -1 : 1) - != (sizeof (CHAR_T) == 1 ? -1 : 1)) - /* The stream is already oriented otherwise. */ - return EOF; -#endif - - if (UNBUFFERED_P (s)) - /* Use a helper function which will allocate a local temporary buffer - for the stream and then call us again. */ - return buffered_vfprintf (s, format, ap); - - /* Initialize local variables. */ - done = 0; - grouping = (const char *) -1; -#ifdef __va_copy - /* This macro will be available soon in gcc's <stdarg.h>. We need it - since on some systems `va_list' is not an integral type. */ - __va_copy (ap_save, ap); -#else - ap_save = ap; -#endif - nspecs_done = 0; - -#ifdef COMPILE_WPRINTF - /* Find the first format specifier. */ - f = lead_str_end = __find_specwc ((const UCHAR_T *) format); -#else - /* Find the first format specifier. */ - f = lead_str_end = __find_specmb ((const UCHAR_T *) format); -#endif - - /* Lock stream. */ - _IO_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, s); - _IO_flockfile (s); - - /* Write the literal text before the first format. */ - outstring ((const UCHAR_T *) format, - lead_str_end - (const UCHAR_T *) format); - - /* If we only have to print a simple string, return now. */ - if (*f == L_('\0')) - goto all_done; - - /* Process whole format string. */ - do - { -#ifdef SHARED -# define REF(Name) &&do_##Name - &&do_form_unknown -#else -# define REF(Name) &&do_##Name -#endif -#define LABEL(Name) do_##Name - STEP0_3_TABLE; - STEP4_TABLE; - - union printf_arg *args_value; /* This is not used here but ... */ - int is_negative; /* Flag for negative number. */ - union - { - unsigned long long int longlong; - unsigned long int word; - } number; - int base; - union printf_arg the_arg; - CHAR_T *string; /* Pointer to argument string. */ - int alt = 0; /* Alternate format. */ - int space = 0; /* Use space prefix if no sign is needed. */ - int left = 0; /* Left-justify output. */ - int showsign = 0; /* Always begin with plus or minus sign. */ - int group = 0; /* Print numbers according grouping rules. */ - int is_long_double = 0; /* Argument is long double/ long long int. */ - int is_short = 0; /* Argument is short int. */ - int is_long = 0; /* Argument is long int. */ - int is_char = 0; /* Argument is promoted (unsigned) char. */ - int is_decimal = 0; /* Argument is decimal floating point. */ - int width = 0; /* Width of output; 0 means none specified. */ - int prec = -1; /* Precision of output; -1 means none specified. */ - /* This flag is set by the 'I' modifier and selects the use of the - `outdigits' as determined by the current locale. */ - int use_outdigits = 0; - UCHAR_T pad = L_(' ');/* Padding character. */ - CHAR_T spec; - - workstart = NULL; - workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)]; - - /* Get current character in format string. */ - JUMP (*++f, step0_jumps); - - /* ' ' flag. */ - LABEL (flag_space): - space = 1; - JUMP (*++f, step0_jumps); - - /* '+' flag. */ - LABEL (flag_plus): - showsign = 1; - JUMP (*++f, step0_jumps); - - /* The '-' flag. */ - LABEL (flag_minus): - left = 1; - pad = L_(' '); - JUMP (*++f, step0_jumps); - - /* The '#' flag. */ - LABEL (flag_hash): - alt = 1; - JUMP (*++f, step0_jumps); - - /* The '0' flag. */ - LABEL (flag_zero): - if (!left) - pad = L_('0'); - JUMP (*++f, step0_jumps); - - /* The '\'' flag. */ - LABEL (flag_quote): - group = 1; - - if (grouping == (const char *) -1) - { -#ifdef COMPILE_WPRINTF - thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC, - _NL_NUMERIC_THOUSANDS_SEP_WC); -#else - thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP); -#endif - - grouping = _NL_CURRENT (LC_NUMERIC, GROUPING); - if (*grouping == '\0' || *grouping == CHAR_MAX -#ifdef COMPILE_WPRINTF - || thousands_sep == L'\0' -#else - || *thousands_sep == '\0' -#endif - ) - grouping = NULL; - } - JUMP (*++f, step0_jumps); - - LABEL (flag_i18n): - use_outdigits = 1; - JUMP (*++f, step0_jumps); - - /* Get width from argument. */ - LABEL (width_asterics): - { - const UCHAR_T *tmp; /* Temporary value. */ - - tmp = ++f; - if (ISDIGIT (*tmp) && read_int (&tmp) && *tmp == L_('$')) - /* The width comes from a positional parameter. */ - goto do_positional; - - width = va_arg (ap, int); - - /* Negative width means left justified. */ - if (width < 0) - { - width = -width; - pad = L_(' '); - left = 1; - } - - if (width + 32 >= (int) (sizeof (work_buffer) - / sizeof (work_buffer[0]))) - { - /* We have to use a special buffer. The "32" is just a safe - bet for all the output which is not counted in the width. */ - if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) - workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) - + (width + 32)); - else - { - workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T)); - if (workstart == NULL) - { - done = -1; - goto all_done; - } - workend = workstart + (width + 32); - } - } - } - JUMP (*f, step1_jumps); - - /* Given width in format string. */ - LABEL (width): - width = read_int (&f); - - if (width + 32 >= (int) (sizeof (work_buffer) / sizeof (work_buffer[0]))) - { - /* We have to use a special buffer. The "32" is just a safe - bet for all the output which is not counted in the width. */ - if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) - workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) - + (width + 32)); - else - { - workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T)); - if (workstart == NULL) - { - done = -1; - goto all_done; - } - workend = workstart + (width + 32); - } - } - if (*f == L_('$')) - /* Oh, oh. The argument comes from a positional parameter. */ - goto do_positional; - JUMP (*f, step1_jumps); - - LABEL (precision): - ++f; - if (*f == L_('*')) - { - const UCHAR_T *tmp; /* Temporary value. */ - - tmp = ++f; - if (ISDIGIT (*tmp) && read_int (&tmp) > 0 && *tmp == L_('$')) - /* The precision comes from a positional parameter. */ - goto do_positional; - - prec = va_arg (ap, int); - - /* If the precision is negative the precision is omitted. */ - if (prec < 0) - prec = -1; - } - else if (ISDIGIT (*f)) - prec = read_int (&f); - else - prec = 0; - if (prec > width - && prec + 32 > (int)(sizeof (work_buffer) / sizeof (work_buffer[0]))) - { - if (__libc_use_alloca ((prec + 32) * sizeof (CHAR_T))) - workend = ((CHAR_T *) alloca ((prec + 32) * sizeof (CHAR_T))) - + (prec + 32); - else - { - workstart = (CHAR_T *) malloc ((prec + 32) * sizeof (CHAR_T)); - if (workstart == NULL) - { - done = -1; - goto all_done; - } - workend = workstart + (prec + 32); - } - } - JUMP (*f, step2_jumps); - - /* Process 'h' modifier. There might another 'h' following. */ - LABEL (mod_half): - is_short = 1; - JUMP (*++f, step3a_jumps); - - /* Process 'hh' modifier. */ - LABEL (mod_halfhalf): - is_short = 0; - is_char = 1; - JUMP (*++f, step4_jumps); - - /* Process 'l' modifier. There might another 'l' following. */ - LABEL (mod_long): - is_long = 1; - JUMP (*++f, step3b_jumps); - - /* Process 'L', 'q', or 'll' modifier. No other modifier is - allowed to follow. */ - LABEL (mod_longlong): - is_long_double = 1; - is_long = 1; - JUMP (*++f, step4_jumps); - - LABEL (mod_size_t): - is_long_double = sizeof (size_t) > sizeof (unsigned long int); - is_long = sizeof (size_t) > sizeof (unsigned int); - JUMP (*++f, step4_jumps); - - LABEL (mod_ptrdiff_t): - is_long_double = sizeof (ptrdiff_t) > sizeof (unsigned long int); - is_long = sizeof (ptrdiff_t) > sizeof (unsigned int); - JUMP (*++f, step4_jumps); - - LABEL (mod_intmax_t): - is_long_double = sizeof (intmax_t) > sizeof (unsigned long int); - is_long = sizeof (intmax_t) > sizeof (unsigned int); - JUMP (*++f, step4_jumps); - - /* Process 'H' modifier. No other modifier is allowed to follow. */ - LABEL (mod_decimal_half): - is_decimal = 1; - is_short = 1; - JUMP (*++f, step4_jumps); - - /* Process 'D' modifier. There might be another 'D' following. */ - LABEL (mod_decimal): - is_decimal = 1; - is_short = 0; - is_long = 0; - JUMP (*++f, step3c_jumps); - - /* Process 'DD' modifier. */ - LABEL (mod_decimal_long): - /* is_decimal = 0; */ - is_decimal = 1; - is_long_double = 1; - JUMP (*++f, step4_jumps); - - /* The previous step3c_jumps or step4_jumps will jump directly - * to the LABELs defined in the process_arg macro. */ - - /* Process current format. */ - while (1) - { - process_arg (((struct printf_spec *) NULL)); - process_string_arg (((struct printf_spec *) NULL)); - - LABEL (form_unknown): - if (spec == L_('\0')) - { - /* The format string ended before the specifier is complete. */ - done = -1; - goto all_done; - } - - /* If we are in the fast loop force entering the complicated - one. */ - goto do_positional; - } - - /* The format is correctly handled. */ - ++nspecs_done; - - if (__builtin_expect (workstart != NULL, 0)) - free (workstart); - workstart = NULL; - - /* Look for next format specifier. */ -#ifdef COMPILE_WPRINTF - f = __find_specwc ((end_of_spec = ++f)); -#else - f = __find_specmb ((end_of_spec = ++f)); -#endif - - /* Write the following constant string. */ - outstring (end_of_spec, f - end_of_spec); - } - while (*f != L_('\0')); - - /* Unlock stream and return. */ - goto all_done; - - /* Here starts the more complex loop to handle positional parameters. */ -do_positional: - { - /* Array with information about the needed arguments. This has to - be dynamically extensible. */ - size_t nspecs = 0; - size_t nspecs_max = 32; /* A more or less arbitrary start value. */ - struct printf_spec *specs - = alloca (nspecs_max * sizeof (struct printf_spec)); - - /* The number of arguments the format string requests. This will - determine the size of the array needed to store the argument - attributes. */ - size_t nargs = 0; - int *args_type; - union printf_arg *args_value = NULL; - - /* Positional parameters refer to arguments directly. This could - also determine the maximum number of arguments. Track the - maximum number. */ - size_t max_ref_arg = 0; - - /* Just a counter. */ - size_t cnt; - - free (workstart); - workstart = NULL; - - if (grouping == (const char *) -1) - { -#ifdef COMPILE_WPRINTF - thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC, - _NL_NUMERIC_THOUSANDS_SEP_WC); -#else - thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP); -#endif - - grouping = _NL_CURRENT (LC_NUMERIC, GROUPING); - if (*grouping == '\0' || *grouping == CHAR_MAX) - grouping = NULL; - } - - for (f = lead_str_end; *f != L_('\0'); f = specs[nspecs++].next_fmt) - { - if (nspecs >= nspecs_max) - { - /* Extend the array of format specifiers. */ - struct printf_spec *old = specs; - - nspecs_max *= 2; - specs = alloca (nspecs_max * sizeof (struct printf_spec)); - - if (specs == &old[nspecs]) - /* Stack grows up, OLD was the last thing allocated; - extend it. */ - nspecs_max += nspecs_max / 2; - else - { - /* Copy the old array's elements to the new space. */ - memcpy (specs, old, nspecs * sizeof (struct printf_spec)); - if (old == &specs[nspecs]) - /* Stack grows down, OLD was just below the new - SPECS. We can use that space when the new space - runs out. */ - nspecs_max += nspecs_max / 2; - } - } - - /* Parse the format specifier. */ -#ifdef COMPILE_WPRINTF - nargs += __parse_one_specwc (f, nargs, &specs[nspecs], &max_ref_arg); -#else - nargs += __parse_one_specmb (f, nargs, &specs[nspecs], &max_ref_arg); -#endif - } - - /* Determine the number of arguments the format string consumes. */ - nargs = MAX (nargs, max_ref_arg); - - /* Allocate memory for the argument descriptions. */ - args_type = alloca (nargs * sizeof (int)); - memset (args_type, s->_flags2 & _IO_FLAGS2_FORTIFY ? '\xff' : '\0', - nargs * sizeof (int)); - args_value = alloca (nargs * sizeof (union printf_arg)); - - /* XXX Could do sanity check here: If any element in ARGS_TYPE is - still zero after this loop, format is invalid. For now we - simply use 0 as the value. */ - - /* Fill in the types of all the arguments. */ - for (cnt = 0; cnt < nspecs; ++cnt) - { - /* If the width is determined by an argument this is an int. */ - if (specs[cnt].width_arg != -1) - args_type[specs[cnt].width_arg] = PA_INT; - - /* If the precision is determined by an argument this is an int. */ - if (specs[cnt].prec_arg != -1) - args_type[specs[cnt].prec_arg] = PA_INT; - - switch (specs[cnt].ndata_args) - { - case 0: /* No arguments. */ - break; - case 1: /* One argument; we already have the type. */ - args_type[specs[cnt].data_arg] = specs[cnt].data_arg_type; - break; - default: - /* We have more than one argument for this format spec. - We must call the arginfo function again to determine - all the types. */ - (void) (*__printf_arginfo_table[specs[cnt].info.spec]) - (&specs[cnt].info, - specs[cnt].ndata_args, &args_type[specs[cnt].data_arg]); - break; - } - } - - /* Now we know all the types and the order. Fill in the argument - values. */ - for (cnt = 0; cnt < nargs; ++cnt) - switch (args_type[cnt]) - { -#define T(tag, mem, type) \ - case tag: \ - args_value[cnt].mem = va_arg (ap_save, type); \ - break - - T (PA_CHAR, pa_int, int); /* Promoted. */ - T (PA_WCHAR, pa_wchar, wint_t); - T (PA_INT|PA_FLAG_SHORT, pa_int, int); /* Promoted. */ - T (PA_INT, pa_int, int); - T (PA_INT|PA_FLAG_LONG, pa_long_int, long int); - T (PA_INT|PA_FLAG_LONG_LONG, pa_long_long_int, long long int); - T (PA_FLOAT, pa_double, double); /* Promoted. */ - T (PA_DOUBLE, pa_double, double); - T (PA_DECIMAL, pa_decimal32, _Decimal32); - T (PA_DECIMAL|PA_FLAG_SHORT, pa_decimal64, _Decimal64); - T (PA_DECIMAL|PA_FLAG_LONG_DOUBLE, pa_decimal128, _Decimal128); - case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: - if (__ldbl_is_dbl) - { - args_value[cnt].pa_double = va_arg (ap_save, double); - args_type[cnt] &= ~PA_FLAG_LONG_DOUBLE; - } - else - args_value[cnt].pa_long_double = va_arg (ap_save, long double); - break; - T (PA_STRING, pa_string, const char *); - T (PA_WSTRING, pa_wstring, const wchar_t *); - T (PA_POINTER, pa_pointer, void *); -#undef T - default: - if ((args_type[cnt] & PA_FLAG_PTR) != 0) - args_value[cnt].pa_pointer = va_arg (ap_save, void *); - else - args_value[cnt].pa_long_double = 0.0; - break; - case -1: - /* Error case. Not all parameters appear in N$ format - strings. We have no way to determine their type. */ - assert (s->_flags2 & _IO_FLAGS2_FORTIFY); - __libc_fatal ("*** invalid %N$ use detected ***\n"); - } - - /* Now walk through all format specifiers and process them. */ - for (; (size_t) nspecs_done < nspecs; ++nspecs_done) - { -#undef REF -#ifdef SHARED -# define REF(Name) &&do2_##Name - &&do_form_unknown -#else -# define REF(Name) &&do2_##Name -#endif -#undef LABEL -#define LABEL(Name) do2_##Name - STEP4_TABLE; - - int is_negative; - union - { - unsigned long long int longlong; - unsigned long int word; - } number; - int base; - union printf_arg the_arg; - CHAR_T *string; /* Pointer to argument string. */ - - /* Fill variables from values in struct. */ - int alt = specs[nspecs_done].info.alt; - int space = specs[nspecs_done].info.space; - int left = specs[nspecs_done].info.left; - int showsign = specs[nspecs_done].info.showsign; - int group = specs[nspecs_done].info.group; - int is_long_double = specs[nspecs_done].info.is_long_double; - int is_short = specs[nspecs_done].info.is_short; - int is_char = specs[nspecs_done].info.is_char; - int is_long = specs[nspecs_done].info.is_long; - int width = specs[nspecs_done].info.width; - int prec = specs[nspecs_done].info.prec; - int use_outdigits = specs[nspecs_done].info.i18n; - int is_decimal = specs[nspecs_done].info.is_decimal; - char pad = specs[nspecs_done].info.pad; - CHAR_T spec = specs[nspecs_done].info.spec; - - workstart = NULL; - workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)]; - - /* Fill in last information. */ - if (specs[nspecs_done].width_arg != -1) - { - /* Extract the field width from an argument. */ - specs[nspecs_done].info.width = - args_value[specs[nspecs_done].width_arg].pa_int; - - if (specs[nspecs_done].info.width < 0) - /* If the width value is negative left justification is - selected and the value is taken as being positive. */ - { - specs[nspecs_done].info.width *= -1; - left = specs[nspecs_done].info.left = 1; - } - width = specs[nspecs_done].info.width; - } - - if (specs[nspecs_done].prec_arg != -1) - { - /* Extract the precision from an argument. */ - specs[nspecs_done].info.prec = - args_value[specs[nspecs_done].prec_arg].pa_int; - - if (specs[nspecs_done].info.prec < 0) - /* If the precision is negative the precision is - omitted. */ - specs[nspecs_done].info.prec = -1; - - prec = specs[nspecs_done].info.prec; - } - - /* Maybe the buffer is too small. */ - if (MAX (prec, width) + 32 > (int) (sizeof (work_buffer) - / sizeof (CHAR_T))) - { - if (__libc_use_alloca ((MAX (prec, width) + 32) - * sizeof (CHAR_T))) - workend = ((CHAR_T *) alloca ((MAX (prec, width) + 32) - * sizeof (CHAR_T)) - + (MAX (prec, width) + 32)); - else - { - workstart = (CHAR_T *) malloc ((MAX (prec, width) + 32) - * sizeof (CHAR_T)); - workend = workstart + (MAX (prec, width) + 32); - } - } - - /* Process format specifiers. */ - while (1) - { - JUMP (spec, step4_jumps); - - process_arg ((&specs[nspecs_done])); - process_string_arg ((&specs[nspecs_done])); - - LABEL (form_unknown): - { - extern printf_function **__printf_function_table; - int function_done; - printf_function *function; - unsigned int i; - const void **ptr; - - function = - (__printf_function_table == NULL ? NULL : - __printf_function_table[specs[nspecs_done].info.spec]); - - if (function == NULL) - function = &printf_unknown; - - ptr = alloca (specs[nspecs_done].ndata_args - * sizeof (const void *)); - - /* Fill in an array of pointers to the argument values. */ - for (i = 0; i < specs[nspecs_done].ndata_args; ++i) - ptr[i] = &args_value[specs[nspecs_done].data_arg + i]; - - /* Call the function. */ - function_done = (*function) (s, &specs[nspecs_done].info, ptr); - - /* If an error occurred we don't have information about # - of chars. */ - if (function_done < 0) - { - done = -1; - goto all_done; - } - - done += function_done; - } - break; - } - - free (workstart); - workstart = NULL; - - /* Write the following constant string. */ - outstring (specs[nspecs_done].end_of_fmt, - specs[nspecs_done].next_fmt - - specs[nspecs_done].end_of_fmt); - } - } - -all_done: - if (__builtin_expect (workstart != NULL, 0)) - free (workstart); - /* Unlock the stream. */ - _IO_funlockfile (s); - _IO_cleanup_region_end (0); - - return done; -} - -/* Handle an unknown format specifier. This prints out a canonicalized - representation of the format spec itself. */ -static int -printf_unknown (FILE *s, const struct printf_info *info, - const void *const *args) - -{ - int done = 0; - CHAR_T work_buffer[MAX (sizeof (info->width), sizeof (info->prec)) * 3]; - CHAR_T *const workend - = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)]; - register CHAR_T *w; - - outchar (L_('%')); - - if (info->alt) - outchar (L_('#')); - if (info->group) - outchar (L_('\'')); - if (info->showsign) - outchar (L_('+')); - else if (info->space) - outchar (L_(' ')); - if (info->left) - outchar (L_('-')); - if (info->pad == L_('0')) - outchar (L_('0')); - if (info->i18n) - outchar (L_('I')); - - if (info->width != 0) - { - w = _itoa_word (info->width, workend, 10, 0); - while (w < workend) - outchar (*w++); - } - - if (info->prec != -1) - { - outchar (L_('.')); - w = _itoa_word (info->prec, workend, 10, 0); - while (w < workend) - outchar (*w++); - } - - if (info->spec != L_('\0')) - outchar (info->spec); - - all_done: - return done; -} - -/* Group the digits according to the grouping rules of the current locale. - The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */ -static CHAR_T * -internal_function -group_number (CHAR_T *w, CHAR_T *rear_ptr, const char *grouping, -#ifdef COMPILE_WPRINTF - wchar_t thousands_sep -#else - const char *thousands_sep -#endif - ) -{ - int len; - CHAR_T *src, *s; -#ifndef COMPILE_WPRINTF - int tlen = strlen (thousands_sep); -#endif - - /* We treat all negative values like CHAR_MAX. */ - - if (*grouping == CHAR_MAX || *grouping <= 0) - /* No grouping should be done. */ - return w; - - len = *grouping++; - - /* Copy existing string so that nothing gets overwritten. */ - src = (CHAR_T *) alloca ((rear_ptr - w) * sizeof (CHAR_T)); - s = (CHAR_T *) __mempcpy (src, w, - (rear_ptr - w) * sizeof (CHAR_T)); - w = rear_ptr; - - /* Process all characters in the string. */ - while (s > src) - { - *--w = *--s; - - if (--len == 0 && s > src) - { - /* A new group begins. */ -#ifdef COMPILE_WPRINTF - *--w = thousands_sep; -#else - int cnt = tlen; - do - *--w = thousands_sep[--cnt]; - while (cnt > 0); -#endif - - if (*grouping == CHAR_MAX -#if CHAR_MIN < 0 - || *grouping < 0 -#endif - ) - { - /* No further grouping to be done. - Copy the rest of the number. */ - do - *--w = *--s; - while (s > src); - break; - } - else if (*grouping != '\0') - /* The previous grouping repeats ad infinitum. */ - len = *grouping++; - else - len = grouping[-1]; - } - } - return w; -} - -/* Helper "class" for `fprintf to unbuffered': creates a temporary buffer. */ -struct helper_file - { - struct _IO_FILE_plus _f; -#ifdef COMPILE_WPRINTF - struct _IO_wide_data _wide_data; -#endif - _IO_FILE *_put_stream; -#ifdef _IO_MTSAFE_IO - _IO_lock_t lock; -#endif - }; - -static int -_IO_helper_overflow (_IO_FILE *s, int c) -{ - _IO_FILE *target = ((struct helper_file*) s)->_put_stream; -#ifdef COMPILE_WPRINTF - int used = s->_wide_data->_IO_write_ptr - s->_wide_data->_IO_write_base; - if (used) - { - _IO_size_t written = _IO_sputn (target, s->_wide_data->_IO_write_base, - used); - s->_wide_data->_IO_write_ptr -= written; - } -#else - int used = s->_IO_write_ptr - s->_IO_write_base; - if (used) - { - _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used); - s->_IO_write_ptr -= written; - } -#endif - return PUTC (c, s); -} - -#ifdef COMPILE_WPRINTF -static const struct _IO_jump_t _IO_helper_jumps = -{ - JUMP_INIT_DUMMY, - JUMP_INIT (finish, INTUSE(_IO_wdefault_finish)), - JUMP_INIT (overflow, _IO_helper_overflow), - JUMP_INIT (underflow, _IO_default_underflow), - JUMP_INIT (uflow, INTUSE(_IO_default_uflow)), - JUMP_INIT (pbackfail, (_IO_pbackfail_t) INTUSE(_IO_wdefault_pbackfail)), - JUMP_INIT (xsputn, INTUSE(_IO_wdefault_xsputn)), - JUMP_INIT (xsgetn, INTUSE(_IO_wdefault_xsgetn)), - JUMP_INIT (seekoff, _IO_default_seekoff), - JUMP_INIT (seekpos, _IO_default_seekpos), - JUMP_INIT (setbuf, _IO_default_setbuf), - JUMP_INIT (sync, _IO_default_sync), - JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)), - JUMP_INIT (read, _IO_default_read), - JUMP_INIT (write, _IO_default_write), - JUMP_INIT (seek, _IO_default_seek), - JUMP_INIT (close, _IO_default_close), - JUMP_INIT (stat, _IO_default_stat) -}; -#else -static const struct _IO_jump_t _IO_helper_jumps = -{ - JUMP_INIT_DUMMY, - JUMP_INIT (finish, INTUSE(_IO_default_finish)), - JUMP_INIT (overflow, _IO_helper_overflow), - JUMP_INIT (underflow, _IO_default_underflow), - JUMP_INIT (uflow, INTUSE(_IO_default_uflow)), - JUMP_INIT (pbackfail, INTUSE(_IO_default_pbackfail)), - JUMP_INIT (xsputn, INTUSE(_IO_default_xsputn)), - JUMP_INIT (xsgetn, INTUSE(_IO_default_xsgetn)), - JUMP_INIT (seekoff, _IO_default_seekoff), - JUMP_INIT (seekpos, _IO_default_seekpos), - JUMP_INIT (setbuf, _IO_default_setbuf), - JUMP_INIT (sync, _IO_default_sync), - JUMP_INIT (doallocate, INTUSE(_IO_default_doallocate)), - JUMP_INIT (read, _IO_default_read), - JUMP_INIT (write, _IO_default_write), - JUMP_INIT (seek, _IO_default_seek), - JUMP_INIT (close, _IO_default_close), - JUMP_INIT (stat, _IO_default_stat) -}; -#endif - -static int -internal_function -buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format, - _IO_va_list args) -{ - CHAR_T buf[_IO_BUFSIZ]; - struct helper_file helper; - register _IO_FILE *hp = (_IO_FILE *) &helper._f; - int result, to_flush; - - /* Orient the stream. */ -#ifdef ORIENT - ORIENT; -#endif - - /* Initialize helper. */ - helper._put_stream = s; -#ifdef COMPILE_WPRINTF - hp->_wide_data = &helper._wide_data; - _IO_wsetp (hp, buf, buf + sizeof buf / sizeof (CHAR_T)); - hp->_mode = 1; -#else - _IO_setp (hp, buf, buf + sizeof buf); - hp->_mode = -1; -#endif - hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS|_IO_USER_LOCK; -#if _IO_JUMPS_OFFSET - hp->_vtable_offset = 0; -#endif -#ifdef _IO_MTSAFE_IO - hp->_lock = NULL; -#endif - hp->_flags2 = s->_flags2; - _IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps; - - /* Now print to helper instead. */ -#ifndef COMPILE_WPRINTF - result = INTUSE(_IO_vfprintf) (hp, format, args); -#else - result = vfprintf (hp, format, args); -#endif - - /* Lock stream. */ - __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, s); - _IO_flockfile (s); - - /* Now flush anything from the helper to the S. */ -#ifdef COMPILE_WPRINTF - if ((to_flush = (hp->_wide_data->_IO_write_ptr - - hp->_wide_data->_IO_write_base)) > 0) - { - if ((int) _IO_sputn (s, hp->_wide_data->_IO_write_base, to_flush) - != to_flush) - result = -1; - } -#else - if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0) - { - if ((int) _IO_sputn (s, hp->_IO_write_base, to_flush) != to_flush) - result = -1; - } -#endif - - /* Unlock the stream. */ - _IO_funlockfile (s); - __libc_cleanup_region_end (0); - - return result; -} - -#undef vfprintf -#ifdef COMPILE_WPRINTF -strong_alias (_IO_vfwprintf, __vfwprintf); -ldbl_weak_alias (_IO_vfwprintf, vfwprintf); -#else -ldbl_strong_alias (_IO_vfprintf_internal, vfprintf); -ldbl_hidden_def (_IO_vfprintf_internal, vfprintf) -ldbl_strong_alias (_IO_vfprintf_internal, _IO_vfprintf); -#endif diff --git a/libc/dfp/sysdeps/dfp/stdio-common/vfscanf.c b/libc/dfp/sysdeps/dfp/stdio-common/vfscanf.c deleted file mode 100644 index ef9d8bdb6..000000000 --- a/libc/dfp/sysdeps/dfp/stdio-common/vfscanf.c +++ /dev/null @@ -1,2924 +0,0 @@ -/* Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <errno.h> -#include <limits.h> -#include <ctype.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <dfpstdlib.h> -#include <string.h> -#include <wchar.h> -#include <wctype.h> -#include <bits/libc-lock.h> -#include <locale/localeinfo.h> - -#ifdef __GNUC__ -# define HAVE_LONGLONG -# define LONGLONG long long -#else -# define LONGLONG long -#endif - -/* Determine whether we have to handle `long long' at all. */ -#if LONG_MAX == LONG_LONG_MAX -# define need_longlong 0 -#else -# define need_longlong 1 -#endif - -/* Determine whether we have to handle `long'. */ -#if INT_MAX == LONG_MAX -# define need_long 0 -#else -# define need_long 1 -#endif - -/* Those are flags in the conversion format. */ -#define LONG 0x0001 /* l: long or double */ -#define LONGDBL 0x0002 /* L: long long or long double */ -#define SHORT 0x0004 /* h: short */ -#define SUPPRESS 0x0008 /* *: suppress assignment */ -#define POINTER 0x0010 /* weird %p pointer (`fake hex') */ -#define NOSKIP 0x0020 /* do not skip blanks */ -#define NUMBER_SIGNED 0x0040 /* signed integer */ -#define GROUP 0x0080 /* ': group numbers */ -#define GNU_MALLOC 0x0100 /* a: malloc strings */ -#define CHAR 0x0200 /* hh: char */ -#define I18N 0x0400 /* I: use locale's digits */ -#define HEXA_FLOAT 0x0800 /* hexadecimal float */ -#define READ_POINTER 0x1000 /* this is a pointer value */ -#define POSIX_MALLOC 0x2000 /* m: malloc strings */ -#define MALLOC (GNU_MALLOC | POSIX_MALLOC) -#define DECIMAL 0x4000 /* H/D/DD: decimal float */ - -#include <locale/localeinfo.h> -#include <libioP.h> -#include <libio.h> - -#undef va_list -#define va_list _IO_va_list - -#ifdef COMPILE_WSCANF -# define ungetc(c, s) ((void) (c == WEOF \ - || (--read_in, \ - INTUSE(_IO_sputbackwc) (s, c)))) -# define ungetc_not_eof(c, s) ((void) (--read_in, \ - INTUSE(_IO_sputbackwc) (s, c))) -# define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \ - : ((c = _IO_getwc_unlocked (s)), \ - (void) (c != WEOF \ - ? ++read_in \ - : (size_t) (inchar_errno = errno)), c)) - -# define MEMCPY(d, s, n) __wmemcpy (d, s, n) -# define ISSPACE(Ch) iswspace (Ch) -# define ISDIGIT(Ch) iswdigit (Ch) -# define ISXDIGIT(Ch) iswxdigit (Ch) -# define TOLOWER(Ch) towlower (Ch) -# define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF -# define __strtoll_internal __wcstoll_internal -# define __strtoull_internal __wcstoull_internal -# define __strtol_internal __wcstol_internal -# define __strtoul_internal __wcstoul_internal -# define __strtold_internal __wcstold_internal -# define __strtod_internal __wcstod_internal -# define __strtof_internal __wcstof_internal - -# define L_(Str) L##Str -# define CHAR_T wchar_t -# define UCHAR_T unsigned int -# define WINT_T wint_t -# undef EOF -# define EOF WEOF -#else -# define ungetc(c, s) ((void) ((int) c == EOF \ - || (--read_in, \ - INTUSE(_IO_sputbackc) (s, (unsigned char) c)))) -# define ungetc_not_eof(c, s) ((void) (--read_in, \ - INTUSE(_IO_sputbackc) (s, (unsigned char) c))) -# define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \ - : ((c = _IO_getc_unlocked (s)), \ - (void) (c != EOF \ - ? ++read_in \ - : (size_t) (inchar_errno = errno)), c)) -# define MEMCPY(d, s, n) memcpy (d, s, n) -# define ISSPACE(Ch) __isspace_l (Ch, loc) -# define ISDIGIT(Ch) __isdigit_l (Ch, loc) -# define ISXDIGIT(Ch) __isxdigit_l (Ch, loc) -# define TOLOWER(Ch) __tolower_l ((unsigned char) (Ch), loc) -# define ORIENT if (_IO_vtable_offset (s) == 0 \ - && _IO_fwide (s, -1) != -1) \ - return EOF - -# define L_(Str) Str -# define CHAR_T char -# define UCHAR_T unsigned char -# define WINT_T int -#endif - -#define encode_error() do { \ - errval = 4; \ - __set_errno (EILSEQ); \ - goto errout; \ - } while (0) -#define conv_error() do { \ - errval = 2; \ - goto errout; \ - } while (0) -#define input_error() do { \ - errval = 1; \ - if (done == 0) done = EOF; \ - goto errout; \ - } while (0) -#define add_ptr_to_free(ptr) \ - do \ - { \ - if (ptrs_to_free == NULL \ - || ptrs_to_free->count == (sizeof (ptrs_to_free->ptrs) \ - / sizeof (ptrs_to_free->ptrs[0]))) \ - { \ - struct ptrs_to_free *new_ptrs = alloca (sizeof (*ptrs_to_free)); \ - new_ptrs->count = 0; \ - new_ptrs->next = ptrs_to_free; \ - ptrs_to_free = new_ptrs; \ - } \ - ptrs_to_free->ptrs[ptrs_to_free->count++] = (ptr); \ - } \ - while (0) -#define ARGCHECK(s, format) \ - do \ - { \ - /* Check file argument for consistence. */ \ - CHECK_FILE (s, EOF); \ - if (s->_flags & _IO_NO_READS) \ - { \ - __set_errno (EBADF); \ - return EOF; \ - } \ - else if (format == NULL) \ - { \ - MAYBE_SET_EINVAL; \ - return EOF; \ - } \ - } while (0) -#define LOCK_STREAM(S) \ - __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \ - _IO_flockfile (S) -#define UNLOCK_STREAM(S) \ - _IO_funlockfile (S); \ - __libc_cleanup_region_end (0) - -struct ptrs_to_free -{ - size_t count; - struct ptrs_to_free *next; - char **ptrs[32]; -}; - -/* Read formatted input from S according to the format string - FORMAT, using the argument list in ARG. - Return the number of assignments made, or -1 for an input error. */ -#ifdef COMPILE_WSCANF -int -_IO_vfwscanf (_IO_FILE *s, const wchar_t *format, _IO_va_list argptr, - int *errp) -#else -int -_IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - int *errp) -#endif -{ - va_list arg; - register const CHAR_T *f = format; - register UCHAR_T fc; /* Current character of the format. */ - register WINT_T done = 0; /* Assignments done. */ - register size_t read_in = 0; /* Chars read in. */ - register WINT_T c = 0; /* Last char read. */ - register int width; /* Maximum field width. */ - register int flags; /* Modifiers for current format element. */ - int errval = 0; -#ifndef COMPILE_WSCANF - __locale_t loc = _NL_CURRENT_LOCALE; - struct locale_data *const curctype = loc->__locales[LC_CTYPE]; -#endif - - /* Errno of last failed inchar call. */ - int inchar_errno = 0; - /* Status for reading F-P nums. */ - char got_dot, got_e, negative; - /* If a [...] is a [^...]. */ - CHAR_T not_in; -#define exp_char not_in - /* Base for integral numbers. */ - int base; - /* Decimal point character. */ -#ifdef COMPILE_WSCANF - wint_t decimal; -#else - const char *decimal; -#endif - /* The thousands character of the current locale. */ -#ifdef COMPILE_WSCANF - wint_t thousands; -#else - const char *thousands; -#endif - struct ptrs_to_free *ptrs_to_free = NULL; - /* State for the conversions. */ - mbstate_t state; - /* Integral holding variables. */ - union - { - long long int q; - unsigned long long int uq; - long int l; - unsigned long int ul; - } num; - /* Character-buffer pointer. */ - char *str = NULL; - wchar_t *wstr = NULL; - char **strptr = NULL; - ssize_t strsize = 0; - /* We must not react on white spaces immediately because they can - possibly be matched even if in the input stream no character is - available anymore. */ - int skip_space = 0; - /* Workspace. */ - CHAR_T *tw; /* Temporary pointer. */ - CHAR_T *wp = NULL; /* Workspace. */ - size_t wpmax = 0; /* Maximal size of workspace. */ - size_t wpsize; /* Currently used bytes in workspace. */ -#define ADDW(Ch) \ - do \ - { \ - if (wpsize == wpmax) \ - { \ - CHAR_T *old = wp; \ - wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \ - wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \ - if (old != NULL) \ - MEMCPY (wp, old, wpsize); \ - } \ - wp[wpsize++] = (Ch); \ - } \ - while (0) - -#ifdef __va_copy - __va_copy (arg, argptr); -#else - arg = (va_list) argptr; -#endif - -#ifdef ORIENT - ORIENT; -#endif - - ARGCHECK (s, format); - - { -#ifndef COMPILE_WSCANF - struct locale_data *const curnumeric = loc->__locales[LC_NUMERIC]; -#endif - - /* Figure out the decimal point character. */ -#ifdef COMPILE_WSCANF - decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC); -#else - decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string; -#endif - /* Figure out the thousands separator character. */ -#ifdef COMPILE_WSCANF - thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC); -#else - thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string; - if (*thousands == '\0') - thousands = NULL; -#endif - } - - /* Lock the stream. */ - LOCK_STREAM (s); - - -#ifndef COMPILE_WSCANF - /* From now on we use `state' to convert the format string. */ - memset (&state, '\0', sizeof (state)); -#endif - - /* Run through the format string. */ - while (*f != '\0') - { - unsigned int argpos; - /* Extract the next argument, which is of type TYPE. - For a %N$... spec, this is the Nth argument from the beginning; - otherwise it is the next argument after the state now in ARG. */ -#ifdef __va_copy -# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \ - ({ unsigned int pos = argpos; \ - va_list arg; \ - __va_copy (arg, argptr); \ - while (--pos > 0) \ - (void) va_arg (arg, void *); \ - va_arg (arg, type); \ - })) -#else -# if 0 - /* XXX Possible optimization. */ -# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \ - ({ va_list arg = (va_list) argptr; \ - arg = (va_list) ((char *) arg \ - + (argpos - 1) \ - * __va_rounded_size (void *)); \ - va_arg (arg, type); \ - })) -# else -# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \ - ({ unsigned int pos = argpos; \ - va_list arg = (va_list) argptr; \ - while (--pos > 0) \ - (void) va_arg (arg, void *); \ - va_arg (arg, type); \ - })) -# endif -#endif - -#ifndef COMPILE_WSCANF - if (!isascii ((unsigned char) *f)) - { - /* Non-ASCII, may be a multibyte. */ - int len = __mbrlen (f, strlen (f), &state); - if (len > 0) - { - do - { - c = inchar (); - if (__builtin_expect (c == EOF, 0)) - input_error (); - else if (c != (unsigned char) *f++) - { - ungetc_not_eof (c, s); - conv_error (); - } - } - while (--len > 0); - continue; - } - } -#endif - - fc = *f++; - if (fc != '%') - { - /* Remember to skip spaces. */ - if (ISSPACE (fc)) - { - skip_space = 1; - continue; - } - - /* Read a character. */ - c = inchar (); - - /* Characters other than format specs must just match. */ - if (__builtin_expect (c == EOF, 0)) - input_error (); - - /* We saw white space char as the last character in the format - string. Now it's time to skip all leading white space. */ - if (skip_space) - { - while (ISSPACE (c)) - if (__builtin_expect (inchar () == EOF, 0)) - input_error (); - skip_space = 0; - } - - if (__builtin_expect (c != fc, 0)) - { - ungetc (c, s); - conv_error (); - } - - continue; - } - - /* This is the start of the conversion string. */ - flags = 0; - - /* Initialize state of modifiers. */ - argpos = 0; - - /* Prepare temporary buffer. */ - wpsize = 0; - - /* Check for a positional parameter specification. */ - if (ISDIGIT ((UCHAR_T) *f)) - { - argpos = (UCHAR_T) *f++ - L_('0'); - while (ISDIGIT ((UCHAR_T) *f)) - argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0')); - if (*f == L_('$')) - ++f; - else - { - /* Oops; that was actually the field width. */ - width = argpos; - argpos = 0; - goto got_width; - } - } - - /* Check for the assignment-suppressing, the number grouping flag, - and the signal to use the locale's digit representation. */ - while (*f == L_('*') || *f == L_('\'') || *f == L_('I')) - switch (*f++) - { - case L_('*'): - flags |= SUPPRESS; - break; - case L_('\''): -#ifdef COMPILE_WSCANF - if (thousands != L'\0') -#else - if (thousands != NULL) -#endif - flags |= GROUP; - break; - case L_('I'): - flags |= I18N; - break; - } - - /* Find the maximum field width. */ - width = 0; - while (ISDIGIT ((UCHAR_T) *f)) - { - width *= 10; - width += (UCHAR_T) *f++ - L_('0'); - } - got_width: - if (width == 0) - width = -1; - - /* Check for type modifiers. */ - switch (*f++) - { - case L_('h'): - /* ints are short ints or chars. */ - if (*f == L_('h')) - { - ++f; - flags |= CHAR; - } - else - flags |= SHORT; - break; - case L_('l'): - if (*f == L_('l')) - { - /* A double `l' is equivalent to an `L'. */ - ++f; - flags |= LONGDBL | LONG; - } - else - /* ints are long ints. */ - flags |= LONG; - break; - case L_('q'): - case L_('L'): - /* doubles are long doubles, and ints are long long ints. */ - flags |= LONGDBL | LONG; - break; - case L_('a'): - /* The `a' is used as a flag only if followed by `s', `S' or - `['. */ - if (*f != L_('s') && *f != L_('S') && *f != L_('[')) - { - --f; - break; - } - /* In __isoc99_*scanf %as, %aS and %a[ extension is not - supported at all. */ - if (s->_flags2 & _IO_FLAGS2_SCANF_STD) - { - --f; - break; - } - /* String conversions (%s, %[) take a `char **' - arg and fill it in with a malloc'd pointer. */ - flags |= GNU_MALLOC; - break; - case L_('m'): - flags |= POSIX_MALLOC; - if (*f == L_('l')) - { - ++f; - flags |= LONG; - } - break; - case L_('z'): - if (need_longlong && sizeof (size_t) > sizeof (unsigned long int)) - flags |= LONGDBL; - else if (sizeof (size_t) > sizeof (unsigned int)) - flags |= LONG; - break; - case L_('j'): - if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int)) - flags |= LONGDBL; - else if (sizeof (uintmax_t) > sizeof (unsigned int)) - flags |= LONG; - break; - case L_('t'): - if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int)) - flags |= LONGDBL; - else if (sizeof (ptrdiff_t) > sizeof (int)) - flags |= LONG; - break; - default: - /* Not a recognized modifier. Backup. */ - --f; - break; - } - - /* End of the format string? */ - if (__builtin_expect (*f == L_('\0'), 0)) - conv_error (); - - /* Find the conversion specifier. */ - fc = *f++; - if (skip_space || (fc != L_('[') && fc != L_('c') - && fc != L_('C') && fc != L_('n'))) - { - /* Eat whitespace. */ - int save_errno = errno; - __set_errno (0); - do - /* We add the additional test for EOF here since otherwise - inchar will restore the old errno value which might be - EINTR but does not indicate an interrupt since nothing - was read at this time. */ - if (__builtin_expect ((c == EOF || inchar () == EOF) - && errno == EINTR, 0)) - input_error (); - while (ISSPACE (c)); - __set_errno (save_errno); - ungetc (c, s); - skip_space = 0; - } - -found_decimal: - switch (fc) - { - case L_('%'): /* Must match a literal '%'. */ - c = inchar (); - if (__builtin_expect (c == EOF, 0)) - input_error (); - if (__builtin_expect (c != fc, 0)) - { - ungetc_not_eof (c, s); - conv_error (); - } - break; - - case L_('n'): /* Answer number of assignments done. */ - /* Corrigendum 1 to ISO C 1990 describes the allowed flags - with the 'n' conversion specifier. */ - if (!(flags & SUPPRESS)) - { - /* Don't count the read-ahead. */ - if (need_longlong && (flags & LONGDBL)) - *ARG (long long int *) = read_in; - else if (need_long && (flags & LONG)) - *ARG (long int *) = read_in; - else if (flags & SHORT) - *ARG (short int *) = read_in; - else if (!(flags & CHAR)) - *ARG (int *) = read_in; - else - *ARG (char *) = read_in; - -#ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1 - /* We have a severe problem here. The ISO C standard - contradicts itself in explaining the effect of the %n - format in `scanf'. While in ISO C:1990 and the ISO C - Amendement 1:1995 the result is described as - - Execution of a %n directive does not effect the - assignment count returned at the completion of - execution of the f(w)scanf function. - - in ISO C Corrigendum 1:1994 the following was added: - - Subclause 7.9.6.2 - Add the following fourth example: - In: - #include <stdio.h> - int d1, d2, n1, n2, i; - i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2); - the value 123 is assigned to d1 and the value3 to n1. - Because %n can never get an input failure the value - of 3 is also assigned to n2. The value of d2 is not - affected. The value 3 is assigned to i. - - We go for now with the historically correct code from ISO C, - i.e., we don't count the %n assignments. When it ever - should proof to be wrong just remove the #ifdef above. */ - ++done; -#endif - } - break; - - case L_('c'): /* Match characters. */ - if ((flags & LONG) == 0) - { - if (width == -1) - width = 1; - -#define STRING_ARG(Str, Type, Width) \ - do if (!(flags & SUPPRESS)) \ - { \ - if (flags & MALLOC) \ - { \ - /* The string is to be stored in a malloc'd buffer. */ \ - /* For %mS using char ** is actually wrong, but \ - shouldn't make a difference on any arch glibc \ - supports and would unnecessarily complicate \ - things. */ \ - strptr = ARG (char **); \ - if (strptr == NULL) \ - conv_error (); \ - /* Allocate an initial buffer. */ \ - strsize = Width; \ - *strptr = (char *) malloc (strsize * sizeof (Type)); \ - Str = (Type *) *strptr; \ - if (Str != NULL) \ - add_ptr_to_free (strptr); \ - else if (flags & POSIX_MALLOC) \ - goto reteof; \ - } \ - else \ - Str = ARG (Type *); \ - if (Str == NULL) \ - conv_error (); \ - } while (0) -#ifdef COMPILE_WSCANF - STRING_ARG (str, char, 100); -#else - STRING_ARG (str, char, (width > 1024 ? 1024 : width)); -#endif - - c = inchar (); - if (__builtin_expect (c == EOF, 0)) - input_error (); - -#ifdef COMPILE_WSCANF - /* We have to convert the wide character(s) into multibyte - characters and store the result. */ - memset (&state, '\0', sizeof (state)); - - do - { - size_t n; - - if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC) - && str + MB_CUR_MAX >= *strptr + strsize) - { - /* We have to enlarge the buffer if the `m' flag - was given. */ - size_t strleng = str - *strptr; - char *newstr; - - newstr = (char *) realloc (*strptr, strsize * 2); - if (newstr == NULL) - { - /* Can't allocate that much. Last-ditch effort. */ - newstr = (char *) realloc (*strptr, - strleng + MB_CUR_MAX); - if (newstr == NULL) - /* c can't have `a' flag, only `m'. */ - goto reteof; - else - { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + MB_CUR_MAX; - } - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize *= 2; - } - } - - n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); - if (__builtin_expect (n == (size_t) -1, 0)) - /* No valid wide character. */ - input_error (); - - /* Increment the output pointer. Even if we don't - write anything. */ - str += n; - } - while (--width > 0 && inchar () != EOF); -#else - if (!(flags & SUPPRESS)) - { - do - { - if ((flags & MALLOC) - && (char *) str == *strptr + strsize) - { - /* Enlarge the buffer. */ - size_t newsize - = strsize - + (strsize >= width ? width - 1 : strsize); - - str = (char *) realloc (*strptr, newsize); - if (str == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - str = (char *) realloc (*strptr, strsize + 1); - if (str == NULL) - /* c can't have `a' flag, only `m'. */ - goto reteof; - else - { - *strptr = (char *) str; - str += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) str; - str += strsize; - strsize = newsize; - } - } - *str++ = c; - } - while (--width > 0 && inchar () != EOF); - } - else - while (--width > 0 && inchar () != EOF); -#endif - - if (!(flags & SUPPRESS)) - { - if ((flags & MALLOC) && str - *strptr != strsize) - { - char *cp = (char *) realloc (*strptr, str - *strptr); - if (cp != NULL) - *strptr = cp; - } - strptr = NULL; - ++done; - } - - break; - } - /* FALLTHROUGH */ - case L_('C'): - if (width == -1) - width = 1; - - STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width)); - - c = inchar (); - if (__builtin_expect (c == EOF, 0)) - input_error (); - -#ifdef COMPILE_WSCANF - /* Just store the incoming wide characters. */ - if (!(flags & SUPPRESS)) - { - do - { - if ((flags & MALLOC) - && wstr == (wchar_t *) *strptr + strsize) - { - size_t newsize - = strsize + (strsize > width ? width - 1 : strsize); - /* Enlarge the buffer. */ - wstr = (wchar_t *) realloc (*strptr, - newsize * sizeof (wchar_t)); - if (wstr == NULL) - { - /* Can't allocate that much. Last-ditch effort. */ - wstr = (wchar_t *) realloc (*strptr, - (strsize + 1) - * sizeof (wchar_t)); - if (wstr == NULL) - /* C or lc can't have `a' flag, only `m' flag. */ - goto reteof; - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - strsize = newsize; - } - } - *wstr++ = c; - } - while (--width > 0 && inchar () != EOF); - } - else - while (--width > 0 && inchar () != EOF); -#else - { - /* We have to convert the multibyte input sequence to wide - characters. */ - char buf[1]; - mbstate_t cstate; - - memset (&cstate, '\0', sizeof (cstate)); - - do - { - /* This is what we present the mbrtowc function first. */ - buf[0] = c; - - if (!(flags & SUPPRESS) && (flags & MALLOC) - && wstr == (wchar_t *) *strptr + strsize) - { - size_t newsize - = strsize + (strsize > width ? width - 1 : strsize); - /* Enlarge the buffer. */ - wstr = (wchar_t *) realloc (*strptr, - newsize * sizeof (wchar_t)); - if (wstr == NULL) - { - /* Can't allocate that much. Last-ditch effort. */ - wstr = (wchar_t *) realloc (*strptr, - ((strsize + 1) - * sizeof (wchar_t))); - if (wstr == NULL) - /* C or lc can't have `a' flag, only `m' flag. */ - goto reteof; - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - strsize = newsize; - } - } - - while (1) - { - size_t n; - - n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL, - buf, 1, &cstate); - - if (n == (size_t) -2) - { - /* Possibly correct character, just not enough - input. */ - if (__builtin_expect (inchar () == EOF, 0)) - encode_error (); - - buf[0] = c; - continue; - } - - if (__builtin_expect (n != 1, 0)) - encode_error (); - - /* We have a match. */ - break; - } - - /* Advance the result pointer. */ - ++wstr; - } - while (--width > 0 && inchar () != EOF); - } -#endif - - if (!(flags & SUPPRESS)) - { - if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize) - { - wchar_t *cp = (wchar_t *) realloc (*strptr, - ((wstr - - (wchar_t *) *strptr) - * sizeof (wchar_t))); - if (cp != NULL) - *strptr = (char *) cp; - } - strptr = NULL; - - ++done; - } - - break; - - case L_('s'): /* Read a string. */ - if (!(flags & LONG)) - { - STRING_ARG (str, char, 100); - - c = inchar (); - if (__builtin_expect (c == EOF, 0)) - input_error (); - -#ifdef COMPILE_WSCANF - memset (&state, '\0', sizeof (state)); -#endif - - do - { - if (ISSPACE (c)) - { - ungetc_not_eof (c, s); - break; - } - -#ifdef COMPILE_WSCANF - /* This is quite complicated. We have to convert the - wide characters into multibyte characters and then - store them. */ - { - size_t n; - - if (!(flags & SUPPRESS) && (flags & MALLOC) - && str + MB_CUR_MAX >= *strptr + strsize) - { - /* We have to enlarge the buffer if the `a' or `m' - flag was given. */ - size_t strleng = str - *strptr; - char *newstr; - - newstr = (char *) realloc (*strptr, strsize * 2); - if (newstr == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - newstr = (char *) realloc (*strptr, - strleng + MB_CUR_MAX); - if (newstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the - string and stop converting, - so at least we don't skip any input. */ - ((char *) (*strptr))[strleng] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + MB_CUR_MAX; - } - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize *= 2; - } - } - - n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, - &state); - if (__builtin_expect (n == (size_t) -1, 0)) - encode_error (); - - assert (n <= MB_CUR_MAX); - str += n; - } -#else - /* This is easy. */ - if (!(flags & SUPPRESS)) - { - *str++ = c; - if ((flags & MALLOC) - && (char *) str == *strptr + strsize) - { - /* Enlarge the buffer. */ - str = (char *) realloc (*strptr, 2 * strsize); - if (str == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - str = (char *) realloc (*strptr, strsize + 1); - if (str == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the - string and stop converting, - so at least we don't skip any input. */ - ((char *) (*strptr))[strsize - 1] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = (char *) str; - str += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) str; - str += strsize; - strsize *= 2; - } - } - } -#endif - } - while ((width <= 0 || --width > 0) && inchar () != EOF); - - if (!(flags & SUPPRESS)) - { -#ifdef COMPILE_WSCANF - /* We have to emit the code to get into the initial - state. */ - char buf[MB_LEN_MAX]; - size_t n = __wcrtomb (buf, L'\0', &state); - if (n > 0 && (flags & MALLOC) - && str + n >= *strptr + strsize) - { - /* Enlarge the buffer. */ - size_t strleng = str - *strptr; - char *newstr; - - newstr = (char *) realloc (*strptr, strleng + n + 1); - if (newstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((char *) (*strptr))[strleng] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + n + 1; - } - } - - str = __mempcpy (str, buf, n); -#endif - *str++ = '\0'; - - if ((flags & MALLOC) && str - *strptr != strsize) - { - char *cp = (char *) realloc (*strptr, str - *strptr); - if (cp != NULL) - *strptr = cp; - } - strptr = NULL; - - ++done; - } - break; - } - /* FALLTHROUGH */ - - case L_('S'): - { -#ifndef COMPILE_WSCANF - mbstate_t cstate; -#endif - - /* Wide character string. */ - STRING_ARG (wstr, wchar_t, 100); - - c = inchar (); - if (__builtin_expect (c == EOF, 0)) - input_error (); - -#ifndef COMPILE_WSCANF - memset (&cstate, '\0', sizeof (cstate)); -#endif - - do - { - if (ISSPACE (c)) - { - ungetc_not_eof (c, s); - break; - } - -#ifdef COMPILE_WSCANF - /* This is easy. */ - if (!(flags & SUPPRESS)) - { - *wstr++ = c; - if ((flags & MALLOC) - && wstr == (wchar_t *) *strptr + strsize) - { - /* Enlarge the buffer. */ - wstr = (wchar_t *) realloc (*strptr, - (2 * strsize) - * sizeof (wchar_t)); - if (wstr == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - wstr = (wchar_t *) realloc (*strptr, - (strsize + 1) - * sizeof (wchar_t)); - if (wstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - strsize *= 2; - } - } - } -#else - { - char buf[1]; - - buf[0] = c; - - while (1) - { - size_t n; - - n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL, - buf, 1, &cstate); - - if (n == (size_t) -2) - { - /* Possibly correct character, just not enough - input. */ - if (__builtin_expect (inchar () == EOF, 0)) - encode_error (); - - buf[0] = c; - continue; - } - - if (__builtin_expect (n != 1, 0)) - encode_error (); - - /* We have a match. */ - ++wstr; - break; - } - - if (!(flags & SUPPRESS) && (flags & MALLOC) - && wstr == (wchar_t *) *strptr + strsize) - { - /* Enlarge the buffer. */ - wstr = (wchar_t *) realloc (*strptr, - (2 * strsize - * sizeof (wchar_t))); - if (wstr == NULL) - { - /* Can't allocate that much. Last-ditch effort. */ - wstr = (wchar_t *) realloc (*strptr, - ((strsize + 1) - * sizeof (wchar_t))); - if (wstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the - string and stop converting, so at - least we don't skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - strsize *= 2; - } - } - } -#endif - } - while ((width <= 0 || --width > 0) && inchar () != EOF); - - if (!(flags & SUPPRESS)) - { - *wstr++ = L'\0'; - - if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize) - { - wchar_t *cp = (wchar_t *) realloc (*strptr, - ((wstr - - (wchar_t *) *strptr) - * sizeof(wchar_t))); - if (cp != NULL) - *strptr = (char *) cp; - } - strptr = NULL; - - ++done; - } - } - break; - - case L_('x'): /* Hexadecimal integer. */ - case L_('X'): /* Ditto. */ - base = 16; - goto number; - - case L_('o'): /* Octal integer. */ - base = 8; - goto number; - - case L_('u'): /* Unsigned decimal integer. */ - base = 10; - goto number; - - case L_('d'): /* Signed decimal integer. */ - base = 10; - flags |= NUMBER_SIGNED; - goto number; - - case L_('i'): /* Generic number. */ - base = 0; - flags |= NUMBER_SIGNED; - - number: - c = inchar (); - if (__builtin_expect (c == EOF, 0)) - input_error (); - - /* Check for a sign. */ - if (c == L_('-') || c == L_('+')) - { - ADDW (c); - if (width > 0) - --width; - c = inchar (); - } - - /* Look for a leading indication of base. */ - if (width != 0 && c == L_('0')) - { - if (width > 0) - --width; - - ADDW (c); - c = inchar (); - - if (width != 0 && TOLOWER (c) == L_('x')) - { - if (base == 0) - base = 16; - if (base == 16) - { - if (width > 0) - --width; - c = inchar (); - } - } - else if (base == 0) - base = 8; - } - - if (base == 0) - base = 10; - - if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0)) - { - int from_level; - int to_level; - int level; -#ifdef COMPILE_WSCANF - const wchar_t *wcdigits[10]; - const wchar_t *wcdigits_extended[10]; -#else - const char *mbdigits[10]; - const char *mbdigits_extended[10]; -#endif - /* "to_inpunct" is a map from ASCII digits to their - equivalent in locale. This is defined for locales - which use an extra digits set. */ - wctrans_t map = __wctrans ("to_inpunct"); - int n; - - from_level = 0; -#ifdef COMPILE_WSCANF - to_level = _NL_CURRENT_WORD (LC_CTYPE, - _NL_CTYPE_INDIGITS_WC_LEN) - 1; -#else - to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1; -#endif - - /* Get the alternative digit forms if there are any. */ - if (__builtin_expect (map != NULL, 0)) - { - /* Adding new level for extra digits set in locale file. */ - ++to_level; - - for (n = 0; n < 10; ++n) - { -#ifdef COMPILE_WSCANF - wcdigits[n] = (const wchar_t *) - _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n); - - wchar_t *wc_extended = (wchar_t *) - alloca ((to_level + 2) * sizeof (wchar_t)); - __wmemcpy (wc_extended, wcdigits[n], to_level); - wc_extended[to_level] = __towctrans (L'0' + n, map); - wc_extended[to_level + 1] = '\0'; - wcdigits_extended[n] = wc_extended; -#else - mbdigits[n] - = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string; - - /* Get the equivalent wide char in map. */ - wint_t extra_wcdigit = __towctrans (L'0' + n, map); - - /* Convert it to multibyte representation. */ - mbstate_t state; - memset (&state, '\0', sizeof (state)); - - char extra_mbdigit[MB_LEN_MAX]; - size_t mblen - = __wcrtomb (extra_mbdigit, extra_wcdigit, &state); - - if (mblen == (size_t) -1) - { - /* Ignore this new level. */ - map = NULL; - break; - } - - /* Calculate the length of mbdigits[n]. */ - const char *last_char = mbdigits[n]; - for (level = 0; level < to_level; ++level) - last_char = strchr (last_char, '\0') + 1; - - size_t mbdigits_len = last_char - mbdigits[n]; - - /* Allocate memory for extended multibyte digit. */ - char *mb_extended; - mb_extended = (char *) alloca (mbdigits_len + mblen + 1); - - /* And get the mbdigits + extra_digit string. */ - *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n], - mbdigits_len), - extra_mbdigit, mblen) = '\0'; - mbdigits_extended[n] = mb_extended; -#endif - } - } - - /* Read the number into workspace. */ - while (c != EOF && width != 0) - { - /* In this round we get the pointer to the digit strings - and also perform the first round of comparisons. */ - for (n = 0; n < 10; ++n) - { - /* Get the string for the digits with value N. */ -#ifdef COMPILE_WSCANF - if (__builtin_expect (map != NULL, 0)) - wcdigits[n] = wcdigits_extended[n]; - else - wcdigits[n] = (const wchar_t *) - _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n); - wcdigits[n] += from_level; - - if (c == (wint_t) *wcdigits[n]) - { - to_level = from_level; - break; - } - - /* Advance the pointer to the next string. */ - ++wcdigits[n]; -#else - const char *cmpp; - int avail = width > 0 ? width : INT_MAX; - - if (__builtin_expect (map != NULL, 0)) - mbdigits[n] = mbdigits_extended[n]; - else - mbdigits[n] - = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string; - - for (level = 0; level < from_level; level++) - mbdigits[n] = strchr (mbdigits[n], '\0') + 1; - - cmpp = mbdigits[n]; - while ((unsigned char) *cmpp == c && avail >= 0) - { - if (*++cmpp == '\0') - break; - else - { - if (avail == 0 || inchar () == EOF) - break; - --avail; - } - } - - if (*cmpp == '\0') - { - if (width > 0) - width = avail; - to_level = from_level; - break; - } - - /* We are pushing all read characters back. */ - if (cmpp > mbdigits[n]) - { - ungetc (c, s); - while (--cmpp > mbdigits[n]) - ungetc_not_eof ((unsigned char) *cmpp, s); - c = (unsigned char) *cmpp; - } - - /* Advance the pointer to the next string. */ - mbdigits[n] = strchr (mbdigits[n], '\0') + 1; -#endif - } - - if (n == 10) - { - /* Have not yet found the digit. */ - for (level = from_level + 1; level <= to_level; ++level) - { - /* Search all ten digits of this level. */ - for (n = 0; n < 10; ++n) - { -#ifdef COMPILE_WSCANF - if (c == (wint_t) *wcdigits[n]) - break; - - /* Advance the pointer to the next string. */ - ++wcdigits[n]; -#else - const char *cmpp; - int avail = width > 0 ? width : INT_MAX; - - cmpp = mbdigits[n]; - while ((unsigned char) *cmpp == c && avail >= 0) - { - if (*++cmpp == '\0') - break; - else - { - if (avail == 0 || inchar () == EOF) - break; - --avail; - } - } - - if (*cmpp == '\0') - { - if (width > 0) - width = avail; - break; - } - - /* We are pushing all read characters back. */ - if (cmpp > mbdigits[n]) - { - ungetc (c, s); - while (--cmpp > mbdigits[n]) - ungetc_not_eof ((unsigned char) *cmpp, s); - c = (unsigned char) *cmpp; - } - - /* Advance the pointer to the next string. */ - mbdigits[n] = strchr (mbdigits[n], '\0') + 1; -#endif - } - - if (n < 10) - { - /* Found it. */ - from_level = level; - to_level = level; - break; - } - } - } - - if (n < 10) - c = L_('0') + n; - else if (flags & GROUP) - { - /* Try matching against the thousands separator. */ -#ifdef COMPILE_WSCANF - if (c != thousands) - break; -#else - const char *cmpp = thousands; - int avail = width > 0 ? width : INT_MAX; - - while ((unsigned char) *cmpp == c && avail >= 0) - { - ADDW (c); - if (*++cmpp == '\0') - break; - else - { - if (avail == 0 || inchar () == EOF) - break; - --avail; - } - } - - if (*cmpp != '\0') - { - /* We are pushing all read characters back. */ - if (cmpp > thousands) - { - wpsize -= cmpp - thousands; - ungetc (c, s); - while (--cmpp > thousands) - ungetc_not_eof ((unsigned char) *cmpp, s); - c = (unsigned char) *cmpp; - } - break; - } - - if (width > 0) - width = avail; - - /* The last thousands character will be added back by - the ADDW below. */ - --wpsize; -#endif - } - else - break; - - ADDW (c); - if (width > 0) - --width; - - c = inchar (); - } - } - else - /* Read the number into workspace. */ - while (c != EOF && width != 0) - { - if (base == 16) - { - if (!ISXDIGIT (c)) - break; - } - else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base) - { - if (base == 10 && (flags & GROUP)) - { - /* Try matching against the thousands separator. */ -#ifdef COMPILE_WSCANF - if (c != thousands) - break; -#else - const char *cmpp = thousands; - int avail = width > 0 ? width : INT_MAX; - - while ((unsigned char) *cmpp == c && avail >= 0) - { - ADDW (c); - if (*++cmpp == '\0') - break; - else - { - if (avail == 0 || inchar () == EOF) - break; - --avail; - } - } - - if (*cmpp != '\0') - { - /* We are pushing all read characters back. */ - if (cmpp > thousands) - { - wpsize -= cmpp - thousands; - ungetc (c, s); - while (--cmpp > thousands) - ungetc_not_eof ((unsigned char) *cmpp, s); - c = (unsigned char) *cmpp; - } - break; - } - - if (width > 0) - width = avail; - - /* The last thousands character will be added back by - the ADDW below. */ - --wpsize; -#endif - } - else - break; - } - ADDW (c); - if (width > 0) - --width; - - c = inchar (); - } - - if (wpsize == 0 - || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-')))) - { - /* There was no number. If we are supposed to read a pointer - we must recognize "(nil)" as well. */ - if (__builtin_expect (wpsize == 0 - && (flags & READ_POINTER) - && (width < 0 || width >= 0) - && c == '(' - && TOLOWER (inchar ()) == L_('n') - && TOLOWER (inchar ()) == L_('i') - && TOLOWER (inchar ()) == L_('l') - && inchar () == L_(')'), 1)) - /* We must produce the value of a NULL pointer. A single - '0' digit is enough. */ - ADDW (L_('0')); - else - { - /* The last read character is not part of the number - anymore. */ - ungetc (c, s); - - conv_error (); - } - } - else - /* The just read character is not part of the number anymore. */ - ungetc (c, s); - - /* Convert the number. */ - ADDW (L_('\0')); - if (need_longlong && (flags & LONGDBL)) - { - if (flags & NUMBER_SIGNED) - num.q = __strtoll_internal (wp, &tw, base, flags & GROUP); - else - num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP); - } - else - { - if (flags & NUMBER_SIGNED) - num.l = __strtol_internal (wp, &tw, base, flags & GROUP); - else - num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP); - } - if (__builtin_expect (wp == tw, 0)) - conv_error (); - - if (!(flags & SUPPRESS)) - { - if (flags & NUMBER_SIGNED) - { - if (need_longlong && (flags & LONGDBL)) - *ARG (LONGLONG int *) = num.q; - else if (need_long && (flags & LONG)) - *ARG (long int *) = num.l; - else if (flags & SHORT) - *ARG (short int *) = (short int) num.l; - else if (!(flags & CHAR)) - *ARG (int *) = (int) num.l; - else - *ARG (signed char *) = (signed char) num.ul; - } - else - { - if (need_longlong && (flags & LONGDBL)) - *ARG (unsigned LONGLONG int *) = num.uq; - else if (need_long && (flags & LONG)) - *ARG (unsigned long int *) = num.ul; - else if (flags & SHORT) - *ARG (unsigned short int *) - = (unsigned short int) num.ul; - else if (!(flags & CHAR)) - *ARG (unsigned int *) = (unsigned int) num.ul; - else - *ARG (unsigned char *) = (unsigned char) num.ul; - } - ++done; - } - break; - - case L_('H'): /* _Decimal32 */ - base = 10; - /*number_signed = 1;*/ - negative = 1; - flags |= DECIMAL | SHORT; - fc = *f++; - /* Pick up trailing float modifier. */ - goto found_decimal; - - case L_('D'): /* _Decimal64 */ - flags |= DECIMAL; - base = 10; - /*number_signed = 1;*/ - negative = 1; - char tfc; - tfc = *f++; - if (tfc == L_('D')) /* _Decimal128 */ - flags |= LONGDBL; - else - --f; /* Only one 'D'. Back it up. It is not %DD. */ - fc = *f++; - /* Pick up trailing float modifier. */ - goto found_decimal; - - case L_('e'): /* Floating-point numbers. */ - case L_('E'): - case L_('f'): - case L_('F'): - case L_('g'): - case L_('G'): - case L_('a'): - case L_('A'): - c = inchar (); - if (width > 0) - --width; - if (__builtin_expect (c == EOF, 0)) - input_error (); - - got_dot = got_e = 0; - - /* Check for a sign. */ - if (c == L_('-') || c == L_('+')) - { - negative = c == L_('-'); - if (__builtin_expect (width == 0 || inchar () == EOF, 0)) - /* EOF is only an input error before we read any chars. */ - conv_error (); - if (width > 0) - --width; - } - else - negative = 0; - - /* Take care for the special arguments "nan" and "inf". */ - if (TOLOWER (c) == L_('n')) - { - /* Maybe "nan". */ - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('a'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('n'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - /* It is "nan". */ - goto scan_float; - } - else if (TOLOWER (c) == L_('i')) - { - /* Maybe "inf" or "infinity". */ - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('n'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('f'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - /* It is as least "inf". */ - if (width != 0 && inchar () != EOF) - { - if (TOLOWER (c) == L_('i')) - { - if (width > 0) - --width; - /* Now we have to read the rest as well. */ - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('n'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('i'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('t'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - if (__builtin_expect (width == 0 - || inchar () == EOF - || TOLOWER (c) != L_('y'), 0)) - conv_error (); - if (width > 0) - --width; - ADDW (c); - } - else - /* Never mind. */ - ungetc (c, s); - } - goto scan_float; - } - - exp_char = L_('e'); - if (width != 0 && c == L_('0')) - { - ADDW (c); - c = inchar (); - if (width > 0) - --width; - if (width != 0 && TOLOWER (c) == L_('x')) - { - /* It is a number in hexadecimal format. */ - ADDW (c); - - flags |= HEXA_FLOAT; - exp_char = L_('p'); - - /* Grouping is not allowed. */ - flags &= ~GROUP; - c = inchar (); - if (width > 0) - --width; - } - } - - while (1) - { - if (ISDIGIT (c)) - ADDW (c); - else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c)) - ADDW (c); - else if (got_e && wp[wpsize - 1] == exp_char - && (c == L_('-') || c == L_('+'))) - ADDW (c); - else if (wpsize > 0 && !got_e - && (CHAR_T) TOLOWER (c) == exp_char) - { - ADDW (exp_char); - got_e = got_dot = 1; - } - else - { -#ifdef COMPILE_WSCANF - if (! got_dot && c == decimal) - { - ADDW (c); - got_dot = 1; - } - else if ((flags & GROUP) != 0 && ! got_dot && c == thousands) - ADDW (c); - else - { - /* The last read character is not part of the number - anymore. */ - ungetc (c, s); - break; - } -#else - const char *cmpp = decimal; - int avail = width > 0 ? width : INT_MAX; - - if (! got_dot) - { - while ((unsigned char) *cmpp == c && avail >= 0) - if (*++cmpp == '\0') - break; - else - { - if (avail == 0 || inchar () == EOF) - break; - --avail; - } - } - - if (*cmpp == '\0') - { - /* Add all the characters. */ - for (cmpp = decimal; *cmpp != '\0'; ++cmpp) - ADDW ((unsigned char) *cmpp); - if (width > 0) - width = avail; - got_dot = 1; - } - else - { - /* Figure out whether it is a thousands separator. - There is one problem: we possibly read more than - one character. We cannot push them back but since - we know that parts of the `decimal' string matched, - we can compare against it. */ - const char *cmp2p = thousands; - - if ((flags & GROUP) != 0 && ! got_dot) - { - while (cmp2p - thousands < cmpp - decimal - && *cmp2p == decimal[cmp2p - thousands]) - ++cmp2p; - if (cmp2p - thousands == cmpp - decimal) - { - while ((unsigned char) *cmp2p == c && avail >= 0) - if (*++cmp2p == '\0') - break; - else - { - if (avail == 0 || inchar () == EOF) - break; - --avail; - } - } - } - - if (cmp2p != NULL && *cmp2p == '\0') - { - /* Add all the characters. */ - for (cmpp = thousands; *cmpp != '\0'; ++cmpp) - ADDW ((unsigned char) *cmpp); - if (width > 0) - width = avail; - } - else - { - /* The last read character is not part of the number - anymore. */ - ungetc (c, s); - break; - } - } -#endif - } - - if (width == 0 || inchar () == EOF) - break; - - if (width > 0) - --width; - } - - wctrans_t map; - if (__builtin_expect ((flags & I18N) != 0, 0) - /* Hexadecimal floats make no sense, fixing localized - digits with ASCII letters. */ - && !(flags & HEXA_FLOAT) - /* Minimum requirement. */ - && (wpsize == 0 || got_dot) - && (map = __wctrans ("to_inpunct")) != NULL) - { - /* Reget the first character. */ - inchar (); - - /* Localized digits, decimal points, and thousands - separator. */ - wint_t wcdigits[12]; - - /* First get decimal equivalent to check if we read it - or not. */ - wcdigits[11] = __towctrans (L'.', map); - - /* If we have not read any character or have just read - locale decimal point which matches the decimal point - for localized FP numbers, then we may have localized - digits. Note, we test GOT_DOT above. */ -#ifdef COMPILE_WSCANF - if (wpsize == 0 || (wpsize == 1 && wcdigits[11] == decimal)) -#else - char mbdigits[12][MB_LEN_MAX + 1]; - - mbstate_t state; - memset (&state, '\0', sizeof (state)); - - bool match_so_far = wpsize == 0; - size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &state); - if (mblen != (size_t) -1) - { - mbdigits[11][mblen] = '\0'; - match_so_far |= (wpsize == strlen (decimal) - && strcmp (decimal, mbdigits[11]) == 0); - } - else - { - size_t decimal_len = strlen (decimal); - /* This should always be the case but the data comes - from a file. */ - if (decimal_len <= MB_LEN_MAX) - { - match_so_far |= wpsize == decimal_len; - memcpy (mbdigits[11], decimal, decimal_len + 1); - } - else - match_so_far = false; - } - - if (match_so_far) -#endif - { - bool have_locthousands = (flags & GROUP) != 0; - - /* Now get the digits and the thousands-sep equivalents. */ - for (int n = 0; n < 11; ++n) - { - if (n < 10) - wcdigits[n] = __towctrans (L'0' + n, map); - else if (n == 10) - { - wcdigits[10] = __towctrans (L',', map); - have_locthousands &= wcdigits[10] != L'\0'; - } - -#ifndef COMPILE_WSCANF - memset (&state, '\0', sizeof (state)); - - size_t mblen = __wcrtomb (mbdigits[n], wcdigits[n], - &state); - if (mblen == (size_t) -1) - { - if (n == 10) - { - if (have_locthousands) - { - size_t thousands_len = strlen (thousands); - if (thousands_len <= MB_LEN_MAX) - memcpy (mbdigits[10], thousands, - thousands_len + 1); - else - have_locthousands = false; - } - } - else - /* Ignore checking against localized digits. */ - goto no_i18nflt; - } - else - mbdigits[n][mblen] = '\0'; -#endif - } - - /* Start checking against localized digits, if - convertion is done correctly. */ - while (1) - { - if (got_e && wp[wpsize - 1] == exp_char - && (c == L_('-') || c == L_('+'))) - ADDW (c); - else if (wpsize > 0 && !got_e - && (CHAR_T) TOLOWER (c) == exp_char) - { - ADDW (exp_char); - got_e = got_dot = 1; - } - else - { - /* Check against localized digits, decimal point, - and thousands separator. */ - int n; - for (n = 0; n < 12; ++n) - { -#ifdef COMPILE_WSCANF - if (c == wcdigits[n]) - { - if (n < 10) - ADDW (L_('0') + n); - else if (n == 11 && !got_dot) - { - ADDW (decimal); - got_dot = 1; - } - else if (n == 10 && have_locthousands - && ! got_dot) - ADDW (thousands); - else - /* The last read character is not part - of the number anymore. */ - n = 12; - - break; - } -#else - const char *cmpp = mbdigits[n]; - int avail = width > 0 ? width : INT_MAX; - - while ((unsigned char) *cmpp == c && avail >= 0) - if (*++cmpp == '\0') - break; - else - { - if (avail == 0 || inchar () == EOF) - break; - --avail; - } - if (*cmpp == '\0') - { - if (width > 0) - width = avail; - - if (n < 10) - ADDW (L_('0') + n); - else if (n == 11 && !got_dot) - { - /* Add all the characters. */ - for (cmpp = decimal; *cmpp != '\0'; - ++cmpp) - ADDW ((unsigned char) *cmpp); - - got_dot = 1; - } - else if (n == 10 && (flags & GROUP) != 0 - && ! got_dot) - { - /* Add all the characters. */ - for (cmpp = thousands; *cmpp != '\0'; - ++cmpp) - ADDW ((unsigned char) *cmpp); - } - else - /* The last read character is not part - of the number anymore. */ - n = 12; - - break; - } - - /* We are pushing all read characters back. */ - if (cmpp > mbdigits[n]) - { - ungetc (c, s); - while (--cmpp > mbdigits[n]) - ungetc_not_eof ((unsigned char) *cmpp, s); - c = (unsigned char) *cmpp; - } -#endif - } - - if (n >= 12) - { - /* The last read character is not part - of the number anymore. */ - ungetc (c, s); - break; - } - } - - if (width == 0 || inchar () == EOF) - break; - - if (width > 0) - --width; - } - } - -#ifndef COMPILE_WSCANF - no_i18nflt: - ; -#endif - } - - /* Have we read any character? If we try to read a number - in hexadecimal notation and we have read only the `0x' - prefix this is an error. */ - if (__builtin_expect (wpsize == 0 - || ((flags & HEXA_FLOAT) && wpsize == 2), 0)) - conv_error (); - - scan_float: - /* Convert the number. */ - ADDW (L_('\0')); - if((flags & DECIMAL) && (flags & SHORT)) - { - _Decimal32 d = __strtod32_internal(wp, &tw, flags & GROUP); - if (!(flags & SUPPRESS) && tw != wp) - /* va_arg is currently busted in libgcc for _Decimal32 so this - * will segfault */ - *ARG (_Decimal32 *) = negative ? -d : d; - } - else if((flags & DECIMAL) && (flags & LONGDBL)) - { - _Decimal128 d = __strtod128_internal(wp, &tw, flags & GROUP); - if (!(flags & SUPPRESS) && tw != wp) - *ARG (_Decimal128 *) = negative ? -d : d; - } - else if (flags & DECIMAL) - { - _Decimal64 d = __strtod64_internal(wp, &tw, flags & GROUP); - if (!(flags & SUPPRESS) && tw != wp) - *ARG (_Decimal64 *) = negative ? -d : d; - } - else if ((flags & LONGDBL) && !__ldbl_is_dbl) - { - long double d = __strtold_internal (wp, &tw, flags & GROUP); - if (!(flags & SUPPRESS) && tw != wp) - *ARG (long double *) = negative ? -d : d; - } - else if (flags & (LONG | LONGDBL)) - { - double d = __strtod_internal (wp, &tw, flags & GROUP); - if (!(flags & SUPPRESS) && tw != wp) - *ARG (double *) = negative ? -d : d; - } - else - { - float d = __strtof_internal (wp, &tw, flags & GROUP); - if (!(flags & SUPPRESS) && tw != wp) - *ARG (float *) = negative ? -d : d; - } - - if (__builtin_expect (tw == wp, 0)) - conv_error (); - - if (!(flags & SUPPRESS)) - ++done; - break; - - case L_('['): /* Character class. */ - if (flags & LONG) - STRING_ARG (wstr, wchar_t, 100); - else - STRING_ARG (str, char, 100); - - if (*f == L_('^')) - { - ++f; - not_in = 1; - } - else - not_in = 0; - - if (width < 0) - /* There is no width given so there is also no limit on the - number of characters we read. Therefore we set width to - a very high value to make the algorithm easier. */ - width = INT_MAX; - -#ifdef COMPILE_WSCANF - /* Find the beginning and the end of the scanlist. We are not - creating a lookup table since it would have to be too large. - Instead we search each time through the string. This is not - a constant lookup time but who uses this feature deserves to - be punished. */ - tw = (wchar_t *) f; /* Marks the beginning. */ - - if (*f == L']') - ++f; - - while ((fc = *f++) != L'\0' && fc != L']'); - - if (__builtin_expect (fc == L'\0', 0)) - conv_error (); - wp = (wchar_t *) f - 1; -#else - /* Fill WP with byte flags indexed by character. - We will use this flag map for matching input characters. */ - if (wpmax < UCHAR_MAX + 1) - { - wpmax = UCHAR_MAX + 1; - wp = (char *) alloca (wpmax); - } - memset (wp, '\0', UCHAR_MAX + 1); - - fc = *f; - if (fc == ']' || fc == '-') - { - /* If ] or - appears before any char in the set, it is not - the terminator or separator, but the first char in the - set. */ - wp[fc] = 1; - ++f; - } - - while ((fc = *f++) != '\0' && fc != ']') - if (fc == '-' && *f != '\0' && *f != ']' - && (unsigned char) f[-2] <= (unsigned char) *f) - { - /* Add all characters from the one before the '-' - up to (but not including) the next format char. */ - for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc) - wp[fc] = 1; - } - else - /* Add the character to the flag map. */ - wp[fc] = 1; - - if (__builtin_expect (fc == '\0', 0)) - conv_error(); -#endif - - if (flags & LONG) - { - size_t now = read_in; -#ifdef COMPILE_WSCANF - if (__builtin_expect (inchar () == WEOF, 0)) - input_error (); - - do - { - wchar_t *runp; - - /* Test whether it's in the scanlist. */ - runp = tw; - while (runp < wp) - { - if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp - && runp != tw - && (unsigned int) runp[-1] <= (unsigned int) runp[1]) - { - /* Match against all characters in between the - first and last character of the sequence. */ - wchar_t wc; - - for (wc = runp[-1] + 1; wc <= runp[1]; ++wc) - if ((wint_t) wc == c) - break; - - if (wc <= runp[1] && !not_in) - break; - if (wc <= runp[1] && not_in) - { - /* The current character is not in the - scanset. */ - ungetc (c, s); - goto out; - } - - runp += 2; - } - else - { - if ((wint_t) *runp == c && !not_in) - break; - if ((wint_t) *runp == c && not_in) - { - ungetc (c, s); - goto out; - } - - ++runp; - } - } - - if (runp == wp && !not_in) - { - ungetc (c, s); - goto out; - } - - if (!(flags & SUPPRESS)) - { - *wstr++ = c; - - if ((flags & MALLOC) - && wstr == (wchar_t *) *strptr + strsize) - { - /* Enlarge the buffer. */ - wstr = (wchar_t *) realloc (*strptr, - (2 * strsize) - * sizeof (wchar_t)); - if (wstr == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - wstr = (wchar_t *) - realloc (*strptr, (strsize + 1) - * sizeof (wchar_t)); - if (wstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - strsize *= 2; - } - } - } - } - while (--width > 0 && inchar () != WEOF); - out: -#else - char buf[MB_LEN_MAX]; - size_t cnt = 0; - mbstate_t cstate; - - if (__builtin_expect (inchar () == EOF, 0)) - input_error (); - - memset (&cstate, '\0', sizeof (cstate)); - - do - { - if (wp[c] == not_in) - { - ungetc_not_eof (c, s); - break; - } - - /* This is easy. */ - if (!(flags & SUPPRESS)) - { - size_t n; - - /* Convert it into a wide character. */ - buf[0] = c; - n = __mbrtowc (wstr, buf, 1, &cstate); - - if (n == (size_t) -2) - { - /* Possibly correct character, just not enough - input. */ - ++cnt; - assert (cnt < MB_CUR_MAX); - continue; - } - cnt = 0; - - ++wstr; - if ((flags & MALLOC) - && wstr == (wchar_t *) *strptr + strsize) - { - /* Enlarge the buffer. */ - wstr = (wchar_t *) realloc (*strptr, - (2 * strsize - * sizeof (wchar_t))); - if (wstr == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - wstr = (wchar_t *) - realloc (*strptr, ((strsize + 1) - * sizeof (wchar_t))); - if (wstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the - string and stop converting, - so at least we don't skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - strsize *= 2; - } - } - } - - if (--width <= 0) - break; - } - while (inchar () != EOF); - - if (__builtin_expect (cnt != 0, 0)) - /* We stopped in the middle of recognizing another - character. That's a problem. */ - encode_error (); -#endif - - if (__builtin_expect (now == read_in, 0)) - /* We haven't succesfully read any character. */ - conv_error (); - - if (!(flags & SUPPRESS)) - { - *wstr++ = L'\0'; - - if ((flags & MALLOC) - && wstr - (wchar_t *) *strptr != strsize) - { - wchar_t *cp = (wchar_t *) - realloc (*strptr, ((wstr - (wchar_t *) *strptr) - * sizeof(wchar_t))); - if (cp != NULL) - *strptr = (char *) cp; - } - strptr = NULL; - - ++done; - } - } - else - { - size_t now = read_in; - - if (__builtin_expect (inchar () == EOF, 0)) - input_error (); - -#ifdef COMPILE_WSCANF - - memset (&state, '\0', sizeof (state)); - - do - { - wchar_t *runp; - size_t n; - - /* Test whether it's in the scanlist. */ - runp = tw; - while (runp < wp) - { - if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp - && runp != tw - && (unsigned int) runp[-1] <= (unsigned int) runp[1]) - { - /* Match against all characters in between the - first and last character of the sequence. */ - wchar_t wc; - - for (wc = runp[-1] + 1; wc <= runp[1]; ++wc) - if ((wint_t) wc == c) - break; - - if (wc <= runp[1] && !not_in) - break; - if (wc <= runp[1] && not_in) - { - /* The current character is not in the - scanset. */ - ungetc (c, s); - goto out2; - } - - runp += 2; - } - else - { - if ((wint_t) *runp == c && !not_in) - break; - if ((wint_t) *runp == c && not_in) - { - ungetc (c, s); - goto out2; - } - - ++runp; - } - } - - if (runp == wp && !not_in) - { - ungetc (c, s); - goto out2; - } - - if (!(flags & SUPPRESS)) - { - if ((flags & MALLOC) - && str + MB_CUR_MAX >= *strptr + strsize) - { - /* Enlarge the buffer. */ - size_t strleng = str - *strptr; - char *newstr; - - newstr = (char *) realloc (*strptr, 2 * strsize); - if (newstr == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - newstr = (char *) realloc (*strptr, - strleng + MB_CUR_MAX); - if (newstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((char *) (*strptr))[strleng] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + MB_CUR_MAX; - } - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize *= 2; - } - } - } - - n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); - if (__builtin_expect (n == (size_t) -1, 0)) - encode_error (); - - assert (n <= MB_CUR_MAX); - str += n; - } - while (--width > 0 && inchar () != WEOF); - out2: -#else - do - { - if (wp[c] == not_in) - { - ungetc_not_eof (c, s); - break; - } - - /* This is easy. */ - if (!(flags & SUPPRESS)) - { - *str++ = c; - if ((flags & MALLOC) - && (char *) str == *strptr + strsize) - { - /* Enlarge the buffer. */ - size_t newsize = 2 * strsize; - - allocagain: - str = (char *) realloc (*strptr, newsize); - if (str == NULL) - { - /* Can't allocate that much. Last-ditch - effort. */ - if (newsize > strsize + 1) - { - newsize = strsize + 1; - goto allocagain; - } - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the - string and stop converting, - so at least we don't skip any input. */ - ((char *) (*strptr))[strsize - 1] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = (char *) str; - str += strsize; - strsize = newsize; - } - } - } - } - while (--width > 0 && inchar () != EOF); -#endif - - if (__builtin_expect (now == read_in, 0)) - /* We haven't succesfully read any character. */ - conv_error (); - - if (!(flags & SUPPRESS)) - { -#ifdef COMPILE_WSCANF - /* We have to emit the code to get into the initial - state. */ - char buf[MB_LEN_MAX]; - size_t n = __wcrtomb (buf, L'\0', &state); - if (n > 0 && (flags & MALLOC) - && str + n >= *strptr + strsize) - { - /* Enlarge the buffer. */ - size_t strleng = str - *strptr; - char *newstr; - - newstr = (char *) realloc (*strptr, strleng + n + 1); - if (newstr == NULL) - { - if (flags & POSIX_MALLOC) - goto reteof; - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((char *) (*strptr))[strleng] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + n + 1; - } - } - - str = __mempcpy (str, buf, n); -#endif - *str++ = '\0'; - - if ((flags & MALLOC) && str - *strptr != strsize) - { - char *cp = (char *) realloc (*strptr, str - *strptr); - if (cp != NULL) - *strptr = cp; - } - strptr = NULL; - - ++done; - } - } - break; - - case L_('p'): /* Generic pointer. */ - base = 16; - /* A PTR must be the same size as a `long int'. */ - flags &= ~(SHORT|LONGDBL); - if (need_long) - flags |= LONG; - flags |= READ_POINTER; - goto number; - - default: - /* If this is an unknown format character punt. */ - conv_error (); - } - } - - /* The last thing we saw int the format string was a white space. - Consume the last white spaces. */ - if (skip_space) - { - do - c = inchar (); - while (ISSPACE (c)); - ungetc (c, s); - } - - errout: - /* Unlock stream. */ - UNLOCK_STREAM (s); - - if (errp != NULL) - *errp |= errval; - - if (done == EOF) - { - reteof: - if (__builtin_expect (ptrs_to_free != NULL, 0)) - { - struct ptrs_to_free *p = ptrs_to_free; - while (p != NULL) - { - for (size_t cnt = 0; cnt < p->count; ++cnt) - { - free (*p->ptrs[cnt]); - *p->ptrs[cnt] = NULL; - } - p = p->next; - free (ptrs_to_free); - ptrs_to_free = p; - } - } - return EOF; - } - else if (__builtin_expect (strptr != NULL, 0)) - { - free (*strptr); - *strptr = NULL; - } - return done; -} - -#ifdef COMPILE_WSCANF -int -__vfwscanf (FILE *s, const wchar_t *format, va_list argptr) -{ - return _IO_vfwscanf (s, format, argptr, NULL); -} -ldbl_weak_alias (__vfwscanf, vfwscanf) -#else -int -___vfscanf (FILE *s, const char *format, va_list argptr) -{ - return _IO_vfscanf_internal (s, format, argptr, NULL); -} -ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf) -ldbl_strong_alias (___vfscanf, __vfscanf) -ldbl_hidden_def (___vfscanf, __vfscanf) -ldbl_weak_alias (___vfscanf, vfscanf) -#endif diff --git a/libc/dfp/sysdeps/dfp/stdlib/stdlib.h b/libc/dfp/sysdeps/dfp/stdlib/stdlib.h deleted file mode 100644 index 85552cffc..000000000 --- a/libc/dfp/sysdeps/dfp/stdlib/stdlib.h +++ /dev/null @@ -1,1000 +0,0 @@ -/* Copyright (C) 1991-2003,2004,2005,2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * ISO C99 Standard: 7.20 General utilities <stdlib.h> - */ - -#ifndef _STDLIB_H - -#include <features.h> - -/* Get size_t, wchar_t and NULL from <stddef.h>. */ -#define __need_size_t -#ifndef __need_malloc_and_calloc -# define __need_wchar_t -# define __need_NULL -#endif -#include <stddef.h> - -__BEGIN_DECLS - -#ifndef __need_malloc_and_calloc -#define _STDLIB_H 1 - -#if defined __USE_XOPEN && !defined _SYS_WAIT_H -/* XPG requires a few symbols from <sys/wait.h> being defined. */ -# include <bits/waitflags.h> -# include <bits/waitstatus.h> - -# ifdef __USE_BSD - -/* Lots of hair to allow traditional BSD use of `union wait' - as well as POSIX.1 use of `int' for the status word. */ - -# if defined __GNUC__ && !defined __cplusplus -# define __WAIT_INT(status) \ - (__extension__ ({ union { __typeof(status) __in; int __i; } __u; \ - __u.__in = (status); __u.__i; })) -# else -# define __WAIT_INT(status) (*(int *) &(status)) -# endif - -/* This is the type of the argument to `wait'. The funky union - causes redeclarations with ether `int *' or `union wait *' to be - allowed without complaint. __WAIT_STATUS_DEFN is the type used in - the actual function definitions. */ - -# if !defined __GNUC__ || __GNUC__ < 2 || defined __cplusplus -# define __WAIT_STATUS void * -# define __WAIT_STATUS_DEFN void * -# else -/* This works in GCC 2.6.1 and later. */ -typedef union - { - union wait *__uptr; - int *__iptr; - } __WAIT_STATUS __attribute__ ((__transparent_union__)); -# define __WAIT_STATUS_DEFN int * -# endif - -# else /* Don't use BSD. */ - -# define __WAIT_INT(status) (status) -# define __WAIT_STATUS int * -# define __WAIT_STATUS_DEFN int * - -# endif /* Use BSD. */ - -/* Define the macros <sys/wait.h> also would define this way. */ -# define WEXITSTATUS(status) __WEXITSTATUS(__WAIT_INT(status)) -# define WTERMSIG(status) __WTERMSIG(__WAIT_INT(status)) -# define WSTOPSIG(status) __WSTOPSIG(__WAIT_INT(status)) -# define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status)) -# define WIFSIGNALED(status) __WIFSIGNALED(__WAIT_INT(status)) -# define WIFSTOPPED(status) __WIFSTOPPED(__WAIT_INT(status)) -# ifdef __WIFCONTINUED -# define WIFCONTINUED(status) __WIFCONTINUED(__WAIT_INT(status)) -# endif -#endif /* X/Open and <sys/wait.h> not included. */ - -__BEGIN_NAMESPACE_STD -/* Returned by `div'. */ -typedef struct - { - int quot; /* Quotient. */ - int rem; /* Remainder. */ - } div_t; - -/* Returned by `ldiv'. */ -#ifndef __ldiv_t_defined -typedef struct - { - long int quot; /* Quotient. */ - long int rem; /* Remainder. */ - } ldiv_t; -# define __ldiv_t_defined 1 -#endif -__END_NAMESPACE_STD - -#if defined __USE_ISOC99 && !defined __lldiv_t_defined -__BEGIN_NAMESPACE_C99 -/* Returned by `lldiv'. */ -__extension__ typedef struct - { - long long int quot; /* Quotient. */ - long long int rem; /* Remainder. */ - } lldiv_t; -# define __lldiv_t_defined 1 -__END_NAMESPACE_C99 -#endif - - -/* The largest number rand will return (same as INT_MAX). */ -#define RAND_MAX 2147483647 - - -/* We define these the same for all machines. - Changes from this to the outside world should be done in `_exit'. */ -#define EXIT_FAILURE 1 /* Failing exit status. */ -#define EXIT_SUCCESS 0 /* Successful exit status. */ - - -/* Maximum length of a multibyte character in the current locale. */ -#define MB_CUR_MAX (__ctype_get_mb_cur_max ()) -extern size_t __ctype_get_mb_cur_max (void) __THROW __wur; - - -__BEGIN_NAMESPACE_STD -/* Convert a string to a floating-point number. */ -extern double atof (__const char *__nptr) - __THROW __attribute_pure__ __nonnull ((1)) __wur; -/* Convert a string to an integer. */ -extern int atoi (__const char *__nptr) - __THROW __attribute_pure__ __nonnull ((1)) __wur; -/* Convert a string to a long integer. */ -extern long int atol (__const char *__nptr) - __THROW __attribute_pure__ __nonnull ((1)) __wur; -__END_NAMESPACE_STD - -#if defined __USE_ISOC99 || (defined __GLIBC_HAVE_LONG_LONG && defined __USE_MISC) -__BEGIN_NAMESPACE_C99 -/* Convert a string to a long long integer. */ -__extension__ extern long long int atoll (__const char *__nptr) - __THROW __attribute_pure__ __nonnull ((1)) __wur; -__END_NAMESPACE_C99 -#endif - -__BEGIN_NAMESPACE_STD -/* Convert a string to a floating-point number. */ -extern double strtod (__const char *__restrict __nptr, - char **__restrict __endptr) - __THROW __nonnull ((1)) __wur; -__END_NAMESPACE_STD - -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Likewise for `float' and `long double' sizes of floating-point numbers. */ -extern float strtof (__const char *__restrict __nptr, - char **__restrict __endptr) __THROW __nonnull ((1)) __wur; - -extern long double strtold (__const char *__restrict __nptr, - char **__restrict __endptr) - __THROW __nonnull ((1)) __wur; -__END_NAMESPACE_C99 -#endif - -__BEGIN_NAMESPACE_STD -/* Convert a string to a long integer. */ -extern long int strtol (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur; -/* Convert a string to an unsigned long integer. */ -extern unsigned long int strtoul (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur; -__END_NAMESPACE_STD - -#if defined __GLIBC_HAVE_LONG_LONG && defined __USE_BSD -/* Convert a string to a quadword integer. */ -__extension__ -extern long long int strtoq (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur; -/* Convert a string to an unsigned quadword integer. */ -__extension__ -extern unsigned long long int strtouq (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur; -#endif /* GCC and use BSD. */ - -#if defined __USE_ISOC99 || (defined __GLIBC_HAVE_LONG_LONG && defined __USE_MISC) -__BEGIN_NAMESPACE_C99 -/* Convert a string to a quadword integer. */ -__extension__ -extern long long int strtoll (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur; -/* Convert a string to an unsigned quadword integer. */ -__extension__ -extern unsigned long long int strtoull (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur; -__END_NAMESPACE_C99 -#endif /* ISO C99 or GCC and use MISC. */ - -#ifdef __STDC_WANT_DEC_FP__ -__BEGIN_NAMESPACE_STD -/* Convert a string to a _Decimal32 number. */ -extern _Decimal32 strtod32 (__const char *__restrict __nptr, - char **__restrict __endptr) - __THROW __nonnull ((1)) __wur; -/* Convert a string to a _Decimal64 number. */ - -extern _Decimal64 strtod64 (__const char *__restrict __nptr, - char **__restrict __endptr) - __THROW __nonnull ((1)) __wur; - -/* Convert a string to a _Decimal128 number. */ -extern _Decimal128 strtod128 (__const char *__restrict __nptr, - char **__restrict __endptr) - __THROW __nonnull ((1)) __wur; -__END_NAMESPACE_STD -#endif - - - -#ifdef __USE_GNU -/* The concept of one static locale per category is not very well - thought out. Many applications will need to process its data using - information from several different locales. Another application is - the implementation of the internationalization handling in the - upcoming ISO C++ standard library. To support this another set of - the functions using locale data exist which have an additional - argument. - - Attention: all these functions are *not* standardized in any form. - This is a proof-of-concept implementation. */ - -/* Structure for reentrant locale using functions. This is an - (almost) opaque type for the user level programs. */ -# include <xlocale.h> - -/* Special versions of the functions above which take the locale to - use as an additional parameter. */ -extern long int strtol_l (__const char *__restrict __nptr, - char **__restrict __endptr, int __base, - __locale_t __loc) __THROW __nonnull ((1, 4)) __wur; - -extern unsigned long int strtoul_l (__const char *__restrict __nptr, - char **__restrict __endptr, - int __base, __locale_t __loc) - __THROW __nonnull ((1, 4)) __wur; - -__extension__ -extern long long int strtoll_l (__const char *__restrict __nptr, - char **__restrict __endptr, int __base, - __locale_t __loc) - __THROW __nonnull ((1, 4)) __wur; - -__extension__ -extern unsigned long long int strtoull_l (__const char *__restrict __nptr, - char **__restrict __endptr, - int __base, __locale_t __loc) - __THROW __nonnull ((1, 4)) __wur; - -extern double strtod_l (__const char *__restrict __nptr, - char **__restrict __endptr, __locale_t __loc) - __THROW __nonnull ((1, 3)) __wur; - -extern float strtof_l (__const char *__restrict __nptr, - char **__restrict __endptr, __locale_t __loc) - __THROW __nonnull ((1, 3)) __wur; - -extern long double strtold_l (__const char *__restrict __nptr, - char **__restrict __endptr, - __locale_t __loc) - __THROW __nonnull ((1, 3)) __wur; -#endif /* GNU */ - - -/* The internal entry points for `strtoX' take an extra flag argument - saying whether or not to parse locale-dependent number grouping. */ - -extern double __strtod_internal (__const char *__restrict __nptr, - char **__restrict __endptr, int __group) - __THROW __nonnull ((1)) __wur; -extern float __strtof_internal (__const char *__restrict __nptr, - char **__restrict __endptr, int __group) - __THROW __nonnull ((1)) __wur; -extern long double __strtold_internal (__const char *__restrict __nptr, - char **__restrict __endptr, - int __group) - __THROW __nonnull ((1)) __wur; -#ifndef __strtol_internal_defined -extern long int __strtol_internal (__const char *__restrict __nptr, - char **__restrict __endptr, - int __base, int __group) - __THROW __nonnull ((1)) __wur; -# define __strtol_internal_defined 1 -#endif -#ifndef __strtoul_internal_defined -extern unsigned long int __strtoul_internal (__const char *__restrict __nptr, - char **__restrict __endptr, - int __base, int __group) - __THROW __nonnull ((1)) __wur; -# define __strtoul_internal_defined 1 -#endif -#if defined __GNUC__ || defined __USE_ISOC99 -# ifndef __strtoll_internal_defined -__extension__ -extern long long int __strtoll_internal (__const char *__restrict __nptr, - char **__restrict __endptr, - int __base, int __group) - __THROW __nonnull ((1)) __wur; -# define __strtoll_internal_defined 1 -# endif -# ifndef __strtoull_internal_defined -__extension__ -extern unsigned long long int __strtoull_internal (__const char * - __restrict __nptr, - char **__restrict __endptr, - int __base, int __group) - __THROW __nonnull ((1)) __wur; -# define __strtoull_internal_defined 1 -# endif -#endif /* GCC */ - -#ifdef __USE_EXTERN_INLINES -/* Define inline functions which call the internal entry points. */ - -__BEGIN_NAMESPACE_STD -extern __inline double -__NTH (strtod (__const char *__restrict __nptr, char **__restrict __endptr)) -{ - return __strtod_internal (__nptr, __endptr, 0); -} -extern __inline long int -__NTH (strtol (__const char *__restrict __nptr, char **__restrict __endptr, - int __base)) -{ - return __strtol_internal (__nptr, __endptr, __base, 0); -} -extern __inline unsigned long int -__NTH (strtoul (__const char *__restrict __nptr, char **__restrict __endptr, - int __base)) -{ - return __strtoul_internal (__nptr, __endptr, __base, 0); -} -__END_NAMESPACE_STD - -# ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -extern __inline float -__NTH (strtof (__const char *__restrict __nptr, char **__restrict __endptr)) -{ - return __strtof_internal (__nptr, __endptr, 0); -} -# ifndef __LDBL_COMPAT -extern __inline long double -__NTH (strtold (__const char *__restrict __nptr, char **__restrict __endptr)) -{ - return __strtold_internal (__nptr, __endptr, 0); -} -# endif -__END_NAMESPACE_C99 -# endif - -# ifdef __USE_BSD -__extension__ extern __inline long long int -__NTH (strtoq (__const char *__restrict __nptr, char **__restrict __endptr, - int __base)) -{ - return __strtoll_internal (__nptr, __endptr, __base, 0); -} -__extension__ extern __inline unsigned long long int -__NTH (strtouq (__const char *__restrict __nptr, char **__restrict __endptr, - int __base)) -{ - return __strtoull_internal (__nptr, __endptr, __base, 0); -} -# endif - -# if defined __USE_MISC || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -__extension__ extern __inline long long int -__NTH (strtoll (__const char *__restrict __nptr, char **__restrict __endptr, - int __base)) -{ - return __strtoll_internal (__nptr, __endptr, __base, 0); -} -__extension__ extern __inline unsigned long long int -__NTH (strtoull (__const char * __restrict __nptr, char **__restrict __endptr, - int __base)) -{ - return __strtoull_internal (__nptr, __endptr, __base, 0); -} -__END_NAMESPACE_C99 -# endif - -__BEGIN_NAMESPACE_STD -extern __inline double -__NTH (atof (__const char *__nptr)) -{ - return strtod (__nptr, (char **) NULL); -} -extern __inline int -__NTH (atoi (__const char *__nptr)) -{ - return (int) strtol (__nptr, (char **) NULL, 10); -} -extern __inline long int -__NTH (atol (__const char *__nptr)) -{ - return strtol (__nptr, (char **) NULL, 10); -} -__END_NAMESPACE_STD - -# if defined __USE_MISC || defined __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -__extension__ extern __inline long long int -__NTH (atoll (__const char *__nptr)) -{ - return strtoll (__nptr, (char **) NULL, 10); -} -__END_NAMESPACE_C99 -# endif -#endif /* Optimizing and Inlining. */ - - -#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED -/* Convert N to base 64 using the digits "./0-9A-Za-z", least-significant - digit first. Returns a pointer to static storage overwritten by the - next call. */ -extern char *l64a (long int __n) __THROW __wur; - -/* Read a number from a string S in base 64 as above. */ -extern long int a64l (__const char *__s) - __THROW __attribute_pure__ __nonnull ((1)) __wur; - -#endif /* Use SVID || extended X/Open. */ - -#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED || defined __USE_BSD -# include <sys/types.h> /* we need int32_t... */ - -/* These are the functions that actually do things. The `random', `srandom', - `initstate' and `setstate' functions are those from BSD Unices. - The `rand' and `srand' functions are required by the ANSI standard. - We provide both interfaces to the same random number generator. */ -/* Return a random long integer between 0 and RAND_MAX inclusive. */ -extern long int random (void) __THROW; - -/* Seed the random number generator with the given number. */ -extern void srandom (unsigned int __seed) __THROW; - -/* Initialize the random number generator to use state buffer STATEBUF, - of length STATELEN, and seed it with SEED. Optimal lengths are 8, 16, - 32, 64, 128 and 256, the bigger the better; values less than 8 will - cause an error and values greater than 256 will be rounded down. */ -extern char *initstate (unsigned int __seed, char *__statebuf, - size_t __statelen) __THROW __nonnull ((2)); - -/* Switch the random number generator to state buffer STATEBUF, - which should have been previously initialized by `initstate'. */ -extern char *setstate (char *__statebuf) __THROW __nonnull ((1)); - - -# ifdef __USE_MISC -/* Reentrant versions of the `random' family of functions. - These functions all use the following data structure to contain - state, rather than global state variables. */ - -struct random_data - { - int32_t *fptr; /* Front pointer. */ - int32_t *rptr; /* Rear pointer. */ - int32_t *state; /* Array of state values. */ - int rand_type; /* Type of random number generator. */ - int rand_deg; /* Degree of random number generator. */ - int rand_sep; /* Distance between front and rear. */ - int32_t *end_ptr; /* Pointer behind state table. */ - }; - -extern int random_r (struct random_data *__restrict __buf, - int32_t *__restrict __result) __THROW __nonnull ((1, 2)); - -extern int srandom_r (unsigned int __seed, struct random_data *__buf) - __THROW __nonnull ((2)); - -extern int initstate_r (unsigned int __seed, char *__restrict __statebuf, - size_t __statelen, - struct random_data *__restrict __buf) - __THROW __nonnull ((2, 4)); - -extern int setstate_r (char *__restrict __statebuf, - struct random_data *__restrict __buf) - __THROW __nonnull ((1, 2)); -# endif /* Use misc. */ -#endif /* Use SVID || extended X/Open || BSD. */ - - -__BEGIN_NAMESPACE_STD -/* Return a random integer between 0 and RAND_MAX inclusive. */ -extern int rand (void) __THROW; -/* Seed the random number generator with the given number. */ -extern void srand (unsigned int __seed) __THROW; -__END_NAMESPACE_STD - -#ifdef __USE_POSIX -/* Reentrant interface according to POSIX.1. */ -extern int rand_r (unsigned int *__seed) __THROW; -#endif - - -#if defined __USE_SVID || defined __USE_XOPEN -/* System V style 48-bit random number generator functions. */ - -/* Return non-negative, double-precision floating-point value in [0.0,1.0). */ -extern double drand48 (void) __THROW; -extern double erand48 (unsigned short int __xsubi[3]) __THROW __nonnull ((1)); - -/* Return non-negative, long integer in [0,2^31). */ -extern long int lrand48 (void) __THROW; -extern long int nrand48 (unsigned short int __xsubi[3]) - __THROW __nonnull ((1)); - -/* Return signed, long integers in [-2^31,2^31). */ -extern long int mrand48 (void) __THROW; -extern long int jrand48 (unsigned short int __xsubi[3]) - __THROW __nonnull ((1)); - -/* Seed random number generator. */ -extern void srand48 (long int __seedval) __THROW; -extern unsigned short int *seed48 (unsigned short int __seed16v[3]) - __THROW __nonnull ((1)); -extern void lcong48 (unsigned short int __param[7]) __THROW __nonnull ((1)); - -# ifdef __USE_MISC -/* Data structure for communication with thread safe versions. This - type is to be regarded as opaque. It's only exported because users - have to allocate objects of this type. */ -struct drand48_data - { - unsigned short int __x[3]; /* Current state. */ - unsigned short int __old_x[3]; /* Old state. */ - unsigned short int __c; /* Additive const. in congruential formula. */ - unsigned short int __init; /* Flag for initializing. */ - unsigned long long int __a; /* Factor in congruential formula. */ - }; - -/* Return non-negative, double-precision floating-point value in [0.0,1.0). */ -extern int drand48_r (struct drand48_data *__restrict __buffer, - double *__restrict __result) __THROW __nonnull ((1, 2)); -extern int erand48_r (unsigned short int __xsubi[3], - struct drand48_data *__restrict __buffer, - double *__restrict __result) __THROW __nonnull ((1, 2)); - -/* Return non-negative, long integer in [0,2^31). */ -extern int lrand48_r (struct drand48_data *__restrict __buffer, - long int *__restrict __result) - __THROW __nonnull ((1, 2)); -extern int nrand48_r (unsigned short int __xsubi[3], - struct drand48_data *__restrict __buffer, - long int *__restrict __result) - __THROW __nonnull ((1, 2)); - -/* Return signed, long integers in [-2^31,2^31). */ -extern int mrand48_r (struct drand48_data *__restrict __buffer, - long int *__restrict __result) - __THROW __nonnull ((1, 2)); -extern int jrand48_r (unsigned short int __xsubi[3], - struct drand48_data *__restrict __buffer, - long int *__restrict __result) - __THROW __nonnull ((1, 2)); - -/* Seed random number generator. */ -extern int srand48_r (long int __seedval, struct drand48_data *__buffer) - __THROW __nonnull ((2)); - -extern int seed48_r (unsigned short int __seed16v[3], - struct drand48_data *__buffer) __THROW __nonnull ((1, 2)); - -extern int lcong48_r (unsigned short int __param[7], - struct drand48_data *__buffer) - __THROW __nonnull ((1, 2)); -# endif /* Use misc. */ -#endif /* Use SVID or X/Open. */ - -#endif /* don't just need malloc and calloc */ - -#ifndef __malloc_and_calloc_defined -# define __malloc_and_calloc_defined -__BEGIN_NAMESPACE_STD -/* Allocate SIZE bytes of memory. */ -extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur; -/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ -extern void *calloc (size_t __nmemb, size_t __size) - __THROW __attribute_malloc__ __wur; -__END_NAMESPACE_STD -#endif - -#ifndef __need_malloc_and_calloc -__BEGIN_NAMESPACE_STD -/* Re-allocate the previously allocated block - in PTR, making the new block SIZE bytes long. */ -extern void *realloc (void *__ptr, size_t __size) - __THROW __attribute_malloc__ __attribute_warn_unused_result__; -/* Free a block allocated by `malloc', `realloc' or `calloc'. */ -extern void free (void *__ptr) __THROW; -__END_NAMESPACE_STD - -#ifdef __USE_MISC -/* Free a block. An alias for `free'. (Sun Unices). */ -extern void cfree (void *__ptr) __THROW; -#endif /* Use misc. */ - -#if defined __USE_GNU || defined __USE_BSD || defined __USE_MISC -# include <alloca.h> -#endif /* Use GNU, BSD, or misc. */ - -#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED -/* Allocate SIZE bytes on a page boundary. The storage cannot be freed. */ -extern void *valloc (size_t __size) __THROW __attribute_malloc__ __wur; -#endif - -#ifdef __USE_XOPEN2K -/* Allocate memory of SIZE bytes with an alignment of ALIGNMENT. */ -extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size) - __THROW __nonnull ((1)) __wur; -#endif - -__BEGIN_NAMESPACE_STD -/* Abort execution and generate a core-dump. */ -extern void abort (void) __THROW __attribute__ ((__noreturn__)); - - -/* Register a function to be called when `exit' is called. */ -extern int atexit (void (*__func) (void)) __THROW __nonnull ((1)); -__END_NAMESPACE_STD - -#ifdef __USE_MISC -/* Register a function to be called with the status - given to `exit' and the given argument. */ -extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg) - __THROW __nonnull ((1)); -#endif - -__BEGIN_NAMESPACE_STD -/* Call all functions registered with `atexit' and `on_exit', - in the reverse of the order in which they were registered - perform stdio cleanup, and terminate program execution with STATUS. */ -extern void exit (int __status) __THROW __attribute__ ((__noreturn__)); -__END_NAMESPACE_STD - -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -/* Terminate the program with STATUS without calling any of the - functions registered with `atexit' or `on_exit'. */ -extern void _Exit (int __status) __THROW __attribute__ ((__noreturn__)); -__END_NAMESPACE_C99 -#endif - - -__BEGIN_NAMESPACE_STD -/* Return the value of envariable NAME, or NULL if it doesn't exist. */ -extern char *getenv (__const char *__name) __THROW __nonnull ((1)) __wur; -__END_NAMESPACE_STD - -/* This function is similar to the above but returns NULL if the - programs is running with SUID or SGID enabled. */ -extern char *__secure_getenv (__const char *__name) - __THROW __nonnull ((1)) __wur; - -#if defined __USE_SVID || defined __USE_XOPEN -/* The SVID says this is in <stdio.h>, but this seems a better place. */ -/* Put STRING, which is of the form "NAME=VALUE", in the environment. - If there is no `=', remove NAME from the environment. */ -extern int putenv (char *__string) __THROW __nonnull ((1)); -#endif - -#if defined __USE_BSD || defined __USE_XOPEN2K -/* Set NAME to VALUE in the environment. - If REPLACE is nonzero, overwrite an existing value. */ -extern int setenv (__const char *__name, __const char *__value, int __replace) - __THROW __nonnull ((2)); - -/* Remove the variable NAME from the environment. */ -extern int unsetenv (__const char *__name) __THROW; -#endif - -#ifdef __USE_MISC -/* The `clearenv' was planned to be added to POSIX.1 but probably - never made it. Nevertheless the POSIX.9 standard (POSIX bindings - for Fortran 77) requires this function. */ -extern int clearenv (void) __THROW; -#endif - - -#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED -/* Generate a unique temporary file name from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the file name unique. - Returns TEMPLATE, or a null pointer if it cannot get a unique file name. */ -extern char *mktemp (char *__template) __THROW __nonnull ((1)) __wur; - -/* Generate a unique temporary file name from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the filename unique. - Returns a file descriptor open on the file for reading and writing, - or -1 if it cannot create a uniquely-named file. - - This function is a possible cancellation points and therefore not - marked with __THROW. */ -# ifndef __USE_FILE_OFFSET64 -extern int mkstemp (char *__template) __nonnull ((1)) __wur; -# else -# ifdef __REDIRECT -extern int __REDIRECT (mkstemp, (char *__template), mkstemp64) - __nonnull ((1)) __wur; -# else -# define mkstemp mkstemp64 -# endif -# endif -# ifdef __USE_LARGEFILE64 -extern int mkstemp64 (char *__template) __nonnull ((1)) __wur; -# endif -#endif - -#ifdef __USE_BSD -/* Create a unique temporary directory from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the directory name unique. - Returns TEMPLATE, or a null pointer if it cannot get a unique name. - The directory is created mode 700. */ -extern char *mkdtemp (char *__template) __THROW __nonnull ((1)) __wur; -#endif - - -__BEGIN_NAMESPACE_STD -/* Execute the given line as a shell command. - - This function is a cancellation point and therefore not marked with - __THROW. */ -extern int system (__const char *__command) __wur; -__END_NAMESPACE_STD - - -#ifdef __USE_GNU -/* Return a malloc'd string containing the canonical absolute name of the - named file. The last file name component need not exist, and may be a - symlink to a nonexistent file. */ -extern char *canonicalize_file_name (__const char *__name) - __THROW __nonnull ((1)) __wur; -#endif - -#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED -/* Return the canonical absolute name of file NAME. The last file name - component need not exist, and may be a symlink to a nonexistent file. - If RESOLVED is null, the result is malloc'd; otherwise, if the canonical - name is PATH_MAX chars or more, returns null with `errno' set to - ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, returns the - name in RESOLVED. */ -extern char *realpath (__const char *__restrict __name, - char *__restrict __resolved) __THROW __wur; -#endif - - -/* Shorthand for type of comparison functions. */ -#ifndef __COMPAR_FN_T -# define __COMPAR_FN_T -typedef int (*__compar_fn_t) (__const void *, __const void *); - -# ifdef __USE_GNU -typedef __compar_fn_t comparison_fn_t; -# endif -#endif - -__BEGIN_NAMESPACE_STD -/* Do a binary search for KEY in BASE, which consists of NMEMB elements - of SIZE bytes each, using COMPAR to perform the comparisons. */ -extern void *bsearch (__const void *__key, __const void *__base, - size_t __nmemb, size_t __size, __compar_fn_t __compar) - __nonnull ((1, 2, 5)) __wur; - -/* Sort NMEMB elements of BASE, of SIZE bytes each, - using COMPAR to perform the comparisons. */ -extern void qsort (void *__base, size_t __nmemb, size_t __size, - __compar_fn_t __compar) __nonnull ((1, 4)); - - -/* Return the absolute value of X. */ -extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur; -extern long int labs (long int __x) __THROW __attribute__ ((__const__)) __wur; -__END_NAMESPACE_STD - -#ifdef __USE_ISOC99 -__extension__ extern long long int llabs (long long int __x) - __THROW __attribute__ ((__const__)) __wur; -#endif - - -__BEGIN_NAMESPACE_STD -/* Return the `div_t', `ldiv_t' or `lldiv_t' representation - of the value of NUMER over DENOM. */ -/* GCC may have built-ins for these someday. */ -extern div_t div (int __numer, int __denom) - __THROW __attribute__ ((__const__)) __wur; -extern ldiv_t ldiv (long int __numer, long int __denom) - __THROW __attribute__ ((__const__)) __wur; -__END_NAMESPACE_STD - -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 -__extension__ extern lldiv_t lldiv (long long int __numer, - long long int __denom) - __THROW __attribute__ ((__const__)) __wur; -__END_NAMESPACE_C99 -#endif - - -#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED -/* Convert floating point numbers to strings. The returned values are - valid only until another call to the same function. */ - -/* Convert VALUE to a string with NDIGIT digits and return a pointer to - this. Set *DECPT with the position of the decimal character and *SIGN - with the sign of the number. */ -extern char *ecvt (double __value, int __ndigit, int *__restrict __decpt, - int *__restrict __sign) __THROW __nonnull ((3, 4)) __wur; - -/* Convert VALUE to a string rounded to NDIGIT decimal digits. Set *DECPT - with the position of the decimal character and *SIGN with the sign of - the number. */ -extern char *fcvt (double __value, int __ndigit, int *__restrict __decpt, - int *__restrict __sign) __THROW __nonnull ((3, 4)) __wur; - -/* If possible convert VALUE to a string with NDIGIT significant digits. - Otherwise use exponential representation. The resulting string will - be written to BUF. */ -extern char *gcvt (double __value, int __ndigit, char *__buf) - __THROW __nonnull ((3)) __wur; - - -# ifdef __USE_MISC -/* Long double versions of above functions. */ -extern char *qecvt (long double __value, int __ndigit, - int *__restrict __decpt, int *__restrict __sign) - __THROW __nonnull ((3, 4)) __wur; -extern char *qfcvt (long double __value, int __ndigit, - int *__restrict __decpt, int *__restrict __sign) - __THROW __nonnull ((3, 4)) __wur; -extern char *qgcvt (long double __value, int __ndigit, char *__buf) - __THROW __nonnull ((3)) __wur; - - -/* Reentrant version of the functions above which provide their own - buffers. */ -extern int ecvt_r (double __value, int __ndigit, int *__restrict __decpt, - int *__restrict __sign, char *__restrict __buf, - size_t __len) __THROW __nonnull ((3, 4, 5)); -extern int fcvt_r (double __value, int __ndigit, int *__restrict __decpt, - int *__restrict __sign, char *__restrict __buf, - size_t __len) __THROW __nonnull ((3, 4, 5)); - -extern int qecvt_r (long double __value, int __ndigit, - int *__restrict __decpt, int *__restrict __sign, - char *__restrict __buf, size_t __len) - __THROW __nonnull ((3, 4, 5)); -extern int qfcvt_r (long double __value, int __ndigit, - int *__restrict __decpt, int *__restrict __sign, - char *__restrict __buf, size_t __len) - __THROW __nonnull ((3, 4, 5)); -# endif /* misc */ -#endif /* use MISC || use X/Open Unix */ - - -__BEGIN_NAMESPACE_STD -/* Return the length of the multibyte character - in S, which is no longer than N. */ -extern int mblen (__const char *__s, size_t __n) __THROW __wur; -/* Return the length of the given multibyte character, - putting its `wchar_t' representation in *PWC. */ -extern int mbtowc (wchar_t *__restrict __pwc, - __const char *__restrict __s, size_t __n) __THROW __wur; -/* Put the multibyte character represented - by WCHAR in S, returning its length. */ -extern int wctomb (char *__s, wchar_t __wchar) __THROW __wur; - - -/* Convert a multibyte string to a wide char string. */ -extern size_t mbstowcs (wchar_t *__restrict __pwcs, - __const char *__restrict __s, size_t __n) __THROW; -/* Convert a wide char string to multibyte string. */ -extern size_t wcstombs (char *__restrict __s, - __const wchar_t *__restrict __pwcs, size_t __n) - __THROW; -__END_NAMESPACE_STD - - -#ifdef __USE_SVID -/* Determine whether the string value of RESPONSE matches the affirmation - or negative response expression as specified by the LC_MESSAGES category - in the program's current locale. Returns 1 if affirmative, 0 if - negative, and -1 if not matching. */ -extern int rpmatch (__const char *__response) __THROW __nonnull ((1)) __wur; -#endif - - -#ifdef __USE_XOPEN_EXTENDED -/* Parse comma separated suboption from *OPTIONP and match against - strings in TOKENS. If found return index and set *VALUEP to - optional value introduced by an equal sign. If the suboption is - not part of TOKENS return in *VALUEP beginning of unknown - suboption. On exit *OPTIONP is set to the beginning of the next - token or at the terminating NUL character. */ -extern int getsubopt (char **__restrict __optionp, - char *__const *__restrict __tokens, - char **__restrict __valuep) - __THROW __nonnull ((1, 2, 3)) __wur; -#endif - - -#ifdef __USE_XOPEN -/* Setup DES tables according KEY. */ -extern void setkey (__const char *__key) __THROW __nonnull ((1)); -#endif - - -/* X/Open pseudo terminal handling. */ - -#ifdef __USE_XOPEN2K -/* Return a master pseudo-terminal handle. */ -extern int posix_openpt (int __oflag) __wur; -#endif - -#ifdef __USE_XOPEN -/* The next four functions all take a master pseudo-tty fd and - perform an operation on the associated slave: */ - -/* Chown the slave to the calling user. */ -extern int grantpt (int __fd) __THROW; - -/* Release an internal lock so the slave can be opened. - Call after grantpt(). */ -extern int unlockpt (int __fd) __THROW; - -/* Return the pathname of the pseudo terminal slave assoicated with - the master FD is open on, or NULL on errors. - The returned storage is good until the next call to this function. */ -extern char *ptsname (int __fd) __THROW __wur; -#endif - -#ifdef __USE_GNU -/* Store at most BUFLEN characters of the pathname of the slave pseudo - terminal associated with the master FD is open on in BUF. - Return 0 on success, otherwise an error number. */ -extern int ptsname_r (int __fd, char *__buf, size_t __buflen) - __THROW __nonnull ((2)); - -/* Open a master pseudo terminal and return its file descriptor. */ -extern int getpt (void); -#endif - -#ifdef __USE_BSD -/* Put the 1 minute, 5 minute and 15 minute load averages into the first - NELEM elements of LOADAVG. Return the number written (never more than - three, but may be less than NELEM), or -1 if an error occurred. */ -extern int getloadavg (double __loadavg[], int __nelem) - __THROW __nonnull ((1)); -#endif - - -/* Define some macros helping to catch buffer overflows. */ -#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus -# include <bits/stdlib.h> -#endif -#ifdef __LDBL_COMPAT -# include <bits/stdlib-ldbl.h> -#endif - -#endif /* don't just need malloc and calloc */ -#undef __need_malloc_and_calloc - -__END_DECLS - -#endif /* stdlib.h */ diff --git a/libc/dfp/sysdeps/dfp/wcsmbs/wchar.h b/libc/dfp/sysdeps/dfp/wcsmbs/wchar.h deleted file mode 100644 index 231d1facd..000000000 --- a/libc/dfp/sysdeps/dfp/wcsmbs/wchar.h +++ /dev/null @@ -1,866 +0,0 @@ -/* Copyright (C) 1995-2004,2005,2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * ISO C99 Standard: 7.24 - * Extended multibyte and wide character utilities <wchar.h> - */ - -#ifndef _WCHAR_H - -#ifndef __need_mbstate_t -# define _WCHAR_H 1 -# include <features.h> -#endif - -#ifdef _WCHAR_H -/* Get FILE definition. */ -# define __need___FILE -# ifdef __USE_UNIX98 -# define __need_FILE -# endif -# include <stdio.h> -/* Get va_list definition. */ -# define __need___va_list -# include <stdarg.h> - -/* Get size_t, wchar_t, wint_t and NULL from <stddef.h>. */ -# define __need_size_t -# define __need_wchar_t -# define __need_NULL -#endif -#define __need_wint_t -#include <stddef.h> - -#include <bits/wchar.h> - -/* We try to get wint_t from <stddef.h>, but not all GCC versions define it - there. So define it ourselves if it remains undefined. */ -#ifndef _WINT_T -/* Integral type unchanged by default argument promotions that can - hold any value corresponding to members of the extended character - set, as well as at least one value that does not correspond to any - member of the extended character set. */ -# define _WINT_T -typedef unsigned int wint_t; -#else -/* Work around problems with the <stddef.h> file which doesn't put - wint_t in the std namespace. */ -# if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES \ - && defined __WINT_TYPE__ -__BEGIN_NAMESPACE_STD -typedef __WINT_TYPE__ wint_t; -__END_NAMESPACE_STD -# endif -#endif - - -#ifndef __mbstate_t_defined -# define __mbstate_t_defined 1 -/* Conversion state information. */ -typedef struct -{ - int __count; - union - { - wint_t __wch; - char __wchb[4]; - } __value; /* Value so far. */ -} __mbstate_t; -#endif -#undef __need_mbstate_t - - -/* The rest of the file is only used if used if __need_mbstate_t is not - defined. */ -#ifdef _WCHAR_H - -__BEGIN_NAMESPACE_C99 -/* Public type. */ -typedef __mbstate_t mbstate_t; -__END_NAMESPACE_C99 -#ifdef __USE_GNU -__USING_NAMESPACE_C99(mbstate_t) -#endif - -#ifndef WCHAR_MIN -/* These constants might also be defined in <inttypes.h>. */ -# define WCHAR_MIN __WCHAR_MIN -# define WCHAR_MAX __WCHAR_MAX -#endif - -#ifndef WEOF -# define WEOF (0xffffffffu) -#endif - -/* For XPG4 compliance we have to define the stuff from <wctype.h> here - as well. */ -#if defined __USE_XOPEN && !defined __USE_UNIX98 -# include <wctype.h> -#endif - - -__BEGIN_DECLS - -__BEGIN_NAMESPACE_STD -/* This incomplete type is defined in <time.h> but needed here because - of `wcsftime'. */ -struct tm; -/* XXX We have to clean this up at some point. Since tm is in the std - namespace but wcsftime is in __c99 the type wouldn't be found - without inserting it in the global namespace. */ -__USING_NAMESPACE_STD(tm) -__END_NAMESPACE_STD - - -__BEGIN_NAMESPACE_C99 -/* Copy SRC to DEST. */ -extern wchar_t *wcscpy (wchar_t *__restrict __dest, - __const wchar_t *__restrict __src) __THROW; -/* Copy no more than N wide-characters of SRC to DEST. */ -extern wchar_t *wcsncpy (wchar_t *__restrict __dest, - __const wchar_t *__restrict __src, size_t __n) - __THROW; - -/* Append SRC onto DEST. */ -extern wchar_t *wcscat (wchar_t *__restrict __dest, - __const wchar_t *__restrict __src) __THROW; -/* Append no more than N wide-characters of SRC onto DEST. */ -extern wchar_t *wcsncat (wchar_t *__restrict __dest, - __const wchar_t *__restrict __src, size_t __n) - __THROW; - -/* Compare S1 and S2. */ -extern int wcscmp (__const wchar_t *__s1, __const wchar_t *__s2) - __THROW __attribute_pure__; -/* Compare N wide-characters of S1 and S2. */ -extern int wcsncmp (__const wchar_t *__s1, __const wchar_t *__s2, size_t __n) - __THROW __attribute_pure__; -__END_NAMESPACE_C99 - -#ifdef __USE_GNU -/* Compare S1 and S2, ignoring case. */ -extern int wcscasecmp (__const wchar_t *__s1, __const wchar_t *__s2) __THROW; - -/* Compare no more than N chars of S1 and S2, ignoring case. */ -extern int wcsncasecmp (__const wchar_t *__s1, __const wchar_t *__s2, - size_t __n) __THROW; - -/* Similar to the two functions above but take the information from - the provided locale and not the global locale. */ -# include <xlocale.h> - -extern int wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2, - __locale_t __loc) __THROW; - -extern int wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2, - size_t __n, __locale_t __loc) __THROW; -#endif - -__BEGIN_NAMESPACE_C99 -/* Compare S1 and S2, both interpreted as appropriate to the - LC_COLLATE category of the current locale. */ -extern int wcscoll (__const wchar_t *__s1, __const wchar_t *__s2) __THROW; -/* Transform S2 into array pointed to by S1 such that if wcscmp is - applied to two transformed strings the result is the as applying - `wcscoll' to the original strings. */ -extern size_t wcsxfrm (wchar_t *__restrict __s1, - __const wchar_t *__restrict __s2, size_t __n) __THROW; -__END_NAMESPACE_C99 - -#ifdef __USE_GNU -/* Similar to the two functions above but take the information from - the provided locale and not the global locale. */ - -/* Compare S1 and S2, both interpreted as appropriate to the - LC_COLLATE category of the given locale. */ -extern int wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2, - __locale_t __loc) __THROW; - -/* Transform S2 into array pointed to by S1 such that if wcscmp is - applied to two transformed strings the result is the as applying - `wcscoll' to the original strings. */ -extern size_t wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2, - size_t __n, __locale_t __loc) __THROW; - -/* Duplicate S, returning an identical malloc'd string. */ -extern wchar_t *wcsdup (__const wchar_t *__s) __THROW __attribute_malloc__; -#endif - -__BEGIN_NAMESPACE_C99 -/* Find the first occurrence of WC in WCS. */ -extern wchar_t *wcschr (__const wchar_t *__wcs, wchar_t __wc) - __THROW __attribute_pure__; -/* Find the last occurrence of WC in WCS. */ -extern wchar_t *wcsrchr (__const wchar_t *__wcs, wchar_t __wc) - __THROW __attribute_pure__; -__END_NAMESPACE_C99 - -#ifdef __USE_GNU -/* This function is similar to `wcschr'. But it returns a pointer to - the closing NUL wide character in case C is not found in S. */ -extern wchar_t *wcschrnul (__const wchar_t *__s, wchar_t __wc) - __THROW __attribute_pure__; -#endif - -__BEGIN_NAMESPACE_C99 -/* Return the length of the initial segmet of WCS which - consists entirely of wide characters not in REJECT. */ -extern size_t wcscspn (__const wchar_t *__wcs, __const wchar_t *__reject) - __THROW __attribute_pure__; -/* Return the length of the initial segmet of WCS which - consists entirely of wide characters in ACCEPT. */ -extern size_t wcsspn (__const wchar_t *__wcs, __const wchar_t *__accept) - __THROW __attribute_pure__; -/* Find the first occurrence in WCS of any character in ACCEPT. */ -extern wchar_t *wcspbrk (__const wchar_t *__wcs, __const wchar_t *__accept) - __THROW __attribute_pure__; -/* Find the first occurrence of NEEDLE in HAYSTACK. */ -extern wchar_t *wcsstr (__const wchar_t *__haystack, __const wchar_t *__needle) - __THROW __attribute_pure__; - -/* Divide WCS into tokens separated by characters in DELIM. */ -extern wchar_t *wcstok (wchar_t *__restrict __s, - __const wchar_t *__restrict __delim, - wchar_t **__restrict __ptr) __THROW; - -/* Return the number of wide characters in S. */ -extern size_t wcslen (__const wchar_t *__s) __THROW __attribute_pure__; -__END_NAMESPACE_C99 - -#ifdef __USE_XOPEN -/* Another name for `wcsstr' from XPG4. */ -extern wchar_t *wcswcs (__const wchar_t *__haystack, __const wchar_t *__needle) - __THROW __attribute_pure__; -#endif - -#ifdef __USE_GNU -/* Return the number of wide characters in S, but at most MAXLEN. */ -extern size_t wcsnlen (__const wchar_t *__s, size_t __maxlen) - __THROW __attribute_pure__; -#endif - - -__BEGIN_NAMESPACE_C99 -/* Search N wide characters of S for C. */ -extern wchar_t *wmemchr (__const wchar_t *__s, wchar_t __c, size_t __n) - __THROW __attribute_pure__; - -/* Compare N wide characters of S1 and S2. */ -extern int wmemcmp (__const wchar_t *__restrict __s1, - __const wchar_t *__restrict __s2, size_t __n) - __THROW __attribute_pure__; - -/* Copy N wide characters of SRC to DEST. */ -extern wchar_t *wmemcpy (wchar_t *__restrict __s1, - __const wchar_t *__restrict __s2, size_t __n) __THROW; - -/* Copy N wide characters of SRC to DEST, guaranteeing - correct behavior for overlapping strings. */ -extern wchar_t *wmemmove (wchar_t *__s1, __const wchar_t *__s2, size_t __n) - __THROW; - -/* Set N wide characters of S to C. */ -extern wchar_t *wmemset (wchar_t *__s, wchar_t __c, size_t __n) __THROW; -__END_NAMESPACE_C99 - -#ifdef __USE_GNU -/* Copy N wide characters of SRC to DEST and return pointer to following - wide character. */ -extern wchar_t *wmempcpy (wchar_t *__restrict __s1, - __const wchar_t *__restrict __s2, size_t __n) - __THROW; -#endif - - -__BEGIN_NAMESPACE_C99 -/* Determine whether C constitutes a valid (one-byte) multibyte - character. */ -extern wint_t btowc (int __c) __THROW; - -/* Determine whether C corresponds to a member of the extended - character set whose multibyte representation is a single byte. */ -extern int wctob (wint_t __c) __THROW; - -/* Determine whether PS points to an object representing the initial - state. */ -extern int mbsinit (__const mbstate_t *__ps) __THROW __attribute_pure__; - -/* Write wide character representation of multibyte character pointed - to by S to PWC. */ -extern size_t mbrtowc (wchar_t *__restrict __pwc, - __const char *__restrict __s, size_t __n, - mbstate_t *__p) __THROW; - -/* Write multibyte representation of wide character WC to S. */ -extern size_t wcrtomb (char *__restrict __s, wchar_t __wc, - mbstate_t *__restrict __ps) __THROW; - -/* Return number of bytes in multibyte character pointed to by S. */ -extern size_t __mbrlen (__const char *__restrict __s, size_t __n, - mbstate_t *__restrict __ps) __THROW; -extern size_t mbrlen (__const char *__restrict __s, size_t __n, - mbstate_t *__restrict __ps) __THROW; -__END_NAMESPACE_C99 - -#ifdef __USE_EXTERN_INLINES -/* Define inline function as optimization. */ - -# ifndef __cplusplus -/* We can use the BTOWC and WCTOB optimizations since we know that all - locales must use ASCII encoding for the values in the ASCII range - and because the wchar_t encoding is always ISO 10646. */ -extern wint_t __btowc_alias (int __c) __asm ("btowc"); -extern __inline wint_t -__NTH (btowc (int __c)) -{ return (__builtin_constant_p (__c) && __c >= '\0' && __c <= '\x7f' - ? (wint_t) __c : __btowc_alias (__c)); } - -extern int __wctob_alias (wint_t __c) __asm ("wctob"); -extern __inline int -__NTH (wctob (wint_t __wc)) -{ return (__builtin_constant_p (__wc) && __wc >= L'\0' && __wc <= L'\x7f' - ? (int) __wc : __wctob_alias (__wc)); } -# endif - -extern __inline size_t -__NTH (mbrlen (__const char *__restrict __s, size_t __n, - mbstate_t *__restrict __ps)) -{ return (__ps != NULL - ? mbrtowc (NULL, __s, __n, __ps) : __mbrlen (__s, __n, NULL)); } -#endif - -__BEGIN_NAMESPACE_C99 -/* Write wide character representation of multibyte character string - SRC to DST. */ -extern size_t mbsrtowcs (wchar_t *__restrict __dst, - __const char **__restrict __src, size_t __len, - mbstate_t *__restrict __ps) __THROW; - -/* Write multibyte character representation of wide character string - SRC to DST. */ -extern size_t wcsrtombs (char *__restrict __dst, - __const wchar_t **__restrict __src, size_t __len, - mbstate_t *__restrict __ps) __THROW; -__END_NAMESPACE_C99 - - -#ifdef __USE_GNU -/* Write wide character representation of at most NMC bytes of the - multibyte character string SRC to DST. */ -extern size_t mbsnrtowcs (wchar_t *__restrict __dst, - __const char **__restrict __src, size_t __nmc, - size_t __len, mbstate_t *__restrict __ps) __THROW; - -/* Write multibyte character representation of at most NWC characters - from the wide character string SRC to DST. */ -extern size_t wcsnrtombs (char *__restrict __dst, - __const wchar_t **__restrict __src, - size_t __nwc, size_t __len, - mbstate_t *__restrict __ps) __THROW; -#endif /* use GNU */ - - -/* The following functions are extensions found in X/Open CAE. */ -#ifdef __USE_XOPEN -/* Determine number of column positions required for C. */ -extern int wcwidth (wchar_t __c) __THROW; - -/* Determine number of column positions required for first N wide - characters (or fewer if S ends before this) in S. */ -extern int wcswidth (__const wchar_t *__s, size_t __n) __THROW; -#endif /* Use X/Open. */ - - -__BEGIN_NAMESPACE_C99 -/* Convert initial portion of the wide string NPTR to `double' - representation. */ -extern double wcstod (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr) __THROW; - -#ifdef __USE_ISOC99 -/* Likewise for `float' and `long double' sizes of floating-point numbers. */ -extern float wcstof (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr) __THROW; -extern long double wcstold (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr) __THROW; -#endif /* C99 */ - - -/* Convert initial portion of wide string NPTR to `long int' - representation. */ -extern long int wcstol (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base) __THROW; - -/* Convert initial portion of wide string NPTR to `unsigned long int' - representation. */ -extern unsigned long int wcstoul (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base) - __THROW; - -#if defined __USE_ISOC99 || (defined __GNUC__ && defined __USE_GNU) -/* Convert initial portion of wide string NPTR to `long int' - representation. */ -__extension__ -extern long long int wcstoll (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base) - __THROW; - -/* Convert initial portion of wide string NPTR to `unsigned long long int' - representation. */ -__extension__ -extern unsigned long long int wcstoull (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __base) __THROW; -#endif /* ISO C99 or GCC and GNU. */ -__END_NAMESPACE_C99 - -#if defined __GNUC__ && defined __USE_GNU -/* Convert initial portion of wide string NPTR to `long int' - representation. */ -__extension__ -extern long long int wcstoq (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base) - __THROW; - -/* Convert initial portion of wide string NPTR to `unsigned long long int' - representation. */ -__extension__ -extern unsigned long long int wcstouq (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __base) __THROW; -#endif /* GCC and use GNU. */ - -#ifdef __STDC_WANT_DEC_FP__ -extern _Decimal32 wcstod32 (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr) __THROW; - -extern _Decimal64 wcstod64 (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr) __THROW; - -extern _Decimal128 wcstod128 (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr) __THROW; -#endif - -#ifdef __USE_GNU -/* The concept of one static locale per category is not very well - thought out. Many applications will need to process its data using - information from several different locales. Another application is - the implementation of the internationalization handling in the - upcoming ISO C++ standard library. To support this another set of - the functions using locale data exist which have an additional - argument. - - Attention: all these functions are *not* standardized in any form. - This is a proof-of-concept implementation. */ - -/* Structure for reentrant locale using functions. This is an - (almost) opaque type for the user level programs. */ -# include <xlocale.h> - -/* Special versions of the functions above which take the locale to - use as an additional parameter. */ -extern long int wcstol_l (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base, - __locale_t __loc) __THROW; - -extern unsigned long int wcstoul_l (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __base, __locale_t __loc) __THROW; - -__extension__ -extern long long int wcstoll_l (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __base, __locale_t __loc) __THROW; - -__extension__ -extern unsigned long long int wcstoull_l (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __base, __locale_t __loc) - __THROW; - -extern double wcstod_l (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, __locale_t __loc) - __THROW; - -extern float wcstof_l (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, __locale_t __loc) - __THROW; - -extern long double wcstold_l (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - __locale_t __loc) __THROW; -#endif /* GNU */ - - -/* The internal entry points for `wcstoX' take an extra flag argument - saying whether or not to parse locale-dependent number grouping. */ -extern double __wcstod_internal (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __group) - __THROW; -extern float __wcstof_internal (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __group) - __THROW; -extern long double __wcstold_internal (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __group) __THROW; - -#if !defined __wcstol_internal_defined \ - && defined __OPTIMIZE__ && __GNUC__ >= 2 -extern long int __wcstol_internal (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __base, int __group) __THROW; -# define __wcstol_internal_defined 1 -#endif -#if !defined __wcstoul_internal_defined \ - && defined __OPTIMIZE__ && __GNUC__ >= 2 -extern unsigned long int __wcstoul_internal (__const wchar_t *__restrict __npt, - wchar_t **__restrict __endptr, - int __base, int __group) __THROW; -# define __wcstoul_internal_defined 1 -#endif -#if !defined __wcstoll_internal_defined \ - && defined __OPTIMIZE__ && __GNUC__ >= 2 -__extension__ -extern long long int __wcstoll_internal (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, - int __base, int __group) __THROW; -# define __wcstoll_internal_defined 1 -#endif -#if !defined __wcstoull_internal_defined \ - && defined __OPTIMIZE__ && __GNUC__ >= 2 -__extension__ -extern unsigned long long int __wcstoull_internal (__const wchar_t * - __restrict __nptr, - wchar_t ** - __restrict __endptr, - int __base, - int __group) __THROW; -# define __wcstoull_internal_defined 1 -#endif - - -#if defined __OPTIMIZE__ && __GNUC__ >= 2 -/* Define inline functions which call the internal entry points. */ -__BEGIN_NAMESPACE_C99 - -extern __inline double -__NTH (wcstod (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr)) -{ return __wcstod_internal (__nptr, __endptr, 0); } -extern __inline long int -__NTH (wcstol (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base)) -{ return __wcstol_internal (__nptr, __endptr, __base, 0); } -extern __inline unsigned long int -__NTH (wcstoul (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base)) -{ return __wcstoul_internal (__nptr, __endptr, __base, 0); } -__END_NAMESPACE_C99 - -# ifdef __USE_GNU -extern __inline float -__NTH (wcstof (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr)) -{ return __wcstof_internal (__nptr, __endptr, 0); } -# ifndef __LDBL_COMPAT -extern __inline long double -__NTH (wcstold (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr)) -{ return __wcstold_internal (__nptr, __endptr, 0); } -# endif -__extension__ -extern __inline long long int -__NTH (wcstoq (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base)) -{ return __wcstoll_internal (__nptr, __endptr, __base, 0); } -__extension__ -extern __inline unsigned long long int -__NTH (wcstouq (__const wchar_t *__restrict __nptr, - wchar_t **__restrict __endptr, int __base)) -{ return __wcstoull_internal (__nptr, __endptr, __base, 0); } -# endif /* Use GNU. */ -#endif /* Optimizing GCC >=2. */ - - -#ifdef __USE_GNU -/* Copy SRC to DEST, returning the address of the terminating L'\0' in - DEST. */ -extern wchar_t *wcpcpy (wchar_t *__dest, __const wchar_t *__src) __THROW; - -/* Copy no more than N characters of SRC to DEST, returning the address of - the last character written into DEST. */ -extern wchar_t *wcpncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n) - __THROW; -#endif /* use GNU */ - - -/* Wide character I/O functions. */ -#if defined __USE_ISOC99 || defined __USE_UNIX98 -__BEGIN_NAMESPACE_C99 - -/* Select orientation for stream. */ -extern int fwide (__FILE *__fp, int __mode) __THROW; - - -/* Write formatted output to STREAM. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int fwprintf (__FILE *__restrict __stream, - __const wchar_t *__restrict __format, ...) - /* __attribute__ ((__format__ (__wprintf__, 2, 3))) */; -/* Write formatted output to stdout. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int wprintf (__const wchar_t *__restrict __format, ...) - /* __attribute__ ((__format__ (__wprintf__, 1, 2))) */; -/* Write formatted output of at most N characters to S. */ -extern int swprintf (wchar_t *__restrict __s, size_t __n, - __const wchar_t *__restrict __format, ...) - __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 4))) */; - -/* Write formatted output to S from argument list ARG. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int vfwprintf (__FILE *__restrict __s, - __const wchar_t *__restrict __format, - __gnuc_va_list __arg) - /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */; -/* Write formatted output to stdout from argument list ARG. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int vwprintf (__const wchar_t *__restrict __format, - __gnuc_va_list __arg) - /* __attribute__ ((__format__ (__wprintf__, 1, 0))) */; -/* Write formatted output of at most N character to S from argument - list ARG. */ -extern int vswprintf (wchar_t *__restrict __s, size_t __n, - __const wchar_t *__restrict __format, - __gnuc_va_list __arg) - __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */; - - -/* Read formatted input from STREAM. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int fwscanf (__FILE *__restrict __stream, - __const wchar_t *__restrict __format, ...) - /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; -/* Read formatted input from stdin. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int wscanf (__const wchar_t *__restrict __format, ...) - /* __attribute__ ((__format__ (__wscanf__, 1, 2))) */; -/* Read formatted input from S. */ -extern int swscanf (__const wchar_t *__restrict __s, - __const wchar_t *__restrict __format, ...) - __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; - -__END_NAMESPACE_C99 -#endif /* Use ISO C99 and Unix98. */ - -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 - -/* Read formatted input from S into argument list ARG. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int vfwscanf (__FILE *__restrict __s, - __const wchar_t *__restrict __format, - __gnuc_va_list __arg) - /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; -/* Read formatted input from stdin into argument list ARG. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern int vwscanf (__const wchar_t *__restrict __format, - __gnuc_va_list __arg) - /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */; -/* Read formatted input from S into argument list ARG. */ -extern int vswscanf (__const wchar_t *__restrict __s, - __const wchar_t *__restrict __format, - __gnuc_va_list __arg) - __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; - -__END_NAMESPACE_C99 -#endif /* Use ISO C99. */ - - -__BEGIN_NAMESPACE_C99 -/* Read a character from STREAM. - - These functions are possible cancellation points and therefore not - marked with __THROW. */ -extern wint_t fgetwc (__FILE *__stream); -extern wint_t getwc (__FILE *__stream); - -/* Read a character from stdin. - - This function is a possible cancellation point and therefore not - marked with __THROW. */ -extern wint_t getwchar (void); - - -/* Write a character to STREAM. - - These functions are possible cancellation points and therefore not - marked with __THROW. */ -extern wint_t fputwc (wchar_t __wc, __FILE *__stream); -extern wint_t putwc (wchar_t __wc, __FILE *__stream); - -/* Write a character to stdout. - - This function is a possible cancellation points and therefore not - marked with __THROW. */ -extern wint_t putwchar (wchar_t __wc); - - -/* Get a newline-terminated wide character string of finite length - from STREAM. - - This function is a possible cancellation points and therefore not - marked with __THROW. */ -extern wchar_t *fgetws (wchar_t *__restrict __ws, int __n, - __FILE *__restrict __stream); - -/* Write a string to STREAM. - - This function is a possible cancellation points and therefore not - marked with __THROW. */ -extern int fputws (__const wchar_t *__restrict __ws, - __FILE *__restrict __stream); - - -/* Push a character back onto the input buffer of STREAM. - - This function is a possible cancellation points and therefore not - marked with __THROW. */ -extern wint_t ungetwc (wint_t __wc, __FILE *__stream); -__END_NAMESPACE_C99 - - -#ifdef __USE_GNU -/* These are defined to be equivalent to the `char' functions defined - in POSIX.1:1996. - - These functions are not part of POSIX and therefore no official - cancellation point. But due to similarity with an POSIX interface - or due to the implementation they are cancellation points and - therefore not marked with __THROW. */ -extern wint_t getwc_unlocked (__FILE *__stream); -extern wint_t getwchar_unlocked (void); - -/* This is the wide character version of a GNU extension. - - This function is not part of POSIX and therefore no official - cancellation point. But due to similarity with an POSIX interface - or due to the implementation it is a cancellation point and - therefore not marked with __THROW. */ -extern wint_t fgetwc_unlocked (__FILE *__stream); - -/* Faster version when locking is not necessary. - - This function is not part of POSIX and therefore no official - cancellation point. But due to similarity with an POSIX interface - or due to the implementation it is a cancellation point and - therefore not marked with __THROW. */ -extern wint_t fputwc_unlocked (wchar_t __wc, __FILE *__stream); - -/* These are defined to be equivalent to the `char' functions defined - in POSIX.1:1996. - - These functions are not part of POSIX and therefore no official - cancellation point. But due to similarity with an POSIX interface - or due to the implementation they are cancellation points and - therefore not marked with __THROW. */ -extern wint_t putwc_unlocked (wchar_t __wc, __FILE *__stream); -extern wint_t putwchar_unlocked (wchar_t __wc); - - -/* This function does the same as `fgetws' but does not lock the stream. - - This function is not part of POSIX and therefore no official - cancellation point. But due to similarity with an POSIX interface - or due to the implementation it is a cancellation point and - therefore not marked with __THROW. */ -extern wchar_t *fgetws_unlocked (wchar_t *__restrict __ws, int __n, - __FILE *__restrict __stream); - -/* This function does the same as `fputws' but does not lock the stream. - - This function is not part of POSIX and therefore no official - cancellation point. But due to similarity with an POSIX interface - or due to the implementation it is a cancellation point and - therefore not marked with __THROW. */ -extern int fputws_unlocked (__const wchar_t *__restrict __ws, - __FILE *__restrict __stream); -#endif - - -__BEGIN_NAMESPACE_C99 -/* Format TP into S according to FORMAT. - Write no more than MAXSIZE wide characters and return the number - of wide characters written, or 0 if it would exceed MAXSIZE. */ -extern size_t wcsftime (wchar_t *__restrict __s, size_t __maxsize, - __const wchar_t *__restrict __format, - __const struct tm *__restrict __tp) __THROW; -__END_NAMESPACE_C99 - -# ifdef __USE_GNU -# include <xlocale.h> - -/* Similar to `wcsftime' but takes the information from - the provided locale and not the global locale. */ -extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize, - __const wchar_t *__restrict __format, - __const struct tm *__restrict __tp, - __locale_t __loc) __THROW; -# endif - -/* The X/Open standard demands that most of the functions defined in - the <wctype.h> header must also appear here. This is probably - because some X/Open members wrote their implementation before the - ISO C standard was published and introduced the better solution. - We have to provide these definitions for compliance reasons but we - do this nonsense only if really necessary. */ -#if defined __USE_UNIX98 && !defined __USE_GNU -# define __need_iswxxx -# include <wctype.h> -#endif - -/* Define some macros helping to catch buffer overflows. */ -#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus -# include <bits/wchar2.h> -#endif - -#ifdef __LDBL_COMPAT -# include <bits/wchar-ldbl.h> -#endif - -__END_DECLS - -#endif /* _WCHAR_H defined */ - -#endif /* wchar.h */ diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions index d4470bd43..83b4af5e7 100644 --- a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions +++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions @@ -1,5 +1,5 @@ libdfp { - GLIBC_2.5 { + GLIBC_2.6 { __addsd3; __adddd3; __addtd3; __subsd3; __subdd3; __subtd3; __mulsd3; __muldd3; __multd3; diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions index d4470bd43..83b4af5e7 100644 --- a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions +++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions @@ -1,5 +1,5 @@ libdfp { - GLIBC_2.5 { + GLIBC_2.6 { __addsd3; __adddd3; __addtd3; __subsd3; __subdd3; __subtd3; __mulsd3; __muldd3; __multd3; diff --git a/libc/dfp/sysdeps/soft-dfp/Versions b/libc/dfp/sysdeps/soft-dfp/Versions index fa6f9e9b6..93d731de2 100644 --- a/libc/dfp/sysdeps/soft-dfp/Versions +++ b/libc/dfp/sysdeps/soft-dfp/Versions @@ -1,5 +1,5 @@ libdfp { - GLIBC_2.5 { + GLIBC_2.6 { __addsd3; __adddd3; __addtd3; __subsd3; __subdd3; __subtd3; __mulsd3; __muldd3; __multd3; diff --git a/libc/math/bits/mathcalls.h b/libc/math/bits/mathcalls.h index 64da6276f..b787695de 100644 --- a/libc/math/bits/mathcalls.h +++ b/libc/math/bits/mathcalls.h @@ -281,7 +281,9 @@ __MATHCALL (rint,, (_Mdouble_ __x)); /* Return X + epsilon if X < Y, X - epsilon if X > Y. */ __MATHCALLX (nextafter,, (_Mdouble_ __x, _Mdouble_ __y), (__const__)); -# if defined __USE_ISOC99 && !defined __LDBL_COMPAT +# if defined __STDC_WANT_DEC_FP__ && __USE_DEC_FP_NEXTTOWARD__ +__MATHCALLX (nexttoward,, (_Mdouble_ __x, _Decimal128 __y), (__const__)); +# elif defined __USE_ISOC99 && !defined __LDBL_COMPAT __MATHCALLX (nexttoward,, (_Mdouble_ __x, long double __y), (__const__)); # endif diff --git a/libc/math/fenv.h b/libc/math/fenv.h index 8a06f024e..4f7237d5a 100644 --- a/libc/math/fenv.h +++ b/libc/math/fenv.h @@ -57,6 +57,10 @@ */ #include <bits/fenv.h> +#ifdef __STDC_WANT_DEC_FP__ +# include <bits/dfpfenv.h> +#endif + __BEGIN_DECLS /* Floating-point exception handling. */ diff --git a/libc/math/math.h b/libc/math/math.h index c50b2e7b0..d6d3651b3 100644 --- a/libc/math/math.h +++ b/libc/math/math.h @@ -64,6 +64,10 @@ __BEGIN_DECLS #define __MATHDECL_1(type, function,suffix, args) \ extern type __MATH_PRECNAME(function,suffix) args __THROW +#ifdef __USE_DEC_FP_NEXTTOWARD__ +#undef __USE_DEC_FP_NEXTTOWARD__ +#endif + #define _Mdouble_ double #define __MATH_PRECNAME(name,r) __CONCAT(name,r) # define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_STD @@ -74,6 +78,87 @@ __BEGIN_DECLS #undef _Mdouble_END_NAMESPACE #undef __MATH_PRECNAME +/* Decimal-Floating point support is outlined in ISO proposed C-specification + WG14 N1176 and IEEE 754r. */ +#ifdef __STDC_WANT_DEC_FP__ +#define DEC_INFINITY __builtin_infd32() +#define DEC_NAN (0.0DF * DEC_INFINITY) +# define HUGE_VAL_D64 __builtin_infd64() +/*# define DEC_INFINITY (9999999.E96DF + 1.E96df) +#define DEC_NAN (0.0DF * DEC_INFINITY) +# define HUGE_VAL_D64 (9.999999999999999E384DD + 1.E384dd) */ +# define HUGE_VAL_D32 HUGE_VAL_D64 +# define HUGE_VAL_D128 HUGE_VAL_D64 + +/* this causes the nexttoward mathcall to get a _Decimal128 second parameter + * rather than a long double one. */ +#define __USE_DEC_FP_NEXTTOWARD__ 1 + +#define __dfp_compatible(X) ((_Decimal128)(__typeof__(X))1.E-50DL == 1.E-50DL) + +/* For _Decimal32 */ +# ifndef _M_Decimal32_ +# define _M_Decimal32_ _Decimal32 +# endif +# define _Mdouble_ _M_Decimal32_ +# ifdef __STDC__ +# define __MATH_PRECNAME(name,r) name##d32##r +# else +# define __MATH_PRECNAME(name,r) name/**/d32/**/r +# endif +# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 +# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 +# include <bits/mathcalls.h> +# include <bits/dfpcalls.h> +# undef _Mdouble_ +# undef _Mdouble_BEGIN_NAMESPACE +# undef _Mdouble_END_NAMESPACE +# undef __MATH_PRECNAME + +/* For _Decimal64 */ +# ifndef _M_Decimal64_ +# define _M_Decimal64_ _Decimal64 +# endif +# define _Mdouble_ _M_Decimal64_ +# ifdef __STDC__ +# define __MATH_PRECNAME(name,r) name##d64##r +# else +# define __MATH_PRECNAME(name,r) name/**/d64/**/r +# endif +# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 +# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 +# include <bits/mathcalls.h> +# include <bits/dfpcalls.h> +# undef _Mdouble_ +# undef _Mdouble_BEGIN_NAMESPACE +# undef _Mdouble_END_NAMESPACE +# undef __MATH_PRECNAME + +/* For _Decimal128 */ +# ifndef _M_Decimal128_ +# define _M_Decimal128_ _Decimal128 +# endif +# define _Mdouble_ _M_Decimal128_ +# ifdef __STDC__ +# define __MATH_PRECNAME(name,r) name##d128##r +# else +# define __MATH_PRECNAME(name,r) name/**/d128/**/r +# endif +# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99 +# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99 +# include <bits/mathcalls.h> +# include <bits/dfpcalls.h> +# undef _Mdouble_ +# undef _Mdouble_BEGIN_NAMESPACE +# undef _Mdouble_END_NAMESPACE +# undef __MATH_PRECNAME + +#endif /* __STDC_WANT_DEC_FP__ */ + +#ifdef __USE_DEC_FP_NEXTTOWARD__ +#undef __USE_DEC_FP_NEXTTOWARD__ +#endif + #if defined __USE_MISC || defined __USE_ISOC99 @@ -194,7 +279,8 @@ extern int signgam; */ -/* All floating-point numbers can be put in one of these categories. */ +/* All decimal and binary floating-point numbers can be put in one of these + categories. */ enum { FP_NAN, @@ -211,68 +297,142 @@ enum /* Return number of classification appropriate for X. */ # ifdef __NO_LONG_DOUBLE_MATH -# define fpclassify(x) \ +# define ____fpclassify(x) \ (sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassify (x)) # else -# define fpclassify(x) \ +# define ____fpclassify(x) \ (sizeof (x) == sizeof (float) \ ? __fpclassifyf (x) \ : sizeof (x) == sizeof (double) \ ? __fpclassify (x) : __fpclassifyl (x)) # endif +# ifdef __STDC_WANT_DEC_FP__ +# define fpclassify(x) \ + ( \ + (!__dfp_compatible(x)? (____fpclassify(x)) : \ + (sizeof (x) == sizeof (_Decimal128)? __fpclassifyd128(x): \ + (sizeof (x) == sizeof (_Decimal64)? __fpclassifyd64(x): \ + __fpclassifyd32(x) \ + ) \ + ) \ + ) \ + ) +# else +# define fpclassify(x) ____fpclassify(x) +# endif + /* Return nonzero value if sign of X is negative. */ # ifdef __NO_LONG_DOUBLE_MATH -# define signbit(x) \ +# define ____signbit(x) \ (sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x)) # else -# define signbit(x) \ +# define ____signbit(x) \ (sizeof (x) == sizeof (float) \ ? __signbitf (x) \ : sizeof (x) == sizeof (double) \ ? __signbit (x) : __signbitl (x)) # endif +# ifdef __STDC_WANT_DEC_FP__ +# define signbit(x) \ + ( \ + (!__dfp_compatible(x)? (____signbit(x)) : \ + (sizeof (x) == sizeof (_Decimal128)? __signbitd128(x): \ + (sizeof (x) == sizeof (_Decimal64)? __signbitd64(x): \ + __signbitd32(x) \ + ) \ + ) \ + ) \ + ) +# else +# define signbit(x) ____signbit(x) +# endif + /* Return nonzero value if X is not +-Inf or NaN. */ # ifdef __NO_LONG_DOUBLE_MATH -# define isfinite(x) \ +# define ____isfinite(x) \ (sizeof (x) == sizeof (float) ? __finitef (x) : __finite (x)) # else -# define isfinite(x) \ +# define ____isfinite(x) \ (sizeof (x) == sizeof (float) \ ? __finitef (x) \ : sizeof (x) == sizeof (double) \ ? __finite (x) : __finitel (x)) # endif +# ifdef __STDC_WANT_DEC_FP__ +# define isfinite(x) \ + ( \ + (!__dfp_compatible(x)? (____isfinite(x)) : \ + (sizeof (x) == sizeof (_Decimal128)? __finited128(x): \ + (sizeof (x) == sizeof (_Decimal64)? __finited64(x): \ + __finited32(x) \ + ) \ + ) \ + ) \ + ) +# else +# define isfinite(x) ____isfinite(x) +# endif + /* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ # define isnormal(x) (fpclassify (x) == FP_NORMAL) /* Return nonzero value if X is a NaN. We could use `fpclassify' but we already have this functions `__isnan' and it is faster. */ # ifdef __NO_LONG_DOUBLE_MATH -# define isnan(x) \ +# define ____isnan(x) \ (sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x)) # else -# define isnan(x) \ - (sizeof (x) == sizeof (float) \ - ? __isnanf (x) \ - : sizeof (x) == sizeof (double) \ +# define ____isnan(x) \ + (sizeof (x) == sizeof (float) \ + ? __isnanf (x) \ + : sizeof (x) == sizeof (double) \ ? __isnan (x) : __isnanl (x)) # endif +# ifdef __STDC_WANT_DEC_FP__ +# define isnan(x) \ + (!__dfp_compatible(x) \ + ? (____isnan(x)) \ + : (sizeof (x) == sizeof (_Decimal128) \ + ? __isnand128(x) \ + : (sizeof (x) == sizeof (_Decimal64) \ + ? __isnand64(x) \ + : __isnand32(x))) \ + ) +# else +# define isnan(x) ____isnan(x) +# endif + /* Return nonzero value is X is positive or negative infinity. */ # ifdef __NO_LONG_DOUBLE_MATH -# define isinf(x) \ +# define _____isinf(x) \ (sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x)) # else -# define isinf(x) \ +# define ____isinf(x) \ (sizeof (x) == sizeof (float) \ ? __isinff (x) \ : sizeof (x) == sizeof (double) \ ? __isinf (x) : __isinfl (x)) # endif +# ifdef __STDC_WANT_DEC_FP__ +# define isinf(x) \ + ( \ + (!__dfp_compatible(x)? (____isinf(x)) : \ + (sizeof (x) == sizeof (_Decimal128)? __isinfd128(x): \ + (sizeof (x) == sizeof (_Decimal64)? __isinfd64(x): \ + __isinfd32(x) \ + ) \ + ) \ + ) \ + ) +# else +# define isinf(x) ____isinf(x) +# endif + /* Bitmasks for the math_errhandling macro. */ # define MATH_ERRNO 1 /* errno set by math functions. */ # define MATH_ERREXCEPT 2 /* Exceptions raised by math functions. */ @@ -381,6 +541,23 @@ extern int matherr (struct exception *__exc); # define M_SQRT1_2l 0.7071067811865475244008443621048490L /* 1/sqrt(2) */ #endif +/* Some useful constants for DFP support (with the DL specifier). Proper + * truncation to DD and DF will be handled by libdfp. */ +#ifdef __STDC_WANT_DEC_FP__ +# define M_Edl 2.7182818284590452353602874713526625DL /* e */ +# define M_LOG2Edl 1.4426950408889634073599246810018921DL /* log_2 e */ +# define M_LOG10Edl 0.4342944819032518276511289189166051DL /* log_10 e */ +# define M_LN2dl 0.6931471805599453094172321214581766DL /* log_e 2 */ +# define M_LN10dl 2.3025850929940456840179914546843642DL /* log_e 10 */ +# define M_PIdl 3.1415926535897932384626433832795029DL /* pi */ +# define M_PI_2dl 1.5707963267948966192313216916397514DL /* pi/2 */ +# define M_PI_4dl 0.7853981633974483096156608458198757DL /* pi/4 */ +# define M_1_PIdl 0.3183098861837906715377675267450287DL /* 1/pi */ +# define M_2_PIdl 0.6366197723675813430755350534900574DL /* 2/pi */ +# define M_2_SQRTPIdl 1.1283791670955125738961589031215452DL /* 2/sqrt(pi) */ +# define M_SQRT2dl 1.4142135623730950488016887242096981DL /* sqrt(2) */ +# define M_SQRT1_2dl 0.7071067811865475244008443621048490DL /* 1/sqrt(2) */ +#endif /* __STDC_WANT_DEC_FP__ */ /* When compiling in strict ISO C compatible mode we must not use the inline functions since they, among other things, do not set the diff --git a/libc/stdio-common/printf-parse.h b/libc/stdio-common/printf-parse.h index f6ad71cd3..a919423ed 100644 --- a/libc/stdio-common/printf-parse.h +++ b/libc/stdio-common/printf-parse.h @@ -60,6 +60,11 @@ union printf_arg const char *pa_string; const wchar_t *pa_wstring; void *pa_pointer; +#ifdef __STDC_DEC_FP__ + _Decimal128 pa_decimal128; + _Decimal64 pa_decimal64; + _Decimal32 pa_decimal32; +#endif }; diff --git a/libc/stdio-common/printf.h b/libc/stdio-common/printf.h index 360cdcce1..3d841e2fe 100644 --- a/libc/stdio-common/printf.h +++ b/libc/stdio-common/printf.h @@ -48,6 +48,9 @@ struct printf_info unsigned int is_char:1; /* hh flag. */ unsigned int wide:1; /* Nonzero for wide character streams. */ unsigned int i18n:1; /* I flag. */ +#ifdef __STDC_DEC_FP__ + unsigned int is_decimal:1; /* H/D/DD flags. */ +#endif wchar_t pad; /* Padding character. */ }; @@ -112,6 +115,9 @@ enum PA_POINTER, /* void * */ PA_FLOAT, /* float */ PA_DOUBLE, /* double */ +#ifdef __STDC_DEC_FP__ + PA_DECIMAL, /* _Decimal* types */ +#endif PA_LAST }; diff --git a/libc/stdio-common/vfprintf.c b/libc/stdio-common/vfprintf.c index d1dc1aaf5..0c87be989 100644 --- a/libc/stdio-common/vfprintf.c +++ b/libc/stdio-common/vfprintf.c @@ -31,6 +31,12 @@ #include "_itoa.h" #include <locale/localeinfo.h> #include <stdio.h> +#ifdef __STDC_DEC_FP__ +#include <printf_dfp.h> +#define IFDEF__STDC_DEC_FP__(...) __VA_ARGS__ +#else +#define IFDEF__STDC_DEC_FP__(...) +#endif /* This code is shared between the standard stdio implementation found in GNU C library and the libio implementation originally found in @@ -236,8 +242,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) /* '8' */ 8, /* '9' */ 8, 0, 0, 0, 0, 0, 0, 0, /* 'A' */ 26, 0, /* 'C' */ 25, +#ifdef __STDC_DEC_FP__ + /* 'D' */ 31, /* 'E' */ 19, /* F */ 19, /* 'G' */ 19, + /* 'H' */ 30, /* 'I' */ 29, 0, 0, +#else 0, /* 'E' */ 19, /* F */ 19, /* 'G' */ 19, 0, /* 'I' */ 29, 0, 0, +#endif /* 'L' */ 12, 0, 0, 0, 0, 0, 0, /* 'S' */ 21, 0, 0, 0, 0, @@ -285,7 +296,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) #define STEP0_3_TABLE \ /* Step 0: at the beginning. */ \ - static JUMP_TABLE_TYPE step0_jumps[30] = \ + static JUMP_TABLE_TYPE step0_jumps[] = \ { \ REF (form_unknown), \ REF (flag_space), /* for ' ' */ \ @@ -316,10 +327,14 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) REF (form_floathex), /* for 'A', 'a' */ \ REF (mod_ptrdiff_t), /* for 't' */ \ REF (mod_intmax_t), /* for 'j' */ \ - REF (flag_i18n), /* for 'I' */ \ + REF (flag_i18n) /* for 'I' */ \ +IFDEF__STDC_DEC_FP__(, \ + REF (mod_decimal_half), /* for 'H' */ \ + REF (mod_decimal) /* for 'D' */ \ +) \ }; \ /* Step 1: after processing width. */ \ - static JUMP_TABLE_TYPE step1_jumps[30] = \ + static JUMP_TABLE_TYPE step1_jumps[] = \ { \ REF (form_unknown), \ REF (form_unknown), /* for ' ' */ \ @@ -351,9 +366,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) REF (mod_ptrdiff_t), /* for 't' */ \ REF (mod_intmax_t), /* for 'j' */ \ REF (form_unknown) /* for 'I' */ \ +IFDEF__STDC_DEC_FP__(, \ + REF (mod_decimal_half), /* for 'H' */ \ + REF (mod_decimal), /* for 'D' */ \ +) \ }; \ /* Step 2: after processing precision. */ \ - static JUMP_TABLE_TYPE step2_jumps[30] = \ + static JUMP_TABLE_TYPE step2_jumps[] = \ { \ REF (form_unknown), \ REF (form_unknown), /* for ' ' */ \ @@ -385,9 +404,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) REF (mod_ptrdiff_t), /* for 't' */ \ REF (mod_intmax_t), /* for 'j' */ \ REF (form_unknown) /* for 'I' */ \ +IFDEF__STDC_DEC_FP__(, \ + REF (mod_decimal_half), /* for 'H' */ \ + REF (mod_decimal) /* for 'D' */ \ +) \ }; \ /* Step 3a: after processing first 'h' modifier. */ \ - static JUMP_TABLE_TYPE step3a_jumps[30] = \ + static JUMP_TABLE_TYPE step3a_jumps[] = \ { \ REF (form_unknown), \ REF (form_unknown), /* for ' ' */ \ @@ -419,9 +442,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) REF (form_unknown), /* for 't' */ \ REF (form_unknown), /* for 'j' */ \ REF (form_unknown) /* for 'I' */ \ +IFDEF__STDC_DEC_FP__(, \ + REF (form_unknown), /* for 'H' */ \ + REF (form_unknown) /* for 'D' */ \ +) \ }; \ /* Step 3b: after processing first 'l' modifier. */ \ - static JUMP_TABLE_TYPE step3b_jumps[30] = \ + static JUMP_TABLE_TYPE step3b_jumps[] = \ { \ REF (form_unknown), \ REF (form_unknown), /* for ' ' */ \ @@ -453,11 +480,52 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) REF (form_unknown), /* for 't' */ \ REF (form_unknown), /* for 'j' */ \ REF (form_unknown) /* for 'I' */ \ +IFDEF__STDC_DEC_FP__(, \ + REF (form_unknown), /* for 'H' */ \ + REF (form_unknown) /* for 'D' */ \ + }; \ + /* Some format codes should not be allowed for decimal-float. */ \ + /* Step 3c: after processing first 'D' modifier. */ \ + static JUMP_TABLE_TYPE step3c_jumps[] = \ + { \ + REF (form_unknown), \ + REF (form_unknown), /* for ' ' */ \ + REF (form_unknown), /* for '+' */ \ + REF (form_unknown), /* for '-' */ \ + REF (form_unknown), /* for '<hash>' */ \ + REF (form_unknown), /* for '0' */ \ + REF (form_unknown), /* for '\'' */ \ + REF (form_unknown), /* for '*' */ \ + REF (form_unknown), /* for '1'...'9' */ \ + REF (form_unknown), /* for '.' */ \ + REF (form_unknown), /* for 'h' */ \ + REF (form_unknown), /* for 'l' */ \ + REF (form_unknown), /* for 'L', 'q' */ \ + REF (form_unknown), /* for 'z', 'Z' */ \ + REF (form_percent), /* for '%' */ \ + REF (form_integer), /* for 'd', 'i' */ \ + REF (form_unsigned), /* for 'u' */ \ + REF (form_octal), /* for 'o' */ \ + REF (form_hexa), /* for 'X', 'x' */ \ + REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \ + REF (form_character), /* for 'c' */ \ + REF (form_string), /* for 's', 'S' */ \ + REF (form_pointer), /* for 'p' */ \ + REF (form_number), /* for 'n' */ \ + REF (form_strerror), /* for 'm' */ \ + REF (form_wcharacter), /* for 'C' */ \ + REF (form_floathex), /* for 'A', 'a' */ \ + REF (form_unknown), /* for 't' */ \ + REF (form_unknown), /* for 'j' */ \ + REF (form_unknown), /* for 'I' */ \ + REF (form_unknown), /* for 'H' */ \ + REF (mod_decimal_long) /* for 'D' */ \ +) \ } #define STEP4_TABLE \ /* Step 4: processing format specifier. */ \ - static JUMP_TABLE_TYPE step4_jumps[30] = \ + static JUMP_TABLE_TYPE step4_jumps[] = \ { \ REF (form_unknown), \ REF (form_unknown), /* for ' ' */ \ @@ -489,6 +557,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) REF (form_unknown), /* for 't' */ \ REF (form_unknown), /* for 'j' */ \ REF (form_unknown) /* for 'I' */ \ +IFDEF__STDC_DEC_FP__(, \ + REF (form_unknown), /* for 'H' */ \ + REF (form_unknown) /* for 'D' */ \ +) \ } @@ -782,14 +854,30 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) .pad = pad, \ .extra = 0, \ .i18n = use_outdigits, \ +IFDEF__STDC_DEC_FP__( .is_decimal = is_decimal, ) \ .wide = sizeof (CHAR_T) != 1 }; \ \ - if (is_long_double) \ + if (is_long_double IFDEF__STDC_DEC_FP__(&& !is_decimal)) \ the_arg.pa_long_double = va_arg (ap, long double); \ +IFDEF__STDC_DEC_FP__( \ + else if (is_long_double && is_decimal) \ + the_arg.pa_decimal128 = va_arg (ap, _Decimal128); \ + else if (is_short && is_decimal) \ + /* The specification indicates that _Decimal32 should */ \ + /* NOT be promoted to _Decimal64 for DFP types. */ \ + the_arg.pa_decimal32 = va_arg (ap, _Decimal32); \ + else if (is_decimal && !is_long_double && !is_short) \ + the_arg.pa_decimal64 = va_arg (ap, _Decimal64); \ +) \ else \ the_arg.pa_double = va_arg (ap, double); \ ptr = (const void *) &the_arg; \ \ +IFDEF__STDC_DEC_FP__( \ + if (is_decimal) \ + function_done = __printf_dfp (s, &info, &ptr); \ + else \ +) \ function_done = __printf_fp (s, &info, &ptr); \ } \ else \ @@ -839,14 +927,28 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) .group = group, \ .pad = pad, \ .extra = 0, \ +IFDEF__STDC_DEC_FP__( .is_decimal = is_decimal, ) \ .wide = sizeof (CHAR_T) != 1 }; \ \ - if (is_long_double) \ + if (is_long_double IFDEF__STDC_DEC_FP__(&& !is_decimal)) \ the_arg.pa_long_double = va_arg (ap, long double); \ +IFDEF__STDC_DEC_FP__( \ + else if (is_long_double && is_decimal) \ + the_arg.pa_decimal128 = va_arg (ap, _Decimal128); \ + else if (is_short && is_decimal) \ + the_arg.pa_decimal32 = va_arg (ap, _Decimal32); \ + else if (is_decimal && !is_long_double && !is_short) \ + the_arg.pa_decimal64 = va_arg (ap, _Decimal64); \ +) \ else \ the_arg.pa_double = va_arg (ap, double); \ ptr = (const void *) &the_arg; \ \ +IFDEF__STDC_DEC_FP__( \ + if (is_decimal) \ + function_done = __printf_dfphex (s, &info, &ptr); \ + else \ +) \ function_done = __printf_fphex (s, &info, &ptr); \ } \ else \ @@ -855,6 +957,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (__ldbl_is_dbl) \ fspec->info.is_long_double = 0; \ \ +IFDEF__STDC_DEC_FP__( \ + /* FIX ME */ \ + if (is_decimal) \ + function_done = __printf_dfphex (s, &fspec->info, &ptr); \ + else \ +) \ function_done = __printf_fphex (s, &fspec->info, &ptr); \ } \ \ @@ -1336,6 +1444,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) int is_short = 0; /* Argument is short int. */ int is_long = 0; /* Argument is long int. */ int is_char = 0; /* Argument is promoted (unsigned) char. */ +#ifdef __STDC_DEC_FP__ + int is_decimal = 0; /* Argument is decimal floating point. */ +#endif int width = 0; /* Width of output; 0 means none specified. */ int prec = -1; /* Precision of output; -1 means none specified. */ /* This flag is set by the 'I' modifier and selects the use of the @@ -1553,6 +1664,31 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) is_long = sizeof (intmax_t) > sizeof (unsigned int); JUMP (*++f, step4_jumps); +#ifdef __STDC_DEC_FP__ + /* Process 'H' modifier. No other modifier is allowed to follow. */ + LABEL (mod_decimal_half): + is_decimal = 1; + is_short = 1; + JUMP (*++f, step4_jumps); + + /* Process 'D' modifier. There might be another 'D' following. */ + LABEL (mod_decimal): + is_decimal = 1; + is_short = 0; + is_long = 0; + JUMP (*++f, step3c_jumps); + + /* Process 'DD' modifier. */ + LABEL (mod_decimal_long): + /* is_decimal = 0; */ + is_decimal = 1; + is_long_double = 1; + JUMP (*++f, step4_jumps); + + /* The previous step3c_jumps or step4_jumps will jump directly + * to the LABELs defined in the process_arg macro. */ +#endif + /* Process current format. */ while (1) { @@ -1730,6 +1866,11 @@ do_positional: T (PA_INT|PA_FLAG_LONG_LONG, pa_long_long_int, long long int); T (PA_FLOAT, pa_double, double); /* Promoted. */ T (PA_DOUBLE, pa_double, double); +#ifdef __STDC_DEC_FP__ + T (PA_DECIMAL, pa_decimal32, _Decimal32); + T (PA_DECIMAL|PA_FLAG_SHORT, pa_decimal64, _Decimal64); + T (PA_DECIMAL|PA_FLAG_LONG_DOUBLE, pa_decimal128, _Decimal128); +#endif case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: if (__ldbl_is_dbl) { @@ -1792,6 +1933,9 @@ do_positional: int width = specs[nspecs_done].info.width; int prec = specs[nspecs_done].info.prec; int use_outdigits = specs[nspecs_done].info.i18n; +#ifdef __STDC_DEC_FP__ + int is_decimal = specs[nspecs_done].info.is_decimal; +#endif char pad = specs[nspecs_done].info.pad; CHAR_T spec = specs[nspecs_done].info.spec; diff --git a/libc/stdio-common/vfscanf.c b/libc/stdio-common/vfscanf.c index e4728d00c..5555919f2 100644 --- a/libc/stdio-common/vfscanf.c +++ b/libc/stdio-common/vfscanf.c @@ -24,6 +24,9 @@ #include <stdio.h> #include <stdint.h> #include <stdlib.h> +#ifdef __STDC_DEC_FP__ +#include <dfpstdlib.h> +#endif #include <string.h> #include <wchar.h> #include <wctype.h> @@ -67,6 +70,9 @@ #define READ_POINTER 0x1000 /* this is a pointer value */ #define POSIX_MALLOC 0x2000 /* m: malloc strings */ #define MALLOC (GNU_MALLOC | POSIX_MALLOC) +#ifdef __STDC_DEC_FP__ +#define DECIMAL 0x4000 /* H/D/DD: decimal float */ +#endif #include <locale/localeinfo.h> #include <libioP.h> @@ -583,6 +589,9 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, skip_space = 0; } +#ifdef __STDC_DEC_FP__ +found_decimal: +#endif switch (fc) { case L_('%'): /* Must match a literal '%'. */ @@ -1777,6 +1786,31 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, } break; +#ifdef __STDC_DEC_FP__ + case L_('H'): /* _Decimal32 */ + base = 10; + /*number_signed = 1;*/ + negative = 1; + flags |= DECIMAL | SHORT; + fc = *f++; + /* Pick up trailing float modifier. */ + goto found_decimal; + + case L_('D'): /* _Decimal64 */ + flags |= DECIMAL; + base = 10; + /*number_signed = 1;*/ + negative = 1; + char tfc; + tfc = *f++; + if (tfc == L_('D')) /* _Decimal128 */ + flags |= LONGDBL; + else + --f; /* Only one 'D'. Back it up. It is not %DD. */ + fc = *f++; + /* Pick up trailing float modifier. */ + goto found_decimal; +#endif case L_('e'): /* Floating-point numbers. */ case L_('E'): case L_('f'): @@ -2253,6 +2287,29 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, scan_float: /* Convert the number. */ ADDW (L_('\0')); +#ifdef __STDC_DEC_FP__ + if((flags & DECIMAL) && (flags & SHORT)) + { + _Decimal32 d = __strtod32_internal(wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) + /* va_arg is currently busted in libgcc for _Decimal32 so this + * will segfault */ + *ARG (_Decimal32 *) = negative ? -d : d; + } + else if((flags & DECIMAL) && (flags & LONGDBL)) + { + _Decimal128 d = __strtod128_internal(wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) + *ARG (_Decimal128 *) = negative ? -d : d; + } + else if (flags & DECIMAL) + { + _Decimal64 d = __strtod64_internal(wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) + *ARG (_Decimal64 *) = negative ? -d : d; + } + else +#endif if ((flags & LONGDBL) && !__ldbl_is_dbl) { long double d = __strtold_internal (wp, &tw, flags & GROUP); diff --git a/libc/stdlib/stdlib.h b/libc/stdlib/stdlib.h index 3c2ea72a5..661e3f0f1 100644 --- a/libc/stdlib/stdlib.h +++ b/libc/stdlib/stdlib.h @@ -219,6 +219,26 @@ __END_NAMESPACE_C99 #endif /* ISO C99 or GCC and use MISC. */ +#ifdef __STDC_WANT_DEC_FP__ +__BEGIN_NAMESPACE_STD +/* Convert a string to a _Decimal32 number. */ +extern _Decimal32 strtod32 (__const char *__restrict __nptr, + char **__restrict __endptr) + __THROW __nonnull ((1)) __wur; +/* Convert a string to a _Decimal64 number. */ + +extern _Decimal64 strtod64 (__const char *__restrict __nptr, + char **__restrict __endptr) + __THROW __nonnull ((1)) __wur; + +/* Convert a string to a _Decimal128 number. */ +extern _Decimal128 strtod128 (__const char *__restrict __nptr, + char **__restrict __endptr) + __THROW __nonnull ((1)) __wur; +__END_NAMESPACE_STD +#endif /* __STDC_WANT_DEC_FP__ */ + + #ifdef __USE_GNU /* The concept of one static locale per category is not very well thought out. Many applications will need to process its data using diff --git a/libc/wcsmbs/wchar.h b/libc/wcsmbs/wchar.h index 885662b07..b116ebb6e 100644 --- a/libc/wcsmbs/wchar.h +++ b/libc/wcsmbs/wchar.h @@ -456,6 +456,17 @@ extern unsigned long long int wcstouq (__const wchar_t *__restrict __nptr, int __base) __THROW; #endif /* GCC and use GNU. */ +#ifdef __STDC_WANT_DEC_FP__ +extern _Decimal32 wcstod32 (__const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr) __THROW; + +extern _Decimal64 wcstod64 (__const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr) __THROW; + +extern _Decimal128 wcstod128 (__const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr) __THROW; +#endif /* __STDC_WANT_DEC_FP__ */ + #ifdef __USE_GNU /* The concept of one static locale per category is not very well thought out. Many applications will need to process its data using |