diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:52 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 18:24:51 -0500 |
commit | f5e48e94a2f4d4bbd6e5628c7f2afafc6dbcc459 (patch) | |
tree | 93b156621dc0303816b37f60ba88051b702d92f6 /lib/mlibc/options/ansi/generic | |
parent | bd5969fc876a10b18613302db7087ef3c40f18e1 (diff) |
build: Build mlibc + add distclean target
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/ansi/generic')
68 files changed, 0 insertions, 10807 deletions
diff --git a/lib/mlibc/options/ansi/generic/assert-stubs.cpp b/lib/mlibc/options/ansi/generic/assert-stubs.cpp deleted file mode 100644 index 6ebb6ed..0000000 --- a/lib/mlibc/options/ansi/generic/assert-stubs.cpp +++ /dev/null @@ -1,13 +0,0 @@ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> - -#include <bits/ensure.h> - -[[gnu::noreturn]] void __assert_fail(const char *assertion, const char *file, unsigned int line, - const char *function) { - fprintf(stderr, "In function %s, file %s:%d: Assertion '%s' failed!\n", - function, file, line, assertion); - abort(); -} diff --git a/lib/mlibc/options/ansi/generic/complex-stubs.c b/lib/mlibc/options/ansi/generic/complex-stubs.c deleted file mode 100644 index 069626b..0000000 --- a/lib/mlibc/options/ansi/generic/complex-stubs.c +++ /dev/null @@ -1,9 +0,0 @@ -#include <complex.h> - -long double cimagl(long double complex z) { - return __imag__(z); -} - -long double creall(long double complex z) { - return __real__(z); -} diff --git a/lib/mlibc/options/ansi/generic/complex/cabs.c b/lib/mlibc/options/ansi/generic/complex/cabs.c deleted file mode 100644 index 2750fab..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cabs.c +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: cabs.c,v 1.1 2007/08/20 16:01:30 drochner Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<cabs>>, <<cabsf>>---complex absolute-value - -INDEX - cabs -INDEX - cabsf - -ANSI_SYNOPSIS - #include <complex.h> - double cabs(double complex <[z]>); - float cabsf(float complex <[z]>); - - -DESCRIPTION - These functions compute compute the complex absolute value - (also called norm, modulus, or magnitude) of <[z]>. - - <<cabsf>> is identical to <<cabs>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The cabs functions return the complex absolute value. - -PORTABILITY - <<cabs>> and <<cabsf>> are ISO C99 - -QUICKREF - <<cabs>> and <<cabsf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> - -double -cabs(double complex z) -{ - - return hypot( creal(z), cimag(z) ); -} diff --git a/lib/mlibc/options/ansi/generic/complex/cabsf.c b/lib/mlibc/options/ansi/generic/complex/cabsf.c deleted file mode 100644 index 635e23e..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cabsf.c +++ /dev/null @@ -1,19 +0,0 @@ -/* $NetBSD: cabsf.c,v 1.1 2007/08/20 16:01:30 drochner Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float -cabsf(float complex z) -{ - - return hypotf( crealf(z), cimagf(z) ); -} diff --git a/lib/mlibc/options/ansi/generic/complex/cacos.c b/lib/mlibc/options/ansi/generic/complex/cacos.c deleted file mode 100644 index 86e1198..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cacos.c +++ /dev/null @@ -1,99 +0,0 @@ -/* $NetBSD: cacos.c,v 1.1 2007/08/20 16:01:30 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<cacos>>, <<cacosf>>---complex arc cosine - -INDEX - cacos -INDEX - cacosf - -ANSI_SYNOPSIS - #include <complex.h> - double complex cacos(double complex <[z]>); - float complex cacosf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex arc cosine of <[z]>, - with branch cuts outside the interval [-1, +1] along the real axis. - - <<cacosf>> is identical to <<cacos>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - These functions return the complex arc cosine value, in the range - of a strip mathematically unbounded along the imaginary axis - and in the interval [0, pi] along the real axis. - @end ifnottex - @tex - These functions return the complex arc cosine value, in the range - of a strip mathematically unbounded along the imaginary axis - and in the interval [<<0>>, $\pi$] along the real axis. - @end tex - -PORTABILITY - <<cacos>> and <<cacosf>> are ISO C99 - -QUICKREF - <<cacos>> and <<cacosf>> are ISO C99 - -*/ - -#include <complex.h> -#include <math.h> - -double complex -cacos(double complex z) -{ - double complex w; - - /* FIXME: The original NetBSD code results in an ICE when trying to - build this function on ARM/Thumb using gcc 4.5.1. For now we use - a hopefully temporary workaround. */ -#if 0 - w = casin(z); - w = (M_PI_2 - creal(w)) - cimag(w) * I; -#else - double complex tmp0, tmp1; - - tmp0 = casin(z); - tmp1 = M_PI_2 - creal(tmp0); - w = tmp1 - (cimag(tmp0) * I); -#endif - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cacosf.c b/lib/mlibc/options/ansi/generic/complex/cacosf.c deleted file mode 100644 index 3874dd5..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cacosf.c +++ /dev/null @@ -1,46 +0,0 @@ -/* $NetBSD: cacosf.c,v 1.1 2007/08/20 16:01:30 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -cacosf(float complex z) -{ - float complex w; - - w = casinf(z); - w = ((float)M_PI_2 - crealf(w)) - cimagf(w) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cacosh.c b/lib/mlibc/options/ansi/generic/complex/cacosh.c deleted file mode 100644 index 3d42c40..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cacosh.c +++ /dev/null @@ -1,93 +0,0 @@ -/* $NetBSD: cacosh.c,v 1.2 2009/08/03 19:41:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<cacosh>>, <<cacoshf>>---complex arc hyperbolic cosine - -INDEX - cacosh -INDEX - cacoshf - -ANSI_SYNOPSIS - #include <complex.h> - double complex cacosh(double complex <[z]>); - float complex cacoshf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex arc hyperbolic cosine of <[z]>, - with a branch cut at values less than 1 along the real axis. - - <<cacoshf>> is identical to <<cacosh>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - These functions return the complex arc hyperbolic cosine value, - in the range of a half-strip of non-negative values along the - real axis and in the interval [-i * pi, +i * pi] along the - imaginary axis. - @end ifnottex - @tex - These functions return the complex arc hyperbolic cosine value, - in the range of a half-strip of non-negative values along the - real axis and in the interval [$-i\pi$, $+i\pi$] along the - imaginary axis. - @end tex - -PORTABILITY - <<cacosh>> and <<cacoshf>> are ISO C99 - -QUICKREF - <<cacosh>> and <<cacoshf>> are ISO C99 - -*/ - - -#include <complex.h> - -double complex -cacosh(double complex z) -{ - double complex w; - -#if 0 /* does not give the principal value */ - w = I * cacos(z); -#else - w = clog(z + csqrt(z + 1) * csqrt(z - 1)); -#endif - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cacoshf.c b/lib/mlibc/options/ansi/generic/complex/cacoshf.c deleted file mode 100644 index 41a557a..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cacoshf.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: cacoshf.c,v 1.2 2009/08/03 19:41:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> - -float complex -cacoshf(float complex z) -{ - float complex w; - -#if 0 /* does not give the principal value */ - w = I * cacosf(z); -#else - w = clogf(z + csqrtf(z + 1) * csqrtf(z - 1)); -#endif - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/carg.c b/lib/mlibc/options/ansi/generic/complex/carg.c deleted file mode 100644 index 0447420..0000000 --- a/lib/mlibc/options/ansi/generic/complex/carg.c +++ /dev/null @@ -1,59 +0,0 @@ -/* $NetBSD: carg.c,v 1.1 2007/08/20 16:01:31 drochner Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<carg>>, <<cargf>>---argument (phase angle) - -INDEX - carg -INDEX - cargf - -ANSI_SYNOPSIS - #include <complex.h> - double carg(double complex <[z]>); - float cargf(float complex <[z]>); - - -DESCRIPTION - These functions compute the argument (also called phase angle) - of <[z]>, with a branch cut along the negative real axis. - - <<cargf>> is identical to <<carg>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - The carg functions return the value of the argument in the - interval [-pi, +pi] - @end ifnottex - @tex - The carg functions return the value of the argument in the - interval [$-\pi$, $+\pi$] - @end tex - -PORTABILITY - <<carg>> and <<cargf>> are ISO C99 - -QUICKREF - <<carg>> and <<cargf>> are ISO C99 - -*/ - -#include <complex.h> -#include <math.h> - -double -carg(double complex z) -{ - - return atan2( cimag(z) , creal(z) ); -} diff --git a/lib/mlibc/options/ansi/generic/complex/cargf.c b/lib/mlibc/options/ansi/generic/complex/cargf.c deleted file mode 100644 index 1683d21..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cargf.c +++ /dev/null @@ -1,19 +0,0 @@ -/* $NetBSD: cargf.c,v 1.1 2007/08/20 16:01:31 drochner Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float -cargf(float complex z) -{ - - return atan2f( cimagf(z), crealf(z) ); -} diff --git a/lib/mlibc/options/ansi/generic/complex/casin.c b/lib/mlibc/options/ansi/generic/complex/casin.c deleted file mode 100644 index 5019fd8..0000000 --- a/lib/mlibc/options/ansi/generic/complex/casin.c +++ /dev/null @@ -1,165 +0,0 @@ -/* $NetBSD: casin.c,v 1.1 2007/08/20 16:01:31 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<casin>>, <<casinf>>---complex arc sine - -INDEX - casin -INDEX - casinf - -ANSI_SYNOPSIS - #include <complex.h> - double complex casin(double complex <[z]>); - float complex casinf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex arc sine of <[z]>, - with branch cuts outside the interval [-1, +1] along the real axis. - - <<casinf>> is identical to <<casin>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - These functions return the complex arc sine value, in the range - of a strip mathematically unbounded along the imaginary axis - and in the interval [-pi/2, +pi/2] along the real axis. - @end ifnottex - @tex - These functions return the complex arc sine value, in the range - of a strip mathematically unbounded along the imaginary axis - and in the interval [$-\pi/2$, $+\pi/2$] along the real axis. - @end tex - -PORTABILITY - <<casin>> and <<casinf>> are ISO C99 - -QUICKREF - <<casin>> and <<casinf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> - -#ifdef __weak_alias -__weak_alias(casin, _casin) -#endif - -double complex -casin(double complex z) -{ - double complex w; - double complex ca, ct, zz, z2; - double x, y; - - x = creal(z); - y = cimag(z); - -#if 0 /* MD: test is incorrect, casin(>1) is defined */ - if (y == 0.0) { - if (fabs(x) > 1.0) { - w = M_PI_2 + 0.0 * I; -#if 0 - mtherr ("casin", DOMAIN); -#endif - } else { - w = asin(x) + 0.0 * I; - } - return w; - } -#endif - -/* Power series expansion */ -/* -b = cabs(z); -if( b < 0.125 ) -{ -z2.r = (x - y) * (x + y); -z2.i = 2.0 * x * y; - -cn = 1.0; -n = 1.0; -ca.r = x; -ca.i = y; -sum.r = x; -sum.i = y; -do - { - ct.r = z2.r * ca.r - z2.i * ca.i; - ct.i = z2.r * ca.i + z2.i * ca.r; - ca.r = ct.r; - ca.i = ct.i; - - cn *= n; - n += 1.0; - cn /= n; - n += 1.0; - b = cn/n; - - ct.r *= b; - ct.i *= b; - sum.r += ct.r; - sum.i += ct.i; - b = fabs(ct.r) + fabs(ct.i); - } -while( b > MACHEP ); -w->r = sum.r; -w->i = sum.i; -return; -} -*/ - - - ca = x + y * I; - ct = ca * I; - /* sqrt( 1 - z*z) */ - /* cmul( &ca, &ca, &zz ) */ - /*x * x - y * y */ - zz = (x - y) * (x + y) + (2.0 * x * y) * I; - - zz = 1.0 - creal(zz) - cimag(zz) * I; - z2 = csqrt(zz); - - zz = ct + z2; - zz = clog(zz); - /* multiply by 1/i = -i */ - w = zz * (-1.0 * I); - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/casinf.c b/lib/mlibc/options/ansi/generic/complex/casinf.c deleted file mode 100644 index 9a9f759..0000000 --- a/lib/mlibc/options/ansi/generic/complex/casinf.c +++ /dev/null @@ -1,122 +0,0 @@ -/* $NetBSD: casinf.c,v 1.1 2007/08/20 16:01:31 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -#ifdef __weak_alias -__weak_alias(casinf, _casinf) -#endif - -float complex -casinf(float complex z) -{ - float complex w; - float complex ca, ct, zz, z2; - float x, y; - - x = crealf(z); - y = cimagf(z); - -#if 0 /* MD: test is incorrect, casin(>1) is defined */ - if (y == 0.0f) { - if (fabsf(x) > 1.0) { - w = M_PI_2 + 0.0f * I; -#if 0 - mtherr ("casin", DOMAIN); -#endif - } else { - w = asinf(x) + 0.0f * I; - } - return w; - } -#endif - -/* Power series expansion */ -/* -b = cabsf(z); -if( b < 0.125 ) -{ -z2.r = (x - y) * (x + y); -z2.i = 2.0 * x * y; - -cn = 1.0; -n = 1.0; -ca.r = x; -ca.i = y; -sum.r = x; -sum.i = y; -do - { - ct.r = z2.r * ca.r - z2.i * ca.i; - ct.i = z2.r * ca.i + z2.i * ca.r; - ca.r = ct.r; - ca.i = ct.i; - - cn *= n; - n += 1.0; - cn /= n; - n += 1.0; - b = cn/n; - - ct.r *= b; - ct.i *= b; - sum.r += ct.r; - sum.i += ct.i; - b = fabsf(ct.r) + fabsf(ct.i); - } -while( b > MACHEP ); -w->r = sum.r; -w->i = sum.i; -return; -} -*/ - - - ca = x + y * I; - ct = ca * I; - /* sqrt( 1 - z*z) */ - /* cmul( &ca, &ca, &zz ) */ - /*x * x - y * y */ - zz = (x - y) * (x + y) + (2.0f * x * y) * I; - - zz = 1.0f - crealf(zz) - cimagf(zz) * I; - z2 = csqrtf(zz); - - zz = ct + z2; - zz = clogf(zz); - /* multiply by 1/i = -i */ - w = zz * (-1.0f * I); - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/casinh.c b/lib/mlibc/options/ansi/generic/complex/casinh.c deleted file mode 100644 index 16238a6..0000000 --- a/lib/mlibc/options/ansi/generic/complex/casinh.c +++ /dev/null @@ -1,97 +0,0 @@ -/* $NetBSD: casinh.c,v 1.1 2007/08/20 16:01:31 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<casinh>>, <<casinhf>>---complex arc hyperbolic sine - -INDEX - casinh -INDEX - casinhf - -ANSI_SYNOPSIS - #include <complex.h> - double complex casinh(double complex <[z]>); - float complex casinhf(float complex <[z]>); - - -DESCRIPTION - @ifnottex - These functions compute the complex arc hyperbolic sine of <[z]>, - with branch cuts outside the interval [-i, +i] along the - imaginary axis. - @end ifnottex - @tex - These functions compute the complex arc hyperbolic sine of <[z]>, - with branch cuts outside the interval [$-i$, $+i$] along the - imaginary axis. - @end tex - - <<casinhf>> is identical to <<casinh>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - These functions return the complex arc hyperbolic sine value, - in the range of a strip mathematically unbounded along the - real axis and in the interval [-i*p/2, +i*p/2] along the - imaginary axis. - @end ifnottex - @tex - These functions return the complex arc hyperbolic sine value, - in the range of a strip mathematically unbounded along the - real axis and in the interval [$-i\pi/2$, $+i\pi/2$] along the - imaginary axis. - @end tex - -PORTABILITY - <<casinh>> and <<casinhf>> are ISO C99 - -QUICKREF - <<casinh>> and <<casinhf>> are ISO C99 - -*/ - - -#include <complex.h> - -double complex -casinh(double complex z) -{ - double complex w; - - w = -1.0 * I * casin(z * I); - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/casinhf.c b/lib/mlibc/options/ansi/generic/complex/casinhf.c deleted file mode 100644 index 0db55a0..0000000 --- a/lib/mlibc/options/ansi/generic/complex/casinhf.c +++ /dev/null @@ -1,44 +0,0 @@ -/* $NetBSD: casinhf.c,v 1.1 2007/08/20 16:01:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> - -float complex -casinhf(float complex z) -{ - float complex w; - - w = -1.0f * I * casinf(z * I); - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/catan.c b/lib/mlibc/options/ansi/generic/complex/catan.c deleted file mode 100644 index 0cf4739..0000000 --- a/lib/mlibc/options/ansi/generic/complex/catan.c +++ /dev/null @@ -1,130 +0,0 @@ -/* $NetBSD: catan.c,v 1.1 2007/08/20 16:01:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<catan>>, <<catanf>>---complex arc tangent - -INDEX - catan -INDEX - catanf - -ANSI_SYNOPSIS - #include <complex.h> - double complex catan(double complex <[z]>); - float complex catanf(float complex <[z]>); - - -DESCRIPTION - @ifnottex - These functions compute the complex arc tangent of <[z]>, - with branch cuts outside the interval [-i, +i] along the - imaginary axis. - @end ifnottex - @tex - These functions compute the complex arc tangent of <[z]>, - with branch cuts outside the interval [$-i$, $+i$] along the - imaginary axis. - @end tex - - <<catanf>> is identical to <<catan>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - These functions return the complex arc tangent value, in the range - of a strip mathematically unbounded along the imaginary axis - and in the interval [-pi/2, +pi/2] along the real axis. - @end ifnottex - @tex - These functions return the complex arc tangent, in the range - of a strip mathematically unbounded along the imaginary axis - and in the interval [$-\pi/2$, $+\pi/2$] along the real axis. - @end tex - -PORTABILITY - <<catan>> and <<catanf>> are ISO C99 - -QUICKREF - <<catan>> and <<catanf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> -#include "cephes_subr.h" - -#ifdef __weak_alias -__weak_alias(catan, _catan) -#endif - -double complex -catan(double complex z) -{ - double complex w; - double a, t, x, x2, y; - - x = creal(z); - y = cimag(z); - - if ((x == 0.0) && (y > 1.0)) - goto ovrf; - - x2 = x * x; - a = 1.0 - x2 - (y * y); - if (a == 0.0) - goto ovrf; - - t = 0.5 * atan2(2.0 * x, a); - w = __mlibc_redupi(t); - - t = y - 1.0; - a = x2 + (t * t); - if (a == 0.0) - goto ovrf; - - t = y + 1.0; - a = (x2 + (t * t))/a; - w = w + (0.25 * log(a)) * I; - return w; - -ovrf: -#if 0 - mtherr ("catan", OVERFLOW); -#endif - w = HUGE_VAL + HUGE_VAL * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/catanf.c b/lib/mlibc/options/ansi/generic/complex/catanf.c deleted file mode 100644 index 33c47df..0000000 --- a/lib/mlibc/options/ansi/generic/complex/catanf.c +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: catanf.c,v 1.1 2007/08/20 16:01:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> -#include "cephes_subrf.h" - -#ifdef __weak_alias -__weak_alias(catanf, _catanf) -#endif - -float complex -catanf(float complex z) -{ - float complex w; - float a, t, x, x2, y; - - x = crealf(z); - y = cimagf(z); - - if ((x == 0.0f) && (y > 1.0f)) - goto ovrf; - - x2 = x * x; - a = 1.0f - x2 - (y * y); - if (a == 0.0f) - goto ovrf; - - t = 0.5f * atan2f(2.0f * x, a); - w = __mlibc_redupif(t); - - t = y - 1.0f; - a = x2 + (t * t); - if (a == 0.0f) - goto ovrf; - - t = y + 1.0f; - a = (x2 + (t * t))/a; - w = w + (0.25f * logf(a)) * I; - return w; - -ovrf: -#if 0 - mtherr ("catan", OVERFLOW); -#endif - w = HUGE_VALF + HUGE_VALF * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/catanh.c b/lib/mlibc/options/ansi/generic/complex/catanh.c deleted file mode 100644 index 2b9ef9e..0000000 --- a/lib/mlibc/options/ansi/generic/complex/catanh.c +++ /dev/null @@ -1,90 +0,0 @@ -/* $NetBSD: catanh.c,v 1.1 2007/08/20 16:01:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<catanh>>, <<catanhf>>---complex arc hyperbolic tangent - -INDEX - catanh -INDEX - catanhf - -ANSI_SYNOPSIS - #include <complex.h> - double complex catanh(double complex <[z]>); - float complex catanhf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex arc hyperbolic tan of <[z]>, - with branch cuts outside the interval [-1, +1] along the - real axis. - - <<catanhf>> is identical to <<catanh>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - These functions return the complex arc hyperbolic tangent value, - in the range of a strip mathematically unbounded along the - real axis and in the interval [-i*p/2, +i*p/2] along the - imaginary axis. - @end ifnottex - @tex - These functions return the complex arc hyperbolic tangent value, - in the range of a strip mathematically unbounded along the - real axis and in the interval [$-i\pi/2$, $+i\pi/2$] along the - imaginary axis. - @end tex - -PORTABILITY - <<catanh>> and <<catanhf>> are ISO C99 - -QUICKREF - <<catanh>> and <<catanhf>> are ISO C99 - -*/ - - -#include <complex.h> - -double complex -catanh(double complex z) -{ - double complex w; - - w = -1.0 * I * catan(z * I); - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/catanhf.c b/lib/mlibc/options/ansi/generic/complex/catanhf.c deleted file mode 100644 index fe6127a..0000000 --- a/lib/mlibc/options/ansi/generic/complex/catanhf.c +++ /dev/null @@ -1,44 +0,0 @@ -/* $NetBSD: catanhf.c,v 1.1 2007/08/20 16:01:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> - -float complex -catanhf(float complex z) -{ - float complex w; - - w = -1.0f * I * catanf(z * I); - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ccos.c b/lib/mlibc/options/ansi/generic/complex/ccos.c deleted file mode 100644 index ebb52bf..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ccos.c +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: ccos.c,v 1.1 2007/08/20 16:01:32 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<ccos>>, <<ccosf>>---complex cosine - -INDEX - ccos -INDEX - ccosf - -ANSI_SYNOPSIS - #include <complex.h> - double complex ccos(double complex <[z]>); - float complex ccosf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex cosine of <[z]>. - - <<ccosf>> is identical to <<ccos>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - These functions return the complex cosine value. - -PORTABILITY - <<ccos>> and <<ccosf>> are ISO C99 - -QUICKREF - <<ccos>> and <<ccosf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> -#include "cephes_subr.h" - -double complex -ccos(double complex z) -{ - double complex w; - double ch, sh; - - __mlibc_cchsh(cimag(z), &ch, &sh); - w = cos(creal(z)) * ch - (sin(creal(z)) * sh) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ccosf.c b/lib/mlibc/options/ansi/generic/complex/ccosf.c deleted file mode 100644 index db7fab3..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ccosf.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: ccosf.c,v 1.1 2007/08/20 16:01:33 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> -#include "cephes_subrf.h" - -float complex -ccosf(float complex z) -{ - float complex w; - float ch, sh; - - __mlibc_cchshf(cimagf(z), &ch, &sh); - w = cosf(crealf(z)) * ch - (sinf(crealf(z)) * sh) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ccosh.c b/lib/mlibc/options/ansi/generic/complex/ccosh.c deleted file mode 100644 index 223a5ed..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ccosh.c +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: ccosh.c,v 1.1 2007/08/20 16:01:33 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<ccosh>>, <<ccoshf>>---complex hyperbolic cosine - -INDEX - ccosh -INDEX - ccoshf - -ANSI_SYNOPSIS - #include <complex.h> - double complex ccosh(double complex <[z]>); - float complex ccoshf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex hyperbolic cosine of <[z]>. - - <<ccoshf>> is identical to <<ccosh>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - These functions return the complex hyperbolic cosine value. - -PORTABILITY - <<ccosh>> and <<ccoshf>> are ISO C99 - -QUICKREF - <<ccosh>> and <<ccoshf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> - -double complex -ccosh(double complex z) -{ - double complex w; - double x, y; - - x = creal(z); - y = cimag(z); - w = cosh(x) * cos(y) + (sinh(x) * sin(y)) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ccoshf.c b/lib/mlibc/options/ansi/generic/complex/ccoshf.c deleted file mode 100644 index af11353..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ccoshf.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: ccoshf.c,v 1.1 2007/08/20 16:01:33 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -ccoshf(float complex z) -{ - float complex w; - float x, y; - - x = crealf(z); - y = cimagf(z); - w = coshf(x) * cosf(y) + (sinhf(x) * sinf(y)) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cephes_subr.c b/lib/mlibc/options/ansi/generic/complex/cephes_subr.c deleted file mode 100644 index fe08b42..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cephes_subr.c +++ /dev/null @@ -1,126 +0,0 @@ -/* $NetBSD: cephes_subr.c,v 1.1 2007/08/20 16:01:33 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> -#include "cephes_subr.h" - -/* calculate cosh and sinh */ - -void -__mlibc_cchsh(double x, double *c, double *s) -{ - double e, ei; - - if (fabs(x) <= 0.5) { - *c = cosh(x); - *s = sinh(x); - } else { - e = exp(x); - ei = 0.5 / e; - e = 0.5 * e; - *s = e - ei; - *c = e + ei; - } -} - -/* Program to subtract nearest integer multiple of PI */ - -/* extended precision value of PI: */ -static const double DP1 = 3.14159265160560607910E0; -static const double DP2 = 1.98418714791870343106E-9; -static const double DP3 = 1.14423774522196636802E-17; -#define MACHEP 1.1e-16 - -double -__mlibc_redupi(double x) -{ - double t; - long i; - - t = x / M_PI; - if (t >= 0.0) - t += 0.5; - else - t -= 0.5; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - -/* Taylor series expansion for cosh(2y) - cos(2x) */ - -double -__mlibc_ctans(double complex z) -{ - double f, x, x2, y, y2, rn, t; - double d; - - x = fabs(2.0 * creal(z)); - y = fabs(2.0 * cimag(z)); - - x = __mlibc_redupi(x); - - x = x * x; - y = y * y; - x2 = 1.0; - y2 = 1.0; - f = 1.0; - rn = 0.0; - d = 0.0; - do { - rn += 1.0; - f *= rn; - rn += 1.0; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 + x2; - t /= f; - d += t; - - rn += 1.0; - f *= rn; - rn += 1.0; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 - x2; - t /= f; - d += t; - } while (fabs(t/d) > MACHEP); - return d; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cephes_subr.h b/lib/mlibc/options/ansi/generic/complex/cephes_subr.h deleted file mode 100644 index 719075e..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cephes_subr.h +++ /dev/null @@ -1,9 +0,0 @@ -/* $NetBSD: cephes_subr.h,v 1.1 2007/08/20 16:01:33 drochner Exp $ */ - -#ifndef __MLIBC_ABI_ONLY - -void __mlibc_cchsh(double, double *, double *); -double __mlibc_redupi(double); -double __mlibc_ctans(double complex); - -#endif /* !__MLIBC_ABI_ONLY */ diff --git a/lib/mlibc/options/ansi/generic/complex/cephes_subrf.c b/lib/mlibc/options/ansi/generic/complex/cephes_subrf.c deleted file mode 100644 index 1ce18e5..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cephes_subrf.c +++ /dev/null @@ -1,125 +0,0 @@ -/* $NetBSD: cephes_subrf.c,v 1.1 2007/08/20 16:01:34 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> -#include "cephes_subrf.h" - -/* calculate cosh and sinh */ - -void -__mlibc_cchshf(float x, float *c, float *s) -{ - float e, ei; - - if (fabsf(x) <= 0.5f) { - *c = coshf(x); - *s = sinhf(x); - } else { - e = expf(x); - ei = 0.5f / e; - e = 0.5f * e; - *s = e - ei; - *c = e + ei; - } -} - -/* Program to subtract nearest integer multiple of PI */ - -/* extended precision value of PI: */ -static const double DP1 = 3.140625; -static const double DP2 = 9.67502593994140625E-4; -static const double DP3 = 1.509957990978376432E-7; -#define MACHEPF 3.0e-8 - -float -__mlibc_redupif(float x) -{ - float t; - long i; - - t = x / (float)M_PI; - if (t >= 0.0f) - t += 0.5f; - else - t -= 0.5f; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - -/* Taylor series expansion for cosh(2y) - cos(2x) */ - -float -__mlibc_ctansf(float complex z) -{ - float f, x, x2, y, y2, rn, t, d; - - x = fabsf(2.0f * crealf(z)); - y = fabsf(2.0f * cimagf(z)); - - x = __mlibc_redupif(x); - - x = x * x; - y = y * y; - x2 = 1.0f; - y2 = 1.0f; - f = 1.0f; - rn = 0.0f; - d = 0.0f; - do { - rn += 1.0f; - f *= rn; - rn += 1.0f; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 + x2; - t /= f; - d += t; - - rn += 1.0f; - f *= rn; - rn += 1.0f; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 - x2; - t /= f; - d += t; - } while (fabsf(t/d) > MACHEPF); - return d; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cephes_subrf.h b/lib/mlibc/options/ansi/generic/complex/cephes_subrf.h deleted file mode 100644 index 84cdd82..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cephes_subrf.h +++ /dev/null @@ -1,9 +0,0 @@ -/* $NetBSD: cephes_subrf.h,v 1.1 2007/08/20 16:01:34 drochner Exp $ */ - -#ifndef __MLIBC_ABI_ONLY - -void __mlibc_cchshf(float, float *, float *); -float __mlibc_redupif(float); -float __mlibc_ctansf(float complex); - -#endif /* !__MLIBC_ABI_ONLY */ diff --git a/lib/mlibc/options/ansi/generic/complex/cexp.c b/lib/mlibc/options/ansi/generic/complex/cexp.c deleted file mode 100644 index b9a3fd0..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cexp.c +++ /dev/null @@ -1,82 +0,0 @@ -/* $NetBSD: cexp.c,v 1.1 2007/08/20 16:01:34 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<cexp>>, <<cexpf>>---complex base-e exponential - -INDEX - cexp -INDEX - cexpf - -ANSI_SYNOPSIS - #include <complex.h> - double complex cexp(double complex <[z]>); - float complex cexpf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex base-<[e]> exponential of <[z]>. - - <<cexpf>> is identical to <<cexp>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The cexp functions return the complex base-<[e]> exponential value. - -PORTABILITY - <<cexp>> and <<cexpf>> are ISO C99 - -QUICKREF - <<cexp>> and <<cexpf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> - -double complex -cexp(double complex z) -{ - double complex w; - double r, x, y; - - x = creal(z); - y = cimag(z); - r = exp(x); - w = r * cos(y) + r * sin(y) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cexpf.c b/lib/mlibc/options/ansi/generic/complex/cexpf.c deleted file mode 100644 index 07fab1f..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cexpf.c +++ /dev/null @@ -1,49 +0,0 @@ -/* $NetBSD: cexpf.c,v 1.1 2007/08/20 16:01:34 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -cexpf(float complex z) -{ - float complex w; - float r, x, y; - - x = crealf(z); - y = cimagf(z); - r = expf(x); - w = r * cosf(y) + r * sinf(y) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cimag.c b/lib/mlibc/options/ansi/generic/complex/cimag.c deleted file mode 100644 index 24619f0..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cimag.c +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: cimag.c,v 1.2 2010/09/15 16:11:29 christos Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<cimag>>, <<cimagf>>---imaginary part - -INDEX - cimag -INDEX - cimagf - -ANSI_SYNOPSIS - #include <complex.h> - double cimag(double complex <[z]>); - float cimagf(float complex <[z]>); - - -DESCRIPTION - These functions compute the imaginary part of <[z]>. - - <<cimagf>> is identical to <<cimag>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The cimag functions return the imaginary part value (as a real). - -PORTABILITY - <<cimag>> and <<cimagf>> are ISO C99 - -QUICKREF - <<cimag>> and <<cimagf>> are ISO C99 - -*/ - - -#include <complex.h> - -#include "fdlibm.h" - -double -cimag(double complex z) -{ - double_complex w = { .z = z }; - - return (IMAG_PART(w)); -} diff --git a/lib/mlibc/options/ansi/generic/complex/cimagf.c b/lib/mlibc/options/ansi/generic/complex/cimagf.c deleted file mode 100644 index 28ed81c..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cimagf.c +++ /dev/null @@ -1,21 +0,0 @@ -/* $NetBSD: cimagf.c,v 1.2 2010/09/15 16:11:29 christos Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> - -#include "fdlibm.h" - -float -cimagf(float complex z) -{ - float_complex w = { .z = z }; - - return (IMAG_PART(w)); -} diff --git a/lib/mlibc/options/ansi/generic/complex/clog.c b/lib/mlibc/options/ansi/generic/complex/clog.c deleted file mode 100644 index f7ad3d2..0000000 --- a/lib/mlibc/options/ansi/generic/complex/clog.c +++ /dev/null @@ -1,91 +0,0 @@ -/* $NetBSD: clog.c,v 1.1 2007/08/20 16:01:35 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<clog>>, <<clogf>>---complex base-e logarithm - -INDEX - clog -INDEX - clogf - -ANSI_SYNOPSIS - #include <complex.h> - double complex clog(double complex <[z]>); - float complex clogf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex natural (base-<[e]>) logarithm - of <[z]>, with a branch cut along the negative real axis. - - <<clogf>> is identical to <<clog>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - @ifnottex - The clog functions return the complex natural logarithm value, in - the range of a strip mathematically unbounded along the real axis - and in the interval [-i*pi , +i*pi] along the imaginary axis. - @end ifnottex - @tex - The clog functions return the complex natural logarithm value, in - the range of a strip mathematically unbounded along the real axis - and in the interval [$-i\pi$, $+i\pi$] along the imaginary axis. - @end tex - -PORTABILITY - <<clog>> and <<clogf>> are ISO C99 - -QUICKREF - <<clog>> and <<clogf>> are ISO C99 - -*/ - -#include <complex.h> -#include <math.h> - -double complex -clog(double complex z) -{ - double complex w; - double p, rr; - - rr = cabs(z); - p = log(rr); - rr = atan2(cimag(z), creal(z)); - w = p + rr * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/clogf.c b/lib/mlibc/options/ansi/generic/complex/clogf.c deleted file mode 100644 index 078cea5..0000000 --- a/lib/mlibc/options/ansi/generic/complex/clogf.c +++ /dev/null @@ -1,49 +0,0 @@ -/* $NetBSD: clogf.c,v 1.1 2007/08/20 16:01:35 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -clogf(float complex z) -{ - float complex w; - float p, rr; - - rr = cabsf(z); - p = logf(rr); - rr = atan2f(cimagf(z), crealf(z)); - w = p + rr * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/conj.c b/lib/mlibc/options/ansi/generic/complex/conj.c deleted file mode 100644 index a761b5a..0000000 --- a/lib/mlibc/options/ansi/generic/complex/conj.c +++ /dev/null @@ -1,56 +0,0 @@ -/* $NetBSD: conj.c,v 1.2 2010/09/15 16:11:29 christos Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<conj>>, <<conjf>>---complex conjugate - -INDEX - conj -INDEX - conjf - -ANSI_SYNOPSIS - #include <complex.h> - double complex conj(double complex <[z]>); - float complex conjf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex conjugate of <[z]>, - by reversing the sign of its imaginary part. - - <<conjf>> is identical to <<conj>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The conj functions return the complex conjugate value. - -PORTABILITY - <<conj>> and <<conjf>> are ISO C99 - -QUICKREF - <<conj>> and <<conjf>> are ISO C99 - -*/ - -#include <complex.h> - -#include "fdlibm.h" - -double complex -conj(double complex z) -{ - double_complex w = { .z = z }; - - IMAG_PART(w) = -IMAG_PART(w); - - return (w.z); -} diff --git a/lib/mlibc/options/ansi/generic/complex/conjf.c b/lib/mlibc/options/ansi/generic/complex/conjf.c deleted file mode 100644 index 0ca71ef..0000000 --- a/lib/mlibc/options/ansi/generic/complex/conjf.c +++ /dev/null @@ -1,23 +0,0 @@ -/* $NetBSD: conjf.c,v 1.2 2010/09/15 16:11:29 christos Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> - -#include "fdlibm.h" - -float complex -conjf(float complex z) -{ - float_complex w = { .z = z }; - - IMAG_PART(w) = -IMAG_PART(w); - - return (w.z); -} diff --git a/lib/mlibc/options/ansi/generic/complex/cpow.c b/lib/mlibc/options/ansi/generic/complex/cpow.c deleted file mode 100644 index b60f7be..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cpow.c +++ /dev/null @@ -1,101 +0,0 @@ -/* $NetBSD: cpow.c,v 1.1 2007/08/20 16:01:35 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<cpow>>, <<cpowf>>---complex power - -INDEX - cpow -INDEX - cpowf - -ANSI_SYNOPSIS - #include <complex.h> - double complex cpow(double complex <[x]>, double complex <[y]>); - float complex cpowf(float complex <[x]>, float complex <[y]>); - - -DESCRIPTION - @ifnottex - The cpow functions compute the complex power function x^y - power, with a branch cut for the first parameter along the - negative real axis. - @end ifnottex - @tex - The cpow functions compute the complex power function $x^y$ - power, with a branch cut for the first parameter along the - negative real axis. - @end tex - - <<cpowf>> is identical to <<cpow>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The cpow functions return the complex power function value. - -PORTABILITY - <<cpow>> and <<cpowf>> are ISO C99 - -QUICKREF - <<cpow>> and <<cpowf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> - -double complex -cpow(double complex a, double complex z) -{ - double complex w; - double x, y, r, theta, absa, arga; - - x = creal(z); - y = cimag(z); - absa = cabs(a); - if (absa == 0.0) { - return (0.0 + 0.0 * I); - } - arga = carg(a); - r = pow(absa, x); - theta = x * arga; - if (y != 0.0) { - r = r * exp(-y * arga); - theta = theta + y * log(absa); - } - w = r * cos(theta) + (r * sin(theta)) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cpowf.c b/lib/mlibc/options/ansi/generic/complex/cpowf.c deleted file mode 100644 index 1e736af..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cpowf.c +++ /dev/null @@ -1,59 +0,0 @@ -/* $NetBSD: cpowf.c,v 1.1 2007/08/20 16:01:36 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -cpowf(float complex a, float complex z) -{ - float complex w; - float x, y, r, theta, absa, arga; - - x = crealf(z); - y = cimagf(z); - absa = cabsf(a); - if (absa == 0.0f) { - return (0.0f + 0.0f * I); - } - arga = cargf(a); - r = powf(absa, x); - theta = x * arga; - if (y != 0.0f) { - r = r * expf(-y * arga); - theta = theta + y * logf(absa); - } - w = r * cosf(theta) + (r * sinf(theta)) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/cproj.c b/lib/mlibc/options/ansi/generic/complex/cproj.c deleted file mode 100644 index 0ed50f2..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cproj.c +++ /dev/null @@ -1,105 +0,0 @@ -/* $NetBSD: cproj.c,v 1.3 2010/09/20 17:51:38 christos Exp $ */ - -/*- - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<cproj>>, <<cprojf>>--- Riemann sphere projection - -INDEX - cproj -INDEX - cprojf - -ANSI_SYNOPSIS - #include <complex.h> - double complex cproj(double complex <[z]>); - float complex cprojf(float complex <[z]>); - - -DESCRIPTION - These functions compute a projection of <[z]> onto the Riemann - sphere: <[z]> projects to <[z]> except that all complex infinities - (even those with one infinite part and one NaN part) project - to positive infinity on the real axis. If <[z]> has an infinite part, - then <<cproj>>(<[z]>) is equivalent to - - INFINITY + I * copysign(0.0, cimag(z)) - - <<cprojf>> is identical to <<cproj>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The cproj functions return the value of the projection onto - the Riemann sphere. - -PORTABILITY - <<cproj>> and <<cprojf>> are ISO C99 - -QUICKREF - <<cproj>> and <<cprojf>> are ISO C99 - -*/ - -/*__RCSID("$NetBSD: cproj.c,v 1.3 2010/09/20 17:51:38 christos Exp $"); */ - -#include <complex.h> -#include <math.h> - -#include "fdlibm.h" - -/* - * cproj(double complex z) - * - * These functions return the value of the projection (not stereographic!) - * onto the Riemann sphere. - * - * z projects to z, except that all complex infinities (even those with one - * infinite part and one NaN part) project to positive infinity on the real axis. - * If z has an infinite part, then cproj(z) shall be equivalent to: - * - * INFINITY + I * copysign(0.0, cimag(z)) - */ -double complex -cproj(double complex z) -{ - double_complex w = { .z = z }; - - if (isinf(creal(z)) || isinf(cimag(z))) { -#ifdef __INFINITY - REAL_PART(w) = __INFINITY; -#else - REAL_PART(w) = INFINITY; -#endif - IMAG_PART(w) = copysign(0.0, cimag(z)); - } - - return (w.z); -} diff --git a/lib/mlibc/options/ansi/generic/complex/cprojf.c b/lib/mlibc/options/ansi/generic/complex/cprojf.c deleted file mode 100644 index 76c3d8a..0000000 --- a/lib/mlibc/options/ansi/generic/complex/cprojf.c +++ /dev/null @@ -1,67 +0,0 @@ -/* $NetBSD: cprojf.c,v 1.3 2010/09/20 17:51:38 christos Exp $ */ - -/*- - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/*__RCSID("$NetBSD: cprojf.c,v 1.3 2010/09/20 17:51:38 christos Exp $"); */ - -#include <complex.h> -#include <math.h> - -#include "fdlibm.h" - -/* - * cprojf(float complex z) - * - * These functions return the value of the projection (not stereographic!) - * onto the Riemann sphere. - * - * z projects to z, except that all complex infinities (even those with one - * infinite part and one NaN part) project to positive infinity on the real axis. - * If z has an infinite part, then cproj(z) shall be equivalent to: - * - * INFINITY + I * copysign(0.0, cimag(z)) - */ - -float complex -cprojf(float complex z) -{ - float_complex w = { .z = z }; - - if (isinf(crealf(z)) || isinf(cimagf(z))) { -#ifdef __INFINITY - REAL_PART(w) = __INFINITY; -#else - REAL_PART(w) = INFINITY; -#endif - IMAG_PART(w) = copysignf(0.0, cimagf(z)); - } - - return (w.z); -} diff --git a/lib/mlibc/options/ansi/generic/complex/creal.c b/lib/mlibc/options/ansi/generic/complex/creal.c deleted file mode 100644 index 07bf96f..0000000 --- a/lib/mlibc/options/ansi/generic/complex/creal.c +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: creal.c,v 1.2 2010/09/15 16:11:29 christos Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<creal>>, <<crealf>>---real part - -INDEX - creal -INDEX - crealf - -ANSI_SYNOPSIS - #include <complex.h> - double creal(double complex <[z]>); - float crealf(float complex <[z]>); - - -DESCRIPTION - These functions compute the real part of <[z]>. - - <<crealf>> is identical to <<creal>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The creal functions return the real part value. - -PORTABILITY - <<creal>> and <<crealf>> are ISO C99 - -QUICKREF - <<creal>> and <<crealf>> are ISO C99 - -*/ - - -#include <complex.h> - -#include "fdlibm.h" - -double -creal(double complex z) -{ - double_complex w = { .z = z }; - - return (REAL_PART(w)); -} diff --git a/lib/mlibc/options/ansi/generic/complex/crealf.c b/lib/mlibc/options/ansi/generic/complex/crealf.c deleted file mode 100644 index 245986d..0000000 --- a/lib/mlibc/options/ansi/generic/complex/crealf.c +++ /dev/null @@ -1,21 +0,0 @@ -/* $NetBSD: crealf.c,v 1.2 2010/09/15 16:11:29 christos Exp $ */ - -/* - * Written by Matthias Drochner <drochner@NetBSD.org>. - * Public domain. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> - -#include "fdlibm.h" - -float -crealf(float complex z) -{ - float_complex w = { .z = z }; - - return (REAL_PART(w)); -} diff --git a/lib/mlibc/options/ansi/generic/complex/csin.c b/lib/mlibc/options/ansi/generic/complex/csin.c deleted file mode 100644 index b32d057..0000000 --- a/lib/mlibc/options/ansi/generic/complex/csin.c +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: csin.c,v 1.1 2007/08/20 16:01:36 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<csin>>, <<csinf>>---complex sine - -INDEX - csin -INDEX - csinf - -ANSI_SYNOPSIS - #include <complex.h> - double complex csin(double complex <[z]>); - float complex csinf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex sine of <[z]>. - - <<csinf>> is identical to <<csin>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - These functions return the complex sine value. - -PORTABILITY - <<csin>> and <<csinf>> are ISO C99 - -QUICKREF - <<csin>> and <<csinf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> -#include "cephes_subr.h" - -double complex -csin(double complex z) -{ - double complex w; - double ch, sh; - - __mlibc_cchsh(cimag(z), &ch, &sh); - w = sin(creal(z)) * ch + (cos(creal(z)) * sh) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/csinf.c b/lib/mlibc/options/ansi/generic/complex/csinf.c deleted file mode 100644 index 0d81d41..0000000 --- a/lib/mlibc/options/ansi/generic/complex/csinf.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: csinf.c,v 1.1 2007/08/20 16:01:36 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> -#include "cephes_subrf.h" - -float complex -csinf(float complex z) -{ - float complex w; - float ch, sh; - - __mlibc_cchshf(cimagf(z), &ch, &sh); - w = sinf(crealf(z)) * ch + (cosf(crealf(z)) * sh) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/csinh.c b/lib/mlibc/options/ansi/generic/complex/csinh.c deleted file mode 100644 index f117162..0000000 --- a/lib/mlibc/options/ansi/generic/complex/csinh.c +++ /dev/null @@ -1,80 +0,0 @@ -/* $NetBSD: csinh.c,v 1.1 2007/08/20 16:01:36 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<csinh>>, <<csinhf>>---complex hyperbolic sine - -INDEX - csinh -INDEX - csinhf - -ANSI_SYNOPSIS - #include <complex.h> - double complex csinh(double complex <[z]>); - float complex csinhf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex hyperbolic sine of <[z]>. - - <<ccoshf>> is identical to <<ccosh>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - These functions return the complex hyperbolic sine value. - -PORTABILITY - <<csinh>> and <<csinhf>> are ISO C99 - -QUICKREF - <<csinh>> and <<csinhf>> are ISO C99 - -*/ - -#include <complex.h> -#include <math.h> - -double complex -csinh(double complex z) -{ - double complex w; - double x, y; - - x = creal(z); - y = cimag(z); - w = sinh(x) * cos(y) + (cosh(x) * sin(y)) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/csinhf.c b/lib/mlibc/options/ansi/generic/complex/csinhf.c deleted file mode 100644 index 3cd6ba7..0000000 --- a/lib/mlibc/options/ansi/generic/complex/csinhf.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: csinhf.c,v 1.1 2007/08/20 16:01:37 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -csinhf(float complex z) -{ - float complex w; - float x, y; - - x = crealf(z); - y = cimagf(z); - w = sinhf(x) * cosf(y) + (coshf(x) * sinf(y)) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/csqrt.c b/lib/mlibc/options/ansi/generic/complex/csqrt.c deleted file mode 100644 index b144b7c..0000000 --- a/lib/mlibc/options/ansi/generic/complex/csqrt.c +++ /dev/null @@ -1,137 +0,0 @@ -/* $NetBSD: csqrt.c,v 1.1 2007/08/20 16:01:37 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<csqrt>>, <<csqrtf>>---complex square root - -INDEX - csqrt -INDEX - csqrtf - -ANSI_SYNOPSIS - #include <complex.h> - double complex csqrt(double complex <[z]>); - float complex csqrtf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex square root of <[z]>, with - a branch cut along the negative real axis. - - <<csqrtf>> is identical to <<csqrt>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - The csqrt functions return the complex square root value, in - the range of the right halfplane (including the imaginary axis). - -PORTABILITY - <<csqrt>> and <<csqrtf>> are ISO C99 - -QUICKREF - <<csqrt>> and <<csqrtf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> - -double complex -csqrt(double complex z) -{ - double complex w; - double x, y, r, t, scale; - - x = creal (z); - y = cimag (z); - - if (y == 0.0) { - if (x == 0.0) { - w = 0.0 + y * I; - } else { - r = fabs(x); - r = sqrt(r); - if (x < 0.0) { - w = 0.0 + r * I; - } else { - w = r + y * I; - } - } - return w; - } - if (x == 0.0) { - r = fabs(y); - r = sqrt(0.5 * r); - if (y > 0) - w = r + r * I; - else - w = r - r * I; - return w; - } - /* Rescale to avoid internal overflow or underflow. */ - if ((fabs(x) > 4.0) || (fabs(y) > 4.0)) { - x *= 0.25; - y *= 0.25; - scale = 2.0; - } else { -#if 1 - x *= 1.8014398509481984e16; /* 2^54 */ - y *= 1.8014398509481984e16; - scale = 7.450580596923828125e-9; /* 2^-27 */ -#else - x *= 4.0; - y *= 4.0; - scale = 0.5; -#endif - } - w = x + y * I; - r = cabs(w); - if (x > 0) { - t = sqrt(0.5 * r + 0.5 * x); - r = scale * fabs((0.5 * y) / t ); - t *= scale; - } else { - r = sqrt(0.5 * r - 0.5 * x); - t = scale * fabs((0.5 * y) / r); - r *= scale; - } - if (y < 0) - w = t - r * I; - else - w = t + r * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/csqrtf.c b/lib/mlibc/options/ansi/generic/complex/csqrtf.c deleted file mode 100644 index 13451fa..0000000 --- a/lib/mlibc/options/ansi/generic/complex/csqrtf.c +++ /dev/null @@ -1,102 +0,0 @@ -/* $NetBSD: csqrtf.c,v 1.1 2007/08/20 16:01:37 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -csqrtf(float complex z) -{ - float complex w; - float x, y, r, t, scale; - - x = crealf (z); - y = cimagf (z); - - if (y == 0.0f) { - if (x < 0.0f) { - w = 0.0f + sqrtf(-x) * I; - return w; - } else if (x == 0.0f) { - return (0.0f + y * I); - } else { - w = sqrtf(x) + y * I; - return w; - } - } - - if (x == 0.0f) { - r = fabsf(y); - r = sqrtf(0.5f * r); - if (y > 0) - w = r + r * I; - else - w = r - r * I; - return w; - } - - /* Rescale to avoid internal overflow or underflow. */ - if ((fabsf(x) > 4.0f) || (fabsf(y) > 4.0f)) { - x *= 0.25f; - y *= 0.25f; - scale = 2.0f; - } else { -#if 1 - x *= 6.7108864e7f; /* 2^26 */ - y *= 6.7108864e7f; - scale = 1.220703125e-4f; /* 2^-13 */ -#else - x *= 4.0f; - y *= 4.0f; - scale = 0.5f; -#endif - } - w = x + y * I; - r = cabsf(w); - if( x > 0 ) { - t = sqrtf(0.5f * r + 0.5f * x); - r = scale * fabsf((0.5f * y) / t); - t *= scale; - } else { - r = sqrtf(0.5f * r - 0.5f * x); - t = scale * fabsf((0.5f * y) / r); - r *= scale; - } - - if (y < 0) - w = t - r * I; - else - w = t + r * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ctan.c b/lib/mlibc/options/ansi/generic/complex/ctan.c deleted file mode 100644 index 600989d..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ctan.c +++ /dev/null @@ -1,91 +0,0 @@ -/* $NetBSD: ctan.c,v 1.1 2007/08/20 16:01:37 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<ctan>>, <<ctanf>>---complex tangent - -INDEX - ctan -INDEX - ctanf - -ANSI_SYNOPSIS - #include <complex.h> - double complex ctan(double complex <[z]>); - float complex ctanf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex tangent of <[z]>. - - <<ctanf>> is identical to <<ctan>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - These functions return the complex tangent value. - -PORTABILITY - <<ctan>> and <<ctanf>> are ISO C99 - -QUICKREF - <<ctan>> and <<ctanf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> -#include "cephes_subr.h" - -double complex -ctan(double complex z) -{ - double complex w; - double d; - - d = cos(2.0 * creal(z)) + cosh(2.0 * cimag(z)); - - if (fabs(d) < 0.25) - d = __mlibc_ctans(z); - - if (d == 0.0) { - /* mtherr ("ctan", OVERFLOW); */ - w = HUGE_VAL + HUGE_VAL * I; - return w; - } - - w = sin(2.0 * creal(z)) / d + (sinh(2.0 * cimag(z)) / d) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ctanf.c b/lib/mlibc/options/ansi/generic/complex/ctanf.c deleted file mode 100644 index 52360e0..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ctanf.c +++ /dev/null @@ -1,58 +0,0 @@ -/* $NetBSD: ctanf.c,v 1.1 2007/08/20 16:01:38 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> -#include "cephes_subrf.h" - -float complex -ctanf(float complex z) -{ - float complex w; - float d; - - d = cosf(2.0f * crealf(z)) + coshf(2.0f * cimagf(z)); - - if (fabsf(d) < 0.25f) - d = __mlibc_ctansf(z); - - if (d == 0.0f) { - /* mtherr ("ctan", OVERFLOW); */ - w = HUGE_VALF + HUGE_VALF * I; - return w; - } - - w = sinf(2.0f * crealf(z)) / d + (sinhf(2.0f * cimagf(z)) / d) * I; - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ctanh.c b/lib/mlibc/options/ansi/generic/complex/ctanh.c deleted file mode 100644 index db27e5b..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ctanh.c +++ /dev/null @@ -1,83 +0,0 @@ -/* $NetBSD: ctanh.c,v 1.1 2007/08/20 16:01:38 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -/* -FUNCTION - <<ctanh>>, <<ctanf>>---complex hyperbolic tangent - -INDEX - ctanh -INDEX - ctanhf - -ANSI_SYNOPSIS - #include <complex.h> - double complex ctanh(double complex <[z]>); - float complex ctanhf(float complex <[z]>); - - -DESCRIPTION - These functions compute the complex hyperbolic tangent of <[z]>. - - <<ctanhf>> is identical to <<ctanh>>, except that it performs - its calculations on <<floats complex>>. - -RETURNS - These functions return the complex hyperbolic tangent value. - -PORTABILITY - <<ctanh>> and <<ctanhf>> are ISO C99 - -QUICKREF - <<ctanh>> and <<ctanhf>> are ISO C99 - -*/ - - -#include <complex.h> -#include <math.h> - -double complex -ctanh(double complex z) -{ - double complex w; - double x, y, d; - - x = creal(z); - y = cimag(z); - d = cosh(2.0 * x) + cos(2.0 * y); - w = sinh(2.0 * x) / d + (sin(2.0 * y) / d) * I; - - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/ctanhf.c b/lib/mlibc/options/ansi/generic/complex/ctanhf.c deleted file mode 100644 index 6aaf20f..0000000 --- a/lib/mlibc/options/ansi/generic/complex/ctanhf.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $NetBSD: ctanhf.c,v 1.1 2007/08/20 16:01:38 drochner Exp $ */ - -/*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software written by Stephen L. Moshier. - * It is redistributed by the NetBSD Foundation by permission of the author. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * imported and modified include for newlib 2010/10/03 - * Marco Atzeri <marco_atzeri@yahoo.it> - */ - -#include <complex.h> -#include <math.h> - -float complex -ctanhf(float complex z) -{ - float complex w; - float x, y, d; - - x = crealf(z); - y = cimagf(z); - d = coshf(2.0f * x) + cosf(2.0f * y); - w = sinhf(2.0f * x) / d + (sinf(2.0f * y) / d) * I; - - return w; -} diff --git a/lib/mlibc/options/ansi/generic/complex/fdlibm.h b/lib/mlibc/options/ansi/generic/complex/fdlibm.h deleted file mode 100644 index 75cdd2a..0000000 --- a/lib/mlibc/options/ansi/generic/complex/fdlibm.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __MLIBC_FDLIBM_H -#define __MLIBC_FDLIBM_H - -#define REAL_PART(z) ((z).parts[0]) -#define IMAG_PART(z) ((z).parts[1]) - -typedef union { - float complex z; - float parts[2]; -} float_complex; - -typedef union { - double complex z; - double parts[2]; -} double_complex; - -#endif diff --git a/lib/mlibc/options/ansi/generic/ctype-stubs.cpp b/lib/mlibc/options/ansi/generic/ctype-stubs.cpp deleted file mode 100644 index 3ce76e9..0000000 --- a/lib/mlibc/options/ansi/generic/ctype-stubs.cpp +++ /dev/null @@ -1,326 +0,0 @@ - -#include <ctype.h> -#include <wctype.h> - -#include <bits/ensure.h> -#include <mlibc/charset.hpp> - -// -------------------------------------------------------------------------------------- -// char ctype functions. -// -------------------------------------------------------------------------------------- - -int isalpha(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_alpha(cp); -} - -int isdigit(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_digit(cp); -} - -int isxdigit(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_xdigit(cp); -} - -int isalnum(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_alnum(cp); -} - -int ispunct(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_punct(cp); -} - -int isgraph(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_graph(cp); -} - -int isblank(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_blank(cp); -} - -int isspace(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_space(cp); -} - -int isprint(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_print(cp); -} - -int islower(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_lower(cp); -} - -int isupper(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_upper(cp); -} - -int iscntrl(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::generic_is_control(cp); -} - -int isascii(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return cp <= 0x7F; -} - -// -------------------------------------------------------------------------------------- -// wchar_t ctype functions. -// -------------------------------------------------------------------------------------- - -int iswalpha(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_alpha(cp); -} - -int iswdigit(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_digit(cp); -} - -int iswxdigit(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_xdigit(cp); -} - -int iswalnum(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_alnum(cp); -} - -int iswpunct(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_punct(cp); -} - -int iswgraph(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_graph(cp); -} - -int iswblank(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_blank(cp); -} - -int iswspace(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_space(cp); -} - -int iswprint(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_print(cp); -} - -int iswlower(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_lower(cp); -} - -int iswupper(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::current_charset()->is_upper(cp); -} - -int iswcntrl(wint_t nc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return 0; - return mlibc::generic_is_control(cp); -} - -// -------------------------------------------------------------------------------------- -// iswctype functions. -// -------------------------------------------------------------------------------------- - -namespace { - enum { - ct_null, - ct_alnum, - ct_alpha, - ct_blank, - ct_cntrl, - ct_digit, - ct_graph, - ct_lower, - ct_print, - ct_punct, - ct_space, - ct_upper, - ct_xdigit, - ct_count - }; -} - -wctype_t wctype(const char *cs) { - frg::string_view s{cs}; - if(s == "alnum") return ct_alnum; - if(s == "alpha") return ct_alpha; - if(s == "blank") return ct_blank; - if(s == "cntrl") return ct_cntrl; - if(s == "digit") return ct_digit; - if(s == "graph") return ct_graph; - if(s == "lower") return ct_lower; - if(s == "print") return ct_print; - if(s == "punct") return ct_punct; - if(s == "space") return ct_space; - if(s == "upper") return ct_upper; - if(s == "xdigit") return ct_xdigit; - mlibc::infoLogger() << "mlibc: wctype(\"" << cs << "\") is not supported" << frg::endlog; - return ct_null; -} - -int iswctype(wint_t wc, wctype_t type) { - switch (type) { - case ct_alnum: - return iswalnum(wc); - case ct_alpha: - return iswalpha(wc); - case ct_blank: - return iswblank(wc); - case ct_cntrl: - return iswcntrl(wc); - case ct_digit: - return iswdigit(wc); - case ct_graph: - return iswgraph(wc); - case ct_lower: - return iswlower(wc); - case ct_print: - return iswprint(wc); - case ct_punct: - return iswpunct(wc); - case ct_space: - return iswspace(wc); - case ct_upper: - return iswupper(wc); - case ct_xdigit: - return iswxdigit(wc); - } - return 0; -} - -// -------------------------------------------------------------------------------------- -// char conversion functions. -// -------------------------------------------------------------------------------------- - -int tolower(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return nc; - return mlibc::current_charset()->to_lower(cp); -} - -int toupper(int nc) { - auto cc = mlibc::current_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(nc, cp); e != mlibc::charcode_error::null) - return nc; - return mlibc::current_charset()->to_upper(cp); -} - -// -------------------------------------------------------------------------------------- -// wchar_t conversion functions. -// -------------------------------------------------------------------------------------- - -wint_t towlower(wint_t wc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(wc, cp); e != mlibc::charcode_error::null) - return wc; - return mlibc::current_charset()->to_lower(cp); -} - -wint_t towupper(wint_t wc) { - auto cc = mlibc::platform_wide_charcode(); - mlibc::codepoint cp; - if(auto e = cc->promote(wc, cp); e != mlibc::charcode_error::null) - return wc; - return mlibc::current_charset()->to_upper(cp); -} - diff --git a/lib/mlibc/options/ansi/generic/environment.cpp b/lib/mlibc/options/ansi/generic/environment.cpp deleted file mode 100644 index 5625592..0000000 --- a/lib/mlibc/options/ansi/generic/environment.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> - -#include <bits/ensure.h> -#include <mlibc/allocator.hpp> -#include <mlibc/debug.hpp> - -#include <frg/string.hpp> -#include <frg/vector.hpp> - -namespace { - char *empty_environment[] = { nullptr }; -} - -char **environ = empty_environment; - -namespace { - -size_t find_environ_index(frg::string_view name) { - for(size_t i = 0; environ[i]; i++) { - frg::string_view view{environ[i]}; - size_t s = view.find_first('='); - if(s == size_t(-1)) { - mlibc::infoLogger() << "mlibc: environment string \"" - << frg::escape_fmt{view.data(), view.size()} - << "\" does not contain an equals sign (=)" << frg::endlog; - continue; - } - if(view.sub_string(0, s) == name) - return i; - } - - return -1; -} - -// Environment vector that is mutated by putenv() and setenv(). -// Cannot be global as it is accessed during library initialization. -frg::vector<char *, MemoryAllocator> &get_vector() { - static frg::vector<char *, MemoryAllocator> vector{getAllocator()}; - return vector; -} - -void update_vector() { - auto &vector = get_vector(); - if(environ == vector.data()) - return; - - // If the environ variable was changed, we copy the environment. - // Note that we must only copy the pointers but not the strings themselves! - vector.clear(); - for(size_t i = 0; environ[i]; i++) - vector.push(environ[i]); - vector.push(nullptr); - - environ = vector.data(); -} - -void assign_variable(frg::string_view name, const char *string, bool overwrite) { - auto &vector = get_vector(); - __ensure(environ == vector.data()); - - auto k = find_environ_index(name); - if(k != size_t(-1)) { - if(overwrite) - vector[k] = const_cast<char *>(string); - }else{ - // Last pointer of environ must always be a null delimiter. - __ensure(!vector.back()); - vector.back() = const_cast<char *>(string); - vector.push(nullptr); - } - - // push() might have re-allocated the vector. - environ = vector.data(); -} - -void unassign_variable(frg::string_view name) { - auto &vector = get_vector(); - __ensure(environ == vector.data()); - - auto k = find_environ_index(name); - if(k == size_t(-1)) - return; - - // Last pointer of environ must always be a null delimiter. - __ensure(vector.size() >= 2 && !vector.back()); - std::swap(vector[k], vector[vector.size() - 2]); - vector.pop(); - vector.back() = nullptr; - - // pop() might have re-allocated the vector. - environ = vector.data(); -} - -} // anonymous namespace - -char *getenv(const char *name) { - auto k = find_environ_index(name); - if(k == size_t(-1)) - return nullptr; - - frg::string_view view{environ[k]}; - size_t s = view.find_first('='); - __ensure(s != size_t(-1)); - return const_cast<char *>(view.data() + s + 1); -} - -namespace mlibc { - -int putenv(char *string) { - frg::string_view view{string}; - size_t s = view.find_first('='); - if(s == size_t(-1)) - __ensure(!"Environment strings need to contain an equals sign"); - - update_vector(); - assign_variable(view.sub_string(0, s), string, true); - return 0; -} - -} // namespace mlibc - -#if __MLIBC_POSIX_OPTION - -int putenv(char *string) { - return mlibc::putenv(string); -} - -int setenv(const char *name, const char *value, int overwrite) { - frg::string_view view{name}; - size_t s = view.find_first('='); - if(s != size_t(-1)) { - mlibc::infoLogger() << "mlibc: environment variable \"" - << frg::escape_fmt{view.data(), view.size()} << "\" contains an equals sign" - << frg::endlog; - errno = EINVAL; - return -1; - } - - // We never free strings here. TODO: Reuse them? - char *string; - __ensure(asprintf(&string, "%s=%s", name, value) > 0); - __ensure(string); - - update_vector(); - assign_variable(name, string, overwrite); - return 0; -} - -int unsetenv(const char *name) { - update_vector(); - unassign_variable(name); - return 0; -} - -int clearenv(void) { - auto vector = get_vector(); - vector.clear(); - update_vector(); - return 0; -} - -#endif /* __MLIBC_POSIX_OPTION */ diff --git a/lib/mlibc/options/ansi/generic/errno-stubs.cpp b/lib/mlibc/options/ansi/generic/errno-stubs.cpp deleted file mode 100644 index 8229a9a..0000000 --- a/lib/mlibc/options/ansi/generic/errno-stubs.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include <errno.h> - -int __thread __mlibc_errno; - -char *program_invocation_name = nullptr; -char *program_invocation_short_name = nullptr; -extern char *__progname __attribute__((__weak__, __alias__("program_invocation_short_name"))); -extern char *__progname_full __attribute__((__weak__, __alias__("program_invocation_name"))); - -int *__errno_location() { - return &__mlibc_errno; -} diff --git a/lib/mlibc/options/ansi/generic/fenv-stubs.cpp b/lib/mlibc/options/ansi/generic/fenv-stubs.cpp deleted file mode 100644 index 7153844..0000000 --- a/lib/mlibc/options/ansi/generic/fenv-stubs.cpp +++ /dev/null @@ -1,43 +0,0 @@ - -#include <bits/ensure.h> -#include <fenv.h> - -// The functions that are not in this file but are defined in the header -// are implemented like musl does in assembly. -extern "C" __attribute__((__visibility__("hidden"))) int __fesetround(int); - -int fegetexceptflag(fexcept_t *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int feholdexcept(fenv_t *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int fesetexceptflag(const fexcept_t *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int fesetround(int r) { - if (r != FE_TONEAREST -#ifdef FE_DOWNWARD - && r != FE_DOWNWARD -#endif -#ifdef FE_UPWARD - && r != FE_UPWARD -#endif -#ifdef FE_TOWARDZERO - && r != FE_TOWARDZERO -#endif - ) - return -1; - return __fesetround(r); -} - -int feupdateenv(const fenv_t *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/ansi/generic/file-io.cpp b/lib/mlibc/options/ansi/generic/file-io.cpp deleted file mode 100644 index e59b109..0000000 --- a/lib/mlibc/options/ansi/generic/file-io.cpp +++ /dev/null @@ -1,745 +0,0 @@ - -#include <errno.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <stdio.h> -#if __MLIBC_GLIBC_OPTION -#include <stdio_ext.h> -#endif - -#include <bits/ensure.h> - -#include <mlibc/debug.hpp> - -#include <abi-bits/fcntl.h> -#include <frg/allocation.hpp> -#include <frg/mutex.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/file-io.hpp> -#include <mlibc/ansi-sysdeps.hpp> -#include <mlibc/lock.hpp> - -namespace mlibc { - -// -------------------------------------------------------------------------------------- -// abstract_file implementation. -// -------------------------------------------------------------------------------------- - -namespace { - using file_list = frg::intrusive_list< - abstract_file, - frg::locate_member< - abstract_file, - frg::default_list_hook<abstract_file>, - &abstract_file::_list_hook - > - >; - - // Useful when debugging the FILE implementation. - constexpr bool globallyDisableBuffering = false; - - // The maximum number of characters we permit the user to ungetc. - constexpr size_t ungetBufferSize = 8; - - // List of files that will be flushed before exit(). - file_list &global_file_list() { - static frg::eternal<file_list> list; - return list.get(); - }; -} - -// For pipe-like streams (seek returns ESPIPE), we need to make sure -// that the buffer only ever contains all-dirty or all-clean data. -// Regarding _type and _bufmode: -// As we might construct FILE objects for FDs that are not actually -// open (e.g. for std{in,out,err}), we defer the type determination and cache the result. - -abstract_file::abstract_file(void (*do_dispose)(abstract_file *)) -: _type{stream_type::unknown}, _bufmode{buffer_mode::unknown}, _do_dispose{do_dispose} { - // TODO: For __fwriting to work correctly, set the __io_mode to 1 if the write is write-only. - __buffer_ptr = nullptr; - __unget_ptr = nullptr; - __buffer_size = 4096; - __offset = 0; - __io_offset = 0; - __valid_limit = 0; - __dirty_begin = 0; - __dirty_end = 0; - __io_mode = 0; - __status_bits = 0; - - global_file_list().push_back(this); -} - -abstract_file::~abstract_file() { - if(__dirty_begin != __dirty_end) - mlibc::infoLogger() << "mlibc warning: File is not flushed before destruction" - << frg::endlog; - - if(__buffer_ptr) - getAllocator().free(__buffer_ptr - ungetBufferSize); - - auto it = global_file_list().iterator_to(this); - global_file_list().erase(it); -} - -void abstract_file::dispose() { - if(!_do_dispose) - return; - _do_dispose(this); -} - -// Note that read() and write() are asymmetric: -// While read() can trigger a write-back, write() can never trigger a read-ahead(). -// This peculiarity is reflected in their code. - -int abstract_file::read(char *buffer, size_t max_size, size_t *actual_size) { - __ensure(max_size); - - if(_init_bufmode()) - return -1; - - size_t unget_length = 0; - if (__unget_ptr != __buffer_ptr) { - unget_length = frg::min(max_size, (size_t)(__buffer_ptr - __unget_ptr)); - memcpy(buffer, __unget_ptr, unget_length); - - __unget_ptr += unget_length; - buffer += unget_length; - max_size -= unget_length; - - if (max_size == 0) { - *actual_size = unget_length; - return 0; - } - } - - if(globallyDisableBuffering || _bufmode == buffer_mode::no_buffer) { - size_t io_size; - if(int e = io_read(buffer, max_size, &io_size); e) { - __status_bits |= __MLIBC_ERROR_BIT; - return e; - } - if(!io_size) - __status_bits |= __MLIBC_EOF_BIT; - *actual_size = io_size + unget_length; - return 0; - } - - // Ensure correct buffer type for pipe-like streams. - // TODO: In order to support pipe-like streams we need to write-back the buffer. - if(__io_mode && __valid_limit) - mlibc::panicLogger() << "mlibc: Cannot read-write to same pipe-like stream" - << frg::endlog; - __io_mode = 0; - - // Clear the buffer, then buffer new data. - if(__offset == __valid_limit) { - // TODO: We only have to write-back/reset if __valid_limit reaches the buffer end. - if(int e = _write_back(); e) - return e; - if(int e = _reset(); e) - return e; - - // Perform a read-ahead. - _ensure_allocation(); - size_t io_size; - if(int e = io_read(__buffer_ptr, __buffer_size, &io_size); e) { - __status_bits |= __MLIBC_ERROR_BIT; - return e; - } - if(!io_size) { - __status_bits |= __MLIBC_EOF_BIT; - *actual_size = 0; - return 0; - } - - __io_offset = io_size; - __valid_limit = io_size; - } - - // Return data from the buffer. - __ensure(__offset < __valid_limit); - - auto chunk = frg::min(size_t(__valid_limit - __offset), max_size); - memcpy(buffer, __buffer_ptr + __offset, chunk); - __offset += chunk; - - *actual_size = chunk + unget_length; - return 0; -} - -int abstract_file::write(const char *buffer, size_t max_size, size_t *actual_size) { - __ensure(max_size); - - if(_init_bufmode()) - return -1; - if(globallyDisableBuffering || _bufmode == buffer_mode::no_buffer) { - // As we do not buffer, nothing can be dirty. - __ensure(__dirty_begin == __dirty_end); - size_t io_size; - if(int e = io_write(buffer, max_size, &io_size); e) { - __status_bits |= __MLIBC_ERROR_BIT; - return e; - } - *actual_size = io_size; - return 0; - } - - // Flush the buffer if necessary. - if(__offset == __buffer_size) { - if(int e = _write_back(); e) - return e; - if(int e = _reset(); e) - return e; - } - - // Ensure correct buffer type for pipe-like streams. - // TODO: We could full support pipe-like files - // by ungetc()ing all data before a write happens, - // however, for now we just report an error. - if(!__io_mode && __valid_limit) // TODO: Only check this for pipe-like streams. - mlibc::panicLogger() << "mlibc: Cannot read-write to same pipe-like stream" - << frg::endlog; - __io_mode = 1; - - __ensure(__offset < __buffer_size); - auto chunk = frg::min(__buffer_size - __offset, max_size); - - // Line-buffered streams perform I/O on full lines. - bool flush_line = false; - if(_bufmode == buffer_mode::line_buffer) { - auto nl = reinterpret_cast<char *>(memchr(buffer, '\n', chunk)); - if(nl) { - chunk = nl + 1 - buffer; - flush_line = true; - } - } - __ensure(chunk); - - // Buffer data (without necessarily performing I/O). - _ensure_allocation(); - memcpy(__buffer_ptr + __offset, buffer, chunk); - - if(__dirty_begin != __dirty_end) { - __dirty_begin = frg::min(__dirty_begin, __offset); - __dirty_end = frg::max(__dirty_end, __offset + chunk); - }else{ - __dirty_begin = __offset; - __dirty_end = __offset + chunk; - } - __valid_limit = frg::max(__offset + chunk, __valid_limit); - __offset += chunk; - - // Flush line-buffered streams. - if(flush_line) { - if(_write_back()) - return -1; - } - - *actual_size = chunk; - return 0; -} - -int abstract_file::unget(char c) { - if (!__unget_ptr) { - // This can happen if the file is unbuffered, but we still need - // a space to store ungetc'd data. - __ensure(!__buffer_ptr); - _ensure_allocation(); - __ensure(__unget_ptr); - } - - if ((size_t)(__buffer_ptr - __unget_ptr) + 1 > ungetBufferSize) - return EOF; - else { - *(--__unget_ptr) = c; - return c; - } -} - -int abstract_file::update_bufmode(buffer_mode mode) { - // setvbuf() has undefined behavior if I/O has been performed. - __ensure(__dirty_begin == __dirty_end - && "update_bufmode() must only be called before performing I/O"); - _bufmode = mode; - return 0; -} - -void abstract_file::purge() { - __offset = 0; - __io_offset = 0; - __valid_limit = 0; - __dirty_end = __dirty_begin; - __unget_ptr = __buffer_ptr; -} - -int abstract_file::flush() { - if (__dirty_end != __dirty_begin) { - if (int e = _write_back(); e) - return e; - } - - if (int e = _save_pos(); e) - return e; - purge(); - return 0; -} - -int abstract_file::tell(off_t *current_offset) { - off_t seek_offset; - if(int e = io_seek(0, SEEK_CUR, &seek_offset); e) - return e; - - *current_offset = seek_offset + (off_t(__offset) - off_t(__io_offset)); - return 0; -} - -int abstract_file::seek(off_t offset, int whence) { - if(int e = _write_back(); e) - return e; - - off_t new_offset; - if(whence == SEEK_CUR) { - auto seek_offset = offset + (off_t(__offset) - off_t(__io_offset)); - if(int e = io_seek(seek_offset, whence, &new_offset); e) { - __status_bits |= __MLIBC_ERROR_BIT; - return e; - } - }else{ - __ensure(whence == SEEK_SET || whence == SEEK_END); - if(int e = io_seek(offset, whence, &new_offset); e) { - __status_bits |= __MLIBC_ERROR_BIT; - return e; - } - } - - // We just forget the current buffer. - // TODO: If the seek is "small", we can just modify our internal offset. - purge(); - - return 0; -} - -int abstract_file::_init_type() { - if(_type != stream_type::unknown) - return 0; - - if(int e = determine_type(&_type); e) - return e; - __ensure(_type != stream_type::unknown); - return 0; -} - -int abstract_file::_init_bufmode() { - if(_bufmode != buffer_mode::unknown) - return 0; - - if(determine_bufmode(&_bufmode)) - return -1; - __ensure(_bufmode != buffer_mode::unknown); - return 0; -} - -int abstract_file::_write_back() { - if(int e = _init_type(); e) - return e; - - if(__dirty_begin == __dirty_end) - return 0; - - // For non-pipe streams, first do a seek to reset the - // I/O position to zero, then do a write(). - if(_type == stream_type::file_like) { - if(__io_offset != __dirty_begin) { - __ensure(__dirty_begin - __io_offset > 0); - off_t new_offset; - if(int e = io_seek(off_t(__dirty_begin) - off_t(__io_offset), SEEK_CUR, &new_offset); e) - return e; - __io_offset = __dirty_begin; - } - }else{ - __ensure(_type == stream_type::pipe_like); - __ensure(__io_offset == __dirty_begin); - } - - // Now, we are in the correct position to write-back everything. - while(__io_offset < __dirty_end) { - size_t io_size; - if(int e = io_write(__buffer_ptr + __io_offset, __dirty_end - __io_offset, &io_size); e) { - __status_bits |= __MLIBC_ERROR_BIT; - return e; - } - __ensure(io_size > 0 && "io_write() is expected to always write at least one byte"); - __io_offset += io_size; - __dirty_begin += io_size; - } - - return 0; -} - -int abstract_file::_save_pos() { - if (int e = _init_type(); e) - return e; - if (int e = _init_bufmode(); e) - return e; - - if (_type == stream_type::file_like && _bufmode != buffer_mode::no_buffer) { - off_t new_offset; - auto seek_offset = (off_t(__offset) - off_t(__io_offset)); - if (int e = io_seek(seek_offset, SEEK_CUR, &new_offset); e) { - __status_bits |= __MLIBC_ERROR_BIT; - mlibc::infoLogger() << "hit io_seek() error " << e << frg::endlog; - return e; - } - return 0; - } - return 0; // nothing to do for the rest -} - -int abstract_file::_reset() { - if(int e = _init_type(); e) - return e; - - // For pipe-like files, we must not forget already read data. - // TODO: Report this error to the user. - if(_type == stream_type::pipe_like) - __ensure(__offset == __valid_limit); - - __ensure(__dirty_begin == __dirty_end); - __offset = 0; - __io_offset = 0; - __valid_limit = 0; - - return 0; -} - -// This may still be called when buffering is disabled, for ungetc. -void abstract_file::_ensure_allocation() { - if(__buffer_ptr) - return; - - auto ptr = getAllocator().allocate(__buffer_size + ungetBufferSize); - __buffer_ptr = reinterpret_cast<char *>(ptr) + ungetBufferSize; - __unget_ptr = __buffer_ptr; -} - -// -------------------------------------------------------------------------------------- -// fd_file implementation. -// -------------------------------------------------------------------------------------- - -fd_file::fd_file(int fd, void (*do_dispose)(abstract_file *), bool force_unbuffered) -: abstract_file{do_dispose}, _fd{fd}, _force_unbuffered{force_unbuffered} { } - -int fd_file::fd() { - return _fd; -} - -int fd_file::close() { - if(__dirty_begin != __dirty_end) - mlibc::infoLogger() << "mlibc warning: File is not flushed before closing" - << frg::endlog; - if(int e = mlibc::sys_close(_fd); e) - return e; - return 0; -} - -int fd_file::reopen(const char *path, const char *mode) { - int mode_flags = parse_modestring(mode); - - int fd; - if(int e = sys_open(path, mode_flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, &fd); e) { - return e; - } - - flush(); - close(); - getAllocator().deallocate(__buffer_ptr, __buffer_size + ungetBufferSize); - - __buffer_ptr = nullptr; - __unget_ptr = nullptr; - __buffer_size = 4096; - _reset(); - _fd = fd; - - if(mode_flags & O_APPEND) { - seek(0, SEEK_END); - } - - return 0; -} - -int fd_file::determine_type(stream_type *type) { - off_t offset; - int e = mlibc::sys_seek(_fd, 0, SEEK_CUR, &offset); - if(!e) { - *type = stream_type::file_like; - return 0; - }else if(e == ESPIPE) { - *type = stream_type::pipe_like; - return 0; - }else{ - return e; - } -} - -int fd_file::determine_bufmode(buffer_mode *mode) { - // When isatty() is not implemented, we fall back to the safest default (no buffering). - if(!mlibc::sys_isatty) { - MLIBC_MISSING_SYSDEP(); - *mode = buffer_mode::no_buffer; - return 0; - } - if(_force_unbuffered) { - *mode = buffer_mode::no_buffer; - return 0; - } - - if(int e = mlibc::sys_isatty(_fd); !e) { - *mode = buffer_mode::line_buffer; - return 0; - }else if(e == ENOTTY) { - *mode = buffer_mode::full_buffer; - return 0; - }else{ - mlibc::infoLogger() << "mlibc: sys_isatty() failed while determining whether" - " stream is interactive" << frg::endlog; - return -1; - } -} - -int fd_file::io_read(char *buffer, size_t max_size, size_t *actual_size) { - ssize_t s; - if(int e = mlibc::sys_read(_fd, buffer, max_size, &s); e) - return e; - *actual_size = s; - return 0; -} - -int fd_file::io_write(const char *buffer, size_t max_size, size_t *actual_size) { - ssize_t s; - if(int e = mlibc::sys_write(_fd, buffer, max_size, &s); e) - return e; - *actual_size = s; - return 0; -} - -int fd_file::io_seek(off_t offset, int whence, off_t *new_offset) { - if(int e = mlibc::sys_seek(_fd, offset, whence, new_offset); e) - return e; - return 0; -} - -int fd_file::parse_modestring(const char *mode) { - // Consume the first char; this must be 'r', 'w' or 'a'. - int flags = 0; - bool has_plus = strchr(mode, '+'); - if(*mode == 'r') { - if(has_plus) { - flags = O_RDWR; - }else{ - flags = O_RDONLY; - } - }else if(*mode == 'w') { - if(has_plus) { - flags = O_RDWR; - }else{ - flags = O_WRONLY; - } - flags |= O_CREAT | O_TRUNC; - }else if(*mode == 'a') { - if(has_plus) { - flags = O_APPEND | O_RDWR; - }else{ - flags = O_APPEND | O_WRONLY; - } - flags |= O_CREAT; - }else{ - mlibc::infoLogger() << "Illegal fopen() mode '" << *mode << "'" << frg::endlog; - } - mode += 1; - - // Consume additional flags. - while(*mode) { - if(*mode == '+') { - mode++; // This is already handled above. - }else if(*mode == 'b') { - mode++; // mlibc assumes that there is no distinction between text and binary. - }else if(*mode == 'e') { - flags |= O_CLOEXEC; - mode++; - }else{ - mlibc::infoLogger() << "Illegal fopen() flag '" << mode << "'" << frg::endlog; - mode++; - } - } - - return flags; -} - -} // namespace mlibc - -namespace { - mlibc::fd_file stdin_file{0}; - mlibc::fd_file stdout_file{1}; - mlibc::fd_file stderr_file{2, nullptr, true}; - - struct stdio_guard { - stdio_guard() { } - - ~stdio_guard() { - // Only flush the files but do not close them. - for(auto it : mlibc::global_file_list()) { - if(int e = it->flush(); e) - mlibc::infoLogger() << "mlibc warning: Failed to flush file before exit()" - << frg::endlog; - } - } - } global_stdio_guard; -} - -FILE *stderr = &stderr_file; -FILE *stdin = &stdin_file; -FILE *stdout = &stdout_file; - -int fileno_unlocked(FILE *file_base) { - auto file = static_cast<mlibc::fd_file *>(file_base); - return file->fd(); -} - -int fileno(FILE *file_base) { - auto file = static_cast<mlibc::fd_file *>(file_base); - frg::unique_lock lock(file->_lock); - return fileno_unlocked(file_base); -} - -FILE *fopen(const char *path, const char *mode) { - int flags = mlibc::fd_file::parse_modestring(mode); - - int fd; - if(int e = mlibc::sys_open(path, flags, 0666, &fd); e) { - errno = e; - return nullptr; - } - - return frg::construct<mlibc::fd_file>(getAllocator(), fd, - mlibc::file_dispose_cb<mlibc::fd_file>); -} - -int fclose(FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - int e = 0; - if(file->flush()) - e = EOF; - if(file->close()) - e = EOF; - file->dispose(); - return e; -} - -int fseek(FILE *file_base, long offset, int whence) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - if(int e = file->seek(offset, whence); e) { - errno = e; - return -1; - } - return 0; -} - -long ftell(FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - off_t current_offset; - if(int e = file->tell(¤t_offset); e) { - errno = e; - return -1; - } - return current_offset; -} - -int fflush_unlocked(FILE *file_base) { - if(file_base == NULL) { - // Only flush the files but do not close them. - for(auto it : mlibc::global_file_list()) { - if(int e = it->flush(); e) - mlibc::infoLogger() << "mlibc warning: Failed to flush file" - << frg::endlog; - } - return 0; - } - auto file = static_cast<mlibc::abstract_file *>(file_base); - if(file->flush()) - return EOF; - return 0; -} -int fflush(FILE *file_base) { - if(file_base == NULL) { - // Only flush the files but do not close them. - for(auto it : mlibc::global_file_list()) { - frg::unique_lock lock(it->_lock); - if(int e = it->flush(); e) - mlibc::infoLogger() << "mlibc warning: Failed to flush file" - << frg::endlog; - } - return 0; - } - - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - if (file->flush()) - return EOF; - return 0; -} - -int setvbuf(FILE *file_base, char *, int mode, size_t) { - // TODO: We could also honor the buffer, but for now use just set the mode. - auto file = static_cast<mlibc::abstract_file *>(file_base); - if(mode == _IONBF) { - if(int e = file->update_bufmode(mlibc::buffer_mode::no_buffer); e) { - errno = e; - return -1; - } - }else if(mode == _IOLBF) { - if(int e = file->update_bufmode(mlibc::buffer_mode::line_buffer); e) { - errno = e; - return -1; - } - }else if(mode == _IOFBF) { - if(int e = file->update_bufmode(mlibc::buffer_mode::full_buffer); e) { - errno = e; - return -1; - } - }else{ - errno = EINVAL; - return -1; - } - - return 0; -} - -void rewind(FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - file->seek(0, SEEK_SET); - file_base->__status_bits &= ~(__MLIBC_EOF_BIT | __MLIBC_ERROR_BIT); -} - -int ungetc(int c, FILE *file_base) { - if (c == EOF) - return EOF; - - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - return file->unget(c); -} - -#if __MLIBC_GLIBC_OPTION -void __fpurge(FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - file->purge(); -} -#endif - diff --git a/lib/mlibc/options/ansi/generic/inttypes-stubs.cpp b/lib/mlibc/options/ansi/generic/inttypes-stubs.cpp deleted file mode 100644 index ae0f9e7..0000000 --- a/lib/mlibc/options/ansi/generic/inttypes-stubs.cpp +++ /dev/null @@ -1,100 +0,0 @@ - -#include <ctype.h> -#include <inttypes.h> -#include <string.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> - -static const char *__mlibc_digits = "0123456789abcdefghijklmnopqrstuvwxyz"; - -intmax_t imaxabs(intmax_t num) { - return num < 0 ? -num : num; -} -imaxdiv_t imaxdiv(intmax_t number, intmax_t denom) { - imaxdiv_t r; - r.quot = number / denom; - r.rem = number % denom; - return r; -} - -template <class T> T strtoxmax(const char *it, char **out, int base) { - T v = 0; - bool negate = false; - const unsigned char *s = (const unsigned char *)it; - int c; - - if(std::is_signed<T>::value) { - if(*s == '+') { - s++; - }else if(*s == '-') { - negate = true; - s++; - } - } - - do { - c = *s++; - } while (isspace(c)); - if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - if(base == 8) { - if(*it != 0) - goto parse_digits; - it++; - }else if(base == 16) { - if(*it != 0) - goto parse_digits; - it++; - if(*it != 'x' && *it != 'X') - goto parse_digits; - it++; - } - -parse_digits: - while(*it) { - if(isspace(*it)) { - it++; - continue; - } - - __ensure(base <= 10); // TODO: For base > 10 we need to implement tolower(). - //auto c = strchr(__mlibc_digits, tolower(*it)); - auto c = strchr(__mlibc_digits, *it); - if(!c || (c - __mlibc_digits) >= base) - break; - v = v * base + (c - __mlibc_digits); - it++; - } - - if(std::is_signed<T>::value) { - if(negate) - v = -v; - } - - if(out) - *out = const_cast<char *>(it); - return v; -} - -intmax_t strtoimax(const char *it, char **out, int base) { - // TODO: This function has to check for overflow! - return strtoxmax<intmax_t>(it, out, base); -} -uintmax_t strtoumax(const char *it, char **out, int base) { - return strtoxmax<uintmax_t>(it, out, base); -} -intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/ansi/generic/locale-stubs.cpp b/lib/mlibc/options/ansi/generic/locale-stubs.cpp deleted file mode 100644 index 38f5859..0000000 --- a/lib/mlibc/options/ansi/generic/locale-stubs.cpp +++ /dev/null @@ -1,195 +0,0 @@ - -#include <limits.h> -#include <locale.h> -#include <string.h> - -#include <bits/ensure.h> - -#include <mlibc/debug.hpp> -#include <frg/optional.hpp> - -namespace { - // Values of the C locale are defined by the C standard. - constexpr lconv c_lconv = { - const_cast<char *>("."), // decimal_point - const_cast<char *>(""), // thousands_sep - const_cast<char *>(""), // grouping - const_cast<char *>(""), // mon_decimal_point - const_cast<char *>(""), // mon_thousands_sep - const_cast<char *>(""), // mon_grouping - const_cast<char *>(""), // positive_sign - const_cast<char *>(""), // negative_sign - const_cast<char *>(""), // currency_symbol - CHAR_MAX, // frac_digits - CHAR_MAX, // p_cs_precedes - CHAR_MAX, // n_cs_precedes - CHAR_MAX, // p_sep_by_space - CHAR_MAX, // n_sep_by_space - CHAR_MAX, // p_sign_posn - CHAR_MAX, // n_sign_posn - const_cast<char *>(""), // int_curr_symbol - CHAR_MAX, // int_frac_digits - CHAR_MAX, // int_p_cs_precedes - CHAR_MAX, // int_n_cs_precedes - CHAR_MAX, // int_p_sep_by_space - CHAR_MAX, // int_n_sep_by_space - CHAR_MAX, // int_p_sign_posn - CHAR_MAX // int_n_sign_posn - }; -} - -namespace mlibc { - struct locale_description { - // Identifier of this locale. used in setlocale(). - const char *name; - lconv lc; - }; - - constinit const locale_description c_locale{ - .name = "C", - .lc = c_lconv - }; - - constinit const locale_description posix_locale{ - .name = "POSIX", - .lc = c_lconv - }; - - const locale_description *query_locale_description(const char *name) { - if(!strcmp(name, "C")) - return &c_locale; - if(!strcmp(name, "POSIX")) - return &posix_locale; - return nullptr; - } - - const locale_description *collate_facet; - const locale_description *ctype_facet; - const locale_description *monetary_facet; - const locale_description *numeric_facet; - const locale_description *time_facet; - const locale_description *messages_facet; -} - -void __mlibc_initLocale() { - mlibc::collate_facet = &mlibc::c_locale; - mlibc::ctype_facet = &mlibc::c_locale; - mlibc::monetary_facet = &mlibc::c_locale; - mlibc::numeric_facet = &mlibc::c_locale; - mlibc::time_facet = &mlibc::c_locale; - mlibc::messages_facet = &mlibc::c_locale; -} - -char *setlocale(int category, const char *name) { - if(category == LC_ALL) { - // ´TODO: Implement correct return value when categories differ. - auto current_desc = mlibc::collate_facet; - __ensure(current_desc == mlibc::ctype_facet); - __ensure(current_desc == mlibc::monetary_facet); - __ensure(current_desc == mlibc::numeric_facet); - __ensure(current_desc == mlibc::time_facet); - __ensure(current_desc == mlibc::messages_facet); - - if(name) { - // Our default C locale is the C locale. - if(!strlen(name)) - name = "C"; - - auto new_desc = mlibc::query_locale_description(name); - if(!new_desc) { - mlibc::infoLogger() << "mlibc: Locale " << name - << " is not supported" << frg::endlog; - return nullptr; - } - - mlibc::collate_facet = new_desc; - mlibc::ctype_facet = new_desc; - mlibc::monetary_facet = new_desc; - mlibc::numeric_facet = new_desc; - mlibc::time_facet = new_desc; - mlibc::messages_facet = new_desc; - } - return const_cast<char *>(current_desc->name); - }else{ - const mlibc::locale_description **facet_ptr; - switch(category) { - case LC_COLLATE: - facet_ptr = &mlibc::collate_facet; - break; - case LC_CTYPE: - facet_ptr = &mlibc::ctype_facet; - break; - case LC_MONETARY: - facet_ptr = &mlibc::monetary_facet; - break; - case LC_NUMERIC: - facet_ptr = &mlibc::numeric_facet; - break; - case LC_TIME: - facet_ptr = &mlibc::time_facet; - break; - case LC_MESSAGES: - facet_ptr = &mlibc::messages_facet; - break; - default: - mlibc::infoLogger() << "mlibc: Unexpected value " << category - << " for category in setlocale()" << frg::endlog; - return nullptr; - } - - auto current_desc = *facet_ptr; - if(name) { - // Our default C locale is the C locale. - if(!strlen(name)) - name = "C"; - - auto new_desc = mlibc::query_locale_description(name); - if(!new_desc) { - mlibc::infoLogger() << "mlibc: Locale " << name - << " is not supported" << frg::endlog; - return nullptr; - } - - *facet_ptr = new_desc; - } - return const_cast<char *>(current_desc->name); - } -} - -namespace { - lconv effective_lc; -} - -struct lconv *localeconv(void) { - // Numeric locale. - const auto &numeric_lc = mlibc::numeric_facet->lc; - effective_lc.decimal_point = numeric_lc.decimal_point; - effective_lc.thousands_sep = numeric_lc.thousands_sep; - effective_lc.grouping = numeric_lc.grouping; - - // Monetary locale. - const auto &monetary_lc = mlibc::monetary_facet->lc; - effective_lc.mon_decimal_point = monetary_lc.mon_decimal_point; - effective_lc.mon_thousands_sep = monetary_lc.mon_thousands_sep; - effective_lc.mon_grouping = monetary_lc.mon_grouping; - effective_lc.positive_sign = monetary_lc.positive_sign; - effective_lc.negative_sign = monetary_lc.negative_sign; - effective_lc.currency_symbol = monetary_lc.currency_symbol; - effective_lc.frac_digits = monetary_lc.frac_digits; - effective_lc.p_cs_precedes = monetary_lc.p_cs_precedes; - effective_lc.n_cs_precedes = monetary_lc.n_cs_precedes; - effective_lc.p_sep_by_space = monetary_lc.p_sep_by_space; - effective_lc.n_sep_by_space = monetary_lc.n_sep_by_space; - effective_lc.p_sign_posn = monetary_lc.p_sign_posn; - effective_lc.n_sign_posn = monetary_lc.n_sign_posn; - effective_lc.int_curr_symbol = monetary_lc.int_curr_symbol; - effective_lc.int_frac_digits = monetary_lc.int_frac_digits; - effective_lc.int_p_cs_precedes = monetary_lc.int_p_cs_precedes; - effective_lc.int_n_cs_precedes = monetary_lc.int_n_cs_precedes; - effective_lc.int_p_sep_by_space = monetary_lc.int_p_sep_by_space; - effective_lc.int_n_sep_by_space = monetary_lc.int_n_sep_by_space; - effective_lc.int_p_sign_posn = monetary_lc.int_p_sign_posn; - effective_lc.int_n_sign_posn = monetary_lc.int_n_sign_posn; - - return &effective_lc; -} diff --git a/lib/mlibc/options/ansi/generic/math-stubs.ignored-cpp b/lib/mlibc/options/ansi/generic/math-stubs.ignored-cpp deleted file mode 100644 index 9be985f..0000000 --- a/lib/mlibc/options/ansi/generic/math-stubs.ignored-cpp +++ /dev/null @@ -1,1831 +0,0 @@ - -#include <math.h> -#include <immintrin.h> - -#include <bits/ensure.h> - -#include <stdint.h> - -#include <mlibc/debug.hpp> - -// Taken from musl. See musl for the license/copyright! -#define FORCE_EVAL(x) do { \ - if (sizeof(x) == sizeof(float)) { \ - volatile float __x; \ - __x = (x); \ - } else if (sizeof(x) == sizeof(double)) { \ - volatile double __x; \ - __x = (x); \ - } else { \ - volatile long double __x; \ - __x = (x); \ - } \ -} while(0) - -namespace ieee754 { - -struct SoftDouble { - typedef uint64_t Bits; - typedef uint64_t Mantissa; - typedef int16_t Exp; - - static constexpr int kMantissaBits = 52; - static constexpr int kExpBits = 11; - static constexpr int kBias = 1023; - - // this exponent represents zeros (when mantissa = 0) and subnormals (when mantissa != 0) - static constexpr Exp kSubExp = -kBias; - // this exponent represents infinities (when mantissa = 0) and NaNs (when mantissa != 0) - static constexpr Exp kInfExp = ((Exp(1) << kExpBits) - 1) - kBias; - - static constexpr Bits kMantissaMask = (Bits(1) << kMantissaBits) - 1; - static constexpr Bits kExpMask = ((Bits(1) << kExpBits) - 1) << kMantissaBits; - static constexpr Bits kSignMask = Bits(1) << (kMantissaBits + kExpBits); - - SoftDouble(bool negative, Mantissa mantissa, Exp exp) - : negative(negative), mantissa(mantissa), exp(exp) { -// mlibc::infoLogger.log() << "(" << (int)negative << ", " << (void *)mantissa -// << ", " << exp << ")" << frg::end_log; - __ensure(mantissa < (Mantissa(1) << kMantissaBits)); - __ensure((exp + kBias) >= 0); - __ensure((exp + kBias) < (Exp(1) << kExpBits)); - } - - const bool negative; - const Mantissa mantissa; - const Exp exp; -}; - -template<typename F> -using Bits = typename F::Bits; - -template<typename F> -using Mantissa = typename F::Mantissa; - -template<typename F> -using Exp = typename F::Exp; - -template<typename F> -bool isZero(F x) { - return x.exp == F::kSubExp && x.mantissa == 0; -} - -template<typename F> -bool isFinite(F x) { - return x.exp != F::kInfExp; -} - -// -------------------------------------------------------- -// Soft float operations -// -------------------------------------------------------- - -template<typename F> -F constZero(bool negative) { - return F(negative, 0, F::kSubExp); -} - -template<typename F> -F constOne(bool negative) { - return F(negative, 0, 0); -} - -template<typename F> -F floor(F x) { - if(!isFinite(x) || isZero(x)) // TODO: need exception for the not-finite case? - return x; - - if(x.exp > F::kMantissaBits) - return x; // x is already integral - - if(x.exp < 0) { - // TODO: raise inexact - // return -1 or +0 - return x.negative ? constOne<F>(true) : constZero<F>(false); - } - - Mantissa<F> mask = F::kMantissaMask >> x.exp; - if(!(x.mantissa & mask)) - return x; // x is already integral - - // TODO: raise inexact - Mantissa<F> integral_position = (Mantissa<F>(1) << F::kMantissaBits) >> x.exp; - if(x.negative) - return F(true, (x.mantissa + integral_position) & (~mask), x.exp); - return F(false, x.mantissa & (~mask), x.exp); -} - -template<typename F> -F ceil(F x) { - if(!isFinite(x) || isZero(x)) // TODO: need exception for the not-finite case? - return x; - - if(x.exp > F::kMantissaBits) - return x; // x is already integral - - if(x.exp < 0) { - // TODO: raise inexact - // return -0 or +1 - return x.negative ? constZero<F>(true) : constOne<F>(false); - } - - Mantissa<F> mask = F::kMantissaMask >> x.exp; - if(!(x.mantissa & mask)) - return x; // x is already integral - - // TODO: raise inexact - Mantissa<F> integral_position = (Mantissa<F>(1) << F::kMantissaBits) >> x.exp; - if(x.negative) - return F(true, x.mantissa & (~mask), x.exp); - return F(false, (x.mantissa + integral_position) & (~mask), x.exp); -} - -// -------------------------------------------------------- -// Soft float <-> bit string conversion functions -// -------------------------------------------------------- - -template<typename F> -uint64_t compileBits(F soft) { - auto bits = Bits<F>(soft.mantissa) | ((Bits<F>(soft.exp) + F::kBias) << soft.kMantissaBits); - return soft.negative ? (F::kSignMask | bits) : bits; -} - -SoftDouble extractBits(uint64_t bits) { - return SoftDouble(bits & SoftDouble::kSignMask, bits & SoftDouble::kMantissaMask, - ((bits & SoftDouble::kExpMask) >> SoftDouble::kMantissaBits) - SoftDouble::kBias); -} - -// -------------------------------------------------------- -// Soft float -> native float conversion functions -// -------------------------------------------------------- - -union DoubleBits { - double fp; - uint64_t bits; -}; - -double compileNative(SoftDouble soft) { - DoubleBits word; - word.bits = compileBits(soft); - return word.fp; -} - -SoftDouble extractNative(double native) { - DoubleBits word; - word.fp = native; - return extractBits(word.bits); -} - -} // namespace ieee754 - -int __mlibc_fpclassify(double x) { - return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x); -} -int __mlibc_fpclassifyf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -int __mlibc_fpclassifyl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double acos(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float acosf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double acosl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double asin(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float asinf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double asinl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double atan(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float atanf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double atanl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double atan2(double x, double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float atan2f(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double atan2l(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// Taken from musl. See musl for the license/copyright! -float __sindf(double x) { - /* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */ - static const double S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ - S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ - S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ - S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */ - - double r, s, w, z; - - /* Try to optimize for parallel evaluation as in __tandf.c. */ - z = x*x; - w = z*z; - r = S3 + z*S4; - s = z*x; - return (x + s*(S1 + z*S2)) + s*w*r; -} - -// Taken from musl. See musl for the license/copyright! -float __cosdf(double x) { - /* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */ - static const double C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ - C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ - C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ - C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ - - double r, w, z; - - /* Try to optimize for parallel evaluation as in __tandf.c. */ - z = x*x; - w = z*z; - r = C2+z*C3; - return ((1.0+z*C0) + w*C1) + (w*z)*r; -} - -float __tandf(double x, int odd) { - /* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */ - static const double T[] = { - 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */ - 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */ - 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */ - 0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */ - 0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */ - 0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */ - }; - - double z,r,w,s,t,u; - - z = x*x; - /* - * Split up the polynomial into small independent terms to give - * opportunities for parallel evaluation. The chosen splitting is - * micro-optimized for Athlons (XP, X64). It costs 2 multiplications - * relative to Horner's method on sequential machines. - * - * We add the small terms from lowest degree up for efficiency on - * non-sequential machines (the lowest degree terms tend to be ready - * earlier). Apart from this, we don't care about order of - * operations, and don't need to to care since we have precision to - * spare. However, the chosen splitting is good for accuracy too, - * and would give results as accurate as Horner's method if the - * small terms were added from highest degree down. - */ - r = T[4] + z*T[5]; - t = T[2] + z*T[3]; - w = z*z; - s = z*x; - u = T[0] + z*T[1]; - r = (x + s*u) + (s*w)*(t + w*r); - return odd ? -1.0/r : r; -} - -#define DBL_EPSILON 2.22044604925031308085e-16 -#define EPS DBL_EPSILON - -/* Get a 32 bit int from a float. */ -#define GET_FLOAT_WORD(w,d) \ -do { \ - union {float f; uint32_t i;} __u; \ - __u.f = (d); \ - (w) = __u.i; \ -} while (0) - -/* Get the more significant 32 bit int from a double. */ -#define GET_HIGH_WORD(hi,d) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (hi) = __u.i >> 32; \ -} while (0) - -/* Get the less significant 32 bit int from a double. */ -#define GET_LOW_WORD(lo,d) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (lo) = (uint32_t)__u.i; \ -} while (0) - -// Taken from musl. See musl for the license/copyright! -int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec) -{ - static const int init_jk[] = {3,4,4,6}; /* initial value for jk */ - - /* - * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi - * - * integer array, contains the (24*i)-th to (24*i+23)-th - * bit of 2/pi after binary point. The corresponding - * floating value is - * - * ipio2[i] * 2^(-24(i+1)). - * - * NB: This table must have at least (e0-3)/24 + jk terms. - * For quad precision (e0 <= 16360, jk = 6), this is 686. - */ - static const int32_t ipio2[] = { - 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, - 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, - 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, - 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, - 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, - 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, - 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, - 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, - 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, - 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, - 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, - - #if LDBL_MAX_EXP > 1024 - 0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6, - 0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2, - 0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35, - 0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30, - 0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C, - 0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4, - 0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770, - 0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7, - 0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19, - 0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522, - 0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16, - 0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6, - 0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E, - 0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48, - 0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3, - 0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF, - 0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55, - 0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612, - 0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929, - 0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC, - 0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B, - 0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C, - 0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4, - 0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB, - 0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC, - 0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C, - 0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F, - 0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5, - 0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437, - 0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B, - 0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA, - 0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD, - 0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3, - 0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3, - 0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717, - 0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F, - 0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61, - 0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB, - 0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51, - 0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0, - 0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C, - 0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6, - 0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC, - 0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED, - 0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328, - 0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D, - 0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0, - 0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B, - 0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4, - 0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3, - 0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F, - 0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD, - 0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B, - 0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4, - 0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761, - 0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31, - 0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30, - 0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262, - 0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E, - 0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1, - 0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C, - 0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4, - 0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08, - 0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196, - 0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9, - 0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4, - 0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC, - 0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C, - 0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0, - 0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C, - 0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0, - 0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC, - 0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22, - 0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893, - 0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7, - 0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5, - 0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F, - 0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4, - 0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF, - 0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B, - 0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2, - 0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138, - 0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E, - 0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569, - 0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34, - 0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9, - 0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D, - 0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F, - 0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855, - 0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569, - 0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B, - 0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE, - 0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41, - 0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49, - 0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F, - 0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110, - 0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8, - 0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365, - 0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A, - 0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270, - 0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5, - 0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616, - 0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B, - 0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0, - #endif - }; - - static const double PIo2[] = { - 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ - 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ - 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ - 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ - 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ - 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ - 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ - 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ - }; - - int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; - double z,fw,f[20],fq[20],q[20]; - - /* initialize jk*/ - jk = init_jk[prec]; - jp = jk; - - /* determine jx,jv,q0, note that 3>q0 */ - jx = nx-1; - jv = (e0-3)/24; if(jv<0) jv=0; - q0 = e0-24*(jv+1); - - /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ - j = jv-jx; m = jx+jk; - for (i=0; i<=m; i++,j++) - f[i] = j<0 ? 0.0 : (double)ipio2[j]; - - /* compute q[0],q[1],...q[jk] */ - for (i=0; i<=jk; i++) { - for (j=0,fw=0.0; j<=jx; j++) - fw += x[j]*f[jx+i-j]; - q[i] = fw; - } - - jz = jk; -recompute: - /* distill q[] into iq[] reversingly */ - for (i=0,j=jz,z=q[jz]; j>0; i++,j--) { - fw = (double)(int32_t)(0x1p-24*z); - iq[i] = (int32_t)(z - 0x1p24*fw); - z = q[j-1]+fw; - } - - /* compute n */ - z = scalbn(z,q0); /* actual value of z */ - z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ - n = (int32_t)z; - z -= (double)n; - ih = 0; - if (q0 > 0) { /* need iq[jz-1] to determine n */ - i = iq[jz-1]>>(24-q0); n += i; - iq[jz-1] -= i<<(24-q0); - ih = iq[jz-1]>>(23-q0); - } - else if (q0 == 0) ih = iq[jz-1]>>23; - else if (z >= 0.5) ih = 2; - - if (ih > 0) { /* q > 0.5 */ - n += 1; carry = 0; - for (i=0; i<jz; i++) { /* compute 1-q */ - j = iq[i]; - if (carry == 0) { - if (j != 0) { - carry = 1; - iq[i] = 0x1000000 - j; - } - } else - iq[i] = 0xffffff - j; - } - if (q0 > 0) { /* rare case: chance is 1 in 12 */ - switch(q0) { - case 1: - iq[jz-1] &= 0x7fffff; break; - case 2: - iq[jz-1] &= 0x3fffff; break; - } - } - if (ih == 2) { - z = 1.0 - z; - if (carry != 0) - z -= scalbn(1.0,q0); - } - } - - /* check if recomputation is needed */ - if (z == 0.0) { - j = 0; - for (i=jz-1; i>=jk; i--) j |= iq[i]; - if (j == 0) { /* need recomputation */ - for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */ - - for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */ - f[jx+i] = (double)ipio2[jv+i]; - for (j=0,fw=0.0; j<=jx; j++) - fw += x[j]*f[jx+i-j]; - q[i] = fw; - } - jz += k; - goto recompute; - } - } - - /* chop off zero terms */ - if (z == 0.0) { - jz -= 1; - q0 -= 24; - while (iq[jz] == 0) { - jz--; - q0 -= 24; - } - } else { /* break z into 24-bit if necessary */ - z = scalbn(z,-q0); - if (z >= 0x1p24) { - fw = (double)(int32_t)(0x1p-24*z); - iq[jz] = (int32_t)(z - 0x1p24*fw); - jz += 1; - q0 += 24; - iq[jz] = (int32_t)fw; - } else - iq[jz] = (int32_t)z; - } - - /* convert integer "bit" chunk to floating-point value */ - fw = scalbn(1.0,q0); - for (i=jz; i>=0; i--) { - q[i] = fw*(double)iq[i]; - fw *= 0x1p-24; - } - - /* compute PIo2[0,...,jp]*q[jz,...,0] */ - for(i=jz; i>=0; i--) { - for (fw=0.0,k=0; k<=jp && k<=jz-i; k++) - fw += PIo2[k]*q[i+k]; - fq[jz-i] = fw; - } - - /* compress fq[] into y[] */ - switch(prec) { - case 0: - fw = 0.0; - for (i=jz; i>=0; i--) - fw += fq[i]; - y[0] = ih==0 ? fw : -fw; - break; - case 1: - case 2: - fw = 0.0; - for (i=jz; i>=0; i--) - fw += fq[i]; - // TODO: drop excess precision here once double_t is used - fw = (double)fw; - y[0] = ih==0 ? fw : -fw; - fw = fq[0]-fw; - for (i=1; i<=jz; i++) - fw += fq[i]; - y[1] = ih==0 ? fw : -fw; - break; - case 3: /* painful */ - for (i=jz; i>0; i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (i=jz; i>1; i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (fw=0.0,i=jz; i>=2; i--) - fw += fq[i]; - if (ih==0) { - y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; - } else { - y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; - } - } - return n&7; -} - -int __rem_pio2f(float x, double *y) { - /* - * invpio2: 53 bits of 2/pi - * pio2_1: first 25 bits of pi/2 - * pio2_1t: pi/2 - pio2_1 - */ - static const double toint = 1.5/EPS, - invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ - pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */ - pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ - - union {float f; uint32_t i;} u = {x}; - double tx[1],ty[1]; - double fn; - uint32_t ix; - int n, sign, e0; - - ix = u.i & 0x7fffffff; - /* 25+53 bit pi is good enough for medium size */ - if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */ - /* Use a specialized rint() to get fn. Assume round-to-nearest. */ - fn = (double)x*invpio2 + toint - toint; - n = (int32_t)fn; - *y = x - fn*pio2_1 - fn*pio2_1t; - return n; - } - if(ix>=0x7f800000) { /* x is inf or NaN */ - *y = x-x; - return 0; - } - /* scale x into [2^23, 2^24-1] */ - sign = u.i>>31; - e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */ - u.i = ix - (e0<<23); - tx[0] = u.f; - n = __rem_pio2_large(tx,ty,e0,1,0); - if (sign) { - *y = -ty[0]; - return -n; - } - *y = ty[0]; - return n; -} - -double cos(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -// Taken from musl. See musl for the license/copyright! -float cosf(float x) { - /* Small multiples of pi/2 rounded to double precision. */ - static const double c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ - c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ - c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ - c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ - - double y; - uint32_t ix; - unsigned n, sign; - - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x != 0 */ - FORCE_EVAL(x + 0x1p120f); - return 1.0f; - } - return __cosdf(x); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */ - return -__cosdf(sign ? x+c2pio2 : x-c2pio2); - else { - if (sign) - return __sindf(x + c1pio2); - else - return __sindf(c1pio2 - x); - } - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix > 0x40afeddf) /* |x| ~> 7*pi/4 */ - return __cosdf(sign ? x+c4pio2 : x-c4pio2); - else { - if (sign) - return __sindf(-x - c3pio2); - else - return __sindf(x - c3pio2); - } - } - - /* cos(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x-x; - - /* general argument reduction needed */ - n = __rem_pio2f(x,&y); - switch (n&3) { - case 0: return __cosdf(y); - case 1: return __sindf(-y); - case 2: return -__cosdf(y); - default: - return __sindf(y); - } -} -long double cosl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double sin(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -// Taken from musl. See musl for the license/copyright! -float sinf(float x) { - /* Small multiples of pi/2 rounded to double precision. */ - static const double s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ - s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ - s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ - s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ - - double y; - uint32_t ix; - int n, sign; - - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __sindf(x); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */ - if (sign) - return -__cosdf(x + s1pio2); - else - return __cosdf(x - s1pio2); - } - return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2)); - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */ - if (sign) - return __cosdf(x + s3pio2); - else - return -__cosdf(x - s3pio2); - } - return __sindf(sign ? x + s4pio2 : x - s4pio2); - } - - /* sin(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x - x; - - /* general argument reduction needed */ - n = __rem_pio2f(x, &y); - switch (n&3) { - case 0: return __sindf(y); - case 1: return __cosdf(y); - case 2: return __sindf(-y); - default: - return -__cosdf(y); - } -} -long double sinl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double tan(double x) { - mlibc::infoLogger() << "mlibc: tan() is not precise" << frg::endlog; - return tanf(x); -} -// Taken from musl. See musl for the license/copyright! -float tanf(float x) { - /* Small multiples of pi/2 rounded to double precision. */ - static const double t1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ - t2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ - t3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ - t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ - - double y; - uint32_t ix; - unsigned n, sign; - - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __tandf(x, 0); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix <= 0x4016cbe3) /* |x| ~<= 3pi/4 */ - return __tandf((sign ? x+t1pio2 : x-t1pio2), 1); - else - return __tandf((sign ? x+t2pio2 : x-t2pio2), 0); - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix <= 0x40afeddf) /* |x| ~<= 7*pi/4 */ - return __tandf((sign ? x+t3pio2 : x-t3pio2), 1); - else - return __tandf((sign ? x+t4pio2 : x-t4pio2), 0); - } - - /* tan(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x - x; - - /* argument reduction */ - n = __rem_pio2f(x, &y); - return __tandf(y, n&1); -} -long double tanl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double acosh(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float acoshf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double acoshl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double asinh(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float asinhf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double asinhl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double atanh(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float atanhf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double atanhl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double cosh(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float coshf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double coshl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double sinh(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float sinhf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double sinhl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double tanh(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float tanhf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double tanhl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double exp(double x) { - static const double half[2] = {0.5,-0.5}, - ln2hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ - ln2lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ - invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ - P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ - P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ - P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ - P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ - P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ - - double hi, lo, c, xx, y; - int k, sign; - uint32_t hx; - - GET_HIGH_WORD(hx, x); - sign = hx>>31; - hx &= 0x7fffffff; /* high word of |x| */ - - /* special cases */ - if (hx >= 0x4086232b) { /* if |x| >= 708.39... */ - if (isnan(x)) - return x; - if (x > 709.782712893383973096) { - /* overflow if x!=inf */ - x *= 0x1p1023; - return x; - } - if (x < -708.39641853226410622) { - /* underflow if x!=-inf */ - FORCE_EVAL((float)(-0x1p-149/x)); - if (x < -745.13321910194110842) - return 0; - } - } - - /* argument reduction */ - if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ - if (hx >= 0x3ff0a2b2) /* if |x| >= 1.5 ln2 */ - k = (int)(invln2*x + half[sign]); - else - k = 1 - sign - sign; - hi = x - k*ln2hi; /* k*ln2hi is exact here */ - lo = k*ln2lo; - x = hi - lo; - } else if (hx > 0x3e300000) { /* if |x| > 2**-28 */ - k = 0; - hi = x; - lo = 0; - } else { - /* inexact if x!=0 */ - FORCE_EVAL(0x1p1023 + x); - return 1 + x; - } - - /* x is now in primary range */ - xx = x*x; - c = x - xx*(P1+xx*(P2+xx*(P3+xx*(P4+xx*P5)))); - y = 1 + (x*c/(2-c) - lo + hi); - if (k == 0) - return y; - return scalbn(y, k); -} -float expf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double expl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double exp2(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -// Taken from musl. See musl for the license/copyright! -float exp2f(float x) { - constexpr int TBLSIZE = 16; - - constexpr float redux = 0x1.8p23f / TBLSIZE; - constexpr float P1 = 0x1.62e430p-1f; - constexpr float P2 = 0x1.ebfbe0p-3f; - constexpr float P3 = 0x1.c6b348p-5f; - constexpr float P4 = 0x1.3b2c9cp-7f; - - constexpr double exp2ft[TBLSIZE] = { - 0x1.6a09e667f3bcdp-1, - 0x1.7a11473eb0187p-1, - 0x1.8ace5422aa0dbp-1, - 0x1.9c49182a3f090p-1, - 0x1.ae89f995ad3adp-1, - 0x1.c199bdd85529cp-1, - 0x1.d5818dcfba487p-1, - 0x1.ea4afa2a490dap-1, - 0x1.0000000000000p+0, - 0x1.0b5586cf9890fp+0, - 0x1.172b83c7d517bp+0, - 0x1.2387a6e756238p+0, - 0x1.306fe0a31b715p+0, - 0x1.3dea64c123422p+0, - 0x1.4bfdad5362a27p+0, - 0x1.5ab07dd485429p+0, - }; - - double t, r, z; - union {float f; uint32_t i;} u = {x}; - union {double f; uint64_t i;} uk; - uint32_t ix, i0, k; - - /* Filter out exceptional cases. */ - ix = u.i & 0x7fffffff; - if (ix > 0x42fc0000) { /* |x| > 126 */ - if (ix > 0x7f800000) /* NaN */ - return x; - if (u.i >= 0x43000000 && u.i < 0x80000000) { /* x >= 128 */ - x *= 0x1p127f; - return x; - } - if (u.i >= 0x80000000) { /* x < -126 */ - if (u.i >= 0xc3160000 || (u.i & 0x0000ffff)) - FORCE_EVAL(-0x1p-149f/x); - if (u.i >= 0xc3160000) /* x <= -150 */ - return 0; - } - } else if (ix <= 0x33000000) { /* |x| <= 0x1p-25 */ - return 1.0f + x; - } - - /* Reduce x, computing z, i0, and k. */ - u.f = x + redux; - i0 = u.i; - i0 += TBLSIZE / 2; - k = i0 / TBLSIZE; - uk.i = (uint64_t)(0x3ff + k)<<52; - i0 &= TBLSIZE - 1; - u.f -= redux; - z = x - u.f; - /* Compute r = exp2(y) = exp2ft[i0] * p(z). */ - r = exp2ft[i0]; - t = r * z; - r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4); - - /* Scale by 2**k */ - return r * uk.f; -} -long double exp2l(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double expm1(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float expm1f(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double expm1l(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double frexp(double x, int *power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float frexpf(float x, int *power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double frexpl(long double x, int *power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double ilogb(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float ilogbf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double ilogbl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double ldexp(double x, int power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float ldexpf(float x, int power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double ldexpl(long double x, int power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double log(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float logf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double logl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double log10(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float log10f(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double log10l(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double log1p(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float log1pf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double log1pl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// Taken from musl. See musl for the license/copyright! -double log2(double x) { - static const double - ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ - ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */ - Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ - Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ - Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ - Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ - Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ - Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ - Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - - union {double f; uint64_t i;} u = {x}; - double hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo; - uint32_t hx; - int k; - - hx = u.i>>32; - k = 0; - if (hx < 0x00100000 || hx>>31) { - if (u.i<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (hx>>31) - return (x-x)/0.0; /* log(-#) = NaN */ - /* subnormal number, scale x up */ - k -= 54; - x *= 0x1p54; - u.f = x; - hx = u.i>>32; - } else if (hx >= 0x7ff00000) { - return x; - } else if (hx == 0x3ff00000 && u.i<<32 == 0) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - hx += 0x3ff00000 - 0x3fe6a09e; - k += (int)(hx>>20) - 0x3ff; - hx = (hx&0x000fffff) + 0x3fe6a09e; - u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); - x = u.f; - - f = x - 1.0; - hfsq = 0.5*f*f; - s = f/(2.0+f); - z = s*s; - w = z*z; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - R = t2 + t1; - - /* - * f-hfsq must (for args near 1) be evaluated in extra precision - * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2). - * This is fairly efficient since f-hfsq only depends on f, so can - * be evaluated in parallel with R. Not combining hfsq with R also - * keeps R small (though not as small as a true `lo' term would be), - * so that extra precision is not needed for terms involving R. - * - * Compiler bugs involving extra precision used to break Dekker's - * theorem for spitting f-hfsq as hi+lo, unless double_t was used - * or the multi-precision calculations were avoided when double_t - * has extra precision. These problems are now automatically - * avoided as a side effect of the optimization of combining the - * Dekker splitting step with the clear-low-bits step. - * - * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra - * precision to avoid a very large cancellation when x is very near - * these values. Unlike the above cancellations, this problem is - * specific to base 2. It is strange that adding +-1 is so much - * harder than adding +-ln2 or +-log10_2. - * - * This uses Dekker's theorem to normalize y+val_hi, so the - * compiler bugs are back in some configurations, sigh. And I - * don't want to used double_t to avoid them, since that gives a - * pessimization and the support for avoiding the pessimization - * is not yet available. - * - * The multi-precision calculations for the multiplications are - * routine. - */ - - /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */ - hi = f - hfsq; - u.f = hi; - u.i &= (uint64_t)-1<<32; - hi = u.f; - lo = f - hi - hfsq + s*(hfsq+R); - - val_hi = hi*ivln2hi; - val_lo = (lo+hi)*ivln2lo + lo*ivln2hi; - - /* spadd(val_hi, val_lo, y), except for not using double_t: */ - y = k; - w = y + val_hi; - val_lo += (y - w) + val_hi; - val_hi = w; - - return val_lo + val_hi; -} -float log2f(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double log2l(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double logb(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float logbf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double logbl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double modf(double x, double *integral) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float modff(float x, float *integral) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double modfl(long double x, long double *integral) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double scalbn(double x, int n) { - union {double f; uint64_t i;} u; - double y = x; - - if (n > 1023) { - y *= 0x1p1023; - n -= 1023; - if (n > 1023) { - y *= 0x1p1023; - n -= 1023; - if (n > 1023) - n = 1023; - } - } else if (n < -1022) { - /* make sure final n < -53 to avoid double - rounding in the subnormal range */ - y *= 0x1p-1022 * 0x1p53; - n += 1022 - 53; - if (n < -1022) { - y *= 0x1p-1022 * 0x1p53; - n += 1022 - 53; - if (n < -1022) - n = -1022; - } - } - u.i = (uint64_t)(0x3ff+n)<<52; - x = y * u.f; - return x; -} -float scalbnf(float x, int power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double scalbnl(long double x, int power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double scalbln(double x, long power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float scalblnf(float x, long power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double scalblnl(long double x, long power) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double cbrt(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float cbrtf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double cbrtl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double fabs(double x) { - return signbit(x) ? -x : x; -} -float fabsf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double fabsl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double hypot(double x, double y) { - __ensure(isfinite(x)); - __ensure(isfinite(y)); - // TODO: fix exception handling - double u = fabs(x); - double v = fabs(y); - if(u > v) - return u * sqrt(1 + (v / u) * (v / u)); - return v * sqrt(1 + (u / v) * (u / v)); -} -float hypotf(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double hypotl(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double pow(double x, double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float powf(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double powl(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double sqrt(double x) { - auto sse_x = _mm_set_sd(x); - return _mm_cvtsd_f64(_mm_sqrt_sd(sse_x, sse_x)); -} -float sqrtf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double sqrtl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double erf(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float erff(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double erfl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double erfc(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float erfcf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double erfcl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double lgamma(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float lgammaf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double lgammal(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double tgamma(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float tgammaf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double tgammal(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double ceil(double x) { - auto soft_x = ieee754::extractNative(x); - auto result = ieee754::ceil(soft_x); - return ieee754::compileNative(result); -} -float ceilf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double ceill(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double floor(double x) { - auto soft_x = ieee754::extractNative(x); - auto result = ieee754::floor(soft_x); - return ieee754::compileNative(result); -} -float floorf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double floorl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double nearbyint(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float nearbyintf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double nearbyintl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double rint(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float rintf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double rintl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -long lrint(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long lrintf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long lrintl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -long long llrint(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long long llrintf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long long llrintl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double round(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float roundf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double roundl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -long lround(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long lroundf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long lroundl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -long long llround(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long long llroundf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long long llroundl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double trunc(double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float truncf(float x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double truncl(long double x) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double fmod(double x, double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float fmodf(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double fmodl(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double remainder(double x, double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float remainderf(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double remainderl(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double remquo(double x, double y, int *quotient) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float remquof(float x, float y, int *quotient) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double remquol(long double x, long double y, int *quotient) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double copysign(double x, double sign) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float copysignf(float x, float sign) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double copysignl(long double x, long double sign) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double nan(const char *tag) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float nanf(const char *tag) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double nanl(const char *tag) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double nextafter(double x, double dir) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float nextafterf(float x, float dir) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double nextafterl(long double x, long double dir) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double nexttoward(double x, long double dir) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float nexttowardf(float x, long double dir) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double nexttowardl(long double x, long double dir) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double fdim(double x, double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -float fdimf(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double fdiml(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double fmax(double x, double y) { - __ensure(isfinite(x) && isfinite(y)); - return x < y ? y : x; -} -float fmaxf(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double fmaxl(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -double fmin(double x, double y) { - __ensure(isfinite(x) && isfinite(y)); - return x < y ? x : y; -} -float fminf(float x, float y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long double fminl(long double x, long double y) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -//gnu extension - -void sincos(double x, double *sx, double *cx) { - mlibc::infoLogger() << "mlibc: sincos() is not precise" << frg::endlog; - float sxf; - float cxf; - sincosf(x, &sxf, &cxf); - *sx = sxf; - *cx = cxf; -} - -void sincosf(float x, float *sx, float *cx) { - // This is a lazy implementation. - __ensure(sx); - __ensure(cx); - *sx = sinf(x); - *cx = cosf(x); -} -void sincosl(long double, long double *, long double *) { - __ensure(!"sincosl() not implemented"); - __builtin_unreachable(); -} - -double exp10(double) { - __ensure(!"exp10() not implemented"); - __builtin_unreachable(); -} -float exp10f(float) { - __ensure(!"exp10f() not implemented"); - __builtin_unreachable(); -} -long double exp10l(long double) { - __ensure(!"exp10l() not implemented"); - __builtin_unreachable(); -} - -double pow10(double) { - __ensure(!"pow10() not implemented"); - __builtin_unreachable(); -} -float pow10f(float) { - __ensure(!"pow10f() not implemented"); - __builtin_unreachable(); -} -long double pow10l(long double) { - __ensure(!"pow10l() not implemented"); - __builtin_unreachable(); -} - diff --git a/lib/mlibc/options/ansi/generic/signal-stubs.cpp b/lib/mlibc/options/ansi/generic/signal-stubs.cpp deleted file mode 100644 index 6da9dc1..0000000 --- a/lib/mlibc/options/ansi/generic/signal-stubs.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -#include <bits/ensure.h> -#include <errno.h> -#include <signal.h> - -#include <mlibc/debug.hpp> -#include <mlibc/ansi-sysdeps.hpp> - -__sighandler signal(int sn, __sighandler handler) { - struct sigaction sa; - sa.sa_handler = handler; - sa.sa_flags = 0; - sa.sa_mask = 0; - struct sigaction old; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigaction, SIG_ERR); - if(int e = mlibc::sys_sigaction(sn, &sa, &old)){ - errno = e; - return SIG_ERR; - } - return old.sa_handler; -} - -int raise(int sig) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getpid && mlibc::sys_kill, -1); - pid_t pid = mlibc::sys_getpid(); - - if (int e = mlibc::sys_kill(pid, sig)) { - errno = e; - return -1; - } - - return 0; -} - -// This is a POSIX extension, but we have it in here for sigsetjmp -int sigprocmask(int how, const sigset_t *__restrict set, sigset_t *__restrict retrieve) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigprocmask, -1); - if(int e = mlibc::sys_sigprocmask(how, set, retrieve); e) { - errno = e; - return -1; - } - return 0; -} - diff --git a/lib/mlibc/options/ansi/generic/stdio-stubs.cpp b/lib/mlibc/options/ansi/generic/stdio-stubs.cpp deleted file mode 100644 index 479a655..0000000 --- a/lib/mlibc/options/ansi/generic/stdio-stubs.cpp +++ /dev/null @@ -1,1270 +0,0 @@ -#include <ctype.h> -#include <errno.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <stdlib.h> -#include <wchar.h> -#include <ctype.h> -#include <limits.h> - -#include <abi-bits/fcntl.h> - -#include <bits/ensure.h> - -#include <mlibc/lock.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/debug.hpp> -#include <mlibc/file-io.hpp> -#include <mlibc/ansi-sysdeps.hpp> -#include <frg/mutex.hpp> -#include <frg/expected.hpp> -#include <frg/printf.hpp> - -template<typename F> -struct PrintfAgent { - PrintfAgent(F *formatter, frg::va_struct *vsp) - : _formatter{formatter}, _vsp{vsp} { } - - frg::expected<frg::format_error> operator() (char c) { - _formatter->append(c); - return {}; - } - frg::expected<frg::format_error> operator() (const char *c, size_t n) { - _formatter->append(c, n); - return {}; - } - - frg::expected<frg::format_error> operator() (char t, frg::format_options opts, - frg::printf_size_mod szmod) { - switch(t) { - case 'c': - if (szmod == frg::printf_size_mod::long_size) { - char c_buf[sizeof(wchar_t)]; - auto c = static_cast<wchar_t>(va_arg(_vsp->args, wint_t)); - mbstate_t shift_state = {}; - if (wcrtomb(c_buf, c, &shift_state) == size_t(-1)) - return frg::format_error::agent_error; - _formatter->append(c_buf); - break; - } - frg::do_printf_chars(*_formatter, t, opts, szmod, _vsp); - break; - case 'p': case 's': - frg::do_printf_chars(*_formatter, t, opts, szmod, _vsp); - break; - case 'd': case 'i': case 'o': case 'x': case 'X': case 'u': - frg::do_printf_ints(*_formatter, t, opts, szmod, _vsp); - break; - case 'f': case 'F': case 'g': case 'G': case 'e': case 'E': - frg::do_printf_floats(*_formatter, t, opts, szmod, _vsp); - break; - case 'm': - __ensure(!opts.fill_zeros); - __ensure(!opts.left_justify); - __ensure(!opts.alt_conversion); - __ensure(opts.minimum_width == 0); - __ensure(szmod == frg::printf_size_mod::default_size); - __ensure(!opts.precision); - _formatter->append(strerror(errno)); - break; - case 'n': { - __ensure(szmod == frg::printf_size_mod::default_size); - auto p = va_arg(_vsp->args, int *); - *p = _formatter->count; - break; - } - default: - mlibc::infoLogger() << "\e[31mmlibc: Unknown printf terminator '" - << t << "'\e[39m" << frg::endlog; - __ensure(!"Illegal printf terminator"); - } - - return {}; - } - -private: - F *_formatter; - frg::va_struct *_vsp; -}; - -struct StreamPrinter { - StreamPrinter(FILE *stream) - : stream(stream), count(0) { } - - void append(char c) { - fwrite_unlocked(&c, 1, 1, stream); - count++; - } - - void append(const char *str) { - fwrite_unlocked(str, strlen(str), 1, stream); - count += strlen(str); - } - - void append(const char *str, size_t n) { - fwrite_unlocked(str, n, 1, stream); - count += n; - } - - FILE *stream; - size_t count; -}; - -struct BufferPrinter { - BufferPrinter(char *buffer) - : buffer(buffer), count(0) { } - - void append(char c) { - buffer[count] = c; - count++; - } - - void append(const char *str) { - // TODO: use strcat - for(size_t i = 0; str[i]; i++) { - buffer[count] = str[i]; - count++; - } - } - - void append(const char *str, size_t n) { - // TODO: use strcat - for(size_t i = 0; i < n; i++) { - buffer[count] = str[i]; - count++; - } - } - - char *buffer; - size_t count; -}; - -struct LimitedPrinter { - LimitedPrinter(char *buffer, size_t limit) - : buffer(buffer), limit(limit), count(0) { } - - void append(char c) { - if(count < limit) - buffer[count] = c; - count++; - } - - void append(const char *str) { - // TODO: use strcat - for(size_t i = 0; str[i]; i++) - append(str[i]); - } - - void append(const char *str, size_t n) { - // TODO: use strcat - for(size_t i = 0; i < n; i++) - append(str[i]); - } - - char *buffer; - size_t limit; - size_t count; -}; - -struct ResizePrinter { - ResizePrinter() - : buffer(nullptr), limit(0), count(0) { } - - void expand() { - if(count == limit) { - auto new_limit = frg::max(2 * limit, size_t(16)); - auto new_buffer = reinterpret_cast<char *>(malloc(new_limit)); - __ensure(new_buffer); - memcpy(new_buffer, buffer, count); - free(buffer); - buffer = new_buffer; - limit = new_limit; - } - __ensure(count < limit); - } - - void append(char c) { - expand(); - buffer[count] = c; - count++; - } - - void append(const char *str) { - for(size_t i = 0; str[i]; i++) - append(str[i]); - } - - void append(const char *str, size_t n) { - for(size_t i = 0; i < n; i++) - append(str[i]); - } - - char *buffer; - size_t limit; - size_t count; -}; - -int remove(const char *filename) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_rmdir, -1); - if(int e = mlibc::sys_rmdir(filename); e) { - if (e == ENOTDIR) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_unlinkat, -1); - if(e = mlibc::sys_unlinkat(AT_FDCWD, filename, 0); e) { - errno = e; - return -1; - } - - return 0; - } - return -1; - } - - return 0; -} - -int rename(const char *path, const char *new_path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_rename, -1); - if(int e = mlibc::sys_rename(path, new_path); e) { - errno = e; - return -1; - } - return 0; -} - -int renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_renameat, -1); - if(int e = mlibc::sys_renameat(olddirfd, old_path, newdirfd, new_path); e) { - errno = e; - return -1; - } - return 0; -} - -FILE *tmpfile(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -char *tmpnam(char *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// fflush() is provided by the POSIX sublibrary -// fopen() is provided by the POSIX sublibrary -FILE *freopen(const char *__restrict path, const char *__restrict mode, FILE *__restrict f) { - auto file = static_cast<mlibc::abstract_file *>(f); - frg::unique_lock lock(file->_lock); - - if(file->reopen(path, mode) == -1) { - errno = EINVAL; - return nullptr; - } - - return f; -} - -void setbuf(FILE *__restrict stream, char *__restrict buffer) { - setvbuf(stream, buffer, buffer ? _IOFBF : _IONBF, BUFSIZ); -} -// setvbuf() is provided by the POSIX sublibrary - -void setlinebuf(FILE *stream) { - setvbuf(stream, NULL, _IOLBF, 0); -} - -void setbuffer(FILE *f, char *buf, size_t size) { - setvbuf(f, buf, buf ? _IOFBF : _IONBF, size); -} - -int fprintf(FILE *__restrict stream, const char *__restrict format, ...) { - va_list args; - va_start(args, format); - int result = vfprintf(stream, format, args); - va_end(args); - return result; -} - -int fscanf(FILE *__restrict stream, const char *__restrict format, ...) { - va_list args; - va_start(args, format); - int result = vfscanf(stream, format, args); - va_end(args); - return result; -} - -int printf(const char *__restrict format, ...) { - va_list args; - va_start(args, format); - int result = vfprintf(stdout, format, args); - va_end(args); - return result; -} - -namespace { - enum { - SCANF_TYPE_CHAR, - SCANF_TYPE_SHORT, - SCANF_TYPE_INTMAX, - SCANF_TYPE_L, - SCANF_TYPE_LL, - SCANF_TYPE_PTRDIFF, - SCANF_TYPE_SIZE_T, - SCANF_TYPE_INT - }; -} - -static void store_int(void *dest, unsigned int size, unsigned long long i) { - switch (size) { - case SCANF_TYPE_CHAR: - *(char *)dest = i; - break; - case SCANF_TYPE_SHORT: - *(short *)dest = i; - break; - case SCANF_TYPE_INTMAX: - *(intmax_t *)dest = i; - break; - case SCANF_TYPE_L: - *(long *)dest = i; - break; - case SCANF_TYPE_LL: - *(long long *)dest = i; - break; - case SCANF_TYPE_PTRDIFF: - *(ptrdiff_t *)dest = i; - break; - case SCANF_TYPE_SIZE_T: - *(size_t *)dest = i; - break; - /* fallthrough */ - case SCANF_TYPE_INT: - default: - *(int *)dest = i; - break; - } -} - -template<typename H> -static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) { - int match_count = 0; - for (; *fmt; fmt++) { - - if (isspace(*fmt)) { - while (isspace(fmt[1])) fmt++; - while (isspace(handler.look_ahead())) - handler.consume(); - continue; - } - - if (*fmt != '%' || fmt[1] == '%') { - if (*fmt == '%') - fmt++; - char c = handler.consume(); - if (c != *fmt) - break; - continue; - } - - void *dest = NULL; - /* %n$ format */ - if (isdigit(*fmt) && fmt[1] == '$') { - /* TODO: dest = get_arg_at_pos(args, *fmt -'0'); */ - fmt += 3; - } else { - if (fmt[1] != '*') { - dest = va_arg(args, void*); - } - fmt++; - } - - int width = 0; - if (*fmt == '*') { - fmt++; - } else if (*fmt == '\'') { - /* TODO: numeric seperators locale stuff */ - mlibc::infoLogger() << "do_scanf: \' not implemented!" << frg::endlog; - fmt++; - continue; - } else if (*fmt == 'm') { - /* TODO: allocate buffer for them */ - mlibc::infoLogger() << "do_scanf: m not implemented!" << frg::endlog; - fmt++; - continue; - } else if (*fmt >= '0' && *fmt <= '9') { - /* read in width specifier */ - width = 0; - while (*fmt >= '0' && *fmt <= '9') { - width = width * 10 + (*fmt - '0'); - fmt++; - continue; - } - } - - /* type modifiers */ - unsigned int type = SCANF_TYPE_INT; - unsigned int base = 10; - switch (*fmt) { - case 'h': { - if (fmt[1] == 'h') { - type = SCANF_TYPE_CHAR; - fmt += 2; - break; - } - type = SCANF_TYPE_SHORT; - fmt++; - break; - } - case 'j': { - type = SCANF_TYPE_INTMAX; - fmt++; - break; - } - case 'l': { - if (fmt[1] == 'l') { - type = SCANF_TYPE_LL; - fmt += 2; - break; - } - type = SCANF_TYPE_L; - fmt++; - break; - } - case 'L': { - type = SCANF_TYPE_LL; - fmt++; - break; - } - case 'q': { - type = SCANF_TYPE_LL; - fmt++; - break; - } - case 't': { - type = SCANF_TYPE_PTRDIFF; - fmt++; - break; - } - case 'z': { - type = SCANF_TYPE_SIZE_T; - fmt++; - break; - } - } - - // Leading whitespace is skipped for most conversions except these. - if (*fmt != 'c' && *fmt != '[' && *fmt != 'n') { - while (isspace(handler.look_ahead())) - handler.consume(); - } - - switch (*fmt) { - case 'd': - case 'u': - base = 10; - [[fallthrough]]; - case 'i': { - bool is_negative = false; - unsigned long long res = 0; - - if((*fmt == 'i' || *fmt == 'd') && handler.look_ahead() == '-') { - handler.consume(); - is_negative = true; - } - - if(*fmt == 'i' && handler.look_ahead() == '0') { - handler.consume(); - if(handler.look_ahead() == 'x') { - handler.consume(); - base = 16; - } else { - base = 8; - } - } - - char c = handler.look_ahead(); - switch (base) { - case 10: - if(!isdigit(c)) - return match_count; - while (c >= '0' && c <= '9') { - handler.consume(); - res = res * 10 + (c - '0'); - c = handler.look_ahead(); - } - break; - case 16: - if (c == '0') { - handler.consume(); - c = handler.look_ahead(); - if (c == 'x') { - handler.consume(); - c = handler.look_ahead(); - } - } - while (true) { - if (c >= '0' && c <= '9') { - handler.consume(); - res = res * 16 + (c - '0'); - } else if (c >= 'a' && c <= 'f') { - handler.consume(); - res = res * 16 + (c - 'a' + 10); - } else if (c >= 'A' && c <= 'F') { - handler.consume(); - res = res * 16 + (c - 'A' + 10); - } else { - break; - } - c = handler.look_ahead(); - } - break; - case 8: - while (c >= '0' && c <= '7') { - handler.consume(); - res = res * 8 + (c - '0'); - c = handler.look_ahead(); - } - break; - } - if (dest) { - if(is_negative) - store_int(dest, type, -res); - else - store_int(dest, type, res); - } - break; - } - case 'o': { - unsigned long long res = 0; - char c = handler.look_ahead(); - while (c >= '0' && c <= '7') { - handler.consume(); - res = res * 8 + (c - '0'); - c = handler.look_ahead(); - } - if (dest) - store_int(dest, type, res); - break; - } - case 'x': - case 'X': { - unsigned long long res = 0; - char c = handler.look_ahead(); - if (c == '0') { - handler.consume(); - c = handler.look_ahead(); - if (c == 'x') { - handler.consume(); - c = handler.look_ahead(); - } - } - while (true) { - if (c >= '0' && c <= '9') { - handler.consume(); - res = res * 16 + (c - '0'); - } else if (c >= 'a' && c <= 'f') { - handler.consume(); - res = res * 16 + (c - 'a' + 10); - } else if (c >= 'A' && c <= 'F') { - handler.consume(); - res = res * 16 + (c - 'A' + 10); - } else { - break; - } - c = handler.look_ahead(); - } - if (dest) - store_int(dest, type, res); - break; - } - case 's': { - char *typed_dest = (char *)dest; - char c = handler.look_ahead(); - int count = 0; - while (c && !isspace(c)) { - handler.consume(); - if (typed_dest) - typed_dest[count] = c; - c = handler.look_ahead(); - count++; - if (width && count >= width) - break; - } - if (typed_dest) - typed_dest[count] = '\0'; - break; - } - case 'c': { - char *typed_dest = (char *)dest; - char c = handler.look_ahead(); - int count = 0; - if (!width) - width = 1; - while (c && count < width) { - handler.consume(); - if (typed_dest) - typed_dest[count] = c; - c = handler.look_ahead(); - count++; - } - break; - } - case '[': { - fmt++; - int invert = 0; - if (*fmt == '^') { - invert = 1; - fmt++; - } - - char scanset[257]; - memset(&scanset[0], invert, sizeof(char) * 257); - scanset[0] = '\0'; - - if (*fmt == '-') { - fmt++; - scanset[1+'-'] = 1 - invert; - } else if (*fmt == ']') { - fmt++; - scanset[1+']'] = 1 - invert; - } - - for (; *fmt != ']'; fmt++) { - if (!*fmt) return EOF; - if (*fmt == '-' && *fmt != ']') { - fmt++; - for (char c = *(fmt - 2); c < *fmt; c++) - scanset[1 + c] = 1 - invert; - } - scanset[1 + *fmt] = 1 - invert; - } - - char *typed_dest = (char *)dest; - int count = 0; - char c = handler.look_ahead(); - while (c && (!width || count < width)) { - handler.consume(); - if (!scanset[1 + c]) - break; - if (typed_dest) - typed_dest[count] = c; - c = handler.look_ahead(); - count++; - } - if (typed_dest) - typed_dest[count] = '\0'; - break; - } - case 'p': { - unsigned long long res = 0; - char c = handler.look_ahead(); - if (c == '0') { - handler.consume(); - c = handler.look_ahead(); - if (c == 'x') { - handler.consume(); - c = handler.look_ahead(); - } - } - while (true) { - if (c >= '0' && c <= '9') { - handler.consume(); - res = res * 16 + (c - '0'); - } else if (c >= 'a' && c <= 'f') { - handler.consume(); - res = res * 16 + (c - 'a'); - } else if (c >= 'A' && c <= 'F') { - handler.consume(); - res = res * 16 + (c - 'A'); - } else { - break; - } - c = handler.look_ahead(); - } - void **typed_dest = (void **)dest; - *typed_dest = (void *)(uintptr_t)res; - break; - } - case 'n': { - int *typed_dest = (int *)dest; - if (typed_dest) - *typed_dest = handler.num_consumed; - continue; - } - } - if (dest) match_count++; - } - return match_count; -} - -int scanf(const char *__restrict format, ...) { - va_list args; - va_start(args, format); - int result = vfscanf(stdin, format, args); - va_end(args); - return result; -} - -int snprintf(char *__restrict buffer, size_t max_size, const char *__restrict format, ...) { - va_list args; - va_start(args, format); - int result = vsnprintf(buffer, max_size, format, args); - va_end(args); - return result; -} - -int sprintf(char *__restrict buffer, const char *__restrict format, ...) { - va_list args; - va_start(args, format); - int result = vsprintf(buffer, format, args); - va_end(args); - return result; -} - -int sscanf(const char *__restrict buffer, const char *__restrict format, ...) { - va_list args; - va_start(args, format); - - int result = vsscanf(buffer, format, args); - - va_end(args); - return result; -} - -int vfprintf(FILE *__restrict stream, const char *__restrict format, __builtin_va_list args) { - frg::va_struct vs; - frg::arg arg_list[NL_ARGMAX + 1]; - vs.arg_list = arg_list; - va_copy(vs.args, args); - auto file = static_cast<mlibc::abstract_file *>(stream); - frg::unique_lock lock(file->_lock); - StreamPrinter p{stream}; -// mlibc::infoLogger() << "printf(" << format << ")" << frg::endlog; - auto res = frg::printf_format(PrintfAgent{&p, &vs}, format, &vs); - if (!res) - return -static_cast<int>(res.error()); - - return p.count; -} - -int vfscanf(FILE *__restrict stream, const char *__restrict format, __builtin_va_list args) { - auto file = static_cast<mlibc::abstract_file *>(stream); - frg::unique_lock lock(file->_lock); - - struct { - char look_ahead() { - char c; - size_t actual_size; - file->read(&c, 1, &actual_size); - if (actual_size) - file->unget(c); - return actual_size ? c : 0; - } - - char consume() { - char c; - size_t actual_size; - file->read(&c, 1, &actual_size); - if (actual_size) - num_consumed++; - return actual_size ? c : 0; - } - - mlibc::abstract_file *file; - int num_consumed; - } handler = {file, 0}; - - return do_scanf(handler, format, args); -} - -int vprintf(const char *__restrict format, __builtin_va_list args){ - return vfprintf(stdout, format, args); -} - -int vscanf(const char *__restrict, __builtin_va_list) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int vsnprintf(char *__restrict buffer, size_t max_size, - const char *__restrict format, __builtin_va_list args) { - frg::va_struct vs; - frg::arg arg_list[NL_ARGMAX + 1]; - vs.arg_list = arg_list; - va_copy(vs.args, args); - LimitedPrinter p{buffer, max_size ? max_size - 1 : 0}; -// mlibc::infoLogger() << "printf(" << format << ")" << frg::endlog; - auto res = frg::printf_format(PrintfAgent{&p, &vs}, format, &vs); - if (!res) - return -static_cast<int>(res.error()); - if (max_size) - p.buffer[frg::min(max_size - 1, p.count)] = 0; - return p.count; -} - -int vsprintf(char *__restrict buffer, const char *__restrict format, __builtin_va_list args) { - frg::va_struct vs; - frg::arg arg_list[NL_ARGMAX + 1]; - vs.arg_list = arg_list; - va_copy(vs.args, args); - BufferPrinter p(buffer); -// mlibc::infoLogger() << "printf(" << format << ")" << frg::endlog; - auto res = frg::printf_format(PrintfAgent{&p, &vs}, format, &vs); - if (!res) - return -static_cast<int>(res.error()); - p.buffer[p.count] = 0; - return p.count; -} - -int vsscanf(const char *__restrict buffer, const char *__restrict format, __builtin_va_list args) { - struct { - char look_ahead() { - return *buffer; - } - - char consume() { - num_consumed++; - return *buffer++; - } - - const char *buffer; - int num_consumed; - } handler = {buffer, 0}; - - int result = do_scanf(handler, format, args); - - return result; -} - -int fwprintf(FILE *__restrict, const wchar_t *__restrict, ...) MLIBC_STUB_BODY -int fwscanf(FILE *__restrict, const wchar_t *__restrict, ...) MLIBC_STUB_BODY -int vfwprintf(FILE *__restrict, const wchar_t *__restrict, __builtin_va_list) MLIBC_STUB_BODY -int vfwscanf(FILE *__restrict, const wchar_t *__restrict, __builtin_va_list) MLIBC_STUB_BODY - -int swprintf(wchar_t *__restrict, size_t, const wchar_t *__restrict, ...) MLIBC_STUB_BODY -int swscanf(wchar_t *__restrict, size_t, const wchar_t *__restrict, ...) MLIBC_STUB_BODY -int vswprintf(wchar_t *__restrict, size_t, const wchar_t *__restrict, __builtin_va_list) MLIBC_STUB_BODY -int vswscanf(wchar_t *__restrict, size_t, const wchar_t *__restrict, __builtin_va_list) MLIBC_STUB_BODY - -int wprintf(const wchar_t *__restrict, ...) MLIBC_STUB_BODY -int wscanf(const wchar_t *__restrict, ...) MLIBC_STUB_BODY -int vwprintf(const wchar_t *__restrict, __builtin_va_list) MLIBC_STUB_BODY -int vwscanf(const wchar_t *__restrict, __builtin_va_list) MLIBC_STUB_BODY - -int fgetc(FILE *stream) { - char c; - auto bytes_read = fread(&c, 1, 1, stream); - if(bytes_read != 1) - return EOF; - return c; -} - -char *fgets(char *__restrict buffer, size_t max_size, FILE *__restrict stream) { - auto file = static_cast<mlibc::abstract_file *>(stream); - frg::unique_lock lock(file->_lock); - return fgets_unlocked(buffer, max_size, stream); -} - -int fputc_unlocked(int c, FILE *stream) { - char d = c; - if(fwrite_unlocked(&d, 1, 1, stream) != 1) - return EOF; - return 1; -} - -int fputc(int c, FILE *stream) { - auto file = static_cast<mlibc::abstract_file *>(stream); - frg::unique_lock lock(file->_lock); - return fputc_unlocked(c, stream); -} - -int fputs_unlocked(const char *__restrict string, FILE *__restrict stream) { - if(fwrite_unlocked(string, strlen(string), 1, stream) != 1) - return EOF; - return 1; -} - -int fputs(const char *__restrict string, FILE *__restrict stream) { - auto file = static_cast<mlibc::abstract_file *>(stream); - frg::unique_lock lock(file->_lock); - return fputs_unlocked(string, stream); -} - -int getc_unlocked(FILE *stream) { - return fgetc_unlocked(stream); -} - -int getc(FILE *stream) { - return fgetc(stream); -} - -int getchar_unlocked(void) { - return fgetc_unlocked(stdin); -} - -int getchar(void) { - return fgetc(stdin); -} - -char *gets(char *s){ - return fgets(s, SIZE_MAX, stdin); -} - -int putc_unlocked(int c, FILE *stream) { - char d = c; - if(fwrite_unlocked(&d, 1, 1, stream) != 1) - return EOF; - return c; -} - -int putc(int c, FILE *stream) { - auto file = static_cast<mlibc::abstract_file *>(stream); - frg::unique_lock lock(file->_lock); - return putc_unlocked(c, stream); -} - -int putchar_unlocked(int c) { - return putc_unlocked(c, stdout); -} - -int putchar(int c) { - auto file = static_cast<mlibc::abstract_file *>(stdout); - frg::unique_lock lock(file->_lock); - return putchar_unlocked(c); -} - -int puts(const char *string) { - auto file = static_cast<mlibc::abstract_file *>(stdout); - frg::unique_lock lock(file->_lock); - - size_t progress = 0; - size_t len = strlen(string); - while(progress < len) { - size_t chunk; - if(file->write(string + progress, - len - progress, &chunk)) { - return EOF; - }else if(!chunk) { - return EOF; - } - - progress += chunk; - } - - size_t unused; - if (!file->write("\n", 1, &unused)) { - return EOF; - } - - return 1; -} - -wint_t fgetwc(FILE *) MLIBC_STUB_BODY -wchar_t *fgetws(wchar_t *__restrict, int, FILE *__restrict) MLIBC_STUB_BODY -wint_t fputwc(wchar_t, FILE *) MLIBC_STUB_BODY -int fputws(const wchar_t *__restrict, FILE *__restrict) MLIBC_STUB_BODY -int fwide(FILE *, int) MLIBC_STUB_BODY -wint_t getwc(FILE *) MLIBC_STUB_BODY -wint_t getwchar(void) MLIBC_STUB_BODY -wint_t putwc(wchar_t, FILE *) MLIBC_STUB_BODY -wint_t putwchar(wchar_t) MLIBC_STUB_BODY -wint_t ungetwc(wint_t, FILE *) MLIBC_STUB_BODY - -size_t fread(void *buffer, size_t size, size_t count, FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - return fread_unlocked(buffer, size, count, file_base); -} - -size_t fwrite(const void *buffer, size_t size , size_t count, FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - frg::unique_lock lock(file->_lock); - return fwrite_unlocked(buffer, size, count, file_base); -} - -int fgetpos(FILE *__restrict, fpos_t *__restrict) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// fseek() is provided by the POSIX sublibrary -int fsetpos(FILE *, const fpos_t *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -// ftell() is provided by the POSIX sublibrary - -void clearerr(FILE *file_base) { - file_base->__status_bits = 0; -} - -int feof(FILE *file_base) { - return file_base->__status_bits & __MLIBC_EOF_BIT; -} - -int ferror(FILE *file_base) { - return file_base->__status_bits & __MLIBC_ERROR_BIT; -} - -void perror(const char *string) { - int error = errno; - if (string && *string) { - fprintf(stderr, "%s: ", string); - } - fprintf(stderr, "%s\n", strerror(error)); -} - -// POSIX extensions. - -ssize_t getline(char **line, size_t *n, FILE *stream) { - return getdelim(line, n, '\n', stream); -} - -ssize_t getdelim(char **line, size_t *n, int delim, FILE *stream) { - // Otherwise, we cannot store the buffer / size. - if(!line || !n) { - errno = EINVAL; - return -1; - } - - char *buffer = *line; - /* set the starting capacity to 512 if buffer = NULL */ - size_t capacity = (!buffer) ? 512 : *n; - size_t nwritten = 0; - - auto file = static_cast<mlibc::abstract_file *>(stream); - frg::unique_lock lock(file->_lock); - - // Avoid allocating if we've already hit the end - auto c = fgetc_unlocked(stream); - if (c == EOF || ferror(stream)) { - return -1; - } else { - file->unget(c); - } - - while (true) { - // Fill the buffer - while (buffer && capacity > 0 && nwritten < capacity - 1) { - auto c = fgetc_unlocked(stream); - if (ferror(stream)) { - return -1; - } else if (c == EOF) { - buffer[nwritten] = 0; - return nwritten; - } - - buffer[nwritten++] = c; - - if (c == delim) { - buffer[nwritten] = 0; - return nwritten; - } - } - - // Double the size of the buffer (but make sure it's at least 1024) - capacity = (capacity >= 1024) ? capacity * 2 : 1024; - buffer = reinterpret_cast<char *>(getAllocator().reallocate(*line, capacity)); - if (!buffer) { - errno = ENOMEM; - return -1; - } - - *line = buffer; - *n = capacity; - } -} - -// GLIBC extensions. - -int asprintf(char **out, const char *format, ...) { - va_list args; - va_start(args, format); - int result = vasprintf(out, format, args); - va_end(args); - return result; -} - -int vasprintf(char **out, const char *format, __builtin_va_list args) { - frg::va_struct vs; - frg::arg arg_list[NL_ARGMAX + 1]; - vs.arg_list = arg_list; - va_copy(vs.args, args); - ResizePrinter p; -// mlibc::infoLogger() << "printf(" << format << ")" << frg::endlog; - auto res = frg::printf_format(PrintfAgent{&p, &vs}, format, &vs); - if (!res) - return -static_cast<int>(res.error()); - p.expand(); - p.buffer[p.count] = 0; - *out = p.buffer; - return p.count; -} - -// Linux unlocked I/O extensions. - -void flockfile(FILE *file_base) { - static_cast<mlibc::abstract_file *>(file_base)->_lock.lock(); -} - -void funlockfile(FILE *file_base) { - static_cast<mlibc::abstract_file *>(file_base)->_lock.unlock(); -} - -int ftrylockfile(FILE *file_base) { - static_cast<mlibc::abstract_file *>(file_base)->_lock.try_lock(); - return 0; -} - -void clearerr_unlocked(FILE *file_base) { - file_base->__status_bits = 0; -} - -int feof_unlocked(FILE *file_base) { - return file_base->__status_bits & __MLIBC_EOF_BIT; -} - -int ferror_unlocked(FILE *file_base) { - return file_base->__status_bits & __MLIBC_ERROR_BIT; -} - -int fgetc_unlocked(FILE *stream) { - unsigned char d; - if(fread_unlocked(&d, 1, 1, stream) != 1) - return EOF; - return (int)d; -} - -size_t fread_unlocked(void *buffer, size_t size, size_t count, FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - if(!size || !count) - return 0; - - // Distinguish two cases here: If the object size is one, we perform byte-wise reads. - // Otherwise, we try to read each object individually. - if(size == 1) { - size_t progress = 0; - while(progress < count) { - size_t chunk; - if(int e = file->read((char *)buffer + progress, - count - progress, &chunk)) { - errno = e; - return 0; - }else if(!chunk) { - // TODO: Handle eof. - break; - } - - progress += chunk; - } - - return progress; - }else{ - for(size_t i = 0; i < count; i++) { - size_t progress = 0; - while(progress < size) { - size_t chunk; - if(int e = file->read((char *)buffer + i * size + progress, - size - progress, &chunk)) { - errno = e; - return 0; - }else if(!chunk) { - // TODO: Handle eof. - break; - } - - progress += chunk; - } - - if(progress < size) - return i; - } - - return count; - } -} - -size_t fwrite_unlocked(const void *buffer, size_t size, size_t count, FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - if(!size || !count) - return 0; - - // Distinguish two cases here: If the object size is one, we perform byte-wise writes. - // Otherwise, we try to write each object individually. - if(size == 1) { - size_t progress = 0; - while(progress < count) { - size_t chunk; - if(file->write((const char *)buffer + progress, - count - progress, &chunk)) { - // TODO: Handle I/O errors. - mlibc::infoLogger() << "mlibc: fwrite() I/O errors are not handled" - << frg::endlog; - break; - }else if(!chunk) { - // TODO: Handle eof. - break; - } - - progress += chunk; - } - - return progress; - }else{ - for(size_t i = 0; i < count; i++) { - size_t progress = 0; - while(progress < size) { - size_t chunk; - if(file->write((const char *)buffer + i * size + progress, - size - progress, &chunk)) { - // TODO: Handle I/O errors. - mlibc::infoLogger() << "mlibc: fwrite() I/O errors are not handled" - << frg::endlog; - break; - }else if(!chunk) { - // TODO: Handle eof. - break; - } - - progress += chunk; - } - - if(progress < size) - return i; - } - - return count; - } -} - -char *fgets_unlocked(char *__restrict buffer, int max_size, FILE *stream) { - __ensure(max_size > 0); - for(int i = 0; ; i++) { - if(i == max_size - 1) { - buffer[i] = 0; - return buffer; - } - - auto c = fgetc_unlocked(stream); - - // If fgetc() fails, there is either an EOF or an I/O error. - if(c == EOF) { - if(i) { - buffer[i] = 0; - return buffer; - } else { - // In this case, the buffer is not changed. - return nullptr; - } - } else { - buffer[i] = c; - } - - if(c == '\n') { - buffer[i + 1] = 0; - return buffer; - } - } -} diff --git a/lib/mlibc/options/ansi/generic/stdlib-stubs.cpp b/lib/mlibc/options/ansi/generic/stdlib-stubs.cpp deleted file mode 100644 index 86b8a9a..0000000 --- a/lib/mlibc/options/ansi/generic/stdlib-stubs.cpp +++ /dev/null @@ -1,511 +0,0 @@ - -#include <errno.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#include <ctype.h> -#include <stdio.h> -#include <wchar.h> -#include <setjmp.h> -#include <limits.h> - -#include <frg/random.hpp> -#include <mlibc/debug.hpp> -#include <bits/ensure.h> -#include <bits/sigset_t.h> - -#include <mlibc/allocator.hpp> -#include <mlibc/charcode.hpp> -#include <mlibc/ansi-sysdeps.hpp> -#include <mlibc/strtofp.hpp> -#include <mlibc/strtol.hpp> -#include <mlibc/global-config.hpp> - -#if __MLIBC_POSIX_OPTION -#include <pthread.h> -#endif // __MLIBC_POSIX_OPTION - -extern "C" int __cxa_atexit(void (*function)(void *), void *argument, void *dso_tag); -void __mlibc_do_finalize(); - -namespace { - // According to the first paragraph of [C11 7.22.7], - // mblen(), mbtowc() and wctomb() have an internal state. - // The string functions mbstowcs() and wcstombs() do *not* have this state. - thread_local __mlibc_mbstate mblen_state = __MLIBC_MBSTATE_INITIALIZER; - thread_local __mlibc_mbstate mbtowc_state = __MLIBC_MBSTATE_INITIALIZER; -} - -double atof(const char *string) { - return strtod(string, NULL); -} -int atoi(const char *string) { - return strtol(string, nullptr, 10); -} -long atol(const char *string) { - return strtol(string, nullptr, 10); -} -long long atoll(const char *string) { - return strtoll(string, nullptr, 10); -} - -// POSIX extensions but are here for simplicities sake. Forward declaration is here -// to avoid exporting sigprocmask when posix is disabled. -int sigprocmask(int, const sigset_t *__restrict, sigset_t *__restrict); -extern "C" { - __attribute__((__returns_twice__)) int __sigsetjmp(sigjmp_buf buffer, int savesigs) { - buffer[0].savesigs = savesigs; - if (savesigs) - sigprocmask(0, NULL, &buffer[0].sigset); - return 0; - } -} - -__attribute__((__noreturn__)) void siglongjmp(sigjmp_buf buffer, int value) { - if (buffer[0].savesigs) - sigprocmask(SIG_SETMASK, &buffer[0].sigset, NULL); - jmp_buf b; - b[0].reg_state = buffer[0].reg_state; - longjmp(b, value); -} - -double strtod(const char *__restrict string, char **__restrict end) { - return mlibc::strtofp<double>(string, end); -} -float strtof(const char *__restrict string, char **__restrict end) { - return mlibc::strtofp<float>(string, end); -} -long double strtold(const char *__restrict string, char **__restrict end) { - return mlibc::strtofp<long double>(string, end); -} - -long strtol(const char *__restrict string, char **__restrict end, int base) { - return mlibc::stringToInteger<long, char>(string, end, base); -} -long long strtoll(const char *__restrict string, char **__restrict end, int base) { - return mlibc::stringToInteger<long long, char>(string, end, base); -} -unsigned long strtoul(const char *__restrict string, char **__restrict end, int base) { - return mlibc::stringToInteger<unsigned long, char>(string, end, base); -} -unsigned long long strtoull(const char *__restrict string, char **__restrict end, int base) { - return mlibc::stringToInteger<unsigned long long, char>(string, end, base); -} - -frg::mt19937 __mlibc_rand_engine; - -int rand() { - // rand() is specified to return a positive number so we discard the MSB. - return static_cast<int>(__mlibc_rand_engine() & 0x7FFFFFFF); -} - -static unsigned temper(unsigned x) { - x ^= x >> 11; - x ^= x << 7 & 0x9D2C5680; - x ^= x << 15 & 0xEFC60000; - x ^= x >> 18; - return x; -} - -int rand_r(unsigned *seed) { - return temper(*seed = *seed * 1103515245 + 12345) / 2; -} - -void srand(unsigned int s) { - __mlibc_rand_engine.seed(s); -} - -void *aligned_alloc(size_t alignment, size_t size) { - void *ptr; - - // alignment must be a power of two, and size % alignment must be 0 - if (alignment & (alignment - 1) || size & (alignment - 1)) { - errno = EINVAL; - return nullptr; - } - - // posix_memalign requires that the alignment is a multiple of sizeof(void *) - if (alignment < sizeof(void *)) - alignment = sizeof(void *); - - int ret = posix_memalign(&ptr, alignment, size); - if (ret) { - errno = ret; - return nullptr; - } - return ptr; - -} -void *calloc(size_t count, size_t size) { - // we want to ensure that count*size > SIZE_MAX doesn't happen - // to prevent overflowing, we divide both sides of the inequality by size and check with that - if(size && count > (SIZE_MAX / size)) { - errno = EINVAL; - return NULL; - } - - // TODO: this could be done more efficient if the OS gives us already zero'd pages - void *ptr = malloc(count * size); - if(!ptr) - return nullptr; - memset(ptr, 0, count * size); - return ptr; -} -// free() is provided by the platform -// malloc() is provided by the platform -// realloc() is provided by the platform - -void abort(void) { - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGABRT); - if (mlibc::sys_sigprocmask) { - mlibc::sys_sigprocmask(SIG_UNBLOCK, &set, nullptr); - } - - raise(SIGABRT); - - sigfillset(&set); - sigdelset(&set, SIGABRT); - if (mlibc::sys_sigprocmask) { - mlibc::sys_sigprocmask(SIG_SETMASK, &set, nullptr); - } - - struct sigaction sa; - sa.sa_handler = SIG_DFL; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - - if (mlibc::sys_sigaction(SIGABRT, &sa, nullptr)) - mlibc::panicLogger() << "mlibc: sigaction failed in abort" << frg::endlog; - - if (raise(SIGABRT)) - mlibc::panicLogger() << "mlibc: raise failed in abort" << frg::endlog; - - __builtin_trap(); -} - -int atexit(void (*func)(void)) { - // TODO: the function pointer types are not compatible; - // the conversion here is undefined behavior. its fine to do - // this on the x86_64 abi though. - __cxa_atexit((void (*) (void *))func, nullptr, nullptr); - return 0; -} -int at_quick_exit(void (*func)(void)) { - (void)func; - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void exit(int status) { - __mlibc_do_finalize(); - mlibc::sys_exit(status); -} - -void _Exit(int status) { - mlibc::sys_exit(status); -} - -// getenv() is provided by POSIX -void quick_exit(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -extern char **environ; - -int system(const char *command) { - int status = -1; - pid_t child; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fork && mlibc::sys_waitpid && - mlibc::sys_execve && mlibc::sys_sigprocmask && mlibc::sys_sigaction, -1); - -#if __MLIBC_POSIX_OPTION - pthread_testcancel(); -#endif // __MLIBC_POSIX_OPTION - - if (!command) { - return 1; - } - - struct sigaction new_sa, old_int, old_quit; - sigset_t new_mask, old_mask; - - new_sa.sa_handler = SIG_IGN; - new_sa.sa_flags = 0; - sigemptyset(&new_sa.sa_mask); - mlibc::sys_sigaction(SIGINT, &new_sa, &old_int); - mlibc::sys_sigaction(SIGQUIT, &new_sa, &old_quit); - - sigemptyset(&new_mask); - sigaddset(&new_mask, SIGCHLD); - mlibc::sys_sigprocmask(SIG_BLOCK, &new_mask, &old_mask); - - if (int e = mlibc::sys_fork(&child)) { - errno = e; - } else if (!child) { - mlibc::sys_sigaction(SIGINT, &old_int, nullptr); - mlibc::sys_sigaction(SIGQUIT, &old_quit, nullptr); - mlibc::sys_sigprocmask(SIG_SETMASK, &old_mask, nullptr); - - const char *args[] = { - "sh", "-c", command, nullptr - }; - - mlibc::sys_execve("/bin/sh", const_cast<char **>(args), environ); - _Exit(127); - } else { - int err; - pid_t unused; - - while ((err = mlibc::sys_waitpid(child, &status, 0, NULL, &unused)) < 0) { - if (err == EINTR) - continue; - - errno = err; - status = -1; - } - } - - mlibc::sys_sigaction(SIGINT, &old_int, nullptr); - mlibc::sys_sigaction(SIGQUIT, &old_quit, nullptr); - mlibc::sys_sigprocmask(SIG_SETMASK, &old_mask, nullptr); - - return status; -} - -char *mktemp(char *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void *bsearch(const void *key, const void *base, size_t count, size_t size, - int (*compare)(const void *, const void *)) { - // Invariant: Element is in the interval [i, j). - size_t i = 0; - size_t j = count; - - while(i < j) { - size_t k = (j - i) / 2; - auto element = reinterpret_cast<const char *>(base) + (i + k) * size; - auto res = compare(key, element); - if(res < 0) { - j = i + k; - }else if(res > 0) { - i = i + k + 1; - }else{ - return const_cast<char *>(element); - } - } - __ensure(i == j); - - return nullptr; -} - -static int qsort_callback(const void *a, const void *b, void *arg) { - auto compare = reinterpret_cast<int (*)(const void *, const void *)>(arg); - - return compare(a, b); -} - -void qsort(void *base, size_t count, size_t size, - int (*compare)(const void *, const void *)) { - return qsort_r(base, count, size, qsort_callback, (void *) compare); -} - -void qsort_r(void *base, size_t count, size_t size, - int (*compare)(const void *, const void *, void *), - void *arg) { - // TODO: implement a faster sort - for(size_t i = 0; i < count; i++) { - void *u = (void *)((uintptr_t)base + i * size); - for(size_t j = i + 1; j < count; j++) { - void *v = (void *)((uintptr_t)base + j * size); - if(compare(u, v, arg) <= 0) - continue; - - // swap u and v - char *u_bytes = (char *)u; - char *v_bytes = (char *)v; - for(size_t k = 0; k < size; k++) { - char temp = u_bytes[k]; - u_bytes[k] = v_bytes[k]; - v_bytes[k] = temp; - } - } - } -} - -int abs(int num) { - return num < 0 ? -num : num; -} - -long labs(long num) { - return num < 0 ? -num : num; -} - -long long llabs(long long num) { - return num < 0 ? -num : num; -} - -div_t div(int number, int denom) { - div_t r; - r.quot = number / denom; - r.rem = number % denom; - return r; -} - -ldiv_t ldiv(long number, long denom) { - ldiv_t r; - r.quot = number / denom; - r.rem = number % denom; - return r; -} - -lldiv_t lldiv(long long number, long long denom) { - lldiv_t r; - r.quot = number / denom; - r.rem = number % denom; - return r; -} - -int mblen(const char *mbs, size_t mb_limit) { - auto cc = mlibc::current_charcode(); - wchar_t wc; - mlibc::code_seq<const char> nseq{mbs, mbs + mb_limit}; - mlibc::code_seq<wchar_t> wseq{&wc, &wc + 1}; - - if(!mbs) { - mblen_state = __MLIBC_MBSTATE_INITIALIZER; - return cc->has_shift_states; - } - - if(auto e = cc->decode_wtranscode(nseq, wseq, mblen_state); e != mlibc::charcode_error::null) - __ensure(!"decode_wtranscode() errors are not handled"); - return nseq.it - mbs; -} - -int mbtowc(wchar_t *__restrict wc, const char *__restrict mb, size_t max_size) { - auto cc = mlibc::current_charcode(); - __ensure(max_size); - - // If wc is NULL, decode into a single local character which we discard - // to obtain the length. - wchar_t tmp_wc; - if (!wc) - wc = &tmp_wc; - - if (mb) { - if (*mb) { - mlibc::code_seq<wchar_t> wseq{wc, wc + 1}; - mlibc::code_seq<const char> nseq{mb, mb + max_size}; - auto e = cc->decode_wtranscode(nseq, wseq, mbtowc_state); - switch(e) { - // We keep the state, so we can simply return here. - case mlibc::charcode_error::input_underflow: - case mlibc::charcode_error::null: { - return nseq.it - mb; - } - case mlibc::charcode_error::illegal_input: { - errno = -EILSEQ; - return -1; - } - case mlibc::charcode_error::dirty: { - mlibc::panicLogger() << "decode_wtranscode() charcode_error::dirty errors are not handled" << frg::endlog; - break; - } - case mlibc::charcode_error::output_overflow: { - mlibc::panicLogger() << "decode_wtranscode() charcode_error::output_overflow errors are not handled" << frg::endlog; - break; - } - } - __builtin_unreachable(); - } else { - *wc = L'\0'; - return 0; // When mbs is a null byte, return 0 - } - } else { - mblen_state = __MLIBC_MBSTATE_INITIALIZER; - return cc->has_shift_states; - } -} - -int wctomb(char *, wchar_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -size_t mbstowcs(wchar_t *wcs, const char *mbs, size_t wc_limit) { - auto cc = mlibc::current_charcode(); - __mlibc_mbstate st = __MLIBC_MBSTATE_INITIALIZER; - mlibc::code_seq<const char> nseq{mbs, nullptr}; - mlibc::code_seq<wchar_t> wseq{wcs, wcs + wc_limit}; - - if(!wcs) { - size_t size; - if(auto e = cc->decode_wtranscode_length(nseq, &size, st); e != mlibc::charcode_error::null) - __ensure(!"decode_wtranscode() errors are not handled"); - return size; - } - - if(auto e = cc->decode_wtranscode(nseq, wseq, st); e != mlibc::charcode_error::null) { - __ensure(!"decode_wtranscode() errors are not handled"); - __builtin_unreachable(); - }else{ - size_t n = wseq.it - wcs; - if(n < wc_limit) // Null-terminate resulting wide string. - wcs[n] = 0; - return n; - } -} - -size_t wcstombs(char *mb_string, const wchar_t *wc_string, size_t max_size) { - return wcsrtombs(mb_string, &wc_string, max_size, 0); -} - -void free(void *ptr) { - // TODO: Print PID only if POSIX option is enabled. - if (mlibc::globalConfig().debugMalloc) { - mlibc::infoLogger() << "mlibc (PID ?): free() on " - << ptr << frg::endlog; - if((uintptr_t)ptr & 1) - mlibc::infoLogger() << __builtin_return_address(0) << frg::endlog; - } - getAllocator().free(ptr); -} - -void *malloc(size_t size) { - auto nptr = getAllocator().allocate(size); - // TODO: Print PID only if POSIX option is enabled. - if (mlibc::globalConfig().debugMalloc) - mlibc::infoLogger() << "mlibc (PID ?): malloc() returns " - << nptr << frg::endlog; - return nptr; -} - -void *realloc(void *ptr, size_t size) { - auto nptr = getAllocator().reallocate(ptr, size); - // TODO: Print PID only if POSIX option is enabled. - if (mlibc::globalConfig().debugMalloc) - mlibc::infoLogger() << "mlibc (PID ?): realloc() on " - << ptr << " returns " << nptr << frg::endlog; - return nptr; -} - -int posix_memalign(void **out, size_t align, size_t size) { - if(align < sizeof(void *)) - return EINVAL; - if(align & (align - 1)) // Make sure that align is a power of two. - return EINVAL; - auto p = getAllocator().allocate(frg::max(align, size)); - if(!p) - return ENOMEM; - // Hope that the alignment was respected. This works on the current allocator. - // TODO: Make the allocator alignment-aware. - __ensure(!(reinterpret_cast<uintptr_t>(p) & (align - 1))); - *out = p; - return 0; -} diff --git a/lib/mlibc/options/ansi/generic/string-stubs.cpp b/lib/mlibc/options/ansi/generic/string-stubs.cpp deleted file mode 100644 index 8defd0e..0000000 --- a/lib/mlibc/options/ansi/generic/string-stubs.cpp +++ /dev/null @@ -1,542 +0,0 @@ -#include <string.h> -#include <errno.h> -#include <wchar.h> -#include <ctype.h> - -#include <bits/ensure.h> -#include <mlibc/strtol.hpp> - -// memset() is defined in options/internals. -// memcpy() is defined in options/internals. -// memmove() is defined in options/internals. -// strlen() is defined in options/internals. - -char *strcpy(char *__restrict dest, const char *src) { - char *dest_bytes = (char *)dest; - char *src_bytes = (char *)src; - while(*src_bytes) - *(dest_bytes++) = *(src_bytes++); - *dest_bytes = 0; - return dest; -} -char *strncpy(char *__restrict dest, const char *src, size_t max_size) { - auto dest_bytes = static_cast<char *>(dest); - auto src_bytes = static_cast<const char *>(src); - size_t i = 0; - while(*src_bytes && i < max_size) { - *(dest_bytes++) = *(src_bytes++); - i++; - } - while(i < max_size) { - *(dest_bytes++) = 0; - i++; - } - return dest; -} - -char *strcat(char *__restrict dest, const char *__restrict src) { - strcpy(dest + strlen(dest), src); - return dest; -} -char *strncat(char *__restrict dest, const char *__restrict src, size_t max_size) { - auto dest_bytes = static_cast<char *>(dest); - auto src_bytes = static_cast<const char *>(src); - dest_bytes += strlen(dest); - size_t i = 0; - while(*src_bytes && i < max_size) { - *(dest_bytes++) = *(src_bytes++); - i++; - } - *dest_bytes = 0; - return dest; -} - -int memcmp(const void *a, const void *b, size_t size) { - for(size_t i = 0; i < size; i++) { - auto a_byte = static_cast<const unsigned char *>(a)[i]; - auto b_byte = static_cast<const unsigned char *>(b)[i]; - if(a_byte < b_byte) - return -1; - if(a_byte > b_byte) - return 1; - } - return 0; -} -int strcmp(const char *a, const char *b) { - size_t i = 0; - while(true) { - unsigned char a_byte = a[i]; - unsigned char b_byte = b[i]; - if(!a_byte && !b_byte) - return 0; - // If only one char is null, one of the following cases applies. - if(a_byte < b_byte) - return -1; - if(a_byte > b_byte) - return 1; - i++; - } -} - -int strcoll(const char *a, const char *b) { - // TODO: strcoll should take "LC_COLLATE" into account. - return strcmp(a, b); -} - -int strncmp(const char *a, const char *b, size_t max_size) { - size_t i = 0; - while(true) { - if(!(i < max_size)) - return 0; - unsigned char a_byte = a[i]; - unsigned char b_byte = b[i]; - if(!a_byte && !b_byte) - return 0; - // If only one char is null, one of the following cases applies. - if(a_byte < b_byte) - return -1; - if(a_byte > b_byte) - return 1; - i++; - } -} - -size_t strxfrm(char *__restrict dest, const char *__restrict src, size_t n) { - // NOTE: This might not work for non ANSI charsets. - size_t l = strlen(src); - - // man page: If the value returned is n or more, the contents of dest are indeterminate. - if(n > l) - strncpy(dest, src, n); - - return l; -} - -void *memchr(const void *s, int c, size_t size) { - auto s_bytes = static_cast<const unsigned char *>(s); - for(size_t i = 0; i < size; i++) - if(s_bytes[i] == static_cast<unsigned char>(c)) - return const_cast<unsigned char *>(s_bytes + i); - return nullptr; -} -char *strchr(const char *s, int c) { - size_t i = 0; - while(s[i]) { - if(s[i] == c) - return const_cast<char *>(&s[i]); - i++; - } - if(c == 0) - return const_cast<char *>(&s[i]); - return nullptr; -} -size_t strcspn(const char *s, const char *chrs) { - size_t n = 0; - while(true) { - if(!s[n] || strchr(chrs, s[n])) - return n; - n++; - } -} -char *strpbrk(const char *s, const char *chrs) { - size_t n = 0; - while(s[n]) { - if(strchr(chrs, s[n])) - return const_cast<char *>(s + n); - n++; - } - return nullptr; -} -char *strrchr(const char *s, int c) { - // The null-terminator is considered to be part of the string. - size_t length = strlen(s); - for(size_t i = 0; i <= length; i++) { - if(s[length - i] == c) - return const_cast<char *>(s + (length - i)); - } - return nullptr; -} -size_t strspn(const char *s, const char *chrs) { - size_t n = 0; - while(true) { - if(!s[n] || !strchr(chrs, s[n])) - return n; - n++; - } -} -char *strstr(const char *s, const char *pattern) { - for(size_t i = 0; s[i]; i++) { - bool found = true; - for(size_t j = 0; pattern[j]; j++) { - if(!pattern[j] || s[i + j] == pattern[j]) - continue; - - found = false; - break; - } - - if(found) - return const_cast<char *>(&s[i]); - } - - return nullptr; -} -char *strtok_r(char *__restrict s, const char *__restrict del, char **__restrict m) { - __ensure(m); - - // We use *m = null to memorize that the entire string was consumed. - char *tok; - if(s) { - tok = s; - }else if(*m) { - tok = *m; - }else { - return nullptr; - } - - // Skip initial delimiters. - // After this loop: *tok is non-null iff we return a token. - while(*tok && strchr(del, *tok)) - tok++; - - // Replace the following delimiter by a null-terminator. - // After this loop: *p is null iff we reached the end of the string. - auto p = tok; - while(*p && !strchr(del, *p)) - p++; - - if(*p) { - *p = 0; - *m = p + 1; - }else{ - *m = nullptr; - } - if(p == tok) - return nullptr; - return tok; -} -char *strtok(char *__restrict s, const char *__restrict delimiter) { - static char *saved; - return strtok_r(s, delimiter, &saved); -} - -// This is a GNU extension. -char *strchrnul(const char *s, int c) { - size_t i = 0; - while(s[i]) { - if(s[i] == c) - return const_cast<char *>(s + i); - i++; - } - return const_cast<char *>(s + i); -} - -double wcstod(const wchar_t *__restrict, wchar_t **__restrict) MLIBC_STUB_BODY -float wcstof(const wchar_t *__restrict, wchar_t **__restrict) MLIBC_STUB_BODY -long double wcstold(const wchar_t *__restrict, wchar_t **__restrict) MLIBC_STUB_BODY - -long wcstol(const wchar_t *__restrict nptr, wchar_t **__restrict endptr, int base) { - return mlibc::stringToInteger<long, wchar_t>(nptr, endptr, base); -} -unsigned long wcstoul(const wchar_t *__restrict nptr, wchar_t **__restrict endptr, int base) { - return mlibc::stringToInteger<unsigned long, wchar_t>(nptr, endptr, base); -} -long long wcstoll(const wchar_t *__restrict nptr, wchar_t **__restrict endptr, int base) { - return mlibc::stringToInteger<long long, wchar_t>(nptr, endptr, base); -} -unsigned long long wcstoull(const wchar_t *__restrict nptr, wchar_t **__restrict endptr, int base) { - return mlibc::stringToInteger<unsigned long long, wchar_t>(nptr, endptr, base); -} - -wchar_t *wcscpy(wchar_t *__restrict dest, const wchar_t *__restrict src) { - wchar_t *a = dest; - while((*dest++ = *src++)); - return a; -} - -wchar_t *wcsncpy(wchar_t *__restrict dest, const wchar_t *__restrict src, size_t n) { - wchar_t *a = dest; - while(n && *src) - n--, *dest++ = *src++; - wmemset(dest, 0, n); - return a; -} - -wchar_t *wmemcpy(wchar_t *__restrict dest, const wchar_t *__restrict src, size_t n) { - memcpy(dest, src, n * sizeof(wchar_t)); - return dest; -} - -wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t n) { - memmove(dest, src, n * sizeof(wchar_t)); - return dest; -} - -wchar_t *wcscat(wchar_t *__restrict dest, const wchar_t *__restrict src) { - wcscpy(dest + wcslen(dest), src); - return dest; -} - -wchar_t *wcsncat(wchar_t *__restrict, const wchar_t *__restrict, size_t) MLIBC_STUB_BODY - -int wcscmp(const wchar_t *l, const wchar_t *r) { - for(; *l == *r && *l && *r; l++, r++); - return *l - *r; -} - -int wcscoll(const wchar_t *, const wchar_t *) MLIBC_STUB_BODY -int wcsncmp(const wchar_t *, const wchar_t *, size_t) MLIBC_STUB_BODY -int wcsxfrm(wchar_t *__restrict, const wchar_t *__restrict, size_t) MLIBC_STUB_BODY - -int wmemcmp(const wchar_t *a, const wchar_t *b, size_t size) { - for(size_t i = 0; i < size; i++) { - auto a_byte = a[i]; - auto b_byte = b[i]; - if(a_byte < b_byte) - return -1; - if(a_byte > b_byte) - return 1; - } - return 0; -} - -wchar_t *wcschr(const wchar_t *s, wchar_t c) { - if(!c) - return (wchar_t *)s + wcslen(s); - for(; *s && *s != c; s++); - return *s ? (wchar_t *)s : 0; -} - -size_t wcscspn(const wchar_t *, const wchar_t *) MLIBC_STUB_BODY -wchar_t *wcspbrk(const wchar_t *, const wchar_t *) MLIBC_STUB_BODY - -wchar_t *wcsrchr(const wchar_t *s, wchar_t c) { - const wchar_t *p; - for(p = s + wcslen(s); p >= s && *p != c; p--); - return p >= s ? (wchar_t *)p : 0; -} - -size_t wcsspn(const wchar_t *, const wchar_t *) MLIBC_STUB_BODY -wchar_t *wcsstr(const wchar_t *, const wchar_t *) MLIBC_STUB_BODY -wchar_t *wcstok(wchar_t *__restrict, const wchar_t *__restrict, wchar_t **__restrict) MLIBC_STUB_BODY - -wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t size) { - auto s_bytes = s; - for(size_t i = 0; i < size; i++) - if(s_bytes[i] == c) - return const_cast<wchar_t *>(s_bytes + i); - return nullptr; -} - -size_t wcslen(const wchar_t *s) { - const wchar_t *a; - for(a = s; *s; s++); - return s-a; -} - -wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n) { - wchar_t *ret = d; - while(n--) - *d++ = c; - return ret; -} - -char *strerror(int e) { - const char *s; - switch(e) { - case EAGAIN: s = "Operation would block (EAGAIN)"; break; - case EACCES: s = "Access denied (EACCESS)"; break; - case EBADF: s = "Bad file descriptor (EBADF)"; break; - case EEXIST: s = "File exists already (EEXIST)"; break; - case EFAULT: s = "Access violation (EFAULT)"; break; - case EINTR: s = "Operation interrupted (EINTR)"; break; - case EINVAL: s = "Invalid argument (EINVAL)"; break; - case EIO: s = "I/O error (EIO)"; break; - case EISDIR: s = "Resource is directory (EISDIR)"; break; - case ENOENT: s = "No such file or directory (ENOENT)"; break; - case ENOMEM: s = "Out of memory (ENOMEM)"; break; - case ENOTDIR: s = "Expected directory instead of file (ENOTDIR)"; break; - case ENOSYS: s = "Operation not implemented (ENOSYS)"; break; - case EPERM: s = "Operation not permitted (EPERM)"; break; - case EPIPE: s = "Broken pipe (EPIPE)"; break; - case ESPIPE: s = "Seek not possible (ESPIPE)"; break; - case ENXIO: s = "No such device or address (ENXIO)"; break; - case ENOEXEC: s = "Exec format error (ENOEXEC)"; break; - case ENOSPC: s = "No space left on device (ENOSPC)"; break; - case ENOTSOCK: s = "Socket operation on non-socket (ENOTSOCK)"; break; - case ENOTCONN: s = "Transport endpoint is not connected (ENOTCONN)"; break; - case EDOM: s = "Numerical argument out of domain (EDOM)"; break; - case EILSEQ: s = "Invalid or incomplete multibyte or wide character (EILSEQ)"; break; - case ERANGE: s = "Numerical result out of range (ERANGE)"; break; - case E2BIG: s = "Argument list too long (E2BIG)"; break; - case EADDRINUSE: s = "Address already in use (EADDRINUSE)"; break; - case EADDRNOTAVAIL: s = "Cannot assign requested address (EADDRNOTAVAIL)"; break; - case EAFNOSUPPORT: s = "Address family not supported by protocol (EAFNOSUPPORT)"; break; - case EALREADY: s = "Operation already in progress (EALREADY)"; break; - case EBADMSG: s = "Bad message (EBADMSG)"; break; - case EBUSY: s = "Device or resource busy (EBUSY)"; break; - case ECANCELED: s = "Operation canceled (ECANCELED)"; break; - case ECHILD: s = "No child processes (ECHILD)"; break; - case ECONNABORTED: s = "Software caused connection abort (ECONNABORTED)"; break; - case ECONNREFUSED: s = "Connection refused (ECONNREFUSED)"; break; - case ECONNRESET: s = "Connection reset by peer (ECONNRESET)"; break; - case EDEADLK: s = "Resource deadlock avoided (EDEADLK)"; break; - case EDESTADDRREQ: s = "Destination address required (EDESTADDRREQ)"; break; - case EDQUOT: s = "Disk quota exceeded (EDQUOT)"; break; - case EFBIG: s = "File too large (EFBIG)"; break; - case EHOSTUNREACH: s = "No route to host (EHOSTUNREACH)"; break; - case EIDRM: s = "Identifier removed (EIDRM)"; break; - case EINPROGRESS: s = "Operation now in progress (EINPROGRESS)"; break; - case EISCONN: s = "Transport endpoint is already connected (EISCONN)"; break; - case ELOOP: s = "Too many levels of symbolic links (ELOOP)"; break; - case EMFILE: s = "Too many open files (EMFILE)"; break; - case EMLINK: s = "Too many links (EMLINK)"; break; - case EMSGSIZE: s = "Message too long (EMSGSIZE)"; break; - case EMULTIHOP: s = "Multihop attempted (EMULTIHOP)"; break; - case ENAMETOOLONG: s = "File name too long (ENAMETOOLONG)"; break; - case ENETDOWN: s = "Network is down (ENETDOWN)"; break; - case ENETRESET: s = "Network dropped connection on reset (ENETRESET)"; break; - case ENETUNREACH: s = "Network is unreachable (ENETUNREACH)"; break; - case ENFILE: s = "Too many open files in system (ENFILE)"; break; - case ENOBUFS: s = "No buffer space available (ENOBUFS)"; break; - case ENODEV: s = "No such device (ENODEV)"; break; - case ENOLCK: s = "No locks available (ENOLCK)"; break; - case ENOLINK: s = "Link has been severed (ENOLINK)"; break; - case ENOMSG: s = "No message of desired type (ENOMSG)"; break; - case ENOPROTOOPT: s = "Protocol not available (ENOPROTOOPT)"; break; - case ENOTEMPTY: s = "Directory not empty (ENOTEMPTY)"; break; - case ENOTRECOVERABLE: s = "Sate not recoverable (ENOTRECOVERABLE)"; break; - case ENOTSUP: s = "Operation not supported (ENOTSUP)"; break; - case ENOTTY: s = "Inappropriate ioctl for device (ENOTTY)"; break; - case EOVERFLOW: s = "Value too large for defined datatype (EOVERFLOW)"; break; -#if EOPNOTSUPP != ENOTSUP - /* these are aliases on the mlibc abi */ - case EOPNOTSUPP: s = "Operation not supported (EOPNOTSUP)"; break; -#endif - case EOWNERDEAD: s = "Owner died (EOWNERDEAD)"; break; - case EPROTO: s = "Protocol error (EPROTO)"; break; - case EPROTONOSUPPORT: s = "Protocol not supported (EPROTONOSUPPORT)"; break; - case EPROTOTYPE: s = "Protocol wrong type for socket (EPROTOTYPE)"; break; - case EROFS: s = "Read-only file system (EROFS)"; break; - case ESRCH: s = "No such process (ESRCH)"; break; - case ESTALE: s = "Stale file handle (ESTALE)"; break; - case ETIMEDOUT: s = "Connection timed out (ETIMEDOUT)"; break; - case ETXTBSY: s = "Text file busy (ETXTBSY)"; break; - case EXDEV: s = "Invalid cross-device link (EXDEV)"; break; - case ENODATA: s = "No data available (ENODATA)"; break; - case ETIME: s = "Timer expired (ETIME)"; break; - case ENOKEY: s = "Required key not available (ENOKEY)"; break; - case ESHUTDOWN: s = "Cannot send after transport endpoint shutdown (ESHUTDOWN)"; break; - case EHOSTDOWN: s = "Host is down (EHOSTDOWN)"; break; - case EBADFD: s = "File descriptor in bad state (EBADFD)"; break; - case ENOMEDIUM: s = "No medium found (ENOMEDIUM)"; break; - case ENOTBLK: s = "Block device required (ENOTBLK)"; break; - case ENONET: s = "Machine is not on the network (ENONET)"; break; - case EPFNOSUPPORT: s = "Protocol family not supported (EPFNOSUPPORT)"; break; - case ESOCKTNOSUPPORT: s = "Socket type not supported (ESOCKTNOSUPPORT)"; break; - case ESTRPIPE: s = "Streams pipe error (ESTRPIPE)"; break; - case EREMOTEIO: s = "Remote I/O error (EREMOTEIO)"; break; - case ERFKILL: s = "Operation not possible due to RF-kill (ERFKILL)"; break; - case EBADR: s = "Invalid request descriptor (EBADR)"; break; - case EUNATCH: s = "Protocol driver not attached (EUNATCH)"; break; - case EMEDIUMTYPE: s = "Wrong medium type (EMEDIUMTYPE)"; break; - case EREMOTE: s = "Object is remote (EREMOTE)"; break; - case EKEYREJECTED: s = "Key was rejected by service (EKEYREJECTED)"; break; - case EUCLEAN: s = "Structure needs cleaning (EUCLEAN)"; break; - case EBADSLT: s = "Invalid slot (EBADSLT)"; break; - case ENOANO: s = "No anode (ENOANO)"; break; - case ENOCSI: s = "No CSI structure available (ENOCSI)"; break; - case ENOSTR: s = "Device not a stream (ENOSTR)"; break; - case ETOOMANYREFS: s = "Too many references: cannot splice (ETOOMANYREFS)"; break; - case ENOPKG: s = "Package not installed (ENOPKG)"; break; - case EKEYREVOKED: s = "Key has been revoked (EKEYREVOKED)"; break; - case EXFULL: s = "Exchange full (EXFULL)"; break; - case ELNRNG: s = "Link number out of range (ELNRNG)"; break; - case ENOTUNIQ: s = "Name not unique on network (ENOTUNIQ)"; break; - case ERESTART: s = "Interrupted system call should be restarted (ERESTART)"; break; - case EUSERS: s = "Too many users (EUSERS)"; break; - -#ifdef EIEIO - case EIEIO: s = "Computer bought the farm; OS internal error (EIEIO)"; break; -#endif - - default: - s = "Unknown error code (?)"; - } - return const_cast<char *>(s); -} -// strlen() is defined in options/internals. - -// POSIX extensions. - -int strerror_r(int e, char *buffer, size_t bufsz) { - auto s = strerror(e); - strncpy(buffer, s, bufsz); - // Note that strerror_r does not set errno on error! - if(strlen(s) >= bufsz) - return ERANGE; - return 0; -} - -void *mempcpy(void *dest, const void *src, size_t len) { - return (char *)memcpy(dest, src, len) + len; -} - -// GNU extensions. -// Taken from musl. -int strverscmp(const char *l0, const char *r0) { - const unsigned char *l = (const unsigned char *)l0; - const unsigned char *r = (const unsigned char *)r0; - size_t i, dp, j; - int z = 1; - - /* Find maximal matching prefix and track its maximal digit - * suffix and whether those digits are all zeros. */ - for(dp = i = 0; l[i] == r[i]; i++) { - int c = l[i]; - if(!c) - return 0; - if(!isdigit(c)) - dp = i + 1, z = 1; - else if(c != '0') - z = 0; - } - - if(l[dp] != '0' && r[dp] != '0') { - /* If we're not looking at a digit sequence that began - * with a zero, longest digit string is greater. */ - for(j = i; isdigit(l[j]); j++) { - if(!isdigit(r[j])) - return 1; - } - if(isdigit(r[j])) - return -1; - } else if(z && dp < i && (isdigit(l[i]) || isdigit(r[i]))) { - /* Otherwise, if common prefix of digit sequence is - * all zeros, digits order less than non-digits. */ - return (unsigned char)(l[i] - '0') - (unsigned char)(r[i] - '0'); - } - - return l[i] - r[i]; -} - -void *memmem(const void *hs, size_t haystackLen, const void *nd, size_t needleLen) { - const char *haystack = static_cast<const char *>(hs); - const char *needle = static_cast<const char *>(nd); - - for (size_t i = 0; i < haystackLen; i++) { - bool found = true; - - for (size_t j = 0; j < needleLen; j++) { - if (i + j >= haystackLen || haystack[i + j] != needle[j]) { - found = false; - break; - } - } - - if(found) - return const_cast<char *>(&haystack[i]); - } - - return nullptr; -} diff --git a/lib/mlibc/options/ansi/generic/threads.cpp b/lib/mlibc/options/ansi/generic/threads.cpp deleted file mode 100644 index 70fa055..0000000 --- a/lib/mlibc/options/ansi/generic/threads.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include <abi-bits/errno.h> -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/thread.hpp> -#include <mlibc/threads.hpp> -#include <threads.h> - -int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { - int res = mlibc::thread_create(thr, 0, reinterpret_cast<void *>(func), arg, true); - - if(!res) { - return thrd_success; - } - - return (res == ENOMEM) ? thrd_nomem : thrd_error; -} - -int thrd_equal(thrd_t t1, thrd_t t2) { - if(t1 == t2) { - return 1; - } - return 0; -} - -thrd_t thrd_current(void) { - return reinterpret_cast<thrd_t>(mlibc::get_current_tcb()); -} - -int thrd_sleep(const struct timespec *, struct timespec *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void thrd_yield(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int thrd_detach(thrd_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int thrd_join(thrd_t thr, int *res) { - if(mlibc::thread_join(thr, res) != 0) { - return thrd_error; - } - - return thrd_success; -} - -__attribute__((__noreturn__)) void thrd_exit(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int mtx_init(mtx_t *mtx, int type) { - struct __mlibc_mutexattr attr; - mlibc::thread_mutexattr_init(&attr); - - if(type & mtx_recursive) { - mlibc::thread_mutexattr_settype(&attr, __MLIBC_THREAD_MUTEX_RECURSIVE); - } - - int res = mlibc::thread_mutex_init(mtx, &attr) == 0 ? thrd_success : thrd_error; - mlibc::thread_mutexattr_destroy(&attr); - - return res; -} - -void mtx_destroy(mtx_t *mtx) { - mlibc::thread_mutex_destroy(mtx); -} - -int mtx_lock(mtx_t *mtx) { - return mlibc::thread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error; -} - -int mtx_unlock(mtx_t *mtx) { - return mlibc::thread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error; -} - -int cnd_init(cnd_t *cond) { - return mlibc::thread_cond_init(cond, 0) == 0 ? thrd_success : thrd_error; -} - -void cnd_destroy(cnd_t *cond) { - mlibc::thread_cond_destroy(cond); -} - -int cnd_broadcast(cnd_t *cond) { - return mlibc::thread_cond_broadcast(cond) == 0 ? thrd_success : thrd_error; -} - -int cnd_wait(cnd_t *cond, mtx_t *mtx) { - return mlibc::thread_cond_timedwait(cond, mtx, nullptr) == 0 ? thrd_success : thrd_error; -} diff --git a/lib/mlibc/options/ansi/generic/time-stubs.cpp b/lib/mlibc/options/ansi/generic/time-stubs.cpp deleted file mode 100644 index b8c7cf5..0000000 --- a/lib/mlibc/options/ansi/generic/time-stubs.cpp +++ /dev/null @@ -1,729 +0,0 @@ - -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <limits.h> -#include <wchar.h> -#include <stdlib.h> -#include <ctype.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/file-window.hpp> -#include <mlibc/ansi-sysdeps.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/lock.hpp> -#include <mlibc/locale.hpp> -#include <mlibc/bitutil.hpp> -#include <mlibc/strings.hpp> - -#include <frg/mutex.hpp> - -const char __utc[] = "UTC"; - -// Variables defined by POSIX. -int daylight; -long timezone; -char *tzname[2]; - -static FutexLock __time_lock; -static file_window *get_localtime_window() { - static file_window window{"/etc/localtime"}; - return &window; -} - -// Function taken from musl -clock_t clock(void) { - struct timespec ts; - - if(clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts)) - return -1; - - if(ts.tv_sec > LONG_MAX / 1000000 || ts.tv_nsec / 1000 > LONG_MAX - 1000000 * ts.tv_sec) - return -1; - - return ts.tv_sec * 1000000 + ts.tv_nsec / 1000; -} - -double difftime(time_t a, time_t b) { - return a - b; -} - -time_t mktime(struct tm *tm) { - return timegm(tm); -} - -/* There is no other implemented value than TIME_UTC; all other values - * are considered erroneous. */ -// Function taken from musl -int timespec_get(struct timespec *ts, int base) { - if(base != TIME_UTC) - return 0; - int ret = clock_gettime(CLOCK_REALTIME, ts); - return ret < 0 ? 0 : base; -} - -char *asctime(const struct tm *ptr) { - static char buf[26]; - return asctime_r(ptr, buf); -} - -char *ctime(const time_t *timer) { - struct tm *tm = localtime(timer); - if(!tm) { - return 0; - } - return asctime(tm); -} - -struct tm *gmtime(const time_t *unix_gmt) { - static thread_local struct tm per_thread_tm; - return gmtime_r(unix_gmt, &per_thread_tm); -} - -struct tm *localtime(const time_t *unix_gmt) { - tzset(); - static thread_local struct tm per_thread_tm; - return localtime_r(unix_gmt, &per_thread_tm); -} - -size_t strftime(char *__restrict dest, size_t max_size, - const char *__restrict format, const struct tm *__restrict tm) { - auto c = format; - auto p = dest; - - while(*c) { - int chunk; - auto space = (dest + max_size) - p; - __ensure(space >= 0); - - if(*c != '%') { - if(!space) - return 0; - *p = *c; - c++; - p++; - continue; - } - - switch(*++c) { - case 'Y': { - chunk = snprintf(p, space, "%d", 1900 + tm->tm_year); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'm': { - chunk = snprintf(p, space, "%.2d", tm->tm_mon + 1); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'd': { - chunk = snprintf(p, space, "%.2d", tm->tm_mday); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'Z': { - chunk = snprintf(p, space, "%s", "GMT"); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'H': { - chunk = snprintf(p, space, "%.2i", tm->tm_hour); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'M': { - chunk = snprintf(p, space, "%.2i", tm->tm_min); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'S': { - chunk = snprintf(p, space, "%.2d", tm->tm_sec); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'R': { - chunk = snprintf(p, space, "%.2i:%.2i", tm->tm_hour, tm->tm_min); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'T': { - chunk = snprintf(p, space, "%.2i:%.2i:%.2i", tm->tm_hour, tm->tm_min, tm->tm_sec); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'F': { - chunk = snprintf(p, space, "%d-%.2d-%.2d", 1900 + tm->tm_year, tm->tm_mon + 1, - tm->tm_mday); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'D': { - chunk = snprintf(p, space, "%.2d/%.2d/%.2d", tm->tm_mon + 1, tm->tm_mday, tm->tm_year % 100); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'a': { - int day = tm->tm_wday; - if(day < 0 || day > 6) - __ensure(!"Day not in bounds."); - - chunk = snprintf(p, space, "%s", mlibc::nl_langinfo(ABDAY_1 + day)); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'b': - case 'B': - case 'h': { - int mon = tm->tm_mon; - if(mon < 0 || mon > 11) - __ensure(!"Month not in bounds."); - - nl_item item = (*c == 'B') ? MON_1 : ABMON_1; - - chunk = snprintf(p, space, "%s", mlibc::nl_langinfo(item + mon)); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'c': { - chunk = snprintf(p, space, "%d/%.2d/%.2d %.2d:%.2d:%.2d", 1900 + tm->tm_year, - tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'e': { - chunk = snprintf(p, space, "%2d", tm->tm_mday); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'l': { - int hour = tm->tm_hour; - if(!hour) - hour = 12; - if(hour > 12) - hour -= 12; - chunk = snprintf(p, space, "%2d", hour); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'I': { - int hour = tm->tm_hour; - if(!hour) - hour = 12; - if(hour > 12) - hour -= 12; - chunk = snprintf(p, space, "%.2d", hour); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'p': { - chunk = snprintf(p, space, "%s", mlibc::nl_langinfo((tm->tm_hour < 12) ? AM_STR : PM_STR)); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'C': { - chunk = snprintf(p, space, "%.2d", (1900 + tm->tm_year) / 100); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'y': { - chunk = snprintf(p, space, "%.2d", (1900 + tm->tm_year) % 100); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'j': { - chunk = snprintf(p, space, "%.3d", tm->tm_yday + 1); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'A': { - chunk = snprintf(p, space, "%s", mlibc::nl_langinfo(DAY_1 + tm->tm_wday)); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'r': { - int hour = tm->tm_hour; - if(!hour) - hour = 12; - if(hour > 12) - hour -= 12; - chunk = snprintf(p, space, "%.2i:%.2i:%.2i %s", hour, tm->tm_min, tm->tm_sec, - mlibc::nl_langinfo((tm->tm_hour < 12) ? AM_STR : PM_STR)); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case '%': { - chunk = snprintf(p, space, "%%"); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 't': { - chunk = snprintf(p, space, "\t"); - if(chunk >= space) - return 0; - p += chunk; - c++; - break; - } - case 'x': { - return strftime(dest, max_size, mlibc::nl_langinfo(D_FMT), tm); - } - case 'X': { - return strftime(dest, max_size, mlibc::nl_langinfo(T_FMT), tm); - } - case '\0': { - chunk = snprintf(p, space, "%%"); - if(chunk >= space) - return 0; - p += chunk; - break; - } - default: - mlibc::panicLogger() << "mlibc: strftime unknown format type: " << c << frg::endlog; - } - } - - auto space = (dest + max_size) - p; - if(!space) - return 0; - - *p = '\0'; - return (p - dest); -} - -size_t wcsftime(wchar_t *__restrict, size_t, const wchar_t *__restrict, - const struct tm *__restrict) { - mlibc::infoLogger() << "mlibc: wcsftime is a stub" << frg::endlog; - return 0; -} - -namespace { - -struct tzfile { - uint8_t magic[4]; - uint8_t version; - uint8_t reserved[15]; - uint32_t tzh_ttisgmtcnt; - uint32_t tzh_ttisstdcnt; - uint32_t tzh_leapcnt; - uint32_t tzh_timecnt; - uint32_t tzh_typecnt; - uint32_t tzh_charcnt; -}; - -struct[[gnu::packed]] ttinfo { - int32_t tt_gmtoff; - unsigned char tt_isdst; - unsigned char tt_abbrind; -}; - -} - -// TODO(geert): this function doesn't parse the TZ environment variable -// or properly handle the case where information might be missing from /etc/localtime -// also we should probably unify the code for this and unix_local_from_gmt() -void tzset(void) { - frg::unique_lock<FutexLock> lock(__time_lock); - // TODO(geert): we can probably cache this somehow - tzfile tzfile_time; - memcpy(&tzfile_time, reinterpret_cast<char *>(get_localtime_window()->get()), sizeof(tzfile)); - tzfile_time.tzh_ttisgmtcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_ttisgmtcnt); - tzfile_time.tzh_ttisstdcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_ttisstdcnt); - tzfile_time.tzh_leapcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_leapcnt); - tzfile_time.tzh_timecnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_timecnt); - tzfile_time.tzh_typecnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_typecnt); - tzfile_time.tzh_charcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_charcnt); - - if(tzfile_time.magic[0] != 'T' || tzfile_time.magic[1] != 'Z' || tzfile_time.magic[2] != 'i' - || tzfile_time.magic[3] != 'f') { - mlibc::infoLogger() << "mlibc: /etc/localtime is not a valid TZinfo file" << frg::endlog; - return; - } - - if(tzfile_time.version != '\0' && tzfile_time.version != '2' && tzfile_time.version != '3') { - mlibc::infoLogger() << "mlibc: /etc/localtime has an invalid TZinfo version" - << frg::endlog; - return; - } - - // There should be at least one entry in the ttinfo table. - // TODO: If there is not, we might want to fall back to UTC, no DST (?). - __ensure(tzfile_time.tzh_typecnt); - - char *abbrevs = reinterpret_cast<char *>(get_localtime_window()->get()) + sizeof(tzfile) - + tzfile_time.tzh_timecnt * sizeof(int32_t) - + tzfile_time.tzh_timecnt * sizeof(uint8_t) - + tzfile_time.tzh_typecnt * sizeof(struct ttinfo); - // start from the last ttinfo entry, this matches the behaviour of glibc and musl - for (int i = tzfile_time.tzh_typecnt; i > 0; i--) { - ttinfo time_info; - memcpy(&time_info, reinterpret_cast<char *>(get_localtime_window()->get()) + sizeof(tzfile) - + tzfile_time.tzh_timecnt * sizeof(int32_t) - + tzfile_time.tzh_timecnt * sizeof(uint8_t) - + i * sizeof(ttinfo), sizeof(ttinfo)); - time_info.tt_gmtoff = mlibc::bit_util<uint32_t>::byteswap(time_info.tt_gmtoff); - if (!time_info.tt_isdst && !tzname[0]) { - tzname[0] = abbrevs + time_info.tt_abbrind; - timezone = -time_info.tt_gmtoff; - } - if (time_info.tt_isdst && !tzname[1]) { - tzname[1] = abbrevs + time_info.tt_abbrind; - timezone = -time_info.tt_gmtoff; - daylight = 1; - } - } -} - -// POSIX extensions. - -int nanosleep(const struct timespec *req, struct timespec *) { - if (req->tv_sec < 0 || req->tv_nsec > 999999999 || req->tv_nsec < 0) { - errno = EINVAL; - return -1; - } - - if(!mlibc::sys_sleep) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_sleep()"); - } - - struct timespec tmp = *req; - - int e = mlibc::sys_sleep(&tmp.tv_sec, &tmp.tv_nsec); - if (!e) { - return 0; - } else { - errno = e; - return -1; - } -} - -int clock_getres(clockid_t clockid, struct timespec *res) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_clock_getres, -1); - if(int e = mlibc::sys_clock_getres(clockid, &res->tv_sec, &res->tv_nsec); e) { - errno = e; - return -1; - } - return 0; -} - -int clock_gettime(clockid_t clock, struct timespec *time) { - if(int e = mlibc::sys_clock_get(clock, &time->tv_sec, &time->tv_nsec); e) { - errno = e; - return -1; - } - return 0; -} - -int clock_nanosleep(clockid_t clockid, int, const struct timespec *req, struct timespec *) { - mlibc::infoLogger() << "clock_nanosleep is implemented as nanosleep!" << frg::endlog; - __ensure(clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC); - return nanosleep(req, nullptr); -} - -int clock_settime(clockid_t, const struct timespec *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -time_t time(time_t *out) { - time_t secs; - long nanos; - if(int e = mlibc::sys_clock_get(CLOCK_REALTIME, &secs, &nanos); e) { - errno = e; - return (time_t)-1; - } - if(out) - *out = secs; - return secs; -} - -namespace { - -void civil_from_days(time_t days_since_epoch, int *year, unsigned int *month, unsigned int *day) { - time_t time = days_since_epoch + 719468; - int era = (time >= 0 ? time : time - 146096) / 146097; - unsigned int doe = static_cast<unsigned int>(time - era * 146097); - unsigned int yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; - int y = static_cast<int>(yoe) + era * 400; - unsigned int doy = doe - (365*yoe + yoe/4 - yoe/100); - unsigned int mp = (5*doy + 2)/153; - unsigned int d = doy - (153*mp+2)/5 + 1; - unsigned int m = mp + (mp < 10 ? 3 : -9); - - *year = y + (m <= 2); - *month = m; - *day = d; -} - -void weekday_from_days(time_t days_since_epoch, unsigned int *weekday) { - *weekday = static_cast<unsigned int>(days_since_epoch >= -4 ? - (days_since_epoch+4) % 7 : (days_since_epoch+5) % 7 + 6); -} - -void yearday_from_date(unsigned int year, unsigned int month, unsigned int day, unsigned int *yday) { - unsigned int n1 = 275 * month / 9; - unsigned int n2 = (month + 9) / 12; - unsigned int n3 = (1 + (year - 4 * year / 4 + 2) / 3); - *yday = n1 - (n2 * n3) + day - 30; -} - -// Looks up the local time rules for a given -// UNIX GMT timestamp (seconds since 1970 GMT, ignoring leap seconds). -// This function assumes the __time_lock has been taken -// TODO(geert): if /etc/localtime isn't available this will fail... In that case -// we should call tzset() and use the variables to compute the variables from -// the tzset() global variables. Look at the musl code for how to do that -int unix_local_from_gmt(time_t unix_gmt, time_t *offset, bool *dst, char **tm_zone) { - tzfile tzfile_time; - memcpy(&tzfile_time, reinterpret_cast<char *>(get_localtime_window()->get()), sizeof(tzfile)); - tzfile_time.tzh_ttisgmtcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_ttisgmtcnt); - tzfile_time.tzh_ttisstdcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_ttisstdcnt); - tzfile_time.tzh_leapcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_leapcnt); - tzfile_time.tzh_timecnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_timecnt); - tzfile_time.tzh_typecnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_typecnt); - tzfile_time.tzh_charcnt = mlibc::bit_util<uint32_t>::byteswap(tzfile_time.tzh_charcnt); - - if(tzfile_time.magic[0] != 'T' || tzfile_time.magic[1] != 'Z' || tzfile_time.magic[2] != 'i' - || tzfile_time.magic[3] != 'f') { - mlibc::infoLogger() << "mlibc: /etc/localtime is not a valid TZinfo file" << frg::endlog; - return -1; - } - - if(tzfile_time.version != '\0' && tzfile_time.version != '2' && tzfile_time.version != '3') { - mlibc::infoLogger() << "mlibc: /etc/localtime has an invalid TZinfo version" - << frg::endlog; - return -1; - } - - int index = -1; - for(size_t i = 0; i < tzfile_time.tzh_timecnt; i++) { - int32_t ttime; - memcpy(&ttime, reinterpret_cast<char *>(get_localtime_window()->get()) + sizeof(tzfile) - + i * sizeof(int32_t), sizeof(int32_t)); - ttime = mlibc::bit_util<uint32_t>::byteswap(ttime); - // If we are before the first transition, the format dicates that - // the first ttinfo entry should be used (and not the ttinfo entry pointed - // to by the first transition time). - if(i && ttime > unix_gmt) { - index = i - 1; - break; - } - } - - // The format dictates that if no transition is applicable, - // the first entry in the file is chosen. - uint8_t ttinfo_index = 0; - if(index >= 0) { - memcpy(&ttinfo_index, reinterpret_cast<char *>(get_localtime_window()->get()) + sizeof(tzfile) - + tzfile_time.tzh_timecnt * sizeof(int32_t) - + index * sizeof(uint8_t), sizeof(uint8_t)); - } - - // There should be at least one entry in the ttinfo table. - // TODO: If there is not, we might want to fall back to UTC, no DST (?). - __ensure(tzfile_time.tzh_typecnt); - - ttinfo time_info; - memcpy(&time_info, reinterpret_cast<char *>(get_localtime_window()->get()) + sizeof(tzfile) - + tzfile_time.tzh_timecnt * sizeof(int32_t) - + tzfile_time.tzh_timecnt * sizeof(uint8_t) - + ttinfo_index * sizeof(ttinfo), sizeof(ttinfo)); - time_info.tt_gmtoff = mlibc::bit_util<uint32_t>::byteswap(time_info.tt_gmtoff); - - char *abbrevs = reinterpret_cast<char *>(get_localtime_window()->get()) + sizeof(tzfile) - + tzfile_time.tzh_timecnt * sizeof(int32_t) - + tzfile_time.tzh_timecnt * sizeof(uint8_t) - + tzfile_time.tzh_typecnt * sizeof(struct ttinfo); - - *offset = time_info.tt_gmtoff; - *dst = time_info.tt_isdst; - *tm_zone = abbrevs + time_info.tt_abbrind; - return 0; -} - -} //anonymous namespace - -struct tm *gmtime_r(const time_t *unix_gmt, struct tm *res) { - int year; - unsigned int month; - unsigned int day; - unsigned int weekday; - unsigned int yday; - - time_t unix_local = *unix_gmt; - - int days_since_epoch = unix_local / (60*60*24); - civil_from_days(days_since_epoch, &year, &month, &day); - weekday_from_days(days_since_epoch, &weekday); - yearday_from_date(year, month, day, &yday); - - res->tm_sec = unix_local % 60; - res->tm_min = (unix_local / 60) % 60; - res->tm_hour = (unix_local / (60*60)) % 24; - res->tm_mday = day; - res->tm_mon = month - 1; - res->tm_year = year - 1900; - res->tm_wday = weekday; - res->tm_yday = yday - 1; - res->tm_isdst = -1; - res->tm_zone = __utc; - res->tm_gmtoff = 0; - - return res; -} - -struct tm *localtime_r(const time_t *unix_gmt, struct tm *res) { - int year; - unsigned int month; - unsigned int day; - unsigned int weekday; - unsigned int yday; - - time_t offset = 0; - bool dst; - char *tm_zone; - frg::unique_lock<FutexLock> lock(__time_lock); - // TODO: Set errno if the conversion fails. - if(unix_local_from_gmt(*unix_gmt, &offset, &dst, &tm_zone)) { - __ensure(!"Error parsing /etc/localtime"); - __builtin_unreachable(); - } - time_t unix_local = *unix_gmt + offset; - - int days_since_epoch = unix_local / (60*60*24); - civil_from_days(days_since_epoch, &year, &month, &day); - weekday_from_days(days_since_epoch, &weekday); - yearday_from_date(year, month, day, &yday); - - res->tm_sec = unix_local % 60; - res->tm_min = (unix_local / 60) % 60; - res->tm_hour = (unix_local / (60*60)) % 24; - res->tm_mday = day; - res->tm_mon = month - 1; - res->tm_year = year - 1900; - res->tm_wday = weekday; - res->tm_yday = yday - 1; - res->tm_isdst = dst; - res->tm_zone = tm_zone; - res->tm_gmtoff = offset; - - return res; -} - -// This implementation of asctime_r is taken from sortix -char *asctime_r(const struct tm *tm, char *buf) { - static char weekday_names[7][4] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - static char month_names[12][4] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", - "Nov", "Dec" }; - sprintf(buf, "%.3s %.3s%3d %.2d:%.2d%.2d %d\n", - weekday_names[tm->tm_wday], - month_names[tm->tm_mon], - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec, - tm->tm_year + 1900); - return buf; -} - -char *ctime_r(const time_t *clock, char *buf) { - return asctime_r(localtime(clock), buf); -} - -time_t timelocal(struct tm *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -constexpr static int days_from_civil(int y, unsigned m, unsigned d) noexcept { - y -= m <= 2; - const int era = (y >= 0 ? y : y - 399) / 400; - const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399] - const unsigned doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1; // [0, 365] - const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - return era * 146097 + static_cast<int>(doe) - 719468; -} - -time_t timegm(struct tm *tm) { - time_t year = tm->tm_year + 1900; - time_t month = tm->tm_mon + 1; - time_t days = days_from_civil(year, month, tm->tm_mday); - time_t secs = (days * 86400) + (tm->tm_hour * 60 * 60) + (tm->tm_min * 60) + tm->tm_sec; - return secs; -} diff --git a/lib/mlibc/options/ansi/generic/uchar.cpp b/lib/mlibc/options/ansi/generic/uchar.cpp deleted file mode 100644 index cb13c12..0000000 --- a/lib/mlibc/options/ansi/generic/uchar.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include <bits/ensure.h> -#include <uchar.h> -#include <wchar.h> - -size_t c32rtomb(char *, char32_t, mbstate_t *) MLIBC_STUB_BODY - -size_t mbrtoc32(char32_t *__restrict pc32, const char *__restrict pmb, size_t max, mbstate_t *__restrict ps) { - static mbstate_t internal_state; - - if(!ps) - ps = &internal_state; - - if(!pmb) - return mbrtoc32(0, "", 1, ps); - - wchar_t wc; - size_t ret = mbrtowc(&wc, pmb, max, ps); - - if (ret <= 4 && pc32) - *pc32 = wc; - - return ret; -} diff --git a/lib/mlibc/options/ansi/generic/wchar-stubs.cpp b/lib/mlibc/options/ansi/generic/wchar-stubs.cpp deleted file mode 100644 index d9f6598..0000000 --- a/lib/mlibc/options/ansi/generic/wchar-stubs.cpp +++ /dev/null @@ -1,783 +0,0 @@ - -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <wchar.h> -#include <wctype.h> -#include <bits/ensure.h> - -#include <mlibc/charcode.hpp> -#include <mlibc/debug.hpp> - -namespace { - // All conversion functions mbrlen(), mbrtowc(), wcrtomb(), - // mbsrtowcs() and wcsrtombs() have an internal state. - __mlibc_mbstate mbrlen_state = __MLIBC_MBSTATE_INITIALIZER; - __mlibc_mbstate mbrtowc_state = __MLIBC_MBSTATE_INITIALIZER; - __mlibc_mbstate mbsrtowcs_state = __MLIBC_MBSTATE_INITIALIZER; - __mlibc_mbstate wcsrtombs_state = __MLIBC_MBSTATE_INITIALIZER; -} - -wint_t btowc(int c) { - if(c == EOF) - return WEOF; - - char nc = c; - auto cc = mlibc::current_charcode(); - wchar_t wc; - if(auto e = cc->promote_wtranscode(nc, wc); e != mlibc::charcode_error::null) - return WEOF; - return wc; -} - -int wctob(wint_t wc) { - // TODO: Revisit this once we have character encoding functions. - return wc; -} - -int mbsinit(const mbstate_t *stp) { - if(!stp) - return -1; - return !stp->__progress && !stp->__shift; -} - -size_t mbrlen(const char *mbs, size_t mb_limit, mbstate_t *stp) { - auto cc = mlibc::current_charcode(); - wchar_t wc; - - if(!stp) - stp = &mbrlen_state; - if(!mbs) { - *stp = __MLIBC_MBSTATE_INITIALIZER; - return 0; - } - - mlibc::code_seq<const char> nseq{mbs, mbs + mb_limit}; - mlibc::code_seq<wchar_t> wseq{&wc, &wc + 1}; - if(auto e = cc->decode_wtranscode(nseq, wseq, *stp); e != mlibc::charcode_error::null) - __ensure(!"decode_wtranscode() errors are not handled"); - return nseq.it - mbs; -} - -size_t mbrtowc(wchar_t *wcp, const char *mbs, size_t mb_limit, mbstate_t *stp) { - auto cc = mlibc::current_charcode(); - - if(!stp) - stp = &mbrtowc_state; - if(!mbs) { - *stp = __MLIBC_MBSTATE_INITIALIZER; - return 0; - } - - wchar_t temp = 0; - if(!wcp) - wcp = &temp; - - mlibc::code_seq<const char> nseq{mbs, mbs + mb_limit}; - mlibc::code_seq<wchar_t> wseq{wcp, wcp + 1}; - if(auto e = cc->decode_wtranscode(nseq, wseq, *stp); e != mlibc::charcode_error::null) { - if(e == mlibc::charcode_error::input_underflow) - return static_cast<size_t>(-2); - __ensure(e == mlibc::charcode_error::illegal_input); - errno = EILSEQ; - return static_cast<size_t>(-1); - }else{ - if (*mbs) { - return nseq.it - mbs; - } else { - *stp = __MLIBC_MBSTATE_INITIALIZER; - *wcp = 0; - return 0; - } - } -} - -size_t wcrtomb(char *mbs, wchar_t wc, mbstate_t *stp) { - auto cc = mlibc::current_charcode(); - - // wcrtomb() always takes a mbstate_t. - __ensure(stp); - - // TODO: Implement the following case: - __ensure(mbs); - - mlibc::code_seq<const wchar_t> wseq{&wc, &wc + 1}; - mlibc::code_seq<char> nseq{mbs, mbs + 4}; // TODO: Replace 4 by some named constant. - if(auto e = cc->encode_wtranscode(nseq, wseq, *stp); e != mlibc::charcode_error::null) { - __ensure(!"encode_wtranscode() errors are not handled"); - __builtin_unreachable(); - }else{ - size_t n = nseq.it - mbs; - if(!n) // Null-terminate resulting wide string. - *mbs = 0; - return n; - } -} - -size_t mbsrtowcs(wchar_t *wcs, const char **mbsp, size_t wc_limit, mbstate_t *stp) { - __ensure(mbsp); - - auto cc = mlibc::current_charcode(); - __mlibc_mbstate st = __MLIBC_MBSTATE_INITIALIZER; - mlibc::code_seq<const char> nseq{*mbsp, nullptr}; - mlibc::code_seq<wchar_t> wseq{wcs, wcs + wc_limit}; - - if(!stp) - stp = &mbsrtowcs_state; - - if(!wcs) { - size_t size; - if(auto e = cc->decode_wtranscode_length(nseq, &size, st); e != mlibc::charcode_error::null) - __ensure(!"decode_wtranscode() errors are not handled"); - return size; - } - - if(auto e = cc->decode_wtranscode(nseq, wseq, st); e != mlibc::charcode_error::null) { - __ensure(!"decode_wtranscode() errors are not handled"); - __builtin_unreachable(); - }else{ - size_t n = wseq.it - wcs; - if(n < wc_limit) // Null-terminate resulting wide string. - wcs[n] = 0; - *mbsp = nullptr; - return n; - } -} - -size_t mbsnrtowcs(wchar_t *wcs, const char **mbsp, size_t mb_limit, size_t wc_limit, mbstate_t *stp) { - __ensure(mbsp); - - auto cc = mlibc::current_charcode(); - __mlibc_mbstate st = __MLIBC_MBSTATE_INITIALIZER; - mlibc::code_seq<const char> nseq{*mbsp, (*mbsp) + mb_limit}; - mlibc::code_seq<wchar_t> wseq{wcs, wcs + wc_limit}; - - if(!stp) - stp = &mbsrtowcs_state; - - if(!wcs) { - size_t size; - if(auto e = cc->decode_wtranscode_length(nseq, &size, st); e != mlibc::charcode_error::null) - __ensure(!"decode_wtranscode() errors are not handled"); - return size; - } - - if(auto e = cc->decode_wtranscode(nseq, wseq, st); e != mlibc::charcode_error::null) { - __ensure(!"decode_wtranscode() errors are not handled"); - __builtin_unreachable(); - }else{ - size_t n = wseq.it - wcs; - if(n < wc_limit) // Null-terminate resulting wide string. - wcs[n] = 0; - *mbsp = nullptr; - return n; - } -} - -size_t wcsrtombs(char *mbs, const wchar_t **wcsp, size_t mb_limit, mbstate_t *stp) { - __ensure(wcsp && "wcsrtombs() with null input"); - auto cc = mlibc::current_charcode(); - mlibc::code_seq<char> nseq{mbs, mbs + mb_limit}; - mlibc::code_seq<const wchar_t> wseq{*wcsp, nullptr}; - - if(!stp) - stp = &wcsrtombs_state; - - if(!mbs) { - size_t size; - if(auto e = cc->encode_wtranscode_length(wseq, &size, *stp); e != mlibc::charcode_error::null) - __ensure(!"decode_wtranscode() errors are not handled"); - return size; - } - - if(auto e = cc->encode_wtranscode(nseq, wseq, *stp); e != mlibc::charcode_error::null) { - __ensure(!"encode_wtranscode() errors are not handled"); - __builtin_unreachable(); - }else{ - *wcsp = wseq.it; - size_t n = nseq.it - mbs; - if(n < mb_limit) // Null-terminate resulting narrow string. - mbs[n] = 0; - return n; - } -} - -size_t wcsnrtombs(char *mbs, const wchar_t **wcsp, size_t wc_limit, size_t mb_limit, mbstate_t *stp) { - __ensure(wcsp && "wcsrtombs() with null input"); - auto cc = mlibc::current_charcode(); - mlibc::code_seq<char> nseq{mbs, mbs + mb_limit}; - mlibc::code_seq<const wchar_t> wseq{*wcsp, (*wcsp) + wc_limit}; - - if(!stp) - stp = &wcsrtombs_state; - - if(!mbs) { - size_t size; - if(auto e = cc->encode_wtranscode_length(wseq, &size, *stp); e != mlibc::charcode_error::null) - __ensure(!"decode_wtranscode() errors are not handled"); - return size; - } - - if(auto e = cc->encode_wtranscode(nseq, wseq, *stp); e != mlibc::charcode_error::null) { - __ensure(!"encode_wtranscode() errors are not handled"); - __builtin_unreachable(); - }else{ - *wcsp = wseq.it; - size_t n = nseq.it - mbs; - if(n < mb_limit) // Null-terminate resulting narrow string. - mbs[n] = 0; - return n; - } -} - -/* - * The code in this anonymous namespace and the wcwidth function below - * are taken from https://github.com/termux/wcwidth/, under the following license: - * - * Copyright (C) Fredrik Fornwall 2016. - * Distributed under the MIT License. - * - * Implementation of wcwidth(3) as a C port of: - * https://github.com/jquast/wcwidth - * - * Report issues at: - * https://github.com/termux/wcwidth - */ - -namespace { - -struct width_interval { - int start; - int end; -}; - -// From https://github.com/jquast/wcwidth/blob/master/wcwidth/table_zero.py -// at commit b29897e5a1b403a0e36f7fc991614981cbc42475 (2020-07-14): -struct width_interval ZERO_WIDTH[] = { - {0x00300, 0x0036f}, // Combining Grave Accent ..Combining Latin Small Le - {0x00483, 0x00489}, // Combining Cyrillic Titlo..Combining Cyrillic Milli - {0x00591, 0x005bd}, // Hebrew Accent Etnahta ..Hebrew Point Meteg - {0x005bf, 0x005bf}, // Hebrew Point Rafe ..Hebrew Point Rafe - {0x005c1, 0x005c2}, // Hebrew Point Shin Dot ..Hebrew Point Sin Dot - {0x005c4, 0x005c5}, // Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot - {0x005c7, 0x005c7}, // Hebrew Point Qamats Qata..Hebrew Point Qamats Qata - {0x00610, 0x0061a}, // Arabic Sign Sallallahou ..Arabic Small Kasra - {0x0064b, 0x0065f}, // Arabic Fathatan ..Arabic Wavy Hamza Below - {0x00670, 0x00670}, // Arabic Letter Superscrip..Arabic Letter Superscrip - {0x006d6, 0x006dc}, // Arabic Small High Ligatu..Arabic Small High Seen - {0x006df, 0x006e4}, // Arabic Small High Rounde..Arabic Small High Madda - {0x006e7, 0x006e8}, // Arabic Small High Yeh ..Arabic Small High Noon - {0x006ea, 0x006ed}, // Arabic Empty Centre Low ..Arabic Small Low Meem - {0x00711, 0x00711}, // Syriac Letter Superscrip..Syriac Letter Superscrip - {0x00730, 0x0074a}, // Syriac Pthaha Above ..Syriac Barrekh - {0x007a6, 0x007b0}, // Thaana Abafili ..Thaana Sukun - {0x007eb, 0x007f3}, // Nko Combining Short High..Nko Combining Double Dot - {0x007fd, 0x007fd}, // Nko Dantayalan ..Nko Dantayalan - {0x00816, 0x00819}, // Samaritan Mark In ..Samaritan Mark Dagesh - {0x0081b, 0x00823}, // Samaritan Mark Epentheti..Samaritan Vowel Sign A - {0x00825, 0x00827}, // Samaritan Vowel Sign Sho..Samaritan Vowel Sign U - {0x00829, 0x0082d}, // Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa - {0x00859, 0x0085b}, // Mandaic Affrication Mark..Mandaic Gemination Mark - {0x008d3, 0x008e1}, // Arabic Small Low Waw ..Arabic Small High Sign S - {0x008e3, 0x00902}, // Arabic Turned Damma Belo..Devanagari Sign Anusvara - {0x0093a, 0x0093a}, // Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe - {0x0093c, 0x0093c}, // Devanagari Sign Nukta ..Devanagari Sign Nukta - {0x00941, 0x00948}, // Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - {0x0094d, 0x0094d}, // Devanagari Sign Virama ..Devanagari Sign Virama - {0x00951, 0x00957}, // Devanagari Stress Sign U..Devanagari Vowel Sign Uu - {0x00962, 0x00963}, // Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - {0x00981, 0x00981}, // Bengali Sign Candrabindu..Bengali Sign Candrabindu - {0x009bc, 0x009bc}, // Bengali Sign Nukta ..Bengali Sign Nukta - {0x009c1, 0x009c4}, // Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - {0x009cd, 0x009cd}, // Bengali Sign Virama ..Bengali Sign Virama - {0x009e2, 0x009e3}, // Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - {0x009fe, 0x009fe}, // Bengali Sandhi Mark ..Bengali Sandhi Mark - {0x00a01, 0x00a02}, // Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi - {0x00a3c, 0x00a3c}, // Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta - {0x00a41, 0x00a42}, // Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu - {0x00a47, 0x00a48}, // Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai - {0x00a4b, 0x00a4d}, // Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama - {0x00a51, 0x00a51}, // Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat - {0x00a70, 0x00a71}, // Gurmukhi Tippi ..Gurmukhi Addak - {0x00a75, 0x00a75}, // Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash - {0x00a81, 0x00a82}, // Gujarati Sign Candrabind..Gujarati Sign Anusvara - {0x00abc, 0x00abc}, // Gujarati Sign Nukta ..Gujarati Sign Nukta - {0x00ac1, 0x00ac5}, // Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - {0x00ac7, 0x00ac8}, // Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - {0x00acd, 0x00acd}, // Gujarati Sign Virama ..Gujarati Sign Virama - {0x00ae2, 0x00ae3}, // Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - {0x00afa, 0x00aff}, // Gujarati Sign Sukun ..Gujarati Sign Two-circle - {0x00b01, 0x00b01}, // Oriya Sign Candrabindu ..Oriya Sign Candrabindu - {0x00b3c, 0x00b3c}, // Oriya Sign Nukta ..Oriya Sign Nukta - {0x00b3f, 0x00b3f}, // Oriya Vowel Sign I ..Oriya Vowel Sign I - {0x00b41, 0x00b44}, // Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - {0x00b4d, 0x00b4d}, // Oriya Sign Virama ..Oriya Sign Virama - {0x00b55, 0x00b56}, // (nil) ..Oriya Ai Length Mark - {0x00b62, 0x00b63}, // Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic - {0x00b82, 0x00b82}, // Tamil Sign Anusvara ..Tamil Sign Anusvara - {0x00bc0, 0x00bc0}, // Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii - {0x00bcd, 0x00bcd}, // Tamil Sign Virama ..Tamil Sign Virama - {0x00c00, 0x00c00}, // Telugu Sign Combining Ca..Telugu Sign Combining Ca - {0x00c04, 0x00c04}, // Telugu Sign Combining An..Telugu Sign Combining An - {0x00c3e, 0x00c40}, // Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii - {0x00c46, 0x00c48}, // Telugu Vowel Sign E ..Telugu Vowel Sign Ai - {0x00c4a, 0x00c4d}, // Telugu Vowel Sign O ..Telugu Sign Virama - {0x00c55, 0x00c56}, // Telugu Length Mark ..Telugu Ai Length Mark - {0x00c62, 0x00c63}, // Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - {0x00c81, 0x00c81}, // Kannada Sign Candrabindu..Kannada Sign Candrabindu - {0x00cbc, 0x00cbc}, // Kannada Sign Nukta ..Kannada Sign Nukta - {0x00cbf, 0x00cbf}, // Kannada Vowel Sign I ..Kannada Vowel Sign I - {0x00cc6, 0x00cc6}, // Kannada Vowel Sign E ..Kannada Vowel Sign E - {0x00ccc, 0x00ccd}, // Kannada Vowel Sign Au ..Kannada Sign Virama - {0x00ce2, 0x00ce3}, // Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - {0x00d00, 0x00d01}, // Malayalam Sign Combining..Malayalam Sign Candrabin - {0x00d3b, 0x00d3c}, // Malayalam Sign Vertical ..Malayalam Sign Circular - {0x00d41, 0x00d44}, // Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - {0x00d4d, 0x00d4d}, // Malayalam Sign Virama ..Malayalam Sign Virama - {0x00d62, 0x00d63}, // Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc - {0x00d81, 0x00d81}, // (nil) ..(nil) - {0x00dca, 0x00dca}, // Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna - {0x00dd2, 0x00dd4}, // Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti - {0x00dd6, 0x00dd6}, // Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga - {0x00e31, 0x00e31}, // Thai Character Mai Han-a..Thai Character Mai Han-a - {0x00e34, 0x00e3a}, // Thai Character Sara I ..Thai Character Phinthu - {0x00e47, 0x00e4e}, // Thai Character Maitaikhu..Thai Character Yamakkan - {0x00eb1, 0x00eb1}, // Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan - {0x00eb4, 0x00ebc}, // Lao Vowel Sign I ..Lao Semivowel Sign Lo - {0x00ec8, 0x00ecd}, // Lao Tone Mai Ek ..Lao Niggahita - {0x00f18, 0x00f19}, // Tibetan Astrological Sig..Tibetan Astrological Sig - {0x00f35, 0x00f35}, // Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung - {0x00f37, 0x00f37}, // Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung - {0x00f39, 0x00f39}, // Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru - {0x00f71, 0x00f7e}, // Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - {0x00f80, 0x00f84}, // Tibetan Vowel Sign Rever..Tibetan Mark Halanta - {0x00f86, 0x00f87}, // Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags - {0x00f8d, 0x00f97}, // Tibetan Subjoined Sign L..Tibetan Subjoined Letter - {0x00f99, 0x00fbc}, // Tibetan Subjoined Letter..Tibetan Subjoined Letter - {0x00fc6, 0x00fc6}, // Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda - {0x0102d, 0x01030}, // Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - {0x01032, 0x01037}, // Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - {0x01039, 0x0103a}, // Myanmar Sign Virama ..Myanmar Sign Asat - {0x0103d, 0x0103e}, // Myanmar Consonant Sign M..Myanmar Consonant Sign M - {0x01058, 0x01059}, // Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal - {0x0105e, 0x01060}, // Myanmar Consonant Sign M..Myanmar Consonant Sign M - {0x01071, 0x01074}, // Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - {0x01082, 0x01082}, // Myanmar Consonant Sign S..Myanmar Consonant Sign S - {0x01085, 0x01086}, // Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - {0x0108d, 0x0108d}, // Myanmar Sign Shan Counci..Myanmar Sign Shan Counci - {0x0109d, 0x0109d}, // Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton - {0x0135d, 0x0135f}, // Ethiopic Combining Gemin..Ethiopic Combining Gemin - {0x01712, 0x01714}, // Tagalog Vowel Sign I ..Tagalog Sign Virama - {0x01732, 0x01734}, // Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod - {0x01752, 0x01753}, // Buhid Vowel Sign I ..Buhid Vowel Sign U - {0x01772, 0x01773}, // Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - {0x017b4, 0x017b5}, // Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - {0x017b7, 0x017bd}, // Khmer Vowel Sign I ..Khmer Vowel Sign Ua - {0x017c6, 0x017c6}, // Khmer Sign Nikahit ..Khmer Sign Nikahit - {0x017c9, 0x017d3}, // Khmer Sign Muusikatoan ..Khmer Sign Bathamasat - {0x017dd, 0x017dd}, // Khmer Sign Atthacan ..Khmer Sign Atthacan - {0x0180b, 0x0180d}, // Mongolian Free Variation..Mongolian Free Variation - {0x01885, 0x01886}, // Mongolian Letter Ali Gal..Mongolian Letter Ali Gal - {0x018a9, 0x018a9}, // Mongolian Letter Ali Gal..Mongolian Letter Ali Gal - {0x01920, 0x01922}, // Limbu Vowel Sign A ..Limbu Vowel Sign U - {0x01927, 0x01928}, // Limbu Vowel Sign E ..Limbu Vowel Sign O - {0x01932, 0x01932}, // Limbu Small Letter Anusv..Limbu Small Letter Anusv - {0x01939, 0x0193b}, // Limbu Sign Mukphreng ..Limbu Sign Sa-i - {0x01a17, 0x01a18}, // Buginese Vowel Sign I ..Buginese Vowel Sign U - {0x01a1b, 0x01a1b}, // Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae - {0x01a56, 0x01a56}, // Tai Tham Consonant Sign ..Tai Tham Consonant Sign - {0x01a58, 0x01a5e}, // Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - {0x01a60, 0x01a60}, // Tai Tham Sign Sakot ..Tai Tham Sign Sakot - {0x01a62, 0x01a62}, // Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai - {0x01a65, 0x01a6c}, // Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - {0x01a73, 0x01a7c}, // Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue - {0x01a7f, 0x01a7f}, // Tai Tham Combining Crypt..Tai Tham Combining Crypt - {0x01ab0, 0x01ac0}, // Combining Doubled Circum..(nil) - {0x01b00, 0x01b03}, // Balinese Sign Ulu Ricem ..Balinese Sign Surang - {0x01b34, 0x01b34}, // Balinese Sign Rerekan ..Balinese Sign Rerekan - {0x01b36, 0x01b3a}, // Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - {0x01b3c, 0x01b3c}, // Balinese Vowel Sign La L..Balinese Vowel Sign La L - {0x01b42, 0x01b42}, // Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe - {0x01b6b, 0x01b73}, // Balinese Musical Symbol ..Balinese Musical Symbol - {0x01b80, 0x01b81}, // Sundanese Sign Panyecek ..Sundanese Sign Panglayar - {0x01ba2, 0x01ba5}, // Sundanese Consonant Sign..Sundanese Vowel Sign Pan - {0x01ba8, 0x01ba9}, // Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - {0x01bab, 0x01bad}, // Sundanese Sign Virama ..Sundanese Consonant Sign - {0x01be6, 0x01be6}, // Batak Sign Tompi ..Batak Sign Tompi - {0x01be8, 0x01be9}, // Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - {0x01bed, 0x01bed}, // Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O - {0x01bef, 0x01bf1}, // Batak Vowel Sign U For S..Batak Consonant Sign H - {0x01c2c, 0x01c33}, // Lepcha Vowel Sign E ..Lepcha Consonant Sign T - {0x01c36, 0x01c37}, // Lepcha Sign Ran ..Lepcha Sign Nukta - {0x01cd0, 0x01cd2}, // Vedic Tone Karshana ..Vedic Tone Prenkha - {0x01cd4, 0x01ce0}, // Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - {0x01ce2, 0x01ce8}, // Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda - {0x01ced, 0x01ced}, // Vedic Sign Tiryak ..Vedic Sign Tiryak - {0x01cf4, 0x01cf4}, // Vedic Tone Candra Above ..Vedic Tone Candra Above - {0x01cf8, 0x01cf9}, // Vedic Tone Ring Above ..Vedic Tone Double Ring A - {0x01dc0, 0x01df9}, // Combining Dotted Grave A..Combining Wide Inverted - {0x01dfb, 0x01dff}, // Combining Deletion Mark ..Combining Right Arrowhea - {0x020d0, 0x020f0}, // Combining Left Harpoon A..Combining Asterisk Above - {0x02cef, 0x02cf1}, // Coptic Combining Ni Abov..Coptic Combining Spiritu - {0x02d7f, 0x02d7f}, // Tifinagh Consonant Joine..Tifinagh Consonant Joine - {0x02de0, 0x02dff}, // Combining Cyrillic Lette..Combining Cyrillic Lette - {0x0302a, 0x0302d}, // Ideographic Level Tone M..Ideographic Entering Ton - {0x03099, 0x0309a}, // Combining Katakana-hirag..Combining Katakana-hirag - {0x0a66f, 0x0a672}, // Combining Cyrillic Vzmet..Combining Cyrillic Thous - {0x0a674, 0x0a67d}, // Combining Cyrillic Lette..Combining Cyrillic Payer - {0x0a69e, 0x0a69f}, // Combining Cyrillic Lette..Combining Cyrillic Lette - {0x0a6f0, 0x0a6f1}, // Bamum Combining Mark Koq..Bamum Combining Mark Tuk - {0x0a802, 0x0a802}, // Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva - {0x0a806, 0x0a806}, // Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant - {0x0a80b, 0x0a80b}, // Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva - {0x0a825, 0x0a826}, // Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - {0x0a82c, 0x0a82c}, // (nil) ..(nil) - {0x0a8c4, 0x0a8c5}, // Saurashtra Sign Virama ..Saurashtra Sign Candrabi - {0x0a8e0, 0x0a8f1}, // Combining Devanagari Dig..Combining Devanagari Sig - {0x0a8ff, 0x0a8ff}, // Devanagari Vowel Sign Ay..Devanagari Vowel Sign Ay - {0x0a926, 0x0a92d}, // Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - {0x0a947, 0x0a951}, // Rejang Vowel Sign I ..Rejang Consonant Sign R - {0x0a980, 0x0a982}, // Javanese Sign Panyangga ..Javanese Sign Layar - {0x0a9b3, 0x0a9b3}, // Javanese Sign Cecak Telu..Javanese Sign Cecak Telu - {0x0a9b6, 0x0a9b9}, // Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - {0x0a9bc, 0x0a9bd}, // Javanese Vowel Sign Pepe..Javanese Consonant Sign - {0x0a9e5, 0x0a9e5}, // Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw - {0x0aa29, 0x0aa2e}, // Cham Vowel Sign Aa ..Cham Vowel Sign Oe - {0x0aa31, 0x0aa32}, // Cham Vowel Sign Au ..Cham Vowel Sign Ue - {0x0aa35, 0x0aa36}, // Cham Consonant Sign La ..Cham Consonant Sign Wa - {0x0aa43, 0x0aa43}, // Cham Consonant Sign Fina..Cham Consonant Sign Fina - {0x0aa4c, 0x0aa4c}, // Cham Consonant Sign Fina..Cham Consonant Sign Fina - {0x0aa7c, 0x0aa7c}, // Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T - {0x0aab0, 0x0aab0}, // Tai Viet Mai Kang ..Tai Viet Mai Kang - {0x0aab2, 0x0aab4}, // Tai Viet Vowel I ..Tai Viet Vowel U - {0x0aab7, 0x0aab8}, // Tai Viet Mai Khit ..Tai Viet Vowel Ia - {0x0aabe, 0x0aabf}, // Tai Viet Vowel Am ..Tai Viet Tone Mai Ek - {0x0aac1, 0x0aac1}, // Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho - {0x0aaec, 0x0aaed}, // Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - {0x0aaf6, 0x0aaf6}, // Meetei Mayek Virama ..Meetei Mayek Virama - {0x0abe5, 0x0abe5}, // Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - {0x0abe8, 0x0abe8}, // Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - {0x0abed, 0x0abed}, // Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek - {0x0fb1e, 0x0fb1e}, // Hebrew Point Judeo-spani..Hebrew Point Judeo-spani - {0x0fe00, 0x0fe0f}, // Variation Selector-1 ..Variation Selector-16 - {0x0fe20, 0x0fe2f}, // Combining Ligature Left ..Combining Cyrillic Titlo - {0x101fd, 0x101fd}, // Phaistos Disc Sign Combi..Phaistos Disc Sign Combi - {0x102e0, 0x102e0}, // Coptic Epact Thousands M..Coptic Epact Thousands M - {0x10376, 0x1037a}, // Combining Old Permic Let..Combining Old Permic Let - {0x10a01, 0x10a03}, // Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo - {0x10a05, 0x10a06}, // Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O - {0x10a0c, 0x10a0f}, // Kharoshthi Vowel Length ..Kharoshthi Sign Visarga - {0x10a38, 0x10a3a}, // Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo - {0x10a3f, 0x10a3f}, // Kharoshthi Virama ..Kharoshthi Virama - {0x10ae5, 0x10ae6}, // Manichaean Abbreviation ..Manichaean Abbreviation - {0x10d24, 0x10d27}, // Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas - {0x10eab, 0x10eac}, // (nil) ..(nil) - {0x10f46, 0x10f50}, // Sogdian Combining Dot Be..Sogdian Combining Stroke - {0x11001, 0x11001}, // Brahmi Sign Anusvara ..Brahmi Sign Anusvara - {0x11038, 0x11046}, // Brahmi Vowel Sign Aa ..Brahmi Virama - {0x1107f, 0x11081}, // Brahmi Number Joiner ..Kaithi Sign Anusvara - {0x110b3, 0x110b6}, // Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - {0x110b9, 0x110ba}, // Kaithi Sign Virama ..Kaithi Sign Nukta - {0x11100, 0x11102}, // Chakma Sign Candrabindu ..Chakma Sign Visarga - {0x11127, 0x1112b}, // Chakma Vowel Sign A ..Chakma Vowel Sign Uu - {0x1112d, 0x11134}, // Chakma Vowel Sign Ai ..Chakma Maayyaa - {0x11173, 0x11173}, // Mahajani Sign Nukta ..Mahajani Sign Nukta - {0x11180, 0x11181}, // Sharada Sign Candrabindu..Sharada Sign Anusvara - {0x111b6, 0x111be}, // Sharada Vowel Sign U ..Sharada Vowel Sign O - {0x111c9, 0x111cc}, // Sharada Sandhi Mark ..Sharada Extra Short Vowe - {0x111cf, 0x111cf}, // (nil) ..(nil) - {0x1122f, 0x11231}, // Khojki Vowel Sign U ..Khojki Vowel Sign Ai - {0x11234, 0x11234}, // Khojki Sign Anusvara ..Khojki Sign Anusvara - {0x11236, 0x11237}, // Khojki Sign Nukta ..Khojki Sign Shadda - {0x1123e, 0x1123e}, // Khojki Sign Sukun ..Khojki Sign Sukun - {0x112df, 0x112df}, // Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara - {0x112e3, 0x112ea}, // Khudawadi Vowel Sign U ..Khudawadi Sign Virama - {0x11300, 0x11301}, // Grantha Sign Combining A..Grantha Sign Candrabindu - {0x1133b, 0x1133c}, // Combining Bindu Below ..Grantha Sign Nukta - {0x11340, 0x11340}, // Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii - {0x11366, 0x1136c}, // Combining Grantha Digit ..Combining Grantha Digit - {0x11370, 0x11374}, // Combining Grantha Letter..Combining Grantha Letter - {0x11438, 0x1143f}, // Newa Vowel Sign U ..Newa Vowel Sign Ai - {0x11442, 0x11444}, // Newa Sign Virama ..Newa Sign Anusvara - {0x11446, 0x11446}, // Newa Sign Nukta ..Newa Sign Nukta - {0x1145e, 0x1145e}, // Newa Sandhi Mark ..Newa Sandhi Mark - {0x114b3, 0x114b8}, // Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - {0x114ba, 0x114ba}, // Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short - {0x114bf, 0x114c0}, // Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - {0x114c2, 0x114c3}, // Tirhuta Sign Virama ..Tirhuta Sign Nukta - {0x115b2, 0x115b5}, // Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - {0x115bc, 0x115bd}, // Siddham Sign Candrabindu..Siddham Sign Anusvara - {0x115bf, 0x115c0}, // Siddham Sign Virama ..Siddham Sign Nukta - {0x115dc, 0x115dd}, // Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - {0x11633, 0x1163a}, // Modi Vowel Sign U ..Modi Vowel Sign Ai - {0x1163d, 0x1163d}, // Modi Sign Anusvara ..Modi Sign Anusvara - {0x1163f, 0x11640}, // Modi Sign Virama ..Modi Sign Ardhacandra - {0x116ab, 0x116ab}, // Takri Sign Anusvara ..Takri Sign Anusvara - {0x116ad, 0x116ad}, // Takri Vowel Sign Aa ..Takri Vowel Sign Aa - {0x116b0, 0x116b5}, // Takri Vowel Sign U ..Takri Vowel Sign Au - {0x116b7, 0x116b7}, // Takri Sign Nukta ..Takri Sign Nukta - {0x1171d, 0x1171f}, // Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - {0x11722, 0x11725}, // Ahom Vowel Sign I ..Ahom Vowel Sign Uu - {0x11727, 0x1172b}, // Ahom Vowel Sign Aw ..Ahom Sign Killer - {0x1182f, 0x11837}, // Dogra Vowel Sign U ..Dogra Sign Anusvara - {0x11839, 0x1183a}, // Dogra Sign Virama ..Dogra Sign Nukta - {0x1193b, 0x1193c}, // (nil) ..(nil) - {0x1193e, 0x1193e}, // (nil) ..(nil) - {0x11943, 0x11943}, // (nil) ..(nil) - {0x119d4, 0x119d7}, // Nandinagari Vowel Sign U..Nandinagari Vowel Sign V - {0x119da, 0x119db}, // Nandinagari Vowel Sign E..Nandinagari Vowel Sign A - {0x119e0, 0x119e0}, // Nandinagari Sign Virama ..Nandinagari Sign Virama - {0x11a01, 0x11a0a}, // Zanabazar Square Vowel S..Zanabazar Square Vowel L - {0x11a33, 0x11a38}, // Zanabazar Square Final C..Zanabazar Square Sign An - {0x11a3b, 0x11a3e}, // Zanabazar Square Cluster..Zanabazar Square Cluster - {0x11a47, 0x11a47}, // Zanabazar Square Subjoin..Zanabazar Square Subjoin - {0x11a51, 0x11a56}, // Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - {0x11a59, 0x11a5b}, // Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - {0x11a8a, 0x11a96}, // Soyombo Final Consonant ..Soyombo Sign Anusvara - {0x11a98, 0x11a99}, // Soyombo Gemination Mark ..Soyombo Subjoiner - {0x11c30, 0x11c36}, // Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - {0x11c38, 0x11c3d}, // Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - {0x11c3f, 0x11c3f}, // Bhaiksuki Sign Virama ..Bhaiksuki Sign Virama - {0x11c92, 0x11ca7}, // Marchen Subjoined Letter..Marchen Subjoined Letter - {0x11caa, 0x11cb0}, // Marchen Subjoined Letter..Marchen Vowel Sign Aa - {0x11cb2, 0x11cb3}, // Marchen Vowel Sign U ..Marchen Vowel Sign E - {0x11cb5, 0x11cb6}, // Marchen Sign Anusvara ..Marchen Sign Candrabindu - {0x11d31, 0x11d36}, // Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign - {0x11d3a, 0x11d3a}, // Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign - {0x11d3c, 0x11d3d}, // Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign - {0x11d3f, 0x11d45}, // Masaram Gondi Vowel Sign..Masaram Gondi Virama - {0x11d47, 0x11d47}, // Masaram Gondi Ra-kara ..Masaram Gondi Ra-kara - {0x11d90, 0x11d91}, // Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign - {0x11d95, 0x11d95}, // Gunjala Gondi Sign Anusv..Gunjala Gondi Sign Anusv - {0x11d97, 0x11d97}, // Gunjala Gondi Virama ..Gunjala Gondi Virama - {0x11ef3, 0x11ef4}, // Makasar Vowel Sign I ..Makasar Vowel Sign U - {0x16af0, 0x16af4}, // Bassa Vah Combining High..Bassa Vah Combining High - {0x16b30, 0x16b36}, // Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta - {0x16f4f, 0x16f4f}, // Miao Sign Consonant Modi..Miao Sign Consonant Modi - {0x16f8f, 0x16f92}, // Miao Tone Right ..Miao Tone Below - {0x16fe4, 0x16fe4}, // (nil) ..(nil) - {0x1bc9d, 0x1bc9e}, // Duployan Thick Letter Se..Duployan Double Mark - {0x1d167, 0x1d169}, // Musical Symbol Combining..Musical Symbol Combining - {0x1d17b, 0x1d182}, // Musical Symbol Combining..Musical Symbol Combining - {0x1d185, 0x1d18b}, // Musical Symbol Combining..Musical Symbol Combining - {0x1d1aa, 0x1d1ad}, // Musical Symbol Combining..Musical Symbol Combining - {0x1d242, 0x1d244}, // Combining Greek Musical ..Combining Greek Musical - {0x1da00, 0x1da36}, // Signwriting Head Rim ..Signwriting Air Sucking - {0x1da3b, 0x1da6c}, // Signwriting Mouth Closed..Signwriting Excitement - {0x1da75, 0x1da75}, // Signwriting Upper Body T..Signwriting Upper Body T - {0x1da84, 0x1da84}, // Signwriting Location Hea..Signwriting Location Hea - {0x1da9b, 0x1da9f}, // Signwriting Fill Modifie..Signwriting Fill Modifie - {0x1daa1, 0x1daaf}, // Signwriting Rotation Mod..Signwriting Rotation Mod - {0x1e000, 0x1e006}, // Combining Glagolitic Let..Combining Glagolitic Let - {0x1e008, 0x1e018}, // Combining Glagolitic Let..Combining Glagolitic Let - {0x1e01b, 0x1e021}, // Combining Glagolitic Let..Combining Glagolitic Let - {0x1e023, 0x1e024}, // Combining Glagolitic Let..Combining Glagolitic Let - {0x1e026, 0x1e02a}, // Combining Glagolitic Let..Combining Glagolitic Let - {0x1e130, 0x1e136}, // Nyiakeng Puachue Hmong T..Nyiakeng Puachue Hmong T - {0x1e2ec, 0x1e2ef}, // Wancho Tone Tup ..Wancho Tone Koini - {0x1e8d0, 0x1e8d6}, // Mende Kikakui Combining ..Mende Kikakui Combining - {0x1e944, 0x1e94a}, // Adlam Alif Lengthener ..Adlam Nukta - {0xe0100, 0xe01ef}, // Variation Selector-17 ..Variation Selector-256 -}; - -// https://github.com/jquast/wcwidth/blob/master/wcwidth/table_wide.py -// at commit b29897e5a1b403a0e36f7fc991614981cbc42475 (2020-07-14): -struct width_interval WIDE_EASTASIAN[] = { - {0x01100, 0x0115f}, // Hangul Choseong Kiyeok ..Hangul Choseong Filler - {0x0231a, 0x0231b}, // Watch ..Hourglass - {0x02329, 0x0232a}, // Left-pointing Angle Brac..Right-pointing Angle Bra - {0x023e9, 0x023ec}, // Black Right-pointing Dou..Black Down-pointing Doub - {0x023f0, 0x023f0}, // Alarm Clock ..Alarm Clock - {0x023f3, 0x023f3}, // Hourglass With Flowing S..Hourglass With Flowing S - {0x025fd, 0x025fe}, // White Medium Small Squar..Black Medium Small Squar - {0x02614, 0x02615}, // Umbrella With Rain Drops..Hot Beverage - {0x02648, 0x02653}, // Aries ..Pisces - {0x0267f, 0x0267f}, // Wheelchair Symbol ..Wheelchair Symbol - {0x02693, 0x02693}, // Anchor ..Anchor - {0x026a1, 0x026a1}, // High Voltage Sign ..High Voltage Sign - {0x026aa, 0x026ab}, // Medium White Circle ..Medium Black Circle - {0x026bd, 0x026be}, // Soccer Ball ..Baseball - {0x026c4, 0x026c5}, // Snowman Without Snow ..Sun Behind Cloud - {0x026ce, 0x026ce}, // Ophiuchus ..Ophiuchus - {0x026d4, 0x026d4}, // No Entry ..No Entry - {0x026ea, 0x026ea}, // Church ..Church - {0x026f2, 0x026f3}, // Fountain ..Flag In Hole - {0x026f5, 0x026f5}, // Sailboat ..Sailboat - {0x026fa, 0x026fa}, // Tent ..Tent - {0x026fd, 0x026fd}, // Fuel Pump ..Fuel Pump - {0x02705, 0x02705}, // White Heavy Check Mark ..White Heavy Check Mark - {0x0270a, 0x0270b}, // Raised Fist ..Raised Hand - {0x02728, 0x02728}, // Sparkles ..Sparkles - {0x0274c, 0x0274c}, // Cross Mark ..Cross Mark - {0x0274e, 0x0274e}, // Negative Squared Cross M..Negative Squared Cross M - {0x02753, 0x02755}, // Black Question Mark Orna..White Exclamation Mark O - {0x02757, 0x02757}, // Heavy Exclamation Mark S..Heavy Exclamation Mark S - {0x02795, 0x02797}, // Heavy Plus Sign ..Heavy Division Sign - {0x027b0, 0x027b0}, // Curly Loop ..Curly Loop - {0x027bf, 0x027bf}, // Double Curly Loop ..Double Curly Loop - {0x02b1b, 0x02b1c}, // Black Large Square ..White Large Square - {0x02b50, 0x02b50}, // White Medium Star ..White Medium Star - {0x02b55, 0x02b55}, // Heavy Large Circle ..Heavy Large Circle - {0x02e80, 0x02e99}, // Cjk Radical Repeat ..Cjk Radical Rap - {0x02e9b, 0x02ef3}, // Cjk Radical Choke ..Cjk Radical C-simplified - {0x02f00, 0x02fd5}, // Kangxi Radical One ..Kangxi Radical Flute - {0x02ff0, 0x02ffb}, // Ideographic Description ..Ideographic Description - {0x03000, 0x0303e}, // Ideographic Space ..Ideographic Variation In - {0x03041, 0x03096}, // Hiragana Letter Small A ..Hiragana Letter Small Ke - {0x03099, 0x030ff}, // Combining Katakana-hirag..Katakana Digraph Koto - {0x03105, 0x0312f}, // Bopomofo Letter B ..Bopomofo Letter Nn - {0x03131, 0x0318e}, // Hangul Letter Kiyeok ..Hangul Letter Araeae - {0x03190, 0x031e3}, // Ideographic Annotation L..Cjk Stroke Q - {0x031f0, 0x0321e}, // Katakana Letter Small Ku..Parenthesized Korean Cha - {0x03220, 0x03247}, // Parenthesized Ideograph ..Circled Ideograph Koto - {0x03250, 0x04dbf}, // Partnership Sign ..(nil) - {0x04e00, 0x0a48c}, // Cjk Unified Ideograph-4e..Yi Syllable Yyr - {0x0a490, 0x0a4c6}, // Yi Radical Qot ..Yi Radical Ke - {0x0a960, 0x0a97c}, // Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo - {0x0ac00, 0x0d7a3}, // Hangul Syllable Ga ..Hangul Syllable Hih - {0x0f900, 0x0faff}, // Cjk Compatibility Ideogr..(nil) - {0x0fe10, 0x0fe19}, // Presentation Form For Ve..Presentation Form For Ve - {0x0fe30, 0x0fe52}, // Presentation Form For Ve..Small Full Stop - {0x0fe54, 0x0fe66}, // Small Semicolon ..Small Equals Sign - {0x0fe68, 0x0fe6b}, // Small Reverse Solidus ..Small Commercial At - {0x0ff01, 0x0ff60}, // Fullwidth Exclamation Ma..Fullwidth Right White Pa - {0x0ffe0, 0x0ffe6}, // Fullwidth Cent Sign ..Fullwidth Won Sign - {0x16fe0, 0x16fe4}, // Tangut Iteration Mark ..(nil) - {0x16ff0, 0x16ff1}, // (nil) ..(nil) - {0x17000, 0x187f7}, // (nil) ..(nil) - {0x18800, 0x18cd5}, // Tangut Component-001 ..(nil) - {0x18d00, 0x18d08}, // (nil) ..(nil) - {0x1b000, 0x1b11e}, // Katakana Letter Archaic ..Hentaigana Letter N-mu-m - {0x1b150, 0x1b152}, // Hiragana Letter Small Wi..Hiragana Letter Small Wo - {0x1b164, 0x1b167}, // Katakana Letter Small Wi..Katakana Letter Small N - {0x1b170, 0x1b2fb}, // Nushu Character-1b170 ..Nushu Character-1b2fb - {0x1f004, 0x1f004}, // Mahjong Tile Red Dragon ..Mahjong Tile Red Dragon - {0x1f0cf, 0x1f0cf}, // Playing Card Black Joker..Playing Card Black Joker - {0x1f18e, 0x1f18e}, // Negative Squared Ab ..Negative Squared Ab - {0x1f191, 0x1f19a}, // Squared Cl ..Squared Vs - {0x1f200, 0x1f202}, // Square Hiragana Hoka ..Squared Katakana Sa - {0x1f210, 0x1f23b}, // Squared Cjk Unified Ideo..Squared Cjk Unified Ideo - {0x1f240, 0x1f248}, // Tortoise Shell Bracketed..Tortoise Shell Bracketed - {0x1f250, 0x1f251}, // Circled Ideograph Advant..Circled Ideograph Accept - {0x1f260, 0x1f265}, // Rounded Symbol For Fu ..Rounded Symbol For Cai - {0x1f300, 0x1f320}, // Cyclone ..Shooting Star - {0x1f32d, 0x1f335}, // Hot Dog ..Cactus - {0x1f337, 0x1f37c}, // Tulip ..Baby Bottle - {0x1f37e, 0x1f393}, // Bottle With Popping Cork..Graduation Cap - {0x1f3a0, 0x1f3ca}, // Carousel Horse ..Swimmer - {0x1f3cf, 0x1f3d3}, // Cricket Bat And Ball ..Table Tennis Paddle And - {0x1f3e0, 0x1f3f0}, // House Building ..European Castle - {0x1f3f4, 0x1f3f4}, // Waving Black Flag ..Waving Black Flag - {0x1f3f8, 0x1f43e}, // Badminton Racquet And Sh..Paw Prints - {0x1f440, 0x1f440}, // Eyes ..Eyes - {0x1f442, 0x1f4fc}, // Ear ..Videocassette - {0x1f4ff, 0x1f53d}, // Prayer Beads ..Down-pointing Small Red - {0x1f54b, 0x1f54e}, // Kaaba ..Menorah With Nine Branch - {0x1f550, 0x1f567}, // Clock Face One Oclock ..Clock Face Twelve-thirty - {0x1f57a, 0x1f57a}, // Man Dancing ..Man Dancing - {0x1f595, 0x1f596}, // Reversed Hand With Middl..Raised Hand With Part Be - {0x1f5a4, 0x1f5a4}, // Black Heart ..Black Heart - {0x1f5fb, 0x1f64f}, // Mount Fuji ..Person With Folded Hands - {0x1f680, 0x1f6c5}, // Rocket ..Left Luggage - {0x1f6cc, 0x1f6cc}, // Sleeping Accommodation ..Sleeping Accommodation - {0x1f6d0, 0x1f6d2}, // Place Of Worship ..Shopping Trolley - {0x1f6d5, 0x1f6d7}, // Hindu Temple ..(nil) - {0x1f6eb, 0x1f6ec}, // Airplane Departure ..Airplane Arriving - {0x1f6f4, 0x1f6fc}, // Scooter ..(nil) - {0x1f7e0, 0x1f7eb}, // Large Orange Circle ..Large Brown Square - {0x1f90c, 0x1f93a}, // (nil) ..Fencer - {0x1f93c, 0x1f945}, // Wrestlers ..Goal Net - {0x1f947, 0x1f978}, // First Place Medal ..(nil) - {0x1f97a, 0x1f9cb}, // Face With Pleading Eyes ..(nil) - {0x1f9cd, 0x1f9ff}, // Standing Person ..Nazar Amulet - {0x1fa70, 0x1fa74}, // Ballet Shoes ..(nil) - {0x1fa78, 0x1fa7a}, // Drop Of Blood ..Stethoscope - {0x1fa80, 0x1fa86}, // Yo-yo ..(nil) - {0x1fa90, 0x1faa8}, // Ringed Planet ..(nil) - {0x1fab0, 0x1fab6}, // (nil) ..(nil) - {0x1fac0, 0x1fac2}, // (nil) ..(nil) - {0x1fad0, 0x1fad6}, // (nil) ..(nil) - {0x20000, 0x2fffd}, // Cjk Unified Ideograph-20..(nil) - {0x30000, 0x3fffd}, // (nil) ..(nil) -}; - -bool intable(struct width_interval* table, int table_length, int c) { - // First quick check for Latin1 etc. characters. - if (c < table[0].start) return false; - - // Binary search in table. - int bot = 0; - int top = table_length - 1; - while (top >= bot) { - int mid = (bot + top) / 2; - if (table[mid].end < c) { - bot = mid + 1; - } else if (table[mid].start > c) { - top = mid - 1; - } else { - return true; - } - } - return false; -} - -} - -int wcwidth(wchar_t ucs) { - // NOTE: created by hand, there isn't anything identifiable other than - // general Cf category code to identify these, and some characters in Cf - // category code are of non-zero width. - if (ucs == 0 || ucs == 0x034F || (0x200B <= ucs && ucs <= 0x200F) || - ucs == 0x2028 || ucs == 0x2029 || (0x202A <= ucs && ucs <= 0x202E) || - (0x2060 <= ucs && ucs <= 0x2063)) { - return 0; - } - - // C0/C1 control characters. - if (ucs < 32 || (0x07F <= ucs && ucs < 0x0A0)) return -1; - - // Combining characters with zero width. - if (intable(ZERO_WIDTH, sizeof(ZERO_WIDTH) / sizeof(struct width_interval), ucs)) return 0; - - return intable(WIDE_EASTASIAN, sizeof(WIDE_EASTASIAN) / sizeof(struct width_interval), ucs) ? 2 : 1; -} - -int wcswidth(const wchar_t *wcs, size_t n) { - int ret = 0; - for(size_t i = 0; i < n && wcs[i]; i++) { - int cols = wcwidth(wcs[i]); - if (cols < 0) - return -1; - ret += cols; - } - - return ret; -} - -wchar_t *wcsdup(const wchar_t *s) { - size_t len = wcslen(s); - wchar_t *ret = (wchar_t *) malloc(sizeof(wchar_t) * (len + 1)); - if(!ret) - return NULL; - wmemcpy(ret, s, len + 1); - return ret; -} - -int wcsncasecmp(const wchar_t* s1, const wchar_t* s2, size_t n) { - for(size_t i = 0; i < n; i++) { - wint_t c1 = towlower(s1[i]); - wint_t c2 = towlower(s2[i]); - if(c1 == L'\0' && c2 == L'\0') - return 0; - if(c1 < c2) - return -1; - if(c1 > c2) - return 1; - } - return 0; -} - -int wcscasecmp(const wchar_t *, const wchar_t *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/ansi/generic/wctype.cpp b/lib/mlibc/options/ansi/generic/wctype.cpp deleted file mode 100644 index 57dcbc9..0000000 --- a/lib/mlibc/options/ansi/generic/wctype.cpp +++ /dev/null @@ -1,9 +0,0 @@ - -#include <wctype.h> -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <frg/string.hpp> - -wctrans_t wctrans(const char *) MLIBC_STUB_BODY -wint_t towctrans(wint_t, wctrans_t) MLIBC_STUB_BODY - |