user: implement mlibc as the libc, finally.
It's finally done.. Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
@@ -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(¤t_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 */
|
||||
@@ -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
Reference in New Issue
Block a user