user: implement mlibc as the libc, finally.

It's finally done..

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-05-02 03:31:49 -04:00
parent 2fa39ad85a
commit 9a9b91c940
2387 changed files with 152741 additions and 315 deletions
@@ -0,0 +1,13 @@
#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();
}
@@ -0,0 +1,9 @@
#include <complex.h>
long double cimagl(long double complex z) {
return __imag__(z);
}
long double creall(long double complex z) {
return __real__(z);
}
@@ -0,0 +1,59 @@
/* $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>>, <<cabsl>>---complex absolute-value
INDEX
cabs
INDEX
cabsf
INDEX
cabsl
SYNOPSIS
#include <complex.h>
double cabs(double complex <[z]>);
float cabsf(float complex <[z]>);
long double cabsl(long double 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 <<float complex>>.
<<cabsl>> is identical to <<cabs>>, except that it performs
its calculations on <<long double complex>>.
RETURNS
The cabs* functions return the complex absolute value.
PORTABILITY
<<cabs>>, <<cabsf>> and <<cabsl>> are ISO C99
QUICKREF
<<cabs>>, <<cabsf>> and <<cabsl>> are ISO C99
*/
#include <complex.h>
#include <math.h>
double
cabs(double complex z)
{
return hypot( creal(z), cimag(z) );
}
@@ -0,0 +1,19 @@
/* $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) );
}
@@ -0,0 +1,99 @@
/* $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
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;
}
@@ -0,0 +1,46 @@
/* $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;
}
@@ -0,0 +1,93 @@
/* $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
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;
}
@@ -0,0 +1,48 @@
/* $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;
}
@@ -0,0 +1,59 @@
/* $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
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) );
}
@@ -0,0 +1,19 @@
/* $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) );
}
@@ -0,0 +1,165 @@
/* $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
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;
}
@@ -0,0 +1,122 @@
/* $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;
}
@@ -0,0 +1,97 @@
/* $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
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;
}
@@ -0,0 +1,44 @@
/* $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;
}
@@ -0,0 +1,128 @@
/* $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
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);
t = 0.5 * atan2(2.0 * x, a);
w = _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;
}
@@ -0,0 +1,77 @@
/* $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);
t = 0.5f * atan2f(2.0f * x, a);
w = _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;
}
@@ -0,0 +1,90 @@
/* $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
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;
}
@@ -0,0 +1,44 @@
/* $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;
}
@@ -0,0 +1,81 @@
/* $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
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;
_cchsh(cimag(z), &ch, &sh);
w = cos(creal(z)) * ch - (sin(creal(z)) * sh) * I;
return w;
}
@@ -0,0 +1,48 @@
/* $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;
_cchshf(cimagf(z), &ch, &sh);
w = cosf(crealf(z)) * ch - (sinf(crealf(z)) * sh) * I;
return w;
}
@@ -0,0 +1,81 @@
/* $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
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;
}
@@ -0,0 +1,48 @@
/* $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;
}
@@ -0,0 +1,126 @@
/* $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
_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
_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
_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 = _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;
}
@@ -0,0 +1,8 @@
/* $NetBSD: cephes_subr.h,v 1.1 2007/08/20 16:01:33 drochner Exp $ */
__attribute__((__visibility__("hidden")))
void _cchsh(double, double *, double *);
__attribute__((__visibility__("hidden")))
double _redupi(double);
__attribute__((__visibility__("hidden")))
double _ctans(double complex);
@@ -0,0 +1,125 @@
/* $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
_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
_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
_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 = _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;
}
@@ -0,0 +1,8 @@
/* $NetBSD: cephes_subrf.h,v 1.1 2007/08/20 16:01:34 drochner Exp $ */
__attribute__((__visibility__("hidden")))
void _cchshf(float, float *, float *);
__attribute__((__visibility__("hidden")))
float _redupif(float);
__attribute__((__visibility__("hidden")))
float _ctansf(float complex);
@@ -0,0 +1,82 @@
/* $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
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;
}
@@ -0,0 +1,49 @@
/* $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;
}
@@ -0,0 +1,60 @@
/* $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>>, <<cimagl>>---imaginary part
INDEX
cimag
INDEX
cimagf
INDEX
cimagl
SYNOPSIS
#include <complex.h>
double cimag(double complex <[z]>);
float cimagf(float complex <[z]>);
long double cimagl(long double complex <[z]>);
DESCRIPTION
These functions compute the imaginary part of <[z]>.
<<cimagf>> is identical to <<cimag>>, except that it performs
its calculations on <<float complex>>.
<<cimagl>> is identical to <<cimag>>, except that it performs
its calculations on <<long double complex>>.
RETURNS
The cimag* functions return the imaginary part value (as a real).
PORTABILITY
<<cimag>>, <<cimagf>> and <<cimagl>> are ISO C99
QUICKREF
<<cimag>>, <<cimagf>> and <<cimagl>> are ISO C99
*/
#include <complex.h>
#include "fdlibm.h"
double
cimag(double complex z)
{
double_complex w = { .z = z };
return (IMAG_PART(w));
}
@@ -0,0 +1,21 @@
/* $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));
}
@@ -0,0 +1,91 @@
/* $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
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;
}
@@ -0,0 +1,49 @@
/* $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;
}
@@ -0,0 +1,56 @@
/* $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
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);
}
@@ -0,0 +1,23 @@
/* $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);
}
@@ -0,0 +1,101 @@
/* $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
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;
}
@@ -0,0 +1,59 @@
/* $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;
}
@@ -0,0 +1,105 @@
/* $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
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);
}
@@ -0,0 +1,67 @@
/* $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);
}
@@ -0,0 +1,60 @@
/* $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>>, <<creall>>---real part
INDEX
creal
INDEX
crealf
INDEX
creall
SYNOPSIS
#include <complex.h>
double creal(double complex <[z]>);
float crealf(float complex <[z]>);
double long creall(long double complex <[z]>);
DESCRIPTION
These functions compute the real part of <[z]>.
<<crealf>> is identical to <<creal>>, except that it performs
its calculations on <<float complex>>.
<<creall>> is identical to <<creal>>, except that it performs
its calculations on <<long double complex>>.
RETURNS
The creal* functions return the real part value.
PORTABILITY
<<creal>>, <<crealf>> and <<creall>> are ISO C99
QUICKREF
<<creal>>, <<crealf>> and <<creall>> are ISO C99
*/
#include <complex.h>
#include "fdlibm.h"
double
creal(double complex z)
{
double_complex w = { .z = z };
return (REAL_PART(w));
}
@@ -0,0 +1,21 @@
/* $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));
}
@@ -0,0 +1,81 @@
/* $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
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;
_cchsh(cimag(z), &ch, &sh);
w = sin(creal(z)) * ch + (cos(creal(z)) * sh) * I;
return w;
}
@@ -0,0 +1,48 @@
/* $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;
_cchshf(cimagf(z), &ch, &sh);
w = sinf(crealf(z)) * ch + (cosf(crealf(z)) * sh) * I;
return w;
}
@@ -0,0 +1,80 @@
/* $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
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;
}
@@ -0,0 +1,48 @@
/* $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;
}
@@ -0,0 +1,137 @@
/* $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
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;
}
@@ -0,0 +1,102 @@
/* $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;
}
@@ -0,0 +1,91 @@
/* $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
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 = _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;
}
@@ -0,0 +1,58 @@
/* $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 = _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;
}
@@ -0,0 +1,83 @@
/* $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
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;
}
@@ -0,0 +1,50 @@
/* $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;
}
@@ -0,0 +1,17 @@
#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
@@ -0,0 +1,326 @@
#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
};
} // namespace
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);
}
@@ -0,0 +1,168 @@
#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 };
} // namespace
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)) {
// GLIBC EXTENSION
update_vector();
unassign_variable(string);
return 0;
}
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 */
@@ -0,0 +1,12 @@
#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;
}
@@ -0,0 +1,43 @@
#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();
}
@@ -0,0 +1,750 @@
#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();
};
} // namespace
// 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))
+ (off_t(__unget_ptr) - off_t(__buffer_ptr));
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 if (*mode == 'x') {
flags |= O_EXCL;
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;
} // namespace
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(&current_offset); e) {
errno = e;
return -1;
}
return current_offset;
}
int fflush_unlocked(FILE *file_base) {
if(file_base == nullptr) {
// 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 == nullptr) {
// 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
@@ -0,0 +1,100 @@
#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_v<T>) {
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_v<T>) {
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();
}
@@ -0,0 +1,196 @@
#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
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;
} // namespace mlibc
[[gnu::constructor]]
static void init_locale() {
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;
} // namespace
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;
}
@@ -0,0 +1,44 @@
#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;
sigemptyset(&sa.sa_mask);
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;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,519 @@
#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/threads.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;
__mlibc_mutex exit_mutex = __MLIBC_THREAD_MUTEX_INITIALIZER;
} // namespace
double atof(const char *string) {
return strtod(string, nullptr);
}
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, nullptr, &buffer[0].__sigset);
return 0;
}
}
__attribute__((__noreturn__)) void siglongjmp(sigjmp_buf buffer, int value) {
if (buffer[0].__savesigs)
sigprocmask(SIG_SETMASK, &buffer[0].__sigset, nullptr);
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 nullptr;
}
// 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) {
// for concurrent calls to exit() or quick_exit(), all but the first shall block until termination
// see https://austingroupbugs.net/view.php?id=1845
mlibc::thread_mutex_lock(&exit_mutex);
__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, nullptr, &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 + frg::min(max_size, MB_CUR_MAX)};
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 *__restrict wcs, const char *__restrict 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 *__restrict mb_string, const wchar_t *__restrict wc_string, size_t max_size) {
const wchar_t *wcs = wc_string;
return wcsrtombs(mb_string, &wcs, max_size, nullptr);
}
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;
}
@@ -0,0 +1,550 @@
#undef _GNU_SOURCE
#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 : nullptr;
}
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 : nullptr;
}
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.
extern "C" char *__gnu_strerror_r(int e, char *buffer, size_t bufsz) {
auto s = strerror(e);
strncpy(buffer, s, bufsz);
return buffer;
}
// 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;
}
@@ -0,0 +1,97 @@
#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, nullptr, 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, nullptr) == 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;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,25 @@
#include <bits/ensure.h>
#include <uchar.h>
#include <wchar.h>
size_t c32rtomb(char *__restrict s, char32_t c32, mbstate_t *__restrict ps) {
return wcrtomb(s, c32, ps);
}
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(nullptr, "", 1, ps);
wchar_t wc;
size_t ret = mbrtowc(&wc, pmb, max, ps);
if (ret <= 4 && pc32)
*pc32 = wc;
return ret;
}
@@ -0,0 +1,790 @@
#include <errno.h>
#include <limits.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;
} // namespace
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 *__restrict mbs, size_t mb_limit, mbstate_t *__restrict 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 *__restrict wcp, const char *__restrict mbs, size_t mb_limit, mbstate_t *__restrict 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 *__restrict mbs, wchar_t wc, mbstate_t *__restrict 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 + MB_LEN_MAX};
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 *__restrict wcs, const char **__restrict mbsp, size_t wc_limit, mbstate_t *__restrict 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 *__restrict wcs, const char **__restrict mbsp, size_t mb_limit, size_t wc_limit, mbstate_t *__restrict 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 *__restrict mbs, const wchar_t **__restrict wcsp, size_t mb_limit, mbstate_t *__restrict stp) {
__ensure(wcsp && "wcsrtombs() with null input");
auto cc = mlibc::current_charcode();
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;
}
mlibc::code_seq<char> nseq{mbs, mbs + mb_limit};
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 *__restrict mbs, const wchar_t **__restrict wcsp, size_t wc_limit, size_t mb_limit, mbstate_t *__restrict 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;
}
} // namespace
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 nullptr;
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();
}
size_t wcsnlen(const wchar_t *, size_t) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
@@ -0,0 +1,9 @@
#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; }
@@ -0,0 +1,8 @@
#ifndef _ALLOCA_H
#define _ALLOCA_H
#define alloca __builtin_alloca
#endif /* _ALLOCA_H */
@@ -0,0 +1,46 @@
#ifndef _ASSERT_H
#define _ASSERT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
/* NOTE: This is not ISO C. Declared in LSB */
__attribute__ ((__noreturn__)) void __assert_fail(const char *assertion, const char *file, unsigned int line,
const char *function);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _ASSERT_H */
#include <mlibc-config.h>
#if __MLIBC_GLIBC_OPTION
# include <bits/glibc/glibc_assert.h>
#endif
/* NOTE: [7.2] requires this be outside the include guard */
#ifdef NDEBUG
#undef assert
#define assert(ignore) ((void)0)
#else /* NDEBUG */
#undef assert
#define assert(assertion) ((void)((assertion) \
|| (__assert_fail(#assertion, __FILE__, __LINE__, __func__), 0)))
#endif /* NDEBUG */
#ifndef __cplusplus
#undef static_assert
#define static_assert _Static_assert
#endif
@@ -0,0 +1,93 @@
#ifndef MLIBC_FENV_H
#define MLIBC_FENV_H
#if defined(__x86_64__) || defined(__i386__)
#define FE_DENORMAL 2
#define FE_DIVBYZERO 4
#define FE_INEXACT 32
#define FE_INVALID 1
#define FE_OVERFLOW 8
#define FE_UNDERFLOW 16
#define FE_ALL_EXCEPT (FE_DENORMAL | FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
#define FE_TONEAREST 0
#define FE_DOWNWARD 0x400
#define FE_UPWARD 0x800
#define FE_TOWARDZERO 0xC00
#elif defined(__aarch64__)
#define FE_INVALID 1
#define FE_DIVBYZERO 2
#define FE_OVERFLOW 4
#define FE_UNDERFLOW 8
#define FE_INEXACT 16
#define FE_ALL_EXCEPT 31
#define FE_TONEAREST 0
#define FE_UPWARD 0x400000
#define FE_DOWNWARD 0x800000
#define FE_TOWARDZERO 0xC00000
#elif defined(__riscv) && __riscv_xlen == 64
#define FE_INEXACT 1
#define FE_UNDERFLOW 2
#define FE_OVERFLOW 4
#define FE_DIVBYZERO 8
#define FE_INVALID 16
#define FE_ALL_EXCEPT 31
#define FE_TONEAREST 0
#define FE_TOWARDZERO 1
#define FE_DOWNWARD 2
#define FE_UPWARD 3
#elif defined (__m68k__)
#if __HAVE_68881__ || __mcffpu__ || __HAVE_FPU_
#define FE_INEXACT 8
#define FE_DIVBYZERO 16
#define FE_UNDERFLOW 32
#define FE_OVERFLOW 64
#define FE_INVALID 128
#define FE_ALL_EXCEPT 0xf8
#define FE_TONEAREST 0
#define FE_TOWARDZERO 16
#define FE_DOWNWARD 32
#define FE_UPWARD 48
#else
#define FE_ALL_EXCEPT 0
#define FE_TONEAREST 0
#endif
#elif defined(__loongarch64)
#define FE_INEXACT 0x010000
#define FE_UNDERFLOW 0x020000
#define FE_OVERFLOW 0x040000
#define FE_DIVBYZERO 0x080000
#define FE_INVALID 0x100000
#define FE_ALL_EXCEPT (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
#define FE_TONEAREST 0x000
#define FE_TOWARDZERO 0x100
#define FE_UPWARD 0x200
#define FE_DOWNWARD 0x300
#else
#error Unknown architecture
#endif
#endif /* MLIBC_FENV_H */
@@ -0,0 +1,8 @@
#ifndef MLIBC_TIME_T
#define MLIBC_TIME_T
typedef long time_t;
#endif
@@ -0,0 +1,13 @@
#ifndef MLIBC_TIMESPEC_H
#define MLIBC_TIMESPEC_H
#include <bits/ansi/time_t.h>
struct timespec {
time_t tv_sec;
long tv_nsec;
};
#endif /* MLIBC_TIMESPEC_H */
@@ -0,0 +1,134 @@
/* $NetBSD: complex.h,v 1.3 2010/09/15 16:11:30 christos Exp $ */
/*
* Written by Matthias Drochner.
* Public domain.
*/
#ifndef _COMPLEX_H
#define _COMPLEX_H
#define complex _Complex
#define _Complex_I 1.0fi
#define I _Complex_I
#define CMPLX(x, y) ((double complex)__builtin_complex((double)(x), (double)(y)))
#define CMPLXF(x, y) ((float complex)__builtin_complex((float)(x), (float)(y)))
#define CMPLXL(x, y) ((long double complex)__builtin_complex((long double)(x), (long double)(y)))
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
/* 7.3.5 Trigonometric functions */
/* 7.3.5.1 The cacos functions */
double complex cacos(double complex __x);
float complex cacosf(float complex __x);
/* 7.3.5.2 The casin functions */
double complex casin(double complex __x);
float complex casinf(float complex __x);
/* 7.3.5.1 The catan functions */
double complex catan(double complex __x);
float complex catanf(float complex __x);
/* 7.3.5.1 The ccos functions */
double complex ccos(double complex __x);
float complex ccosf(float complex __x);
/* 7.3.5.1 The csin functions */
double complex csin(double complex __x);
float complex csinf(float complex __x);
/* 7.3.5.1 The ctan functions */
double complex ctan(double complex __x);
float complex ctanf(float complex __x);
/* 7.3.6 Hyperbolic functions */
/* 7.3.6.1 The cacosh functions */
double complex cacosh(double complex __x);
float complex cacoshf(float complex __x);
/* 7.3.6.2 The casinh functions */
double complex casinh(double complex __x);
float complex casinhf(float complex __x);
/* 7.3.6.3 The catanh functions */
double complex catanh(double complex __x);
float complex catanhf(float complex __x);
/* 7.3.6.4 The ccosh functions */
double complex ccosh(double complex __x);
float complex ccoshf(float complex __x);
/* 7.3.6.5 The csinh functions */
double complex csinh(double complex __x);
float complex csinhf(float complex __x);
/* 7.3.6.6 The ctanh functions */
double complex ctanh(double complex __x);
float complex ctanhf(float complex __x);
/* 7.3.7 Exponential and logarithmic functions */
/* 7.3.7.1 The cexp functions */
double complex cexp(double complex __x);
float complex cexpf(float complex __x);
/* 7.3.7.2 The clog functions */
double complex clog(double complex __x);
float complex clogf(float complex __x);
/* 7.3.8 Power and absolute-value functions */
/* 7.3.8.1 The cabs functions */
/*#ifndef __LIBM0_SOURCE__ */
/* avoid conflict with historical cabs(struct complex) */
/* double cabs(double complex __x) __RENAME(__c99_cabs);
float cabsf(float complex __x) __RENAME(__c99_cabsf);
#endif
*/
double cabs(double complex __x);
float cabsf(float complex __x);
/* 7.3.8.2 The cpow functions */
double complex cpow(double complex __x, double complex __y);
float complex cpowf(float complex __x, float complex __y);
/* 7.3.8.3 The csqrt functions */
double complex csqrt(double complex __x);
float complex csqrtf(float complex __x);
/* 7.3.9 Manipulation functions */
/* 7.3.9.1 The carg functions */
double carg(double complex __x);
float cargf(float complex __x);
/* 7.3.9.2 The cimag functions */
double cimag(double complex __x);
float cimagf(float complex __x);
long double cimagl(long double complex __x);
/* 7.3.9.3 The conj functions */
double complex conj(double complex __x);
float complex conjf(float complex __x);
/*long double complex conjl(long double complex __x); */
/* 7.3.9.4 The cproj functions */
double complex cproj(double complex __x);
float complex cprojf(float complex __x);
/*long double complex cprojl(long double complex __x); */
/* 7.3.9.5 The creal functions */
double creal(double complex __x);
float crealf(float complex __x);
long double creall(long double complex __x);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* ! _COMPLEX_H */
@@ -0,0 +1,46 @@
#ifndef _CTYPE_H
#define _CTYPE_H
#include <mlibc-config.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
/* Character classification function [7.4.1] */
int isalnum(int __c);
int isalpha(int __c);
int isblank(int __c);
int iscntrl(int __c);
int isdigit(int __c);
int isgraph(int __c);
int islower(int __c);
int isprint(int __c);
int ispunct(int __c);
int isspace(int __c);
int isupper(int __c);
int isxdigit(int __c);
/* glibc extensions. */
int isascii(int __c);
/* Character case mapping functions [7.4.2] */
int tolower(int __c);
int toupper(int __c);
#endif /* !__MLIBC_ABI_ONLY */
/* Borrowed from glibc */
#define toascii(c) ((c) & 0x7f)
#ifdef __cplusplus
}
#endif
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_ctype.h>
#endif
#endif /* _CTYPE_H */
@@ -0,0 +1,31 @@
#ifndef _ERRNO_H
#define _ERRNO_H
#include <abi-bits/errno.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
/* Some programs define their own errno as an "extern int" if it is not a macro. */
#define errno __mlibc_errno
extern __thread int __mlibc_errno;
int *__errno_location(void);
/* Linux extensions. */
extern char *program_invocation_name;
extern char *program_invocation_short_name;
extern char *__progname;
extern char *__progname_full;
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _ERRNO_H */
@@ -0,0 +1,44 @@
#ifndef _FENV_H
#define _FENV_H
#include <bits/types.h>
#include <bits/ansi/fenv.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
__mlibc_uint32 __control_word;
__mlibc_uint32 __status_word;
__mlibc_uint32 __unused[5];
__mlibc_uint32 __mxcsr;
} fenv_t;
typedef __mlibc_uint16 fexcept_t;
#ifndef __MLIBC_ABI_ONLY
int feclearexcept(int __excepts);
int fegetenv(fenv_t *__envp);
int fegetexceptflag(fexcept_t *__envp, int __excepts);
int fegetround(void);
int feholdexcept(fenv_t *__envp);
int feraiseexcept(int __excepts);
int fesetenv(const fenv_t *__envp);
int fesetexceptflag(const fexcept_t *__envp, int __excepts);
int fesetround(int __round);
int fetestexcept(int __excepts);
int feupdateenv(const fenv_t *__envp);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#define FE_DFL_ENV ((const fenv_t *) -1)
#endif /* _FENV_H */
@@ -0,0 +1,206 @@
#ifndef _STDINT_H
#define _STDINT_H
#include <stdint.h>
#include <bits/wchar_t.h>
/* Even though this is not strictly not-ABI, it is mlibc-printf specific therefore */
/* gate behind !__MLIBC_ABI_ONLY */
#ifndef __MLIBC_ABI_ONLY
#if UINTPTR_MAX == UINT64_MAX
# define __PRI64 "l"
# define __PRIPTR "l"
#else
# define __PRI64 "ll"
# define __PRIPTR ""
#endif
/* TODO: This is extremly unelegant and fragile. */
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "d"
#define PRIi16 "i"
#define PRIdLEAST16 "d"
#define PRIiLEAST16 "i"
#define PRIdFAST16 "ld"
#define PRIiFAST16 "li"
#define PRId32 "d"
#define PRIi32 "i"
#define PRIdLEAST32 "d"
#define PRIiLEAST32 "i"
#define PRIdFAST32 "ld"
#define PRIiFAST32 "li"
#define PRId64 __PRI64 "d"
#define PRIi64 __PRI64 "i"
#define PRIdLEAST64 __PRI64 "d"
#define PRIiLEAST64 __PRI64 "i"
#define PRIdFAST64 __PRI64 "d"
#define PRIiFAST64 __PRI64 "i"
#define PRIdMAX __PRI64 "d"
#define PRIiMAX __PRI64 "i"
#define PRIdPTR __PRIPTR "d"
#define PRIiPTR __PRIPTR "i"
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "o"
#define PRIu16 "u"
#define PRIx16 "x"
#define PRIX16 "X"
#define PRIoLEAST16 "o"
#define PRIuLEAST16 "u"
#define PRIxLEAST16 "x"
#define PRIXLEAST16 "X"
#define PRIoFAST16 "lo"
#define PRIuFAST16 "lu"
#define PRIxFAST16 "lx"
#define PRIXFAST16 "lX"
#define PRIo32 "o"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#define PRIoLEAST32 "o"
#define PRIuLEAST32 "u"
#define PRIxLEAST32 "x"
#define PRIXLEAST32 "X"
#define PRIoFAST32 "lo"
#define PRIuFAST32 "lu"
#define PRIxFAST32 "lx"
#define PRIXFAST32 "lX"
#define PRIo64 __PRI64 "o"
#define PRIu64 __PRI64 "u"
#define PRIx64 __PRI64 "x"
#define PRIX64 __PRI64 "X"
#define PRIoLEAST64 __PRI64 "o"
#define PRIuLEAST64 __PRI64 "u"
#define PRIxLEAST64 __PRI64 "x"
#define PRIXLEAST64 __PRI64 "X"
#define PRIoFAST64 __PRI64 "o"
#define PRIuFAST64 __PRI64 "u"
#define PRIxFAST64 __PRI64 "x"
#define PRIXFAST64 __PRI64 "X"
#define PRIoMAX __PRI64 "o"
#define PRIuMAX __PRI64 "u"
#define PRIxMAX __PRI64 "x"
#define PRIXMAX __PRI64 "X"
#define PRIoPTR __PRIPTR "o"
#define PRIuPTR __PRIPTR "u"
#define PRIxPTR __PRIPTR "x"
#define PRIXPTR __PRIPTR "X"
#define SCNi8 "hhi"
#define SCNi16 "hi"
#define SCNi32 "i"
#define SCNi64 __PRI64 "i"
#define SCNiLEAST8 "hhi"
#define SCNiLEAST16 "hi"
#define SCNiLEAST32 "i"
#define SCNiLEAST64 __PRI64 "i"
#define SCNiFAST8 "hhi"
#define SCNiFAST16 __PRIPTR "i"
#define SCNiFAST32 __PRIPTR "i"
#define SCNiFAST64 __PRI64 "i"
#define SCNiMAX __PRI64 "i"
#define SCNiPTR __PRIPTR "i"
#define SCNd8 "hhd"
#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 __PRI64 "d"
#define SCNdLEAST8 "hhd"
#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 __PRI64 "d"
#define SCNdFAST8 "hhd"
#define SCNdFAST16 __PRIPTR "d"
#define SCNdFAST32 __PRIPTR "d"
#define SCNdFAST64 __PRI64 "d"
#define SCNdMAX __PRI64 "d"
#define SCNdPTR __PRIPTR "d"
#define SCNu8 "hhu"
#define SCNu16 "hu"
#define SCNu32 "u"
#define SCNu64 __PRI64 "u"
#define SCNuLEAST8 "hhu"
#define SCNuLEAST16 "hu"
#define SCNuLEAST32 "u"
#define SCNuLEAST64 __PRI64 "u"
#define SCNuFAST8 "hhu"
#define SCNuFAST16 __PRIPTR "u"
#define SCNuFAST32 __PRIPTR "u"
#define SCNuFAST64 __PRI64 "u"
#define SCNuMAX __PRI64 "u"
#define SCNuPTR __PRIPTR "u"
#define SCNo8 "hho"
#define SCNo16 "ho"
#define SCNo32 "o"
#define SCNo64 __PRI64 "o"
#define SCNoLEAST8 "hho"
#define SCNoLEAST16 "ho"
#define SCNoLEAST32 "o"
#define SCNoLEAST64 __PRI64 "o"
#define SCNoFAST8 "hho"
#define SCNoFAST16 __PRIPTR "o"
#define SCNoFAST32 __PRIPTR "o"
#define SCNoFAST64 __PRI64 "o"
#define SCNoMAX __PRI64 "o"
#define SCNoPTR __PRIPTR "o"
#define SCNx8 "hhx"
#define SCNx16 "hx"
#define SCNx32 "x"
#define SCNx64 __PRI64 "x"
#define SCNxLEAST8 "hhx"
#define SCNxLEAST16 "hx"
#define SCNxLEAST32 "x"
#define SCNxLEAST64 __PRI64 "x"
#define SCNxFAST8 "hhx"
#define SCNxFAST16 __PRIPTR "x"
#define SCNxFAST32 __PRIPTR "x"
#define SCNxFAST64 __PRI64 "x"
#define SCNxMAX __PRI64 "x"
#define SCNxPTR __PRIPTR "x"
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
#ifndef __MLIBC_ABI_ONLY
intmax_t imaxabs(intmax_t __x);
imaxdiv_t imaxdiv(intmax_t __x, intmax_t __y);
intmax_t strtoimax(const char *__restrict __string, char **__restrict __end, int __base);
uintmax_t strtoumax(const char *__restrict __string, char **__restrict __end, int __base);
intmax_t wcstoimax(const wchar_t *__restrict __string, wchar_t **__restrict __end, int __base);
uintmax_t wcstoumax(const wchar_t *__restrict __string, wchar_t **__restrict __end, int __base);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _STDINT_H */
@@ -0,0 +1,123 @@
#ifndef _LIMITS_H
#define _LIMITS_H
#define CHAR_BIT 8
#ifndef MB_LEN_MAX
# define MB_LEN_MAX 4
#endif
#ifdef LONG_MAX
# ifdef LONG_MAX == INT32_MAX
# define LONG_BIT 32
# else
/* Safe assumption */
# define LONG_BIT 64
# endif
#elif defined __LONG_MAX__
# if __LONG_MAX__ == INT32_MAX
# define LONG_BIT 32
# else
/* Safe assumption */
# define LONG_BIT 64
# endif
#else
# error "Unsupported configuration, please define either LONG_MAX or __LONG_MAX__"
#endif
#undef SCHAR_MIN
#undef SCHAR_MAX
#undef CHAR_MIN
#undef CHAR_MAX
#undef UCHAR_MAX
#undef SHRT_MIN
#undef SHRT_MAX
#undef USHRT_MAX
#undef INT_MIN
#undef INT_MAX
#undef UINT_MAX
#undef LONG_MIN
#undef LONG_MAX
#undef ULONG_MAX
#undef LLONG_MIN
#undef LLONG_MAX
#undef ULLONG_MAX
#define SCHAR_MIN (-__SCHAR_MAX__ - 1)
#define SCHAR_MAX __SCHAR_MAX__
#if __SCHAR_MAX__ == __INT_MAX__
# define UCHAR_MAX (__SCHAR_MAX__ * 2U + 1U)
#else
# define UCHAR_MAX (__SCHAR_MAX__ * 2 + 1)
#endif
#ifdef __CHAR_UNSIGNED__
# define CHAR_MAX UCHAR_MAX
# if __SCHAR_MAX__ == __INT_MAX__
# define CHAR_MIN 0U
# else
# define CHAR_MIN 0
# endif
#else
# define CHAR_MAX SCHAR_MAX
# define CHAR_MIN SCHAR_MIN
#endif
#define SHRT_MIN (-__SHRT_MAX__ - 1)
#define SHRT_MAX __SHRT_MAX__
#if __SHRT_MAX__ == __INT_MAX__
# define USHRT_MAX (__SHRT_MAX__ * 2U + 1U)
#else
# define USHRT_MAX (__SHRT_MAX__ * 2 + 1)
#endif
#define INT_MIN (-__INT_MAX__ - 1)
#define INT_MAX __INT_MAX__
#define UINT_MAX (__INT_MAX__ * 2U + 1U)
#define LONG_MIN (-__LONG_MAX__ - 1L)
#define LONG_MAX __LONG_MAX__
#define ULONG_MAX (__LONG_MAX__ * 2UL + 1UL)
#define LLONG_MIN (-__LONG_LONG_MAX__ - 1LL)
#define LLONG_MAX __LONG_LONG_MAX__
#define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)
#define NAME_MAX 255
#define PATH_MAX 4096
#define LINE_MAX 4096
#define PIPE_BUF 4096
#define CHARCLASS_NAME_MAX 14
#define RE_DUP_MAX 255
#if !defined(NGROUPS_MAX)
/* This value is a guaranteed minimum, get the current maximum from sysconf */
#define NGROUPS_MAX 8
#endif /* !defined(NGROUPS_MAX) */
/* POSIX states 9 is the minimum for NL_ARGMAX */
#define NL_ARGMAX 9
#if INTPTR_MAX == INT64_MAX
# define SSIZE_MAX LONG_MAX
#elif INTPTR_MAX == INT32_MAX
# define SSIZE_MAX INT_MAX
#endif
#define _POSIX_ARG_MAX 4096
#define _POSIX_OPEN_MAX 16
#define _POSIX_HOST_NAME_MAX 255
#define _POSIX_NAME_MAX 14
#define _POSIX_TZNAME_MAX 6
#define _XOPEN_NAME_MAX 255
/* This value is a guaranteed minimum, get the current maximum from sysconf */
#define TZNAME_MAX _POSIX_TZNAME_MAX
#define PTHREAD_STACK_MIN 16384
#define PTHREAD_KEYS_MAX 1024
#include <abi-bits/limits.h>
#endif /* _LIMITS_H */
@@ -0,0 +1,83 @@
#ifndef _LOCALE_H
#define _LOCALE_H
#include <mlibc-config.h>
#include <bits/null.h>
#define LC_ALL 1
#define LC_COLLATE 2
#define LC_CTYPE 3
#define LC_MONETARY 4
#define LC_NUMERIC 5
#define LC_TIME 6
#define LC_MESSAGES 7
#define LC_MEASUREMENT 11
#define LC_GLOBAL_LOCALE ((locale_t) -1L)
#define LC_CTYPE_MASK (1<<LC_CTYPE)
#define LC_NUMERIC_MASK (1<<LC_NUMERIC)
#define LC_TIME_MASK (1<<LC_TIME)
#define LC_COLLATE_MASK (1<<LC_COLLATE)
#define LC_MONETARY_MASK (1<<LC_MONETARY)
#define LC_MESSAGES_MASK (1<<LC_MESSAGES)
#define LC_MEASUREMENT_MASK (1<<LC_MEASUREMENT)
#define LC_ALL_MASK 0x7FFFFFFF
#ifdef __cplusplus
extern "C" {
#endif
struct lconv {
char *decimal_point;
char *thousands_sep;
char *grouping;
char *mon_decimal_point;
char *mon_thousands_sep;
char *mon_grouping;
char *positive_sign;
char *negative_sign;
char *currency_symbol;
char frac_digits;
char p_cs_precedes;
char n_cs_precedes;
char p_sep_by_space;
char n_sep_by_space;
char p_sign_posn;
char n_sign_posn;
char *int_curr_symbol;
char int_frac_digits;
char int_p_cs_precedes;
char int_n_cs_precedes;
char int_p_sep_by_space;
char int_n_sep_by_space;
char int_p_sign_posn;
char int_n_sign_posn;
};
#ifndef __MLIBC_ABI_ONLY
/* [C11/7.11.1] setlocale() function */
char *setlocale(int __category, const char *__locale);
/* [C11/7.11.2] Locale inquiry function */
struct lconv *localeconv(void);
#endif /* !__MLIBC_ABI_ONLY */
/* posix extension */
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_locale.h>
#endif /* __MLIBC_POSIX_OPTION */
#ifdef __cplusplus
}
#endif
#endif /* _LOCALE_H */
@@ -0,0 +1,383 @@
#ifndef _MATH_H
#define _MATH_H
#include <bits/inline-definition.h>
/* this is a posix extension */
#define M_E 2.7182818284590452354
#define M_LOG2E 1.4426950408889634074
#define M_LOG10E 0.43429448190325182765
#define M_LN2 0.69314718055994530942
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.78539816339744830962
#define M_1_PI 0.31830988618379067154
#define M_2_PI 0.63661977236758134308
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT1_2 0.70710678118654752440
#define M_PIl 3.141592653589793238462643383279502884L
/* The following two definitions are from musl. */
#define FP_ILOGBNAN (-1 - (int)(((unsigned)-1) >> 1))
#define FP_ILOGB0 FP_ILOGBNAN
#ifdef __cplusplus
extern "C" {
#endif
typedef double double_t;
typedef float float_t;
#define HUGE_VAL (__builtin_huge_val())
#define HUGE_VALF (__builtin_huge_valf())
#define HUGE_VALL (__builtin_huge_vall())
#define INFINITY (__builtin_inff())
#define NAN (__builtin_nanf(""))
/* [C11/7.12.1 Treatment of error conditions] */
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
#define math_errhandling 3
/* [C11/7.12.3 Classification macros] */
/* NOTE: fpclassify always returns exactly one of those constants */
/* However making them bitwise disjoint simplifies isfinite() etc. */
#define FP_INFINITE 1
#define FP_NAN 2
#define FP_NORMAL 4
#define FP_SUBNORMAL 8
#define FP_ZERO 16
#ifndef __MLIBC_ABI_ONLY
int __fpclassify(double __x);
int __fpclassifyf(float __x);
int __fpclassifyl(long double __x);
#define fpclassify(x) \
(sizeof(x) == sizeof(double) ? __fpclassify(x) : \
(sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \
(sizeof(x) == sizeof(long double) ? __fpclassifyl(x) : \
0)))
#define isfinite(x) (fpclassify(x) & (FP_NORMAL | FP_SUBNORMAL | FP_ZERO))
#define isnan(x) (fpclassify(x) == FP_NAN)
#define isinf(x) (fpclassify(x) == FP_INFINITE)
#define isnormal(x) (fpclassify(x) == FP_NORMAL)
/* FIXME: this is gcc specific */
#define signbit(x) (__builtin_signbit(x))
/* [C11/7.12.14 Comparison macros] */
#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y)))
__MLIBC_INLINE_DEFINITION int __mlibc_isless(double_t __x, double_t __y) { return !isunordered(__x, __y) && __x < __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessf(float_t __x, float_t __y) { return !isunordered(__x, __y) && __x < __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessl(long double __x, long double __y) { return !isunordered(__x, __y) && __x < __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessequal(double_t __x, double_t __y) { return !isunordered(__x, __y) && __x <= __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessequalf(float_t __x, float_t __y) { return !isunordered(__x, __y) && __x <= __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessequall(long double __x, long double __y) { return !isunordered(__x, __y) && __x <= __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessgreater(double_t __x, double_t __y) { return !isunordered(__x, __y) && __x != __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessgreaterf(float_t __x, float_t __y) { return !isunordered(__x, __y) && __x != __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_islessgreaterl(long double __x, long double __y) { return !isunordered(__x, __y) && __x != __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_isgreater(double_t __x, double_t __y) { return !isunordered(__x, __y) && __x > __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_isgreaterf(float_t __x, float_t __y) { return !isunordered(__x, __y) && __x > __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_isgreaterl(long double __x, long double __y) { return !isunordered(__x, __y) && __x > __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_isgreaterequal(double_t __x, double_t __y) { return !isunordered(__x, __y) && __x >= __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_isgreaterequalf(float_t __x, float_t __y) { return !isunordered(__x, __y) && __x >= __y; }
__MLIBC_INLINE_DEFINITION int __mlibc_isgreaterequall(long double __x, long double __y) { return !isunordered(__x, __y) && __x >= __y; }
/* TODO: We chould use _Generic here but that does not work in C++ code. */
#define __MLIBC_CHOOSE_COMPARISON(x, y, p) ( \
sizeof((x)+(y)) == sizeof(float) ? p##f(x, y) : \
sizeof((x)+(y)) == sizeof(double) ? p(x, y) : \
p##l(x, y) )
#define isless(x, y) __MLIBC_CHOOSE_COMPARISON(x, y, __mlibc_isless)
#define islessequal(x, y) __MLIBC_CHOOSE_COMPARISON(x, y, __mlibc_islessequal)
#define islessgreater(x, y) __MLIBC_CHOOSE_COMPARISON(x, y, __mlibc_islessgreater)
#define isgreater(x, y) __MLIBC_CHOOSE_COMPARISON(x, y, __mlibc_isgreater)
#define isgreaterequal(x, y) __MLIBC_CHOOSE_COMPARISON(x, y, __mlibc_isgreaterequal)
/* this is a gnu extension */
void sincos(double __x, double *__sin, double *__cos);
void sincosf(float __x, float *__sin, float *__cos);
void sincosl(long double __x, long double *__sin, long double *__cos);
double exp10(double __x);
float exp10f(float __x);
long double exp10l(long double __x);
double pow10(double __x);
float pow10f(float __x);
long double pow10l(long double __x);
/* [C11/7.12.4 Trigonometric functions] */
double acos(double __x);
float acosf(float __x);
long double acosl(long double __x);
double asin(double __x);
float asinf(float __x);
long double asinl(long double __x);
double atan(double __x);
float atanf(float __x);
long double atanl(long double __x);
double atan2(double __x, double __y);
float atan2f(float __x, float __y);
long double atan2l(long double __x, long double __y);
double cos(double __x);
float cosf(float __x);
long double cosl(long double __x);
double sin(double __x);
float sinf(float __x);
long double sinl(long double __x);
double tan(double __x);
float tanf(float __x);
long double tanl(long double __x);
/* [C11/7.12.5 Hyperbolic functions] */
double acosh(double __x);
float acoshf(float __x);
long double acoshl(long double __x);
double asinh(double __x);
float asinhf(float __x);
long double asinhl(long double __x);
double atanh(double __x);
float atanhf(float __x);
long double atanhl(long double __x);
double cosh(double __x);
float coshf(float __x);
long double coshl(long double __x);
double sinh(double __x);
float sinhf(float __x);
long double sinhl(long double __x);
double tanh(double __x);
float tanhf(float __x);
long double tanhl(long double __x);
/* [C11/7.12.6 Exponential and logarithmic functions] */
double exp(double __x);
float expf(float __x);
long double expl(long double __x);
double exp2(double __x);
float exp2f(float __x);
long double exp2l(long double __x);
double expm1(double __x);
float expm1f(float __x);
long double expm1l(long double __x);
double frexp(double __x, int *__power);
float frexpf(float __x, int *__power);
long double frexpl(long double __x, int *__power);
int ilogb(double __x);
int ilogbf(float __x);
int ilogbl(long double __x);
double ldexp(double __x, int __power);
float ldexpf(float __x, int __power);
long double ldexpl(long double __x, int __power);
double log(double __x);
float logf(float __x);
long double logl(long double __x);
double log10(double __x);
float log10f(float __x);
long double log10l(long double __x);
double log1p(double __x);
float log1pf(float __x);
long double log1pl(long double __x);
double log2(double __x);
float log2f(float __x);
long double log2l(long double __x);
double logb(double __x);
float logbf(float __x);
long double logbl(long double __x);
double modf(double __x, double *__integral);
float modff(float __x, float *__integral);
long double modfl(long double __x, long double *__integral);
double scalbn(double __x, int __power);
float scalbnf(float __x, int __power);
long double scalbnl(long double __x, int __power);
double scalbln(double __x, long __power);
float scalblnf(float __x, long __power);
long double scalblnl(long double __x, long __power);
/* [C11/7.12.7 Power and absolute-value functions] */
double cbrt(double __x);
float cbrtf(float __x);
long double cbrtl(long double __x);
double fabs(double __x);
float fabsf(float __x);
long double fabsl(long double __x);
double hypot(double __x, double __y);
float hypotf(float __x, float __y);
long double hypotl(long double __x, long double __y);
double pow(double __x, double __y);
float powf(float __x, float __y);
long double powl(long double __x, long double __y);
double sqrt(double __x);
float sqrtf(float __x);
long double sqrtl(long double __x);
/* [C11/7.12.8 Error and gamma functions] */
double erf(double __x);
float erff(float __x);
long double erfl(long double __x);
double erfc(double __x);
float erfcf(float __x);
long double erfcl(long double __x);
double lgamma(double __x);
float lgammaf(float __x);
long double lgammal(long double __x);
double tgamma(double __x);
float tgammaf(float __x);
long double tgammal(long double __x);
/* [C11/7.12.9 Nearest integer functions] */
double ceil(double __x);
float ceilf(float __x);
long double ceill(long double __x);
double floor(double __x);
float floorf(float __x);
long double floorl(long double __x);
double nearbyint(double __x);
float nearbyintf(float __x);
long double nearbyintl(long double __x);
double rint(double __x);
float rintf(float __x);
long double rintl(long double __x);
long lrint(double __x);
long lrintf(float __x);
long lrintl(long double __x);
long long llrint(double __x);
long long llrintf(float __x);
long long llrintl(long double __x);
double round(double __x);
float roundf(float __x);
long double roundl(long double __x);
long lround(double __x);
long lroundf(float __x);
long lroundl(long double __x);
long long llround(double __x);
long long llroundf(float __x);
long long llroundl(long double __x);
double trunc(double __x);
float truncf(float __x);
long double truncl(long double __x);
/* [C11/7.12.10 Remainder functions] */
double fmod(double __x, double __y);
float fmodf(float __x, float __y);
long double fmodl(long double __x, long double __y);
double remainder(double __x, double __y);
float remainderf(float __x, float __y);
long double remainderl(long double __x, long double __y);
double remquo(double __x, double __y, int *__quotient);
float remquof(float __x, float __y, int *__quotient);
long double remquol(long double __x, long double __y, int *__quotient);
/* [C11/7.12.11 Manipulation functions] */
double copysign(double __x, double __sign);
float copysignf(float __x, float __sign);
long double copysignl(long double __x, long double __sign);
double nan(const char *__tag);
float nanf(const char *__tag);
long double nanl(const char *__tag);
double nextafter(double __x, double __dir);
float nextafterf(float __x, float __dir);
long double nextafterl(long double __x, long double __dir);
double nexttoward(double __x, long double __dir);
float nexttowardf(float __x, long double __dir);
long double nexttowardl(long double __x, long double __dir);
/* [C11/7.12.12 Maximum, minimum and positive difference functions] */
double fdim(double __x, double __y);
float fdimf(float __x, float __y);
long double fdiml(long double __x, long double __y);
double fmax(double __x, double __y);
float fmaxf(float __x, float __y);
long double fmaxl(long double __x, long double __y);
double fmin(double __x, double __y);
float fminf(float __x, float __y);
long double fminl(long double __x, long double __y);
/* [C11/7.12.13 Floating multiply-add] */
double fma(double __x, double __y, double __z);
float fmaf(float __x, float __y, float __z);
long double fmal(long double __x, long double __y, long double __z);
extern int signgam;
#define __signgam signgam
/* BSD floating-point classification functions - obsolete */
int finite(double __x);
int finitef(float __x);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _MATH_H */
@@ -0,0 +1,72 @@
#ifndef MLIBC_ANSI_SYSDEPS
#define MLIBC_ANSI_SYSDEPS
#include <stddef.h>
#include <abi-bits/seek-whence.h>
#include <abi-bits/vm-flags.h>
#include <abi-bits/pid_t.h>
#include <abi-bits/mode_t.h>
#include <bits/off_t.h>
#include <bits/ssize_t.h>
#include <bits/ansi/time_t.h>
#include <signal.h>
#include <stdarg.h>
struct rusage;
namespace [[gnu::visibility("hidden")]] mlibc {
[[noreturn]] void sys_exit(int status);
[[noreturn, gnu::weak]] void sys_thread_exit();
// If *stack is not null, it should point to the lowest addressable byte of the stack.
// Returns the new stack pointer in *stack and the stack base in *stack_base.
[[gnu::weak]] int sys_prepare_stack(void **stack, void *entry, void *user_arg, void* tcb, size_t *stack_size, size_t *guard_size, void **stack_base);
[[gnu::weak]] int sys_clone(void *tcb, pid_t *pid_out, void *stack);
int sys_futex_wait(int *pointer, int expected, const struct timespec *time);
int sys_futex_wake(int *pointer);
int sys_open(const char *pathname, int flags, mode_t mode, int *fd);
[[gnu::weak]] int sys_flock(int fd, int options);
[[gnu::weak]] int sys_open_dir(const char *path, int *handle);
[[gnu::weak]] int sys_read_entries(int handle, void *buffer, size_t max_size,
size_t *bytes_read);
int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read);
int sys_write(int fd, const void *buf, size_t count, ssize_t *bytes_written);
[[gnu::weak]] int sys_pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read);
int sys_seek(int fd, off_t offset, int whence, off_t *new_offset);
int sys_close(int fd);
int sys_clock_get(int clock, time_t *secs, long *nanos);
[[gnu::weak]] int sys_clock_set(int clock, time_t secs, long nanos);
[[gnu::weak]] int sys_clock_getres(int clock, time_t *secs, long *nanos);
[[gnu::weak]] int sys_sleep(time_t *secs, long *nanos);
// In contrast to the isatty() library function, the sysdep function uses return value
// zero (and not one) to indicate that the file is a terminal.
[[gnu::weak]] int sys_isatty(int fd);
[[gnu::weak]] int sys_rmdir(const char *path);
[[gnu::weak]] int sys_unlinkat(int dirfd, const char *path, int flags);
[[gnu::weak]] int sys_rename(const char *path, const char *new_path);
[[gnu::weak]] int sys_renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path);
[[gnu::weak]] int sys_sigprocmask(int how, const sigset_t *__restrict set,
sigset_t *__restrict retrieve);
[[gnu::weak]] int sys_sigaction(int, const struct sigaction *__restrict,
struct sigaction *__restrict);
[[gnu::weak]] int sys_fork(pid_t *child);
[[gnu::weak]] int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid);
[[gnu::weak]] int sys_execve(const char *path, char *const argv[], char *const envp[]);
[[gnu::weak]] pid_t sys_getpid();
[[gnu::weak]] int sys_kill(int, int);
} //namespace mlibc
#endif // MLIBC_ANSI_SYSDEPS
@@ -0,0 +1,10 @@
#ifndef MLIBC_ENVIRONMENT_HPP
#define MLIBC_ENVIRONMENT_HPP
namespace mlibc {
int putenv(char *string);
} // namespace mlibc
#endif // MLIBC_ENVIRONMENT_HPP
@@ -0,0 +1,130 @@
#ifndef MLIBC_FILE_IO_HPP
#define MLIBC_FILE_IO_HPP
#include <stdio.h>
#include <mlibc/lock.hpp>
#include <mlibc/allocator.hpp>
#include <frg/list.hpp>
namespace mlibc {
enum class stream_type {
unknown,
file_like,
pipe_like
};
enum class buffer_mode {
unknown,
no_buffer,
line_buffer,
full_buffer
};
struct StdioLock {
bool uselock = true;
RecursiveFutexLock futexlock;
void lock() {
if (uselock) {
futexlock.lock();
}
}
void unlock() {
if (uselock) {
futexlock.unlock();
}
}
void try_lock() {
if (uselock) {
futexlock.try_lock();
}
}
};
struct abstract_file : __mlibc_file_base {
public:
abstract_file(void (*do_dispose)(abstract_file *) = nullptr);
abstract_file(const abstract_file &) = delete;
abstract_file &operator= (const abstract_file &) = delete;
virtual ~abstract_file();
void dispose();
virtual int close() = 0;
virtual int reopen(const char *path, const char *mode) = 0;
int read(char *buffer, size_t max_size, size_t *actual_size);
int write(const char *buffer, size_t max_size, size_t *actual_size);
int unget(char c);
int update_bufmode(buffer_mode mode);
void purge();
int flush();
int tell(off_t *current_offset);
int seek(off_t offset, int whence);
protected:
virtual int determine_type(stream_type *type) = 0;
virtual int determine_bufmode(buffer_mode *mode) = 0;
virtual int io_read(char *buffer, size_t max_size, size_t *actual_size) = 0;
virtual int io_write(const char *buffer, size_t max_size, size_t *actual_size) = 0;
virtual int io_seek(off_t offset, int whence, off_t *new_offset) = 0;
int _reset();
private:
int _init_type();
int _init_bufmode();
int _write_back();
int _save_pos();
void _ensure_allocation();
stream_type _type;
buffer_mode _bufmode;
void (*_do_dispose)(abstract_file *);
public:
// lock for file operations
StdioLock _lock;
// All files are stored in a global linked list, so that they can be flushed at exit().
frg::default_list_hook<abstract_file> _list_hook;
};
struct fd_file : abstract_file {
fd_file(int fd, void (*do_dispose)(abstract_file *) = nullptr, bool force_unbuffered = false);
int fd();
int close() override;
int reopen(const char *path, const char *mode) override;
static int parse_modestring(const char *mode);
protected:
int determine_type(stream_type *type) override;
int determine_bufmode(buffer_mode *mode) override;
int io_read(char *buffer, size_t max_size, size_t *actual_size) override;
int io_write(const char *buffer, size_t max_size, size_t *actual_size) override;
int io_seek(off_t offset, int whence, off_t *new_offset) override;
private:
// Underlying file descriptor.
int _fd;
bool _force_unbuffered;
};
template <typename T>
void file_dispose_cb(abstract_file *base) {
frg::destruct(getAllocator(), static_cast<T *>(base));
}
} // namespace mlibc
#endif // MLIBC_FILE_IO_HPP
@@ -0,0 +1,57 @@
#ifndef _SETJMP_H
#define _SETJMP_H
#include <mlibc-config.h>
#include <bits/machine.h>
#include <abi-bits/signal.h>
#ifdef __cplusplus
extern "C" {
#endif
/* [C11/7.13] Non-local jumps */
typedef struct __jmp_buf {
struct __mlibc_jmpbuf_register_state __reg_state;
} jmp_buf[1];
#ifndef __MLIBC_ABI_ONLY
__attribute__((__returns_twice__)) int setjmp(jmp_buf __buffer);
__attribute__((__noreturn__)) void longjmp(jmp_buf __buffer, int __value);
/* setjmp is defined as a function macro in the ISO C standard */
#define setjmp(env) setjmp(env)
#if __MLIBC_POSIX_OPTION
__attribute__((__returns_twice__)) int _setjmp(jmp_buf __buffer);
/* POSIX-2017.1 says _longjmp shall be declared as a function */
__attribute__((__noreturn__)) void _longjmp(jmp_buf __buffer, int __value);
#endif /* __MLIBC_POSIX_OPTION */
#endif /* !__MLIBC_ABI_ONLY */
/* POSIX Non-local jumps signal extensions */
typedef struct __sigjmp_buf {
struct __mlibc_jmpbuf_register_state __reg_state;
int __savesigs;
sigset_t __sigset;
} sigjmp_buf[1];
#ifndef __MLIBC_ABI_ONLY
#if __MLIBC_POSIX_OPTION
__attribute__((__returns_twice__)) int sigsetjmp(sigjmp_buf __buffer, int __savesigs);
__attribute__((__noreturn__)) void siglongjmp(sigjmp_buf __buffer, int __value);
#endif /* __MLIBC_POSIX_OPTION */
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _SETJMP_H */
@@ -0,0 +1,48 @@
#ifndef _SIGNAL_H
#define _SIGNAL_H
#include <abi-bits/signal.h>
#include <mlibc-config.h>
#ifdef __cplusplus
extern "C" {
#endif
/* [7.14] Signal handling basics */
typedef int sig_atomic_t;
#define CLD_EXITED 1
#define CLD_KILLED 2
#define CLD_DUMPED 3
#define CLD_TRAPPED 4
#define CLD_STOPPED 5
#define CLD_CONTINUED 6
#ifndef __MLIBC_ABI_ONLY
/* [7.14.1] signal() function */
__sighandler signal(int __sig, __sighandler __handler);
/* [7.14.2] raise() function */
int raise(int __sig);
#endif /* !__MLIBC_ABI_ONLY */
#define _NSIG NSIG
#ifdef __cplusplus
}
#endif
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_signal.h>
#endif
#if __MLIBC_GLIBC_OPTION
# include <bits/glibc/glibc_signal.h>
#endif
#endif /* _SIGNAL_H */
@@ -0,0 +1,6 @@
#ifndef _STDC_PREDEF_H
#define _STDC_PREDEF_H
#define __STDC_ISO_10646__ 201206L
#endif /* _STDC_PREDEF_H */
@@ -0,0 +1,231 @@
#ifndef _STDIO_H
#define _STDIO_H
#include <abi-bits/seek-whence.h>
#include <bits/null.h>
#include <bits/file.h>
#include <bits/size_t.h>
#include <mlibc-config.h>
/* Glibc extensions require ssize_t. */
#include <bits/ssize_t.h>
#include <bits/off_t.h>
#ifdef __cplusplus
extern "C" {
#endif
/* [C11-7.21.1] I/O related types */
#define __MLIBC_EOF_BIT 1
#define __MLIBC_ERROR_BIT 2
struct __mlibc_file_base {
/* Buffer for I/O operations. */
/* We reserve a few extra bytes for ungetc operations. This means */
/* that __buffer_ptr will point a few bytes *into* the allocation. */
char *__buffer_ptr;
/* Number of bytes the buffer can hold. */
size_t __buffer_size;
/* Current offset inside the buffer. */
size_t __offset;
/* Position inside the buffer that matches the current file pointer. */
size_t __io_offset;
/* Valid region of the buffer. */
size_t __valid_limit;
/* Begin and end of the dirty region inside the buffer. */
size_t __dirty_begin;
size_t __dirty_end;
/* This points to the same place as __buffer_ptr, or a few bytes earlier */
/* if there are bytes pushed by ungetc. If buffering is disabled, calls */
/* to ungetc will trigger an allocation. */
char *__unget_ptr;
/* 0 if we are currently reading from the buffer. */
/* 1 if we are currently writing to the buffer. */
/* This is only really important for pipe-like streams. */
int __io_mode;
/* EOF and error bits. */
int __status_bits;
};
typedef off_t fpos_t;
/* [C11-7.21.1] I/O related macros */
#define _IOFBF 1
#define _IOLBF 2
#define _IONBF 3
#define BUFSIZ 512
#define EOF (-1)
#define FOPEN_MAX 1024
#define FILENAME_MAX 256
#define L_tmpnam 256
#define TMP_MAX 1024
#ifndef __MLIBC_ABI_ONLY
extern FILE *stderr;
extern FILE *stdin;
extern FILE *stdout;
/* [C11-7.21.4] Operations on files */
int remove(const char *__filename);
int rename(const char *__old_path, const char *__new_path);
int renameat(int __olddirfd, const char *__old_path, int __newdirfd, const char *__new_path);
FILE *tmpfile(void);
char *tmpnam(char *__buffer);
/* [C11-7.21.5] File access functions */
int fclose(FILE *__stream);
int fflush(FILE *__stream);
FILE *fopen(const char *__restrict __filename, const char *__restrict __mode);
FILE *freopen(const char *__restrict __filename, const char *__restrict __mode, FILE *__restrict __stream);
void setbuf(FILE *__restrict __stream, char *__restrict __buffer);
int setvbuf(FILE *__restrict __stream, char *__restrict __buffer, int __mode, size_t __size);
void setlinebuf(FILE *__stream);
void setbuffer(FILE *__stream, char *__buffer, size_t __size);
/* [C11-7.21.6] Formatted input/output functions */
__attribute__((__format__(__printf__, 2, 3)))
int fprintf(FILE *__restrict __stream, const char *__restrict __format, ...);
__attribute__((__format__(__scanf__, 2, 3)))
int fscanf(FILE *__restrict __stream, const char *__restrict __format, ...);
__attribute__((__format__(__printf__, 1, 2)))
int printf(const char *__restrict __format, ...);
__attribute__((__format__(__scanf__, 1, 2)))
int scanf(const char *__restrict __format, ...);
__attribute__((__format__(__printf__, 3, 4)))
int snprintf(char *__restrict __buffer, size_t __max_size, const char *__restrict __format, ...);
__attribute__((__format__(__printf__, 2, 3)))
int sprintf(char *__restrict __buffer, const char *__restrict __format, ...);
__attribute__((__format__(__scanf__, 2, 3)))
int sscanf(const char *__restrict __buffer, const char *__restrict __format, ...);
__attribute__((__format__(__printf__, 2, 0)))
int vfprintf(FILE *__restrict __stream, const char *__restrict __format, __builtin_va_list __args);
__attribute__((__format__(__scanf__, 2, 0)))
int vfscanf(FILE *__restrict __stream, const char *__restrict __format, __builtin_va_list __args);
__attribute__((__format__(__printf__, 1, 0)))
int vprintf(const char *__restrict __format, __builtin_va_list __args);
__attribute__((__format__(__scanf__, 1, 0)))
int vscanf(const char *__restrict __format, __builtin_va_list __args);
__attribute__((__format__(__printf__, 3, 0)))
int vsnprintf(char *__restrict __buffer, size_t __max_size,
const char *__restrict __format, __builtin_va_list __args);
__attribute__((__format__(__printf__, 2, 0)))
int vsprintf(char *__restrict __buffer, const char *__restrict __format, __builtin_va_list __args);
__attribute__((__format__(__scanf__, 2, 0)))
int vsscanf(const char *__restrict __buffer, const char *__restrict __format, __builtin_va_list __args);
/* this is a gnu extension */
__attribute__((__format__(__printf__, 2, 0)))
int vasprintf(char **__buffer, const char *__format, __builtin_va_list __args);
/* [C11-7.21.7] Character input/output functions */
int fgetc(FILE *__stream);
char *fgets(char *__restrict __buffer, int __max_size, FILE *__restrict __stream);
int fputc(int __c, FILE *__stream);
int fputs(const char *__restrict __string, FILE *__restrict __stream);
char *gets(char *__s);
int getc(FILE *__stream);
int getchar(void);
int putc(int __c, FILE *__stream);
int putchar(int __c);
int puts(const char *__string);
int ungetc(int __c, FILE *__stream);
/* [C11-7.21.8] Direct input/output functions */
size_t fread(void *__restrict __buffer, size_t __size, size_t __count, FILE *__restrict __stream);
size_t fwrite(const void *__restrict __buffer, size_t __size, size_t __count, FILE *__restrict __stream);
/* [C11-7.21.9] File positioning functions */
int fgetpos(FILE *__restrict __stream, fpos_t *__restrict __position);
int fseek(FILE *__stream, long __offset, int __whence);
int fsetpos(FILE *__stream, const fpos_t *__position);
long ftell(FILE *__stream);
void rewind(FILE *__stream);
/* [C11-7.21.10] Error handling functions */
void clearerr(FILE *__stream);
int feof(FILE *__stream);
int ferror(FILE *__stream);
void perror(const char *__string);
/* POSIX unlocked I/O extensions. */
int getc_unlocked(FILE *__stream);
int getchar_unlocked(void);
int putc_unlocked(int __c, FILE *__stream);
int putchar_unlocked(int __c);
/* GLIBC extensions. */
ssize_t getline(char **__linep, size_t *__sizep, FILE *__stream);
ssize_t getdelim(char **__linep, size_t *__sizep, int __delim, FILE *__stream);
__attribute__((__format__(__printf__, 2, 3)))
int asprintf(char **__buffer, const char *__format, ...);
/* Linux unlocked I/O extensions. */
void flockfile(FILE *__stream);
void funlockfile(FILE *__stream);
int ftrylockfile(FILE *__stream);
void clearerr_unlocked(FILE *__stream);
int feof_unlocked(FILE *__stream);
int ferror_unlocked(FILE *__stream);
int fileno_unlocked(FILE *__stream);
int fflush_unlocked(FILE *__stream);
int fgetc_unlocked(FILE *__stream);
int fputc_unlocked(int __c, FILE *__stream);
size_t fread_unlocked(void *__restrict __buffer, size_t __size, size_t __count, FILE *__restrict __stream);
size_t fwrite_unlocked(const void *__restrict __buffer, size_t __size, size_t __count, FILE *__restrict __stream);
char *fgets_unlocked(char *__restrict __buffer, int __size, FILE *__restrict __stream);
int fputs_unlocked(const char *__restrict __buffer, FILE *__restrict __stream);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_stdio.h>
#endif
#endif /* _STDIO_H */
@@ -0,0 +1,131 @@
#ifndef _STDLIB_H
#define _STDLIB_H
#include <alloca.h>
#include <mlibc-config.h>
#include <abi-bits/wait.h>
#include <bits/null.h>
#include <bits/size_t.h>
#include <bits/wchar_t.h>
#ifdef __cplusplus
extern "C" {
#endif
/* [7.22] General utilities */
typedef struct {
int quot, rem;
} div_t;
typedef struct {
long quot, rem;
} ldiv_t;
typedef struct {
long long quot, rem;
} lldiv_t;
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#define RAND_MAX 0x7FFFFFFF
/* TODO: this should not be a compile-time constant */
#define MB_CUR_MAX ((size_t)4)
#ifndef __MLIBC_ABI_ONLY
/* [7.22.1] Numeric conversion functions */
double atof(const char *__string);
int atoi(const char *__string);
long atol(const char *__string);
long long atoll(const char *__string);
double strtod(const char *__restrict __string, char **__restrict __end);
float strtof(const char *__restrict __string, char **__restrict __end);
long double strtold(const char *__restrict __string, char **__restrict __end);
long strtol(const char *__restrict __string, char **__restrict __end, int __base);
long long strtoll(const char *__restrict __string, char **__restrict __end, int __base);
unsigned long strtoul(const char *__restrict __string, char **__restrict __end, int __base);
unsigned long long strtoull(const char *__restrict __string, char **__restrict __end, int __base);
/* [7.22.2] Pseudo-random sequence generation functions */
int rand(void);
int rand_r(unsigned *__seed);
void srand(unsigned int __seed);
/* [7.22.3] Memory management functions */
void *aligned_alloc(size_t __alignment, size_t __size);
void *calloc(size_t __count, size_t __size);
void free(void *__pointer);
void *malloc(size_t __size);
void *realloc(void *__pointer, size_t __size);
int posix_memalign(void **__out, size_t __alignment, size_t __size);
/* [7.22.4] Communication with the environment */
__attribute__((__noreturn__)) void abort(void);
int atexit(void (*__func)(void));
int at_quick_exit(void (*__func)(void));
__attribute__((__noreturn__)) void exit(int __status);
__attribute__((__noreturn__)) void _Exit(int __status);
char *getenv(const char *__name);
__attribute__((__noreturn__)) void quick_exit(int __status);
int system(const char *__string);
/* GLIBC extension. */
char *mktemp(char *__pattern);
/* [7.22.5] Searching and sorting utilities */
void *bsearch(const void *__key, const void *__base, size_t __count, size_t __size,
int (*__compare)(const void *__a, const void *__b));
void qsort(void *__base, size_t __count, size_t __size,
int (*__compare)(const void *__a, const void *__b));
void qsort_r(void *__base, size_t __nmemb, size_t __size,
int (*__compar)(const void *__a, const void *__b, void *__arg),
void *__arg);
/* [7.22.6] Integer arithmetic functions */
int abs(int __number);
long labs(long __number);
long long llabs(long long __number);
div_t div(int __number, int __denom);
ldiv_t ldiv(long __number, long __denom);
lldiv_t lldiv(long long __number, long long __denom);
/* [7.22.7] Multibyte character conversion functions */
int mblen(const char *__mbs, size_t __limit);
int mbtowc(wchar_t *__restrict __wc, const char *__restrict __mb_chr, size_t __max_size);
int wctomb(char *__mb_chr, wchar_t __wc);
/* [7.22.8] Multibyte string conversion functions */
size_t mbstowcs(wchar_t *__restrict __wc_string, const char *__restrict __mb_string, size_t __max_size);
size_t wcstombs(char *__restrict __mb_string, const wchar_t *__restrict __wc_string, size_t __max_size);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#if __MLIBC_BSD_OPTION
# include <bits/bsd/bsd_stdlib.h>
#endif
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_stdlib.h>
#endif
#if __MLIBC_GLIBC_OPTION
# include <bits/glibc/glibc_stdlib.h>
#endif
#endif /* _STDLIB_H */
@@ -0,0 +1,112 @@
#ifndef _STRING_H
#define _STRING_H
#include <mlibc-config.h>
#include <bits/null.h>
#include <bits/size_t.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
/* [7.24.2] Copying functions */
void *memcpy(void *__restrict __dest, const void *__restrict __src, size_t __size);
void *memmove(void *__dest, const void *__src, size_t __size);
char *strcpy(char *__restrict __dest, const char *src);
char *strncpy(char *__restrict __dest, const char *__src, size_t __max_size);
/* [7.24.3] Concatenation functions */
char *strcat(char *__restrict __dest, const char *__restrict __src);
char *strncat(char *__restrict __dest, const char *__restrict __src, size_t __max_size);
/* [7.24.4] Comparison functions */
int memcmp(const void *__a, const void *__b, size_t __size);
int strcmp(const char *__a, const char *__b);
int strcoll(const char *__a, const char *__b);
int strncmp(const char *__a, const char *__b, size_t __max_size);
size_t strxfrm(char *__restrict __dest, const char *__restrict __src, size_t __max_size);
/* [7.24.5] Search functions */
void *memchr(const void *__s, int __c, size_t __size);
char *strchr(const char *__s, int __c);
size_t strcspn(const char *__s, const char *__chrs);
char *strpbrk(const char *__s, const char *__chrs);
char *strrchr(const char *__s, int __c);
size_t strspn(const char *__s, const char *__chrs);
char *strstr(const char *__pattern, const char *__s);
char *strtok(char *__restrict __s, const char *__restrict __delimiter);
/* This is a GNU extension. */
char *strchrnul(const char * __s, int __c);
/* [7.24.6] Miscellaneous functions */
void *memset(void *__dest, int __c, size_t __size);
char *strerror(int __errnum);
size_t strlen(const char *__s);
#endif /* !__MLIBC_ABI_ONLY */
#if __MLIBC_POSIX_OPTION && defined(_DEFAULT_SOURCE)
#include <strings.h>
#endif
#ifndef __MLIBC_ABI_ONLY
/* POSIX extensions. */
#if defined(_GNU_SOURCE)
char *strerror_r(int __errnum, char *__buffer, size_t __size) __asm__("__gnu_strerror_r");
#else
int strerror_r(int __errnum, char *__buffer, size_t __size);
#endif
void *mempcpy(void *__dest, const void *__src, size_t __size);
/* GNU extensions. */
int strverscmp(const char *__l0, const char *__r0);
int ffsl(long __i);
int ffsll(long long __i);
void *memmem(const void *__haystack, size_t __haystacklen, const void *__needle, size_t __needlelen);
/* Handling the basename mess:
* If <libgen.h> is included *at all*, we use the XPG-defined basename
* implementation, otherwise, we use the GNU one. Since our ABI previously
* provided the XPG one under basename, we'll have to diverge from GNU here and
* provide __mlibc_gnu_basename instead.
*/
#if __MLIBC_GLIBC_OPTION && defined(_GNU_SOURCE) && !defined(basename)
char *__mlibc_gnu_basename_c(const char *__path);
# ifdef __cplusplus
extern "C++" {
static inline const char *__mlibc_gnu_basename(const char *__path) {
return __mlibc_gnu_basename_c(__path);
}
static inline char *__mlibc_gnu_basename(char *__path) {
return __mlibc_gnu_basename_c(__path);
}
}
# else
# define __mlibc_gnu_basename __mlibc_gnu_basename_c
# endif
#define basename __mlibc_gnu_basename
#endif
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_string.h>
#endif
#endif /* _STRING_H */
@@ -0,0 +1,61 @@
#ifndef _THREADS_H
#define _THREADS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <bits/threads.h>
enum {
mtx_plain,
mtx_recursive,
mtx_timed
};
enum {
thrd_success,
thrd_timedout,
thrd_busy,
thrd_error,
thrd_nomem
};
typedef struct __mlibc_thread_data *thrd_t;
typedef struct __mlibc_mutex mtx_t;
typedef struct __mlibc_cond cnd_t;
#ifndef __cplusplus
#define thread_local _Thread_local
#endif
typedef int (*thrd_start_t)(void* __arg);
#ifndef __MLIBC_ABI_ONLY
int thrd_create(thrd_t *__thr, thrd_start_t __func, void *__arg);
int thrd_equal(thrd_t __lhs, thrd_t __rhs);
thrd_t thrd_current(void);
int thrd_sleep(const struct timespec *__duration, struct timespec *__remaining);
void thrd_yield(void);
int thrd_detach(thrd_t __thr);
int thrd_join(thrd_t __thr, int *__res);
__attribute__((__noreturn__)) void thrd_exit(int __res);
int mtx_init(mtx_t *__mtx, int __type);
void mtx_destroy(mtx_t *__mtx);
int mtx_lock(mtx_t *__mtx);
int mtx_unlock(mtx_t *__mtx);
int cnd_init(cnd_t *__cond);
void cnd_destroy(cnd_t *__cond);
int cnd_broadcast(cnd_t *__cond);
int cnd_wait(cnd_t *__cond, mtx_t *__mtx);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _THREADS_H */
@@ -0,0 +1,142 @@
#ifndef _TIME_H
#define _TIME_H
#include <bits/null.h>
#include <bits/size_t.h>
#include <bits/ansi/time_t.h>
#include <bits/ansi/timespec.h>
#include <mlibc-config.h>
/* [7.27.1] Components of time */
#define CLOCKS_PER_SEC ((clock_t)1000000)
#define TIME_UTC 1
/* POSIX extensions. */
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
#define CLOCK_MONOTONIC_RAW 4
#define CLOCK_REALTIME_COARSE 5
#define CLOCK_MONOTONIC_COARSE 6
#define CLOCK_BOOTTIME 7
#define CLOCK_REALTIME_ALARM 8
#define CLOCK_BOOTTIME_ALARM 9
#define CLOCK_TAI 11
#ifdef __cplusplus
extern "C" {
#endif
/* [7.27.1] Components of time */
typedef long clock_t; /* Matches Linux' ABI. */
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
long int tm_gmtoff;
const char *tm_zone;
};
#ifndef __MLIBC_ABI_ONLY
/* [7.27.2] Time manipulation functions */
clock_t clock(void);
double difftime(time_t __a, time_t __b);
time_t mktime(struct tm *__ptr);
time_t time(time_t *__timer);
int timespec_get(struct timespec *__ptr, int __base);
/* [7.27.3] Time conversion functions */
char *asctime(const struct tm *__ptr);
char *ctime(const time_t *__timer);
struct tm *gmtime(const time_t *__timer);
struct tm *gmtime_r(const time_t *__restrict __timer, struct tm *__restrict __result);
struct tm *localtime(const time_t *__timer);
size_t strftime(char *__restrict __dest, size_t __max_size,
const char *__restrict __format, const struct tm *__restrict __ptr);
void tzset(void);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
/* POSIX extensions. */
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_time.h>
# include <bits/posix/timer_t.h>
#endif /* __MLIBC_POSIX_OPTION */
#include <abi-bits/clockid_t.h>
#define TIMER_ABSTIME 1
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
extern int daylight;
extern long timezone;
extern char *tzname[2];
int nanosleep(const struct timespec *__req, struct timespec *__rem);
int clock_getres(clockid_t __clockid, struct timespec *__res);
int clock_gettime(clockid_t __clockid, struct timespec *__res);
int clock_nanosleep(clockid_t __clockid, int __flags, const struct timespec *__req, struct timespec *__rem);
int clock_settime(clockid_t __clockid, const struct timespec *__time);
struct tm *localtime_r(const time_t *__timer, struct tm *__buf);
char *asctime_r(const struct tm *__tm, char *__buf);
char *ctime_r(const time_t *__timer, char *__buf);
#if __MLIBC_POSIX_OPTION
#include <abi-bits/pid_t.h>
char *strptime(const char *__restrict __buf, const char *__restrict __format,
struct tm *__restrict __tm);
int clock_getcpuclockid(pid_t __pid, clockid_t *__clockid);
#endif /* __MLIBC_POSIX_OPTION */
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
/* GNU extensions. */
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
time_t timelocal(struct tm *__tm);
time_t timegm(struct tm *__tm);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _TIME_H */
@@ -0,0 +1,28 @@
#ifndef _UCHAR_H
#define _UCHAR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <bits/mbstate.h>
#include <bits/size_t.h>
/* These are builtin types since C++11. */
#if !defined(__cplusplus) || __cplusplus < 201100L
typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;
#endif
#ifndef __MLIBC_ABI_ONLY
size_t c32rtomb(char *__restrict __s, char32_t __c32, mbstate_t *__restrict __ps);
size_t mbrtoc32(char32_t *__restrict __pc32, const char *__restrict __pmb, size_t __max, mbstate_t *__restrict __ps);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _UCHAR_H */
@@ -0,0 +1,128 @@
#ifndef _WCHAR_H
#define _WCHAR_H
#include <bits/null.h>
#include <bits/size_t.h>
#include <bits/wchar_t.h>
#include <bits/wchar.h>
#include <bits/wint_t.h>
#include <bits/mbstate.h>
#include <bits/file.h>
#define WEOF 0xffffffffU
#ifdef __cplusplus
extern "C" {
#endif
/* MISSING: struct tm */
#ifndef __MLIBC_ABI_ONLY
/* [7.28.2] Wide formatted I/O functions */
int fwprintf(FILE *__restrict __stream, const wchar_t *__restrict __format, ...);
int fwscanf(FILE *__restrict __stream, const wchar_t *__restrict __format, ...);
int vfwprintf(FILE *__restrict __stream, const wchar_t *__restrict __format, __builtin_va_list __args);
int vfwscanf(FILE *__restrict __stream, const wchar_t *__restrict __format, __builtin_va_list __args);
int swprintf(wchar_t *__restrict __buffer, size_t __max_size, const wchar_t *__restrict __format, ...);
int swscanf(wchar_t *__restrict __buffer, const wchar_t *__restrict __format, ...);
int vswprintf(wchar_t *__restrict __buffer, size_t __max_size, const wchar_t *__restrict __format, __builtin_va_list __args);
int vswscanf(wchar_t *__restrict __buffer, const wchar_t *__restrict __format, __builtin_va_list __args);
int wprintf(const wchar_t *__restrict __format, ...);
int wscanf(const wchar_t *__restrict __format, ...);
int vwprintf(const wchar_t *__restrict __format, __builtin_va_list __args);
int vwscanf(const wchar_t *__restrict __format, __builtin_va_list __args);
/* [7.28.3] Wide character I/O functions */
wint_t fgetwc(FILE *__stream);
wchar_t *fgetws(wchar_t *__restrict __buffer, int __size, FILE *__restrict __stream);
wint_t fputwc(wchar_t __wc, FILE *__stream);
int fputws(const wchar_t *__restrict __buffer, FILE *__restrict __stream);
int fwide(FILE *__stream, int __mode);
wint_t getwc(FILE *__stream);
wint_t getwchar(void);
wint_t putwc(wchar_t __wc, FILE *__stream);
wint_t putwchar(wchar_t __wc);
wint_t ungetwc(wint_t __wc, FILE *__stream);
/* [7.28.4] Wide string functions */
double wcstod(const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr);
float wcstof(const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr);
long double wcstold(const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr);
long wcstol(const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base);
long long wcstoll(const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base);
unsigned long wcstoul(const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base);
unsigned long long wcstoull(const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base);
wchar_t *wcscpy(wchar_t *__restrict __dest, const wchar_t *__restrict __src);
wchar_t *wcsncpy(wchar_t *__restrict __dest, const wchar_t *__restrict __src, size_t __size);
wchar_t *wmemcpy(wchar_t *__restrict __dest, const wchar_t *__restrict __src, size_t __size);
wchar_t *wmemmove(wchar_t *__dest, const wchar_t *__src, size_t __size);
wchar_t *wcscat(wchar_t *__restrict __dest, const wchar_t *__restrict __src);
wchar_t *wcsncat(wchar_t *__restrict __dest, const wchar_t *__restrict __src, size_t __size);
int wcscmp(const wchar_t *__a, const wchar_t *__b);
int wcscoll(const wchar_t *__a, const wchar_t *__b);
int wcsncmp(const wchar_t *__a, const wchar_t *__b, size_t __size);
int wcsxfrm(wchar_t *__restrict __dest, const wchar_t *__restrict __src, size_t __size);
int wmemcmp(const wchar_t *__a, const wchar_t *__b, size_t __size);
wchar_t *wcschr(const wchar_t *__s, wchar_t __wc);
size_t wcscspn(const wchar_t *__dest, const wchar_t *__wchrs);
wchar_t *wcspbrk(const wchar_t *__s, const wchar_t *__wchrs);
wchar_t *wcsrchr(const wchar_t *__s, wchar_t __wc);
size_t wcsspn(const wchar_t *__s, const wchar_t *__wchrs);
wchar_t *wcsstr(const wchar_t *__s, const wchar_t *__b);
wchar_t *wcstok(wchar_t *__restrict __s, const wchar_t *__restrict __delimiter, wchar_t **__restrict __ptr);
wchar_t *wmemchr(const wchar_t *__s, wchar_t __wc, size_t __size);
size_t wcslen(const wchar_t *__s);
wchar_t *wmemset(wchar_t *__dest, wchar_t __wc, size_t __size);
/* [7.28.5] Wide date/time functions */
/* POSIX says:
* The tag tm is declared as naming an incomplete structure type, the contents of which are
* described in the header <time.h>. */
struct tm;
size_t wcsftime(wchar_t *__restrict __buffer, size_t __max_size, const wchar_t *__restrict __format,
const struct tm *__restrict __time);
/* [7.28.6] Wide conversion functions */
wint_t btowc(int __wc);
int wctob(wint_t __wc);
int mbsinit(const mbstate_t *__state);
size_t mbrlen(const char *__restrict __mbs, size_t __mbs_limit, mbstate_t *__restrict __stp);
size_t mbrtowc(wchar_t *__restrict __wcp, const char *__restrict __mbs, size_t __mbs_limit, mbstate_t *__restrict __stp);
size_t wcrtomb(char *__restrict __mbs, wchar_t __wc, mbstate_t *__restrict __stp);
size_t mbsrtowcs(wchar_t *__restrict __wcs, const char **__restrict __mbs, size_t __mb_limit, mbstate_t *__restrict __stp);
size_t mbsnrtowcs(wchar_t *__restrict __wcs, const char **__restrict __mbs, size_t __mb_limit, size_t __wc_limit,
mbstate_t *__restrict __stp);
size_t wcsrtombs(char *__restrict __mbs, const wchar_t **__restrict __wcs, size_t __mb_limit, mbstate_t *__restrict __stp);
size_t wcsnrtombs(char *__restrict __mbs, const wchar_t **__restrict __wcs, size_t __mb_limit, size_t __wc_limit,
mbstate_t *__restrict __stp);
/* POSIX extensions */
int wcwidth(wchar_t __wc);
int wcswidth(const wchar_t *__s, size_t __size);
wchar_t *wcsdup(const wchar_t *__s);
int wcsncasecmp(const wchar_t *__a, const wchar_t *__b, size_t __size);
int wcscasecmp(const wchar_t *__a, const wchar_t *__b);
size_t wcsnlen(const wchar_t *__s, size_t __maxlen);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _WCHAR_H */
@@ -0,0 +1,51 @@
#ifndef _WCTYPE_H
#define _WCTYPE_H
#include <mlibc-config.h>
#include <bits/wint_t.h>
#include <bits/wctype_t.h>
#include <bits/wctrans_t.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
/* [C11/7.30.2.2] Extensible wide character classification functions. */
int iswalnum(wint_t __wc);
int iswalpha(wint_t __wc);
int iswblank(wint_t __wc);
int iswcntrl(wint_t __wc);
int iswdigit(wint_t __wc);
int iswgraph(wint_t __wc);
int iswlower(wint_t __wc);
int iswprint(wint_t __wc);
int iswpunct(wint_t __wc);
int iswspace(wint_t __wc);
int iswupper(wint_t __wc);
int iswxdigit(wint_t __wc);
wctype_t wctype(const char *__string);
int iswctype(wint_t __wc, wctype_t __type);
/* [C11/7.30.3] Wide character case mapping utilities. */
wint_t towlower(wint_t __wc);
wint_t towupper(wint_t __wc);
wctrans_t wctrans(const char *__string);
wint_t towctrans(wint_t __wc, wctrans_t __trans);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#if __MLIBC_POSIX_OPTION
# include <bits/posix/posix_wctype.h>
#endif
#endif /* _WCTYPE_H */
+329
View File
@@ -0,0 +1,329 @@
ansi_sources = files(
'generic/stdlib.cpp',
'generic/assert.cpp',
'generic/complex.c',
'generic/complex/csqrt.c',
'generic/complex/csinhf.c',
'generic/complex/ccoshf.c',
'generic/complex/cacosh.c',
'generic/complex/casinf.c',
'generic/complex/clogf.c',
'generic/complex/csqrtf.c',
'generic/complex/cimag.c',
'generic/complex/catanh.c',
'generic/complex/carg.c',
'generic/complex/cproj.c',
'generic/complex/cephes_subr.c',
'generic/complex/ccos.c',
'generic/complex/cexp.c',
'generic/complex/crealf.c',
'generic/complex/cabs.c',
'generic/complex/csinh.c',
'generic/complex/casinhf.c',
'generic/complex/cephes_subrf.c',
'generic/complex/creal.c',
'generic/complex/casin.c',
'generic/complex/conjf.c',
'generic/complex/cpowf.c',
'generic/complex/cacosf.c',
'generic/complex/csinf.c',
'generic/complex/ctanh.c',
'generic/complex/ctanhf.c',
'generic/complex/cargf.c',
'generic/complex/cabsf.c',
'generic/complex/cpow.c',
'generic/complex/csin.c',
'generic/complex/cprojf.c',
'generic/complex/catan.c',
'generic/complex/ctanf.c',
'generic/complex/ctan.c',
'generic/complex/clog.c',
'generic/complex/catanf.c',
'generic/complex/cacos.c',
'generic/complex/cexpf.c',
'generic/complex/ccosh.c',
'generic/complex/cimagf.c',
'generic/complex/cacoshf.c',
'generic/complex/conj.c',
'generic/complex/catanhf.c',
'generic/complex/ccosf.c',
'generic/complex/casinh.c',
'generic/ctype.cpp',
'generic/environment.cpp',
'generic/errno.cpp',
'generic/fenv.cpp',
'generic/file-io.cpp',
'generic/inttypes.cpp',
'generic/locale.cpp',
'generic/signal.cpp',
'generic/stdio.cpp',
'generic/stdlib.cpp',
'generic/string.cpp',
'generic/threads.cpp',
'generic/time.cpp',
'generic/uchar.cpp',
'generic/wchar.cpp',
'generic/wctype.cpp',
)
if not no_headers
install_headers(
'include/alloca.h',
'include/assert.h',
'include/complex.h',
'include/ctype.h',
'include/errno.h',
'include/fenv.h',
'include/inttypes.h',
'include/limits.h',
'include/locale.h',
'include/math.h',
'include/setjmp.h',
'include/signal.h',
'include/stdc-predef.h',
'include/stdio.h',
'include/stdlib.h',
'include/string.h',
'include/threads.h',
'include/time.h',
'include/uchar.h',
'include/wchar.h',
'include/wctype.h',
)
install_headers(
'include/bits/ansi/timespec.h',
'include/bits/ansi/time_t.h',
'include/bits/ansi/fenv.h',
subdir: 'bits/ansi'
)
endif
if not headers_only
c_compiler = meson.get_compiler('c')
if c_compiler.get_id() == 'gcc'
compiler_c_args = ['-Wno-unused', '-Wno-maybe-uninitialized']
elif c_compiler.get_id() == 'clang'
compiler_c_args = ['-Wno-unused-parameter', '-Wno-unused-but-set-variable']
endif
libc_sublibs += static_library('mlibc-musl-math',
'musl-generic-math/acos.c',
'musl-generic-math/acosf.c',
'musl-generic-math/acosh.c',
'musl-generic-math/acoshf.c',
'musl-generic-math/acoshl.c',
'musl-generic-math/acosl.c',
'musl-generic-math/asin.c',
'musl-generic-math/asinf.c',
'musl-generic-math/asinh.c',
'musl-generic-math/asinhf.c',
'musl-generic-math/asinhl.c',
'musl-generic-math/asinl.c',
'musl-generic-math/atan2.c',
'musl-generic-math/atan2f.c',
'musl-generic-math/atan2l.c',
'musl-generic-math/atan.c',
'musl-generic-math/atanf.c',
'musl-generic-math/atanh.c',
'musl-generic-math/atanhf.c',
'musl-generic-math/atanhl.c',
'musl-generic-math/atanl.c',
'musl-generic-math/cbrt.c',
'musl-generic-math/cbrtf.c',
'musl-generic-math/cbrtl.c',
'musl-generic-math/ceil.c',
'musl-generic-math/ceilf.c',
'musl-generic-math/ceill.c',
'musl-generic-math/copysign.c',
'musl-generic-math/copysignf.c',
'musl-generic-math/copysignl.c',
'musl-generic-math/__cos.c',
'musl-generic-math/cos.c',
'musl-generic-math/__cosdf.c',
'musl-generic-math/cosf.c',
'musl-generic-math/cosh.c',
'musl-generic-math/coshf.c',
'musl-generic-math/coshl.c',
'musl-generic-math/__cosl.c',
'musl-generic-math/cosl.c',
'musl-generic-math/erf.c',
'musl-generic-math/erff.c',
'musl-generic-math/erfl.c',
'musl-generic-math/exp10.c',
'musl-generic-math/exp10f.c',
'musl-generic-math/exp10l.c',
'musl-generic-math/exp2.c',
'musl-generic-math/exp2f.c',
'musl-generic-math/exp2l.c',
'musl-generic-math/exp.c',
'musl-generic-math/expf.c',
'musl-generic-math/expl.c',
'musl-generic-math/expm1.c',
'musl-generic-math/expm1f.c',
'musl-generic-math/expm1l.c',
'musl-generic-math/__expo2.c',
'musl-generic-math/__expo2f.c',
'musl-generic-math/fabs.c',
'musl-generic-math/fabsf.c',
'musl-generic-math/fabsl.c',
'musl-generic-math/fdim.c',
'musl-generic-math/fdimf.c',
'musl-generic-math/fdiml.c',
'musl-generic-math/finite.c',
'musl-generic-math/finitef.c',
'musl-generic-math/floor.c',
'musl-generic-math/floorf.c',
'musl-generic-math/floorl.c',
'musl-generic-math/fma.c',
'musl-generic-math/fmaf.c',
'musl-generic-math/fmal.c',
'musl-generic-math/fmax.c',
'musl-generic-math/fmaxf.c',
'musl-generic-math/fmaxl.c',
'musl-generic-math/fmin.c',
'musl-generic-math/fminf.c',
'musl-generic-math/fminl.c',
'musl-generic-math/fmod.c',
'musl-generic-math/fmodf.c',
'musl-generic-math/fmodl.c',
'musl-generic-math/__fpclassify.c',
'musl-generic-math/__fpclassifyf.c',
'musl-generic-math/__fpclassifyl.c',
'musl-generic-math/frexp.c',
'musl-generic-math/frexpf.c',
'musl-generic-math/frexpl.c',
'musl-generic-math/hypot.c',
'musl-generic-math/hypotf.c',
'musl-generic-math/hypotl.c',
'musl-generic-math/ilogb.c',
'musl-generic-math/ilogbf.c',
'musl-generic-math/ilogbl.c',
'musl-generic-math/__invtrigl.c',
'musl-generic-math/j0.c',
'musl-generic-math/j0f.c',
'musl-generic-math/j1.c',
'musl-generic-math/j1f.c',
'musl-generic-math/jn.c',
'musl-generic-math/jnf.c',
'musl-generic-math/ldexp.c',
'musl-generic-math/ldexpf.c',
'musl-generic-math/ldexpl.c',
'musl-generic-math/lgamma.c',
'musl-generic-math/lgammaf.c',
'musl-generic-math/lgammaf_r.c',
'musl-generic-math/lgammal.c',
'musl-generic-math/lgamma_r.c',
'musl-generic-math/llrint.c',
'musl-generic-math/llrintf.c',
'musl-generic-math/llrintl.c',
'musl-generic-math/llround.c',
'musl-generic-math/llroundf.c',
'musl-generic-math/llroundl.c',
'musl-generic-math/log10.c',
'musl-generic-math/log10f.c',
'musl-generic-math/log10l.c',
'musl-generic-math/log1p.c',
'musl-generic-math/log1pf.c',
'musl-generic-math/log1pl.c',
'musl-generic-math/log2.c',
'musl-generic-math/log2f.c',
'musl-generic-math/log2l.c',
'musl-generic-math/logb.c',
'musl-generic-math/logbf.c',
'musl-generic-math/logbl.c',
'musl-generic-math/log.c',
'musl-generic-math/logf.c',
'musl-generic-math/logl.c',
'musl-generic-math/lrint.c',
'musl-generic-math/lrintf.c',
'musl-generic-math/lrintl.c',
'musl-generic-math/lround.c',
'musl-generic-math/lroundf.c',
'musl-generic-math/lroundl.c',
'musl-generic-math/modf.c',
'musl-generic-math/modff.c',
'musl-generic-math/modfl.c',
'musl-generic-math/nan.c',
'musl-generic-math/nanf.c',
'musl-generic-math/nanl.c',
'musl-generic-math/nearbyint.c',
'musl-generic-math/nearbyintf.c',
'musl-generic-math/nearbyintl.c',
'musl-generic-math/nextafter.c',
'musl-generic-math/nextafterf.c',
'musl-generic-math/nextafterl.c',
'musl-generic-math/nexttoward.c',
'musl-generic-math/nexttowardf.c',
'musl-generic-math/nexttowardl.c',
'musl-generic-math/__polevll.c',
'musl-generic-math/pow.c',
'musl-generic-math/powf.c',
'musl-generic-math/powl.c',
'musl-generic-math/remainder.c',
'musl-generic-math/remainderf.c',
'musl-generic-math/remainderl.c',
'musl-generic-math/__rem_pio2.c',
'musl-generic-math/__rem_pio2f.c',
'musl-generic-math/__rem_pio2_large.c',
'musl-generic-math/__rem_pio2l.c',
'musl-generic-math/remquo.c',
'musl-generic-math/remquof.c',
'musl-generic-math/remquol.c',
'musl-generic-math/rint.c',
'musl-generic-math/rintf.c',
'musl-generic-math/rintl.c',
'musl-generic-math/round.c',
'musl-generic-math/roundf.c',
'musl-generic-math/roundl.c',
'musl-generic-math/scalb.c',
'musl-generic-math/scalbf.c',
'musl-generic-math/scalbln.c',
'musl-generic-math/scalblnf.c',
'musl-generic-math/scalblnl.c',
'musl-generic-math/scalbn.c',
'musl-generic-math/scalbnf.c',
'musl-generic-math/scalbnl.c',
'musl-generic-math/__signbit.c',
'musl-generic-math/__signbitf.c',
'musl-generic-math/__signbitl.c',
'musl-generic-math/signgam.c',
'musl-generic-math/significand.c',
'musl-generic-math/significandf.c',
'musl-generic-math/__sin.c',
'musl-generic-math/sin.c',
'musl-generic-math/sincos.c',
'musl-generic-math/sincosf.c',
'musl-generic-math/sincosl.c',
'musl-generic-math/__sindf.c',
'musl-generic-math/sinf.c',
'musl-generic-math/sinh.c',
'musl-generic-math/sinhf.c',
'musl-generic-math/sinhl.c',
'musl-generic-math/__sinl.c',
'musl-generic-math/sinl.c',
'musl-generic-math/sqrt.c',
'musl-generic-math/sqrtf.c',
'musl-generic-math/sqrtl.c',
'musl-generic-math/__tan.c',
'musl-generic-math/tan.c',
'musl-generic-math/__tandf.c',
'musl-generic-math/tanf.c',
'musl-generic-math/tanh.c',
'musl-generic-math/tanhf.c',
'musl-generic-math/tanhl.c',
'musl-generic-math/__tanl.c',
'musl-generic-math/tanl.c',
'musl-generic-math/tgamma.c',
'musl-generic-math/tgammaf.c',
'musl-generic-math/tgammal.c',
'musl-generic-math/trunc.c',
'musl-generic-math/truncf.c',
'musl-generic-math/truncl.c',
pic: true,
include_directories: libc_include_dirs,
dependencies: libc_deps,
c_args: [compiler_c_args, '-Wno-implicit', '-Wno-parentheses', '-Wno-sign-compare', '-Wno-attributes', '-Wno-unknown-pragmas'])
endif
@@ -0,0 +1,71 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __cos( x, y )
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
*
* Algorithm
* 1. Since cos(-x) = cos(x), we need only to consider positive x.
* 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
* 3. cos(x) is approximated by a polynomial of degree 14 on
* [0,pi/4]
* 4 14
* cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
* where the remez error is
*
* | 2 4 6 8 10 12 14 | -58
* |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
* | |
*
* 4 6 8 10 12 14
* 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
* cos(x) ~ 1 - x*x/2 + r
* since cos(x+y) ~ cos(x) - sin(x)*y
* ~ cos(x) - x*y,
* a correction term is necessary in cos(x) and hence
* cos(x+y) = 1 - (x*x/2 - (r - x*y))
* For better accuracy, rearrange to
* cos(x+y) ~ w + (tmp + (r-x*y))
* where w = 1 - x*x/2 and tmp is a tiny correction term
* (1 - x*x/2 == w + tmp exactly in infinite precision).
* The exactness of w + tmp in infinite precision depends on w
* and tmp having the same precision as x. If they have extra
* precision due to compiler bugs, then the extra precision is
* only good provided it is retained in all terms of the final
* expression for cos(). Retention happens in all cases tested
* under FreeBSD, so don't pessimize things by forcibly clipping
* any extra precision in w.
*/
#include "libm.h"
static const double
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
double __cos(double x, double y)
{
double_t hz,z,r,w;
z = x*x;
w = z*z;
r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
hz = 0.5*z;
w = 1.0-hz;
return w + (((1.0-w)-hz) + (z*r-x*y));
}
@@ -0,0 +1,35 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Debugged and optimized by Bruce D. Evans.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
/* |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 */
float __cosdf(double x)
{
double_t 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;
}
@@ -0,0 +1,96 @@
/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */
/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
#if LDBL_MANT_DIG == 64
/*
* ld80 version of __cos.c. See __cos.c for most comments.
*/
/*
* Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:
* |cos(x) - c(x)| < 2**-75.1
*
* The coefficients of c(x) were generated by a pari-gp script using
* a Remez algorithm that searches for the best higher coefficients
* after rounding leading coefficients to a specified precision.
*
* Simpler methods like Chebyshev or basic Remez barely suffice for
* cos() in 64-bit precision, because we want the coefficient of x^2
* to be precisely -0.5 so that multiplying by it is exact, and plain
* rounding of the coefficients of a good polynomial approximation only
* gives this up to about 64-bit precision. Plain rounding also gives
* a mediocre approximation for the coefficient of x^4, but a rounding
* error of 0.5 ulps for this coefficient would only contribute ~0.01
* ulps to the final error, so this is unimportant. Rounding errors in
* higher coefficients are even less important.
*
* In fact, coefficients above the x^4 one only need to have 53-bit
* precision, and this is more efficient. We get this optimization
* almost for free from the complications needed to search for the best
* higher coefficients.
*/
static const long double
C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */
static const double
C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */
C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */
C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */
C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */
C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */
C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */
#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))
#elif LDBL_MANT_DIG == 113
/*
* ld128 version of __cos.c. See __cos.c for most comments.
*/
/*
* Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
* |cos(x) - c(x))| < 2**-122.0
*
* 113-bit precision requires more care than 64-bit precision, since
* simple methods give a minimax polynomial with coefficient for x^2
* that is 1 ulp below 0.5, but we want it to be precisely 0.5. See
* above for more details.
*/
static const long double
C1 = 0.04166666666666666666666666666666658424671L,
C2 = -0.001388888888888888888888888888863490893732L,
C3 = 0.00002480158730158730158730158600795304914210L,
C4 = -0.2755731922398589065255474947078934284324e-6L,
C5 = 0.2087675698786809897659225313136400793948e-8L,
C6 = -0.1147074559772972315817149986812031204775e-10L,
C7 = 0.4779477332386808976875457937252120293400e-13L;
static const double
C8 = -0.1561920696721507929516718307820958119868e-15,
C9 = 0.4110317413744594971475941557607804508039e-18,
C10 = -0.8896592467191938803288521958313920156409e-21,
C11 = 0.1601061435794535138244346256065192782581e-23;
#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \
z*(C8+z*(C9+z*(C10+z*C11)))))))))))
#endif
long double __cosl(long double x, long double y)
{
long double hz,z,r,w;
z = x*x;
r = POLY(z);
hz = 0.5*z;
w = 1.0-hz;
return w + (((1.0-w)-hz) + (z*r-x*y));
}
#endif
@@ -0,0 +1,16 @@
#include "libm.h"
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
static const int k = 2043;
static const double kln2 = 0x1.62066151add8bp+10;
/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
double __expo2(double x)
{
double scale;
/* note that k is odd and scale*scale overflows */
INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0);
/* exp(x - k ln2) * 2**(k-1) */
return exp(x - kln2) * scale * scale;
}
@@ -0,0 +1,16 @@
#include "libm.h"
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
static const int k = 235;
static const float kln2 = 0x1.45c778p+7f;
/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
float __expo2f(float x)
{
float scale;
/* note that k is odd and scale*scale overflows */
SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
/* exp(x - k ln2) * 2**(k-1) */
return expf(x - kln2) * scale * scale;
}

Some files were not shown because too many files have changed in this diff Show More