mirror of https://github.com/flysand7/ciabatta.git
Steal some math funcs
This commit is contained in:
parent
6f57efcaa9
commit
2320a22706
109
bake.cmd
109
bake.cmd
|
@ -1,54 +1,55 @@
|
||||||
@echo off
|
@echo off
|
||||||
setlocal enabledelayedexpansion
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
:: Make sure that if I ctrl+c out of the script the dir is popped
|
:: Make sure that if I ctrl+c out of the script the dir is popped
|
||||||
:: If there's anything that requires user input, this script will break
|
:: If there's anything that requires user input, this script will break
|
||||||
:: in that case I recommend you removing the 'echo y' part.
|
:: in that case I recommend you removing the 'echo y' part.
|
||||||
:: although you will have to confirm termination of the script twice
|
:: although you will have to confirm termination of the script twice
|
||||||
if "%~1" neq "_start_" (
|
if "%~1" neq "_start_" (
|
||||||
pushd %~pd0
|
pushd %~pd0
|
||||||
echo y | cmd /c "%~f0" _start_ %*
|
echo y | cmd /c "%~f0" _start_ %*
|
||||||
popd
|
popd
|
||||||
exit /b
|
exit /b
|
||||||
)
|
)
|
||||||
shift /1
|
shift /1
|
||||||
|
|
||||||
set CIABATTA_OPTIONS=-Iinc -Wall -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS
|
set CIABATTA_OPTIONS=-Iinc -Wall -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS
|
||||||
set PLATFORM=win
|
set PLATFORM=win
|
||||||
|
|
||||||
if "%1"=="test" (
|
if "%1"=="test" (
|
||||||
goto :skip_crt_compilation
|
goto :skip_crt_compilation
|
||||||
)
|
)
|
||||||
:: For each C file in code/ we check whether it's OS-dependent.
|
:: For each C file in code/ we check whether it's OS-dependent.
|
||||||
:: If so, we check whether the platform is the chosen one. If not, we ignore
|
:: If so, we check whether the platform is the chosen one. If not, we ignore
|
||||||
:: that file (set ok=0). Otherwise we compile it.
|
:: that file (set ok=0). Otherwise we compile it.
|
||||||
:: Man, batch files are sure scary, when you try to do something serious
|
:: Man, batch files are sure scary, when you try to do something serious
|
||||||
:: it took me a lot of time to figure out how to write this if it breaks
|
:: it took me a lot of time to figure out how to write this if it breaks
|
||||||
:: im gonna be seriously disappointed :kekw:
|
:: im gonna be seriously disappointed :kekw:
|
||||||
del ciabatta.lib 2> nul
|
del ciabatta.lib 2> nul
|
||||||
for /R code %%F in (*.c) do (
|
for /R code %%F in (*.c) do (
|
||||||
set ok=1
|
set ok=1
|
||||||
set os_dependent=0
|
set os_dependent=0
|
||||||
set is_cur_os=0
|
set is_cur_os=0
|
||||||
echo %%F | findstr /c:"%~pd0code\os" > nul
|
echo %%F | findstr /c:"%~pd0code\os" > nul
|
||||||
if !errorlevel! neq 1 (
|
if !errorlevel! neq 1 (
|
||||||
set os_dependent=1
|
set os_dependent=1
|
||||||
)
|
)
|
||||||
echo %%F | findstr /c:"%~pd0code\os\%PLATFORM%" > nul
|
echo %%F | findstr /c:"%~pd0code\os\%PLATFORM%" > nul
|
||||||
if !errorlevel! neq 1 (
|
if !errorlevel! neq 1 (
|
||||||
set is_cur_os=1
|
set is_cur_os=1
|
||||||
)
|
)
|
||||||
if "!os_dependent!"=="1" if "!is_cur_os!"=="0" (
|
if "!os_dependent!"=="1" if "!is_cur_os!"=="0" (
|
||||||
set ok=0
|
set ok=0
|
||||||
)
|
)
|
||||||
if "!ok!"=="1" (
|
if "!ok!"=="1" (
|
||||||
echo %%F
|
echo %%F
|
||||||
clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS%
|
clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS%
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
llvm-ar rc ciabatta.lib build\*.obj
|
llvm-ar rc ciabatta.lib build\*.obj
|
||||||
del build\*.obj
|
del build\*.obj
|
||||||
|
|
||||||
:skip_crt_compilation
|
:skip_crt_compilation
|
||||||
echo Compiling test..
|
echo Compiling test..
|
||||||
clang test\test6.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%
|
clang -fno-builtin test\test_math.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%
|
||||||
|
::cl test\test_math.c /Iinc -D_CRT_SECURE_NO_WARNINGS /Z7 /link ciabatta.lib kernel32.lib user32.lib shell32.lib -nostdlib -nodefaultlibs
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
@echo off
|
@echo off
|
||||||
setlocal enabledelayedexpansion
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
set PLATFORM=win
|
set PLATFORM=win
|
||||||
set CIABATTA_OPTIONS=--crt none -I %% -I inc
|
set CIABATTA_OPTIONS=--crt none -I %% -I inc
|
||||||
|
|
||||||
del ciabatta.lib
|
del ciabatta.lib
|
||||||
cuik %CIABATTA_OPTIONS% code\*.c code\os\%PLATFORM%\*.c -c -o ciabatta.obj
|
cuik %CIABATTA_OPTIONS% code\*.c code\os\%PLATFORM%\*.c -c -o ciabatta.obj
|
||||||
lib /out:ciabatta.lib ciabatta.obj
|
lib /out:ciabatta.lib ciabatta.obj
|
||||||
|
|
||||||
cuik test\test.c --lib ciabatta.lib,kernel32.lib,user32.lib,shell32.lib %CIABATTA_OPTIONS%
|
cuik test\test.c --lib ciabatta.lib,kernel32.lib,user32.lib,shell32.lib %CIABATTA_OPTIONS%
|
||||||
del ciabatta.obj
|
del ciabatta.obj
|
||||||
|
|
|
@ -0,0 +1,264 @@
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <fenv.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#include <_compiler.h>
|
||||||
|
#if defined(_compiler_clang) || defined(_compiler_gnu)
|
||||||
|
#define just_do_it(t) __attribute__((unused)) volatile t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int _fpclassify(double x) {
|
||||||
|
union {double f; uint64_t i;} u = {x};
|
||||||
|
int e = u.i>>52 & 0x7ff;
|
||||||
|
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||||
|
if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
|
||||||
|
return FP_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _fpclassifyf(float x) {
|
||||||
|
union {float f; uint32_t i;} u = {x};
|
||||||
|
int e = u.i>>23 & 0xff;
|
||||||
|
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||||
|
if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
|
||||||
|
return FP_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _fpclassifyl(long double x) {
|
||||||
|
return _fpclassify(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int _signbit(double x) {
|
||||||
|
union {
|
||||||
|
double d;
|
||||||
|
uint64_t i;
|
||||||
|
} y = { x };
|
||||||
|
return y.i>>63;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _signbitf(float x) {
|
||||||
|
union {
|
||||||
|
float f;
|
||||||
|
uint32_t i;
|
||||||
|
} y = { x };
|
||||||
|
return y.i>>31;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _signbitl(long double x) {
|
||||||
|
return _signbit(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
double copysign(double x, double y) {
|
||||||
|
union {double f; uint64_t i;} ux={x}, uy={y};
|
||||||
|
ux.i &= ~(1ULL<<63);
|
||||||
|
ux.i |= uy.i & (1ULL<<63);
|
||||||
|
return ux.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float copysignf(float x, float y) {
|
||||||
|
union {float f; uint32_t i;} ux={x}, uy={y};
|
||||||
|
ux.i &= 0x7fffffff;
|
||||||
|
ux.i |= uy.i & 0x80000000;
|
||||||
|
return ux.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double copysignl(long double x, long double y) {
|
||||||
|
return copysign(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
double nan(const char *s) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nanf(const char *s) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double nanl(const char *s) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double rint(double x) {
|
||||||
|
static const double_t toint = 1/DBL_EPSILON;
|
||||||
|
union {double f; uint64_t i;} u = {x};
|
||||||
|
int e = u.i>>52 & 0x7ff;
|
||||||
|
int s = u.i>>63;
|
||||||
|
double y;
|
||||||
|
if (e >= 0x3ff+52) return x;
|
||||||
|
if (s) y = x - toint + toint;
|
||||||
|
else y = x + toint - toint;
|
||||||
|
if (y == 0) return s ? -0.0 : +0.0;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rintf(float x) {
|
||||||
|
static const float toint = 1/FLT_EPSILON;
|
||||||
|
union {float f; uint32_t i;} u = {x};
|
||||||
|
int e = u.i>>23 & 0xff;
|
||||||
|
int s = u.i>>31;
|
||||||
|
float y;
|
||||||
|
if (e >= 0x7f+23) return x;
|
||||||
|
if (s) y = x - toint + toint;
|
||||||
|
else y = x + toint - toint;
|
||||||
|
if (y == 0) return s ? -0.0f : 0.0f;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double rintl(long double x) {
|
||||||
|
return rint(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double nearbyint(double x) {
|
||||||
|
#pragma STDC FENV_ACCESS ON
|
||||||
|
int e = fetestexcept(FE_INEXACT);
|
||||||
|
x = rint(x);
|
||||||
|
if (!e) feclearexcept(FE_INEXACT);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nearbyintf(float x) {
|
||||||
|
#pragma STDC FENV_ACCESS ON
|
||||||
|
int e = fetestexcept(FE_INEXACT);
|
||||||
|
x = rintf(x);
|
||||||
|
if (!e) feclearexcept(FE_INEXACT);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double nearbyintl(long double x) {
|
||||||
|
return nearbyint(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double nextafter(double x, double y) {
|
||||||
|
union {double f; uint64_t i;} ux={x}, uy={y};
|
||||||
|
uint64_t ax, ay;
|
||||||
|
int e;
|
||||||
|
if (isnan(x) || isnan(y)) return x + y;
|
||||||
|
if (ux.i == uy.i) return y;
|
||||||
|
ax = ux.i & -1ULL/2;
|
||||||
|
ay = uy.i & -1ULL/2;
|
||||||
|
if (ax == 0) {
|
||||||
|
if (ay == 0) return y;
|
||||||
|
ux.i = (uy.i & 1ULL<<63) | 1;
|
||||||
|
} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63)) {
|
||||||
|
ux.i--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ux.i++;
|
||||||
|
}
|
||||||
|
e = ux.i >> 52 & 0x7ff;
|
||||||
|
/* raise overflow if ux.f is infinite and x is finite */
|
||||||
|
if (e == 0x7ff) just_do_it(float) _x = x+x;
|
||||||
|
/* raise underflow if ux.f is subnormal or zero */
|
||||||
|
if (e == 0) just_do_it(float) _x = x*x + ux.f*ux.f;
|
||||||
|
return ux.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nextafterf(float x, float y) {
|
||||||
|
union {float f; uint32_t i;} ux={x}, uy={y};
|
||||||
|
uint32_t ax, ay, e;
|
||||||
|
|
||||||
|
if (isnan(x) || isnan(y)) return x + y;
|
||||||
|
if (ux.i == uy.i) return y;
|
||||||
|
ax = ux.i & 0x7fffffff;
|
||||||
|
ay = uy.i & 0x7fffffff;
|
||||||
|
if (ax == 0) {
|
||||||
|
if (ay == 0) return y;
|
||||||
|
ux.i = (uy.i & 0x80000000) | 1;
|
||||||
|
} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000)) {
|
||||||
|
ux.i--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ux.i++;
|
||||||
|
}
|
||||||
|
e = ux.i & 0x7f800000;
|
||||||
|
/* raise overflow if ux.f is infinite and x is finite */
|
||||||
|
if (e == 0x7f800000) just_do_it(float) _x = x+x;
|
||||||
|
/* raise underflow if ux.f is subnormal or zero */
|
||||||
|
if (e == 0) just_do_it(float) _x = x*x + ux.f*ux.f;
|
||||||
|
return ux.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double nextafterl(long double x, long double y) {
|
||||||
|
return nextafter(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
double nexttoward(double x, long double y) {
|
||||||
|
return nextafter(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float nexttowardf(float x, long double y) {
|
||||||
|
union {float f; uint32_t i;} ux = {x};
|
||||||
|
uint32_t e;
|
||||||
|
if (isnan(x) || isnan(y)) return x + y;
|
||||||
|
if (x == y) return y;
|
||||||
|
if (x == 0) {
|
||||||
|
ux.i = 1;
|
||||||
|
if (signbit(y)) ux.i |= 0x80000000;
|
||||||
|
} else if (x < y) {
|
||||||
|
if (signbit(x)) ux.i--;
|
||||||
|
else ux.i++;
|
||||||
|
} else {
|
||||||
|
if (signbit(x)) ux.i++;
|
||||||
|
else ux.i--;
|
||||||
|
}
|
||||||
|
e = ux.i & 0x7f800000;
|
||||||
|
/* raise overflow if ux.f is infinite and x is finite */
|
||||||
|
if (e == 0x7f800000) just_do_it(float) _x = x+x;
|
||||||
|
/* raise underflow if ux.f is subnormal or zero */
|
||||||
|
if (e == 0) just_do_it(float) _x = x*x + ux.f*ux.f;
|
||||||
|
return ux.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double nexttowardl(long double x, long double y) {
|
||||||
|
return nextafterl(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double round(double x) {
|
||||||
|
static const double_t toint = 1/DBL_EPSILON;
|
||||||
|
union {double f; uint64_t i;} u = {x};
|
||||||
|
int e = u.i >> 52 & 0x7ff;
|
||||||
|
double_t y;
|
||||||
|
if (e >= 0x3ff+52) return x;
|
||||||
|
if (u.i >> 63) x = -x;
|
||||||
|
if (e < 0x3ff-1) {
|
||||||
|
/* raise inexact if x!=0 */
|
||||||
|
just_do_it(float) _x = x + toint;
|
||||||
|
return 0*u.f;
|
||||||
|
}
|
||||||
|
y = x + toint - toint - x;
|
||||||
|
if (y > 0.5) y = y + x - 1;
|
||||||
|
else if (y <= -0.5) y = y + x + 1;
|
||||||
|
else y = y + x;
|
||||||
|
if (u.i >> 63) y = -y;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float roundf(float x) {
|
||||||
|
static const double_t toint = 1/FLT_EPSILON;
|
||||||
|
union {float f; uint32_t i;} u = {x};
|
||||||
|
int e = u.i >> 23 & 0xff;
|
||||||
|
float_t y;
|
||||||
|
if (e >= 0x7f+23) return x;
|
||||||
|
if (u.i >> 31) x = -x;
|
||||||
|
if (e < 0x7f-1) {
|
||||||
|
just_do_it(float) _x = x + toint;
|
||||||
|
return 0*u.f;
|
||||||
|
}
|
||||||
|
y = x + toint - toint - x;
|
||||||
|
if (y > 0.5f) y = y + x - 1;
|
||||||
|
else if (y <= -0.5f) y = y + x + 1;
|
||||||
|
else y = y + x;
|
||||||
|
if (u.i >> 31) y = -y;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double roundl(long double x) {
|
||||||
|
return round(x);
|
||||||
|
}
|
|
@ -1,139 +0,0 @@
|
||||||
|
|
||||||
// Instantiates 'template' macros for floating-point values
|
|
||||||
// When including expecting the following parameters to be defined:
|
|
||||||
// ftype: Floating-point type to consider
|
|
||||||
// itype: Signed integer type corresponding to ftype's bitwidth
|
|
||||||
// f_ebits: Number of bits in the exponent
|
|
||||||
// f_mbits: Number of bits in the mantissa
|
|
||||||
// suffix(name): appends corresponding suffix to the given name,
|
|
||||||
// e.g. f for floats
|
|
||||||
|
|
||||||
#define f_nbits (1+f_ebits+f_mbits)
|
|
||||||
#define f_emax ((1ULL << (f_ebits-1)) - 1)
|
|
||||||
#define f_emin (1 - f_emax)
|
|
||||||
#define f_ebias f_emax
|
|
||||||
|
|
||||||
// Extracting fields from the float
|
|
||||||
#define f_eoffs (f_mbits)
|
|
||||||
#define f_soffs (f_mbits+f_ebits)
|
|
||||||
#define f_emask ((1ULL << f_ebits) - 1)
|
|
||||||
#define f_mmask ((1ULL << f_mbits) - 1)
|
|
||||||
#define f_smask 1ULL
|
|
||||||
#define f_eval(b) (((b) >> f_eoffs) & f_emask)
|
|
||||||
#define f_sval(b) (((b) >> f_soffs) & f_smask)
|
|
||||||
#define f_mval(b) (((b) >> 0) & f_mmask)
|
|
||||||
#define f_abs(b) ((b) & ~(f_smask << f_soffs))
|
|
||||||
#define f_exp(b) (f_eval(b) - f_ebias)
|
|
||||||
|
|
||||||
#define f_qexp(b) (f_eval(b) - f_ebias - f_mbits)
|
|
||||||
#define f_qman(b) (((b) & f_mmask) | (f_mmask+1))
|
|
||||||
|
|
||||||
#define b_cons(s,e,m) (((itype)s << f_soffs) | ((itype)e << f_eoffs) | (itype)(m))
|
|
||||||
|
|
||||||
// Converting float to integer bits
|
|
||||||
static inline itype suffix(f_bits)(ftype f) {
|
|
||||||
union _u {
|
|
||||||
ftype f;
|
|
||||||
itype b;
|
|
||||||
} u;
|
|
||||||
u.f = f;
|
|
||||||
return u.b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline ftype suffix(f_frombits)(itype b) {
|
|
||||||
union _u {
|
|
||||||
ftype f;
|
|
||||||
itype b;
|
|
||||||
} u;
|
|
||||||
u.b = b;
|
|
||||||
return u.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Floating-point classification
|
|
||||||
int suffix(_fpclassify)(ftype f) {
|
|
||||||
itype bits = suffix(f_bits)(f);
|
|
||||||
itype exp = f_eval(bits);
|
|
||||||
itype man = f_mval(bits);
|
|
||||||
if(exp == f_emask) {
|
|
||||||
if(man == 0) return FP_INFINITE;
|
|
||||||
else return FP_NAN;
|
|
||||||
}
|
|
||||||
else if(exp == 0) {
|
|
||||||
if(man == 0) return FP_ZERO;
|
|
||||||
else return FP_SUBNORMAL;
|
|
||||||
}
|
|
||||||
else return FP_NORMAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffix(_signbit)(ftype f) {
|
|
||||||
itype bits = suffix(f_bits)(f);
|
|
||||||
itype sign = f_sval(bits);
|
|
||||||
return sign;
|
|
||||||
}
|
|
||||||
|
|
||||||
ftype suffix(copysign)(ftype x, ftype y) {
|
|
||||||
itype xbits = suffix(f_bits)(x);
|
|
||||||
itype ybits = suffix(f_bits)(y);
|
|
||||||
itype exp = f_eval(xbits);
|
|
||||||
itype man = f_mval(xbits);
|
|
||||||
itype sgn = f_sval(ybits);
|
|
||||||
itype rbits = b_cons(sgn, exp, man);
|
|
||||||
return suffix(f_frombits)(rbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Floating-point non-signaling comparison
|
|
||||||
|
|
||||||
static Ordering suffix(_ordering)(ftype x, ftype y) {
|
|
||||||
itype xclass = suffix(_fpclassify)(x);
|
|
||||||
itype yclass = suffix(_fpclassify)(y);
|
|
||||||
if(xclass == FP_NAN || yclass == FP_NAN) {
|
|
||||||
return UN;
|
|
||||||
}
|
|
||||||
itype xbits = suffix(f_bits)(x);
|
|
||||||
itype ybits = suffix(f_bits)(y);
|
|
||||||
itype xsgn = f_sval(xbits);
|
|
||||||
itype ysgn = f_sval(ybits);
|
|
||||||
itype xabs = f_abs(xbits);
|
|
||||||
itype yabs = f_abs(ybits);
|
|
||||||
if(xsgn == ysgn) {
|
|
||||||
if(xabs > yabs) return GR;
|
|
||||||
if(xabs < yabs) return LS;
|
|
||||||
return EQ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(xabs == 0 && yabs == 0) return EQ;
|
|
||||||
if(xsgn) return LS;
|
|
||||||
if(ysgn) return GR;
|
|
||||||
}
|
|
||||||
return UN; // I may be stupid
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffix(_isgrt)(ftype x, ftype y) {
|
|
||||||
int ord = suffix(_ordering)(x, y);
|
|
||||||
return ord == GR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffix(_isgeq)(ftype x, ftype y) {
|
|
||||||
int ord = suffix(_ordering)(x, y);
|
|
||||||
return ord == GR || ord == EQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffix(_isles)(ftype x, ftype y) {
|
|
||||||
int ord = suffix(_ordering)(x, y);
|
|
||||||
return ord == LS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffix(_isleq)(ftype x, ftype y) {
|
|
||||||
int ord = suffix(_ordering)(x, y);
|
|
||||||
return ord == LS || ord == EQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffix(_isleg)(ftype x, ftype y) {
|
|
||||||
int ord = suffix(_ordering)(x, y);
|
|
||||||
return ord == LS || ord == GR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffix(_isuno)(ftype x, ftype y) {
|
|
||||||
int ord = suffix(_ordering)(x, y);
|
|
||||||
return ord == UN;
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// Used for float comparisons in ieee754.h
|
|
||||||
enum Ordering {
|
|
||||||
LS,
|
|
||||||
EQ,
|
|
||||||
GR,
|
|
||||||
UN,
|
|
||||||
} typedef Ordering;
|
|
||||||
|
|
||||||
#define ftype float
|
|
||||||
#define itype int32_t
|
|
||||||
#define f_ebits 8
|
|
||||||
#define f_mbits 23
|
|
||||||
#define suffix(n) n ## f
|
|
||||||
#include "ieee754.h"
|
|
||||||
#include "pow.h"
|
|
||||||
#undef suffix
|
|
||||||
#undef f_mbits
|
|
||||||
#undef f_ebits
|
|
||||||
#undef itype
|
|
||||||
#undef ftype
|
|
||||||
|
|
||||||
#define ftype double
|
|
||||||
#define itype int64_t
|
|
||||||
#define f_ebits 11
|
|
||||||
#define f_mbits 52
|
|
||||||
#define suffix(n) n
|
|
||||||
#include "ieee754.h"
|
|
||||||
#include "pow.h"
|
|
||||||
#undef suffix
|
|
||||||
#undef f_mbits
|
|
||||||
#undef f_ebits
|
|
||||||
#undef itype
|
|
||||||
#undef ftype
|
|
||||||
|
|
||||||
_Static_assert(sizeof(long double) == sizeof(double),
|
|
||||||
"Are these 'long doubles' in the same room with us right now?");
|
|
||||||
|
|
||||||
#define ftype long double
|
|
||||||
#define itype int64_t
|
|
||||||
#define f_ebits 11
|
|
||||||
#define f_mbits 52
|
|
||||||
#define suffix(n) n ## l
|
|
||||||
#include "ieee754.h"
|
|
||||||
#include "pow.h"
|
|
||||||
#undef suffix
|
|
||||||
#undef f_mbits
|
|
||||||
#undef f_ebits
|
|
||||||
#undef itype
|
|
||||||
#undef ftype
|
|
103
code/math/pow.h
103
code/math/pow.h
|
@ -1,103 +0,0 @@
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if !defined(_isqrt_defined)
|
|
||||||
#define _isqrt_defined
|
|
||||||
static uint64_t _isqrt(uint64_t num, uint64_t *remp) {
|
|
||||||
// To find a square root of a number
|
|
||||||
// We get rid of zero
|
|
||||||
if(num == 0) {
|
|
||||||
*remp = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Then, starting from the bottom, split num into 2-digit pairs
|
|
||||||
// and find the top-most non-zero pair
|
|
||||||
uint64_t i = 0;
|
|
||||||
while(i != (sizeof(uint64_t)*8) && (num >> i) != 0) {
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
// Then we start taking guesses such that at each step
|
|
||||||
// sqrt^2 <= number made of consequent pairs of exausted integers
|
|
||||||
uint64_t sqrt = 0;
|
|
||||||
uint64_t rem = 0;
|
|
||||||
// Repeat until remainder is equal to zero:
|
|
||||||
do {
|
|
||||||
i -= 2;
|
|
||||||
// Bring the next two digits of the number to our remainder
|
|
||||||
rem = (rem << 2) | ((num >> i) & 0x3);
|
|
||||||
// Find d such that d(2sqrt+d) <= rem
|
|
||||||
// Since d could be either 0 or 1 we simply check 1, otherwise its 0
|
|
||||||
uint64_t d = 1;
|
|
||||||
uint64_t t = ((sqrt<<2)|1);
|
|
||||||
if(t <= rem) {
|
|
||||||
rem -= t;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
d = 0;
|
|
||||||
}
|
|
||||||
// Append the digit to sqrt from the right
|
|
||||||
sqrt = (sqrt<<1)|d;
|
|
||||||
} while(i != 0);
|
|
||||||
|
|
||||||
*remp = rem;
|
|
||||||
return sqrt;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For all it's worth this shit is simply equivalent to
|
|
||||||
// _isqrt((uint64)x)
|
|
||||||
// I hate porgaming.
|
|
||||||
ftype suffix(sqrt)(ftype x) {
|
|
||||||
if(x < 0) {
|
|
||||||
#if math_errhandling & MATH_ERRNO
|
|
||||||
errno = EDOM;
|
|
||||||
#endif
|
|
||||||
return NAN;
|
|
||||||
}
|
|
||||||
if(x == 0 || isinf(x)) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
if(isnan(x)) {
|
|
||||||
return NAN;
|
|
||||||
}
|
|
||||||
itype bits = suffix(f_bits)(x);
|
|
||||||
itype exp = f_qexp(bits);
|
|
||||||
itype man = f_qman(bits);
|
|
||||||
// Get lots of precision by shifting man right by max bits
|
|
||||||
// and subtracting this from the exponent
|
|
||||||
itype bit = 0; // highest set-bit of man
|
|
||||||
while((man >> (bit+1)) != 0) ++bit;
|
|
||||||
itype prec_shift_n = f_nbits - bit - 3;
|
|
||||||
man <<= prec_shift_n;
|
|
||||||
exp -= prec_shift_n;
|
|
||||||
// Now do the sqrt of 2^exp * man
|
|
||||||
// If exp is odd then 2^{2k+1}*sqrt(man) = 2^{2k}*sqrt{2*man}
|
|
||||||
if((2 + (exp % 2)) % 2 != 0) {
|
|
||||||
man <<= 1;
|
|
||||||
}
|
|
||||||
// Take exp sqrt
|
|
||||||
exp >>= 1;
|
|
||||||
// Take sqrt of mantissa
|
|
||||||
uint64_t rem;
|
|
||||||
man = (itype)_isqrt(man, &rem);
|
|
||||||
// Now sqrt(x) = 2^exp * man
|
|
||||||
// we need to normalize this shit
|
|
||||||
bit = 0; // highest set-bit of man
|
|
||||||
while((man >> (bit+1)) != 0) ++bit;
|
|
||||||
exp += bit;
|
|
||||||
man <<= f_nbits-bit;
|
|
||||||
exp += f_ebias;
|
|
||||||
man >>= f_nbits-f_mbits;
|
|
||||||
man &= f_mmask;
|
|
||||||
// Cons it back
|
|
||||||
bits = b_cons(0, exp, man);
|
|
||||||
return suffix(f_frombits)(bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
ftype suffix(hypot)(ftype x, ftype y)
|
|
||||||
{
|
|
||||||
if(isinf(x) || isinf(y)) {
|
|
||||||
return INFINITY;
|
|
||||||
}
|
|
||||||
return suffix(sqrt)(x*x + y*y);
|
|
||||||
}
|
|
438
code/printf.h
438
code/printf.h
|
@ -1,218 +1,220 @@
|
||||||
|
|
||||||
//TODO: verify printf("%d", 0). From the code it looked like it would print
|
#include <math.h>
|
||||||
// an empty string.
|
|
||||||
|
//TODO: verify printf("%d", 0). From the code it looked like it would print
|
||||||
// NOTE: this file doesn't exist in a vacuum, it's a template for generating
|
// an empty string.
|
||||||
// the formatted print, you should define FMT_CHAR_TYPE before including it
|
|
||||||
inline static int FMT_FUNC_NAME (void *ctx, OutputFunc out, const FMT_CHAR_TYPE *fmt, va_list args) {
|
// NOTE: this file doesn't exist in a vacuum, it's a template for generating
|
||||||
size_t full_length = 0;
|
// the formatted print, you should define FMT_CHAR_TYPE before including it
|
||||||
|
inline static int FMT_FUNC_NAME (void *ctx, OutputFunc out, const FMT_CHAR_TYPE *fmt, va_list args) {
|
||||||
while (*fmt) {
|
size_t full_length = 0;
|
||||||
// skip any normal non percent text
|
|
||||||
const FMT_CHAR_TYPE *start = fmt;
|
while (*fmt) {
|
||||||
while (*fmt && *fmt != '%') fmt++;
|
// skip any normal non percent text
|
||||||
|
const FMT_CHAR_TYPE *start = fmt;
|
||||||
// print all those non percent text
|
while (*fmt && *fmt != '%') fmt++;
|
||||||
out(ctx, fmt - start, start);
|
|
||||||
full_length += (fmt - start);
|
// print all those non percent text
|
||||||
|
out(ctx, fmt - start, start);
|
||||||
// null terminated
|
full_length += (fmt - start);
|
||||||
if (*fmt == '\0') break;
|
|
||||||
fmt += 1;
|
// null terminated
|
||||||
|
if (*fmt == '\0') break;
|
||||||
if (*fmt == '%') {
|
fmt += 1;
|
||||||
out(ctx, 1, "%");
|
|
||||||
fmt++;
|
if (*fmt == '%') {
|
||||||
continue;
|
out(ctx, 1, "%");
|
||||||
}
|
fmt++;
|
||||||
|
continue;
|
||||||
unsigned int precision = 0;
|
}
|
||||||
if (*fmt == '.') {
|
|
||||||
// custom precision
|
unsigned int precision = 0;
|
||||||
fmt++;
|
if (*fmt == '.') {
|
||||||
|
// custom precision
|
||||||
if (isdigit(*fmt)) {
|
fmt++;
|
||||||
// just a small atoi
|
|
||||||
// TODO: handle overflow, just in case(?)
|
if (isdigit(*fmt)) {
|
||||||
while (isdigit(*fmt)) {
|
// just a small atoi
|
||||||
precision *= 10u;
|
// TODO: handle overflow, just in case(?)
|
||||||
precision += (*fmt - '0');
|
while (isdigit(*fmt)) {
|
||||||
|
precision *= 10u;
|
||||||
fmt++;
|
precision += (*fmt - '0');
|
||||||
}
|
|
||||||
} else if (*fmt == '*') {
|
fmt++;
|
||||||
int p = va_arg(args, int);
|
}
|
||||||
|
} else if (*fmt == '*') {
|
||||||
precision = p >= 0 ? ((unsigned int)p) : 0;
|
int p = va_arg(args, int);
|
||||||
fmt++;
|
|
||||||
}
|
precision = p >= 0 ? ((unsigned int)p) : 0;
|
||||||
}
|
fmt++;
|
||||||
|
}
|
||||||
// integer length specifiers
|
}
|
||||||
enum {
|
|
||||||
CHAR,
|
// integer length specifiers
|
||||||
SHORT,
|
enum {
|
||||||
INT,
|
CHAR,
|
||||||
LONG,
|
SHORT,
|
||||||
LLONG
|
INT,
|
||||||
} int_length = INT;
|
LONG,
|
||||||
|
LLONG
|
||||||
if (*fmt == 'l') {
|
} int_length = INT;
|
||||||
fmt++;
|
|
||||||
|
if (*fmt == 'l') {
|
||||||
if (*fmt == 'l') {
|
fmt++;
|
||||||
int_length = LLONG;
|
|
||||||
fmt++;
|
if (*fmt == 'l') {
|
||||||
} else {
|
int_length = LLONG;
|
||||||
int_length = LONG;
|
fmt++;
|
||||||
}
|
} else {
|
||||||
} else if (*fmt == 'h') {
|
int_length = LONG;
|
||||||
fmt++;
|
}
|
||||||
|
} else if (*fmt == 'h') {
|
||||||
if (*fmt == 'h') {
|
fmt++;
|
||||||
int_length = CHAR;
|
|
||||||
fmt++;
|
if (*fmt == 'h') {
|
||||||
} else {
|
int_length = CHAR;
|
||||||
int_length = SHORT;
|
fmt++;
|
||||||
}
|
} else {
|
||||||
} else if (*fmt == 'z') {
|
int_length = SHORT;
|
||||||
fmt++;
|
}
|
||||||
|
} else if (*fmt == 'z') {
|
||||||
int_length = _Generic((size_t)0,
|
fmt++;
|
||||||
unsigned char: CHAR,
|
|
||||||
unsigned short: SHORT,
|
int_length = _Generic((size_t)0,
|
||||||
unsigned int: INT,
|
unsigned char: CHAR,
|
||||||
unsigned long: LONG,
|
unsigned short: SHORT,
|
||||||
unsigned long long: LLONG);
|
unsigned int: INT,
|
||||||
}
|
unsigned long: LONG,
|
||||||
|
unsigned long long: LLONG);
|
||||||
FMT_CHAR_TYPE ch = *fmt++;
|
}
|
||||||
const char* characters = "0123456789abcdef";
|
|
||||||
if (ch == 'X') characters = "0123456789ABCDEF";
|
FMT_CHAR_TYPE ch = *fmt++;
|
||||||
|
const char* characters = "0123456789abcdef";
|
||||||
switch (ch) {
|
if (ch == 'X') characters = "0123456789ABCDEF";
|
||||||
case 'c': {
|
|
||||||
const char chr = va_arg(args, int);
|
switch (ch) {
|
||||||
out(ctx, 1, &chr);
|
case 'c': {
|
||||||
full_length ++;
|
const char chr = va_arg(args, int);
|
||||||
break;
|
out(ctx, 1, &chr);
|
||||||
}
|
full_length ++;
|
||||||
case 'f':
|
break;
|
||||||
case 'L': {
|
}
|
||||||
double d = va_arg(args, double);
|
case 'f':
|
||||||
|
case 'L': {
|
||||||
if(isinf(d)) {
|
double d = va_arg(args, double);
|
||||||
out(ctx, sizeof"inf"-1, "inf");
|
|
||||||
break;
|
if(signbit(d)) { // TODO: negative zero
|
||||||
}
|
out(ctx, 1, "-");
|
||||||
else if(isnan(d)) {
|
d = -d;
|
||||||
out(ctx, sizeof"nan"-1, "nan");
|
}
|
||||||
break;
|
|
||||||
}
|
if(isinf(d)) {
|
||||||
|
out(ctx, sizeof"inf"-1, "inf");
|
||||||
if(d < 0) { // TODO: negative zero
|
break;
|
||||||
out(ctx, 1, "-");
|
}
|
||||||
d = -d;
|
else if(isnan(d)) {
|
||||||
}
|
out(ctx, sizeof"nan"-1, "nan");
|
||||||
|
break;
|
||||||
uint64_t w = (uint64_t)d;
|
}
|
||||||
d -= w;
|
|
||||||
FMT_CHAR_TYPE buffer[20];
|
uint64_t w = (uint64_t)d;
|
||||||
size_t len = sizeof(buffer);
|
d -= w;
|
||||||
do {
|
FMT_CHAR_TYPE buffer[20];
|
||||||
buffer[--len] = characters[w % 10];
|
size_t len = sizeof(buffer);
|
||||||
w /= 10;
|
do {
|
||||||
} while(w != 0);
|
buffer[--len] = characters[w % 10];
|
||||||
out(ctx, sizeof(buffer) - (len * sizeof(FMT_CHAR_TYPE)), buffer + len);
|
w /= 10;
|
||||||
|
} while(w != 0);
|
||||||
char dot = '.';
|
out(ctx, sizeof(buffer) - (len * sizeof(FMT_CHAR_TYPE)), buffer + len);
|
||||||
out(ctx, 1, &dot);
|
|
||||||
|
char dot = '.';
|
||||||
for(int i = 0; i != 6; ++i) {
|
out(ctx, 1, &dot);
|
||||||
d *= 10;
|
|
||||||
int dv = (int)d;
|
for(int i = 0; i != 6; ++i) {
|
||||||
d -= dv;
|
d *= 10;
|
||||||
char digit = characters[dv];
|
int dv = (int)d;
|
||||||
out(ctx, 1, &digit);
|
d -= dv;
|
||||||
}
|
char digit = characters[dv];
|
||||||
} break;
|
out(ctx, 1, &digit);
|
||||||
case 's': {
|
}
|
||||||
const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*);
|
} break;
|
||||||
size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX);
|
case 's': {
|
||||||
|
const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*);
|
||||||
out(ctx, len, str);
|
size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX);
|
||||||
full_length += len;
|
|
||||||
break;
|
out(ctx, len, str);
|
||||||
}
|
full_length += len;
|
||||||
|
break;
|
||||||
case 'b':
|
}
|
||||||
case 'o':
|
|
||||||
case 'i':
|
case 'b':
|
||||||
case 'u':
|
case 'o':
|
||||||
case 'd':
|
case 'i':
|
||||||
case 'x':
|
case 'u':
|
||||||
case 'X': {
|
case 'd':
|
||||||
int base = 10;
|
case 'x':
|
||||||
switch (ch) {
|
case 'X': {
|
||||||
case 'X': case 'x': base = 16; break;
|
int base = 10;
|
||||||
case 'o': base = 8; break;
|
switch (ch) {
|
||||||
case 'b': base = 2; break;
|
case 'X': case 'x': base = 16; break;
|
||||||
default: base = 10; break;
|
case 'o': base = 8; break;
|
||||||
}
|
case 'b': base = 2; break;
|
||||||
|
default: base = 10; break;
|
||||||
uintmax_t i;
|
}
|
||||||
if (ch == 'd' || ch == 'i') {
|
|
||||||
intmax_t num = 0;
|
uintmax_t i;
|
||||||
switch (int_length) {
|
if (ch == 'd' || ch == 'i') {
|
||||||
case CHAR: num = (char) va_arg(args, int); break;
|
intmax_t num = 0;
|
||||||
case SHORT: num = (short) va_arg(args, int); break;
|
switch (int_length) {
|
||||||
case INT: num = va_arg(args, int); break;
|
case CHAR: num = (char) va_arg(args, int); break;
|
||||||
case LONG: num = va_arg(args, long); break;
|
case SHORT: num = (short) va_arg(args, int); break;
|
||||||
case LLONG: num = va_arg(args, long long); break;
|
case INT: num = va_arg(args, int); break;
|
||||||
default: break;
|
case LONG: num = va_arg(args, long); break;
|
||||||
}
|
case LLONG: num = va_arg(args, long long); break;
|
||||||
|
default: break;
|
||||||
if (num < 0) {
|
}
|
||||||
out(ctx, 1, "-");
|
|
||||||
i = -num;
|
if (num < 0) {
|
||||||
full_length += 1;
|
out(ctx, 1, "-");
|
||||||
} else {
|
i = -num;
|
||||||
i = num;
|
full_length += 1;
|
||||||
}
|
} else {
|
||||||
} else {
|
i = num;
|
||||||
switch (int_length) {
|
}
|
||||||
case CHAR: i = (char) va_arg(args, int); break;
|
} else {
|
||||||
case SHORT: i = (short) va_arg(args, int); break;
|
switch (int_length) {
|
||||||
case INT: i = va_arg(args, int); break;
|
case CHAR: i = (char) va_arg(args, int); break;
|
||||||
case LONG: i = va_arg(args, long); break;
|
case SHORT: i = (short) va_arg(args, int); break;
|
||||||
case LLONG: i = va_arg(args, long long); break;
|
case INT: i = va_arg(args, int); break;
|
||||||
default: i = 0; break;
|
case LONG: i = va_arg(args, long); break;
|
||||||
}
|
case LLONG: i = va_arg(args, long long); break;
|
||||||
}
|
default: i = 0; break;
|
||||||
|
}
|
||||||
if (i == 0) {
|
}
|
||||||
out(ctx, 1, "0");
|
|
||||||
full_length += 1;
|
if (i == 0) {
|
||||||
} else {
|
out(ctx, 1, "0");
|
||||||
FMT_CHAR_TYPE buffer[20];
|
full_length += 1;
|
||||||
size_t len = sizeof(buffer);
|
} else {
|
||||||
|
FMT_CHAR_TYPE buffer[20];
|
||||||
// we build the number in reverse
|
size_t len = sizeof(buffer);
|
||||||
while (i != 0) {
|
|
||||||
buffer[--len] = characters[i % base];
|
// we build the number in reverse
|
||||||
i /= base;
|
while (i != 0) {
|
||||||
}
|
buffer[--len] = characters[i % base];
|
||||||
|
i /= base;
|
||||||
out(ctx, sizeof(buffer) - (len * sizeof(FMT_CHAR_TYPE)), buffer + len);
|
}
|
||||||
full_length += (sizeof(buffer) - len);
|
|
||||||
}
|
out(ctx, sizeof(buffer) - (len * sizeof(FMT_CHAR_TYPE)), buffer + len);
|
||||||
break;
|
full_length += (sizeof(buffer) - len);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default: break;
|
}
|
||||||
}
|
|
||||||
}
|
default: break;
|
||||||
|
}
|
||||||
return full_length;
|
}
|
||||||
}
|
|
||||||
|
return full_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
278
code/stdio.c
278
code/stdio.c
|
@ -1,139 +1,139 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <_os.h>
|
#include <_os.h>
|
||||||
|
|
||||||
#define __STDC_WANT_LIB_EXT1__ 1
|
#define __STDC_WANT_LIB_EXT1__ 1
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int remove(const char *filename)
|
int remove(const char *filename)
|
||||||
{
|
{
|
||||||
return _os_del_file(filename);
|
return _os_del_file(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rename(const char *old, const char *new)
|
int rename(const char *old, const char *new)
|
||||||
{
|
{
|
||||||
return _os_mov_file(old, new);
|
return _os_mov_file(old, new);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *tmpnam(char *s)
|
char *tmpnam(char *s)
|
||||||
{
|
{
|
||||||
static char static_buffer[L_tmpnam];
|
static char static_buffer[L_tmpnam];
|
||||||
char *buffer = s;
|
char *buffer = s;
|
||||||
if(s == NULL) buffer = static_buffer;
|
if(s == NULL) buffer = static_buffer;
|
||||||
return _os_tmpname(buffer);
|
return _os_tmpname(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fopen(const char *restrict filename, const char *restrict mode)
|
FILE *fopen(const char *restrict filename, const char *restrict mode)
|
||||||
{
|
{
|
||||||
// Basically defined UB here by introducing missing modes
|
// Basically defined UB here by introducing missing modes
|
||||||
// It is simpler to implement that way I think.
|
// It is simpler to implement that way I think.
|
||||||
int base_mode = mode[0];
|
int base_mode = mode[0];
|
||||||
int binary = 0;
|
int binary = 0;
|
||||||
int exclusive = 0;
|
int exclusive = 0;
|
||||||
int update = 0;
|
int update = 0;
|
||||||
for(; *mode != 0; ++mode) {
|
for(; *mode != 0; ++mode) {
|
||||||
if(*mode == 'x') exclusive = 1;
|
if(*mode == 'x') exclusive = 1;
|
||||||
if(*mode == 'b') binary = 1;
|
if(*mode == 'b') binary = 1;
|
||||||
if(*mode == '+') update = 1;
|
if(*mode == '+') update = 1;
|
||||||
}
|
}
|
||||||
if(base_mode == 'r' && exclusive) return NULL;
|
if(base_mode == 'r' && exclusive) return NULL;
|
||||||
if(base_mode == 'a' && exclusive) return NULL;
|
if(base_mode == 'a' && exclusive) return NULL;
|
||||||
|
|
||||||
_OS_ModeFlags mode_flags = {
|
_OS_ModeFlags mode_flags = {
|
||||||
.base_mode = base_mode,
|
.base_mode = base_mode,
|
||||||
.binary = binary,
|
.binary = binary,
|
||||||
.update = update,
|
.update = update,
|
||||||
.exclusive = exclusive,
|
.exclusive = exclusive,
|
||||||
};
|
};
|
||||||
|
|
||||||
return _os_fopen(filename, mode_flags);
|
return _os_fopen(filename, mode_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fclose(FILE *stream)
|
int fclose(FILE *stream)
|
||||||
{
|
{
|
||||||
return _os_fclose(stream);
|
return _os_fclose(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:kekw:
|
// TODO:kekw:
|
||||||
FILE *freopen(
|
FILE *freopen(
|
||||||
const char *restrict filename,
|
const char *restrict filename,
|
||||||
const char *restrict mode,
|
const char *restrict mode,
|
||||||
FILE *restrict stream)
|
FILE *restrict stream)
|
||||||
{
|
{
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]);
|
typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]);
|
||||||
|
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
// Instantiate formatted print functions
|
// Instantiate formatted print functions
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
// TODO: instantiate wide char variants of print
|
// TODO: instantiate wide char variants of print
|
||||||
#define FMT_FUNC_NAME fmt_print_char
|
#define FMT_FUNC_NAME fmt_print_char
|
||||||
#define FMT_CHAR_TYPE char
|
#define FMT_CHAR_TYPE char
|
||||||
#define FMT_STRLEN_S(s, maxsize) strnlen_s(s, maxsize)
|
#define FMT_STRLEN_S(s, maxsize) strnlen_s(s, maxsize)
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t used, capacity;
|
size_t used, capacity;
|
||||||
char* string;
|
char* string;
|
||||||
} StrPrintCtx;
|
} StrPrintCtx;
|
||||||
|
|
||||||
FILE *stdout, *stderr, *stdin;
|
FILE *stdout, *stderr, *stdin;
|
||||||
|
|
||||||
#define CALL_PRINTF(fmt_func, ctx, out, fmt) \
|
#define CALL_PRINTF(fmt_func, ctx, out, fmt) \
|
||||||
va_list args; \
|
va_list args; \
|
||||||
va_start(args, fmt); \
|
va_start(args, fmt); \
|
||||||
int result = fmt_func(ctx, out, fmt, args); \
|
int result = fmt_func(ctx, out, fmt, args); \
|
||||||
va_end(args)
|
va_end(args)
|
||||||
|
|
||||||
static void string_write(void *ctx, size_t n, const char *restrict str) {
|
static void string_write(void *ctx, size_t n, const char *restrict str) {
|
||||||
StrPrintCtx *c = ctx;
|
StrPrintCtx *c = ctx;
|
||||||
memcpy(c->string + c->used, str, n);
|
memcpy(c->string + c->used, str, n);
|
||||||
c->used += n;
|
c->used += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fprintf(FILE *file, const char *restrict fmt, ...) {
|
int fprintf(FILE *file, const char *restrict fmt, ...) {
|
||||||
CALL_PRINTF(fmt_print_char, file, _os_file_write, fmt);
|
CALL_PRINTF(fmt_print_char, file, _os_file_write, fmt);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf(const char *restrict fmt, ...) {
|
int printf(const char *restrict fmt, ...) {
|
||||||
CALL_PRINTF(fmt_print_char, stdout, _os_file_write, fmt);
|
CALL_PRINTF(fmt_print_char, stdout, _os_file_write, fmt);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) {
|
int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) {
|
||||||
StrPrintCtx ctx = { 0, n, s };
|
StrPrintCtx ctx = { 0, n, s };
|
||||||
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
|
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprintf(char *restrict s, const char *restrict fmt, ...) {
|
int sprintf(char *restrict s, const char *restrict fmt, ...) {
|
||||||
StrPrintCtx ctx = { 0, SIZE_MAX, s };
|
StrPrintCtx ctx = { 0, SIZE_MAX, s };
|
||||||
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
|
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfprintf(FILE *file, const char *restrict fmt, va_list args) {
|
int vfprintf(FILE *file, const char *restrict fmt, va_list args) {
|
||||||
return fmt_print_char(file, _os_file_write, fmt, args);
|
return fmt_print_char(file, _os_file_write, fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vprintf(const char *restrict fmt, va_list args) {
|
int vprintf(const char *restrict fmt, va_list args) {
|
||||||
return fmt_print_char(stdout, _os_file_write, fmt, args);
|
return fmt_print_char(stdout, _os_file_write, fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list args) {
|
int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list args) {
|
||||||
StrPrintCtx ctx = { 0, n, s };
|
StrPrintCtx ctx = { 0, n, s };
|
||||||
return fmt_print_char(&ctx, string_write, fmt, args);
|
return fmt_print_char(&ctx, string_write, fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsprintf(char *restrict s, const char *restrict fmt, va_list args) {
|
int vsprintf(char *restrict s, const char *restrict fmt, va_list args) {
|
||||||
StrPrintCtx ctx = { 0, SIZE_MAX, s };
|
StrPrintCtx ctx = { 0, SIZE_MAX, s };
|
||||||
return fmt_print_char(&ctx, string_write, fmt, args);
|
return fmt_print_char(&ctx, string_write, fmt, args);
|
||||||
}
|
}
|
||||||
|
|
32
inc/ctype.h
32
inc/ctype.h
|
@ -1,16 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int isalnum(int c);
|
int isalnum(int c);
|
||||||
int isalpha(int c);
|
int isalpha(int c);
|
||||||
int isblank(int c);
|
int isblank(int c);
|
||||||
int iscntrl(int c);
|
int iscntrl(int c);
|
||||||
int isdigit(int c);
|
int isdigit(int c);
|
||||||
int isgraph(int c);
|
int isgraph(int c);
|
||||||
int islower(int c);
|
int islower(int c);
|
||||||
int isprint(int c);
|
int isprint(int c);
|
||||||
int ispunct(int c);
|
int ispunct(int c);
|
||||||
int isspace(int c);
|
int isspace(int c);
|
||||||
int isupper(int c);
|
int isupper(int c);
|
||||||
int isxdigit(int c);
|
int isxdigit(int c);
|
||||||
int tolower(int c);
|
int tolower(int c);
|
||||||
int toupper(int c);
|
int toupper(int c);
|
||||||
|
|
18
inc/errno.h
18
inc/errno.h
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define EDOM 1
|
#define EDOM 1
|
||||||
#define EILSEQ 2
|
#define EILSEQ 2
|
||||||
#define ERANGE 3
|
#define ERANGE 3
|
||||||
|
|
||||||
// TODO: make it thread-local
|
// TODO: make it thread-local
|
||||||
extern int errno;
|
extern int errno;
|
||||||
|
|
120
inc/fenv.h
120
inc/fenv.h
|
@ -1,61 +1,61 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef unsigned fexcept_t;
|
typedef unsigned fexcept_t;
|
||||||
typedef unsigned fenv_t;
|
typedef unsigned fenv_t;
|
||||||
|
|
||||||
#define FE_INVALID (1 << 0)
|
#define FE_INVALID (1 << 0)
|
||||||
#define FE_DIVBYZERO (1 << 2)
|
#define FE_DIVBYZERO (1 << 2)
|
||||||
#define FE_OVERFLOW (1 << 3)
|
#define FE_OVERFLOW (1 << 3)
|
||||||
#define FE_UNDERFLOW (1 << 4)
|
#define FE_UNDERFLOW (1 << 4)
|
||||||
#define FE_INEXACT (1 << 5)
|
#define FE_INEXACT (1 << 5)
|
||||||
// Implementation-defined flags
|
// Implementation-defined flags
|
||||||
#define FE_DENORM (1 << 1)
|
#define FE_DENORM (1 << 1)
|
||||||
#define FE_DAZ (1 << 6)
|
#define FE_DAZ (1 << 6)
|
||||||
|
|
||||||
#define FE_ALL_EXCEPT \
|
#define FE_ALL_EXCEPT \
|
||||||
( FE_INVALID \
|
( FE_INVALID \
|
||||||
| FE_DIVBYZERO \
|
| FE_DIVBYZERO \
|
||||||
| FE_OVERFLOW \
|
| FE_OVERFLOW \
|
||||||
| FE_UNDERFLOW \
|
| FE_UNDERFLOW \
|
||||||
| FE_INEXACT \
|
| FE_INEXACT \
|
||||||
| FE_DENORM \
|
| FE_DENORM \
|
||||||
| FE_DAZ )
|
| FE_DAZ )
|
||||||
|
|
||||||
#define FE_TONEAREST 0x00
|
#define FE_TONEAREST 0x00
|
||||||
#define FE_DOWNWARD 0x01
|
#define FE_DOWNWARD 0x01
|
||||||
#define FE_UPWARD 0x02
|
#define FE_UPWARD 0x02
|
||||||
#define FE_TOWARDZERO 0x03
|
#define FE_TOWARDZERO 0x03
|
||||||
|
|
||||||
extern fenv_t _fe_dfl_env;
|
extern fenv_t _fe_dfl_env;
|
||||||
#define FE_DFL_ENV (&_fe_dfl_env)
|
#define FE_DFL_ENV (&_fe_dfl_env)
|
||||||
|
|
||||||
// Exceptions
|
// Exceptions
|
||||||
|
|
||||||
int feclearexcept(int excepts);
|
int feclearexcept(int excepts);
|
||||||
int fegetexceptflag(fexcept_t *flagp, int excepts);
|
int fegetexceptflag(fexcept_t *flagp, int excepts);
|
||||||
int feraiseexcept(int excepts);
|
int feraiseexcept(int excepts);
|
||||||
int fesetexceptflag(const fexcept_t *flagp, int excepts);
|
int fesetexceptflag(const fexcept_t *flagp, int excepts);
|
||||||
int fetestexcept(int excepts);
|
int fetestexcept(int excepts);
|
||||||
|
|
||||||
// Rounding behaviour
|
// Rounding behaviour
|
||||||
|
|
||||||
int fegetround(void);
|
int fegetround(void);
|
||||||
int fesetround(int round);
|
int fesetround(int round);
|
||||||
|
|
||||||
// Environment
|
// Environment
|
||||||
|
|
||||||
int fegetenv(fenv_t *env);
|
int fegetenv(fenv_t *env);
|
||||||
int fesetenv(fenv_t *env);
|
int fesetenv(fenv_t *env);
|
||||||
int feholdexcept(fenv_t *envp);
|
int feholdexcept(fenv_t *envp);
|
||||||
int feupdateenv(fenv_t const *envp);
|
int feupdateenv(fenv_t const *envp);
|
||||||
|
|
||||||
// Non-standard functions
|
// Non-standard functions
|
||||||
|
|
||||||
int _feenabletraps(int excepts);
|
int _feenabletraps(int excepts);
|
||||||
int _fedisabletraps(int excepts);
|
int _fedisabletraps(int excepts);
|
||||||
|
|
||||||
#if defined(_CIABATTA_EXT)
|
#if defined(_CIABATTA_EXT)
|
||||||
#define feenabletraps _feenabletraps
|
#define feenabletraps _feenabletraps
|
||||||
#define _fedisabletraps _fedisabletraps
|
#define _fedisabletraps _fedisabletraps
|
||||||
#endif
|
#endif
|
90
inc/locale.h
90
inc/locale.h
|
@ -1,45 +1,45 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define _COL_IGNORE_SPACE 0x1
|
#define _COL_IGNORE_SPACE 0x1
|
||||||
#define _COL_IGNORE_SYMBOL 0x2
|
#define _COL_IGNORE_SYMBOL 0x2
|
||||||
|
|
||||||
struct lconv {
|
struct lconv {
|
||||||
// LC_NUMERIC
|
// LC_NUMERIC
|
||||||
char *decimal_point; // "."
|
char *decimal_point; // "."
|
||||||
char *thousands_sep; // ""
|
char *thousands_sep; // ""
|
||||||
char *grouping; // ""
|
char *grouping; // ""
|
||||||
// LC_MONETARY
|
// LC_MONETARY
|
||||||
char *mon_decimal_point; // ""
|
char *mon_decimal_point; // ""
|
||||||
char *mon_thousands_sep; // ""
|
char *mon_thousands_sep; // ""
|
||||||
char *mon_grouping; // ""
|
char *mon_grouping; // ""
|
||||||
char *positive_sign; // ""
|
char *positive_sign; // ""
|
||||||
char *negative_sign; // ""
|
char *negative_sign; // ""
|
||||||
char *currency_symbol; // ""
|
char *currency_symbol; // ""
|
||||||
char frac_digits; // CHAR_MAX
|
char frac_digits; // CHAR_MAX
|
||||||
char p_cs_precedes; // CHAR_MAX
|
char p_cs_precedes; // CHAR_MAX
|
||||||
char n_cs_precedes; // CHAR_MAX
|
char n_cs_precedes; // CHAR_MAX
|
||||||
char p_sep_by_space; // CHAR_MAX
|
char p_sep_by_space; // CHAR_MAX
|
||||||
char n_sep_by_space; // CHAR_MAX
|
char n_sep_by_space; // CHAR_MAX
|
||||||
char p_sign_posn; // CHAR_MAX
|
char p_sign_posn; // CHAR_MAX
|
||||||
char n_sign_posn; // CHAR_MAX
|
char n_sign_posn; // CHAR_MAX
|
||||||
char *int_curr_symbol; // ""
|
char *int_curr_symbol; // ""
|
||||||
char int_frac_digits; // CHAR_MAX
|
char int_frac_digits; // CHAR_MAX
|
||||||
char int_p_cs_precedes; // CHAR_MAX
|
char int_p_cs_precedes; // CHAR_MAX
|
||||||
char int_n_cs_precedes; // CHAR_MAX
|
char int_n_cs_precedes; // CHAR_MAX
|
||||||
char int_p_sep_by_space; // CHAR_MAX
|
char int_p_sep_by_space; // CHAR_MAX
|
||||||
char int_n_sep_by_space; // CHAR_MAX
|
char int_n_sep_by_space; // CHAR_MAX
|
||||||
char int_p_sign_posn; // CHAR_MAX
|
char int_p_sign_posn; // CHAR_MAX
|
||||||
char int_n_sign_posn; // CHAR_MAX
|
char int_n_sign_posn; // CHAR_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
// Locale categories
|
// Locale categories
|
||||||
#define LC_ALL 0
|
#define LC_ALL 0
|
||||||
#define LC_COLLATE 1
|
#define LC_COLLATE 1
|
||||||
#define LC_CTYPE 2
|
#define LC_CTYPE 2
|
||||||
#define LC_MONETARY 3
|
#define LC_MONETARY 3
|
||||||
#define LC_NUMERIC 4
|
#define LC_NUMERIC 4
|
||||||
#define LC_TIME 5
|
#define LC_TIME 5
|
||||||
|
|
||||||
char *setlocale(int category, const char *locale);
|
char *setlocale(int category, const char *locale);
|
||||||
struct lconv *localeconv(void);
|
struct lconv *localeconv(void);
|
||||||
|
|
522
inc/math.h
522
inc/math.h
|
@ -1,220 +1,302 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef float float_t;
|
typedef float float_t;
|
||||||
typedef double double_t;
|
typedef double double_t;
|
||||||
|
|
||||||
#ifndef _HUGE_ENUF
|
#ifndef _HUGE_ENUF
|
||||||
#define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow
|
#define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
|
#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
|
||||||
#define HUGE_VAL ((double)INFINITY)
|
#define HUGE_VAL ((double)INFINITY)
|
||||||
#define HUGE_VALF ((float)INFINITY)
|
#define HUGE_VALF ((float)INFINITY)
|
||||||
|
|
||||||
#define NAN (-(float)(INFINITY * 0.0F))
|
#define NAN (-(float)(INFINITY * 0.0F))
|
||||||
|
|
||||||
// FP_ILOGB0
|
#define FP_ILOGBNAN (-1-0x7fffffff)
|
||||||
// FP_ILOGBNAN
|
#define FP_ILOGB0 FP_ILOGBNAN
|
||||||
|
|
||||||
#define MATH_ERRNO 1
|
#define MATH_ERRNO 1
|
||||||
#define MATH_ERREXCEPT 2
|
#define MATH_ERREXCEPT 2
|
||||||
|
|
||||||
#define math_errhandling MATH_ERRNO
|
#define math_errhandling MATH_ERRNO
|
||||||
|
|
||||||
// Classification
|
// Classification
|
||||||
#define FP_INFINITE 0
|
#define FP_INFINITE 0
|
||||||
#define FP_NAN 1
|
#define FP_NAN 1
|
||||||
#define FP_NORMAL 2
|
#define FP_NORMAL 2
|
||||||
#define FP_SUBNORMAL 3
|
#define FP_SUBNORMAL 3
|
||||||
#define FP_ZERO 4
|
#define FP_ZERO 4
|
||||||
int _fpclassify(double f);
|
int _fpclassify(double);
|
||||||
int _fpclassifyf(float f);
|
int _fpclassifyf(float);
|
||||||
#define fpclassify(x) (sizeof(x)==4?_fpclassifyf(x):_fpclassify(x))
|
int _fpclassifyl(long double);
|
||||||
#define isfinite(x) (fpclassify(x) != FP_INFINITE && fpclassify(x) != FP_NAN)
|
#define fpclassify(x) (sizeof(x)==4?_fpclassifyf(x)\
|
||||||
#define isinf(x) (fpclassify(x) == FP_INFINITE)
|
:sizeof(x)==8?_fpclassify(x) \
|
||||||
#define isnan(x) (fpclassify(x) == FP_NAN)
|
: _fpclassifyl(x))
|
||||||
#define isnormal(x) (fpclassify(x) == FP_NORMAL)
|
#define isfinite(x) (fpclassify(x) != FP_INFINITE && fpclassify(x) != FP_NAN)
|
||||||
|
#define isinf(x) (fpclassify(x) == FP_INFINITE)
|
||||||
// Sign bit shit
|
#define isnan(x) (fpclassify(x) == FP_NAN)
|
||||||
int _signbit(double f);
|
#define isnormal(x) (fpclassify(x) == FP_NORMAL)
|
||||||
int _signbitf(float f);
|
|
||||||
#define signbit(x) (sizeof(x)==4?_signbitf(x):signbit(x))
|
// signbit shit
|
||||||
float copysignf(float x, float y);
|
int _signbit(double);
|
||||||
|
int _signbitf(float);
|
||||||
// Ordering
|
int _signbitl(long double);
|
||||||
#define isgreater(x) (sizeof(x)==4?_isgrtf(x):_isgrt(x))
|
#define signbit(x) (sizeof(x) == sizeof(float) ? _signbitf(x) \
|
||||||
#define isgreaterequal(x) (sizeof(x)==4?_isgeqf(x):_isgeq(x))
|
:sizeof(x) == sizeof(double) ? _signbit(x) \
|
||||||
#define isless(x) (sizeof(x)==4?_islesf(x):_isles(x))
|
: _signbitl(x))
|
||||||
#define islessequal(x) (sizeof(x)==4?_isleqf(x):_isleq(x))
|
|
||||||
#define islessgreater(x) (sizeof(x)==4?_islegf(x):_isleg(x))
|
// Ordering
|
||||||
#define isunordered(x) (sizeof(x)==4?_isunof(x):_isuno(x))
|
#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y)))
|
||||||
|
#define isgreater(x,y) (!isunordered(x,y) && ((x) > (y)))
|
||||||
double acos(double x);
|
#define isgreaterequal(x,y) (!isunordered(x,y) && ((x) >= (y)))
|
||||||
float acosf(float x);
|
#define isless(x,y) (!isunordered(x,y) && ((x) < (y)))
|
||||||
|
#define islessequal(x,y) (!isunordered(x,y) && ((x) <= (y)))
|
||||||
double asin(double x);
|
#define islessgreater(x,y) (!isunordered(x,y) && ((x) != (y)))
|
||||||
float asinf(float x);
|
|
||||||
|
#if defined(_USE_MATH_DEFINES)
|
||||||
double atan(double x);
|
#define M_E 2.7182818284590452354
|
||||||
float atanf(float x);
|
#define M_LOG2E 1.4426950408889634074
|
||||||
|
#define M_LOG10E 0.43429448190325182765
|
||||||
double atan2(double y, double x);
|
#define M_LN2 0.69314718055994530942
|
||||||
float atan2f(float y, float x);
|
#define M_LN10 2.30258509299404568402
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
double cos(double x);
|
#define M_PI_2 1.57079632679489661923
|
||||||
float cosf(float x);
|
#define M_PI_4 0.78539816339744830962
|
||||||
|
#define M_1_PI 0.31830988618379067154
|
||||||
double sin(double x);
|
#define M_2_PI 0.63661977236758134308
|
||||||
float sinf(float x);
|
#define M_2_SQRTPI 1.12837916709551257390
|
||||||
|
#define M_SQRT2 1.41421356237309504880
|
||||||
double tan(double x);
|
#define M_SQRT1_2 0.70710678118654752440
|
||||||
float tanf(float x);
|
#endif
|
||||||
|
|
||||||
double acosh(double x);
|
// Floating-point function prototypes
|
||||||
float acoshf(float x);
|
double acos(double);
|
||||||
|
float acosf(float);
|
||||||
double asinh(double x);
|
long double acosl(long double);
|
||||||
float asinhf(float x);
|
|
||||||
|
double acosh(double);
|
||||||
double atanh(double x);
|
float acoshf(float);
|
||||||
float atanhf(float x);
|
long double acoshl(long double);
|
||||||
|
|
||||||
double cosh(double x);
|
double asin(double);
|
||||||
float coshf(float x);
|
float asinf(float);
|
||||||
|
long double asinl(long double);
|
||||||
double sinh(double x);
|
|
||||||
float sinhf(float x);
|
double asinh(double);
|
||||||
|
float asinhf(float);
|
||||||
double tanh(double x);
|
long double asinhl(long double);
|
||||||
float tanhf(float x);
|
|
||||||
|
double atan(double);
|
||||||
double exp(double x);
|
float atanf(float);
|
||||||
float expf(float x);
|
long double atanl(long double);
|
||||||
|
|
||||||
double exp2(double x);
|
double atan2(double, double);
|
||||||
float exp2f(float x);
|
float atan2f(float, float);
|
||||||
|
long double atan2l(long double, long double);
|
||||||
double expm1(double x);
|
|
||||||
float expm1f(float x);
|
double atanh(double);
|
||||||
|
float atanhf(float);
|
||||||
double frexp(double value, int *exp);
|
long double atanhl(long double);
|
||||||
float frexpf(float value, int *exp);
|
|
||||||
|
double cbrt(double);
|
||||||
int ilogb(double x);
|
float cbrtf(float);
|
||||||
int ilogbf(float x);
|
long double cbrtl(long double);
|
||||||
|
|
||||||
double ldexp(double x, int exp);
|
double ceil(double);
|
||||||
float ldexpf(float x, int exp);
|
float ceilf(float);
|
||||||
|
long double ceill(long double);
|
||||||
double log(double x);
|
|
||||||
float logf(float x);
|
double copysign(double, double);
|
||||||
|
float copysignf(float, float);
|
||||||
double log10(double x);
|
long double copysignl(long double, long double);
|
||||||
float log10f(float x);
|
|
||||||
|
double cos(double);
|
||||||
double log1p(double x);
|
float cosf(float);
|
||||||
float log1pf(float x);
|
long double cosl(long double);
|
||||||
|
|
||||||
double log2(double x);
|
double cosh(double);
|
||||||
float log2f(float x);
|
float coshf(float);
|
||||||
|
long double coshl(long double);
|
||||||
double logb(double x);
|
|
||||||
float logbf(float x);
|
double erf(double);
|
||||||
|
float erff(float);
|
||||||
double modf(double value, double *iptr);
|
long double erfl(long double);
|
||||||
float modff(float value, float *iptr);
|
|
||||||
|
double erfc(double);
|
||||||
double scalbn(double x, int n);
|
float erfcf(float);
|
||||||
float scalbnf(float x, int n);
|
long double erfcl(long double);
|
||||||
|
|
||||||
double scalbln(double x, long int n);
|
double exp(double);
|
||||||
float scalblnf(float x, long int n);
|
float expf(float);
|
||||||
|
long double expl(long double);
|
||||||
double cbrt(double x);
|
|
||||||
float cbrtf(float x);
|
double exp2(double);
|
||||||
|
float exp2f(float);
|
||||||
double fabs(double x);
|
long double exp2l(long double);
|
||||||
float fabsf(float x);
|
|
||||||
|
double expm1(double);
|
||||||
double hypot(double x, double y);
|
float expm1f(float);
|
||||||
float hypotf(float x, float y);
|
long double expm1l(long double);
|
||||||
|
|
||||||
double pow(double x, double y);
|
double fabs(double);
|
||||||
float powf(float x, float y);
|
float fabsf(float);
|
||||||
|
long double fabsl(long double);
|
||||||
double sqrt(double x);
|
|
||||||
float sqrtf(float x);
|
double fdim(double, double);
|
||||||
|
float fdimf(float, float);
|
||||||
double erf(double x);
|
long double fdiml(long double, long double);
|
||||||
float erff(float x);
|
|
||||||
|
double floor(double);
|
||||||
double erfc(double x);
|
float floorf(float);
|
||||||
float erfcf(float x);
|
long double floorl(long double);
|
||||||
|
|
||||||
double lgamma(double x);
|
double fma(double, double, double);
|
||||||
float lgammaf(float x);
|
float fmaf(float, float, float);
|
||||||
|
long double fmal(long double, long double, long double);
|
||||||
double tgamma(double x);
|
|
||||||
float tgammaf(float x);
|
double fmax(double, double);
|
||||||
|
float fmaxf(float, float);
|
||||||
double ceil(double x);
|
long double fmaxl(long double, long double);
|
||||||
float ceilf(float x);
|
|
||||||
|
double fmin(double, double);
|
||||||
double floor(double x);
|
float fminf(float, float);
|
||||||
float floorf(float x);
|
long double fminl(long double, long double);
|
||||||
|
|
||||||
double nearbyint(double x);
|
double fmod(double, double);
|
||||||
float nearbyintf(float x);
|
float fmodf(float, float);
|
||||||
|
long double fmodl(long double, long double);
|
||||||
double rint(double x);
|
|
||||||
float rintf(float x);
|
double frexp(double, int *);
|
||||||
|
float frexpf(float, int *);
|
||||||
long int lrint(double x);
|
long double frexpl(long double, int *);
|
||||||
long int lrintf(float x);
|
|
||||||
|
double hypot(double, double);
|
||||||
long long int llrint(double x);
|
float hypotf(float, float);
|
||||||
long long int llrintf(float x);
|
long double hypotl(long double, long double);
|
||||||
|
|
||||||
double round(double x);
|
int ilogb(double);
|
||||||
float roundf(float x);
|
int ilogbf(float);
|
||||||
|
int ilogbl(long double);
|
||||||
long int lround(double x);
|
|
||||||
long int lroundf(float x);
|
double ldexp(double, int);
|
||||||
|
float ldexpf(float, int);
|
||||||
long long int llround(double x);
|
long double ldexpl(long double, int);
|
||||||
long long int llroundf(float x);
|
|
||||||
|
double lgamma(double);
|
||||||
double trunc(double x);
|
float lgammaf(float);
|
||||||
float truncf(float x);
|
long double lgammal(long double);
|
||||||
|
|
||||||
double fmod(double x, double y);
|
long long llrint(double);
|
||||||
float fmodf(float x, float y);
|
long long llrintf(float);
|
||||||
|
long long llrintl(long double);
|
||||||
double remainder(double x, double y);
|
|
||||||
float remainderf(float x, float y);
|
long long llround(double);
|
||||||
|
long long llroundf(float);
|
||||||
double remquo(double x, double y, int *quo);
|
long long llroundl(long double);
|
||||||
float remquof(float x, float y, int *quo);
|
|
||||||
|
double log(double);
|
||||||
double copysign(double x, double y);
|
float logf(float);
|
||||||
float copysignf(float x, float y);
|
long double logl(long double);
|
||||||
|
|
||||||
double nan(const char *tagp);
|
double log10(double);
|
||||||
float nanf(const char *tagp);
|
float log10f(float);
|
||||||
|
long double log10l(long double);
|
||||||
double nextafter(double x, double y);
|
|
||||||
float nextafterf(float x, float y);
|
double log1p(double);
|
||||||
|
float log1pf(float);
|
||||||
double fdim(double x, double y);
|
long double log1pl(long double);
|
||||||
float fdimf(float x, float y);
|
|
||||||
|
double log2(double);
|
||||||
double fmax(double x, double y);
|
float log2f(float);
|
||||||
float fmaxf(float x, float y);
|
long double log2l(long double);
|
||||||
|
|
||||||
double fmin(double x, double y);
|
double logb(double);
|
||||||
float fminf(float x, float y);
|
float logbf(float);
|
||||||
|
long double logbl(long double);
|
||||||
double fma(double x, double y, double z);
|
|
||||||
float fmaf(float x, float y, float z);
|
long lrint(double);
|
||||||
|
long lrintf(float);
|
||||||
|
long lrintl(long double);
|
||||||
|
|
||||||
|
long lround(double);
|
||||||
|
long lroundf(float);
|
||||||
|
long lroundl(long double);
|
||||||
|
|
||||||
|
double modf(double, double *);
|
||||||
|
float modff(float, float *);
|
||||||
|
long double modfl(long double, long double *);
|
||||||
|
|
||||||
|
double nan(const char *);
|
||||||
|
float nanf(const char *);
|
||||||
|
long double nanl(const char *);
|
||||||
|
|
||||||
|
double nearbyint(double);
|
||||||
|
float nearbyintf(float);
|
||||||
|
long double nearbyintl(long double);
|
||||||
|
|
||||||
|
double nextafter(double, double);
|
||||||
|
float nextafterf(float, float);
|
||||||
|
long double nextafterl(long double, long double);
|
||||||
|
|
||||||
|
double nexttoward(double, long double);
|
||||||
|
float nexttowardf(float, long double);
|
||||||
|
long double nexttowardl(long double, long double);
|
||||||
|
|
||||||
|
double pow(double, double);
|
||||||
|
float powf(float, float);
|
||||||
|
long double powl(long double, long double);
|
||||||
|
|
||||||
|
double remainder(double, double);
|
||||||
|
float remainderf(float, float);
|
||||||
|
long double remainderl(long double, long double);
|
||||||
|
|
||||||
|
double remquo(double, double, int *);
|
||||||
|
float remquof(float, float, int *);
|
||||||
|
long double remquol(long double, long double, int *);
|
||||||
|
|
||||||
|
double rint(double);
|
||||||
|
float rintf(float);
|
||||||
|
long double rintl(long double);
|
||||||
|
|
||||||
|
double round(double);
|
||||||
|
float roundf(float);
|
||||||
|
long double roundl(long double);
|
||||||
|
|
||||||
|
double scalbln(double, long);
|
||||||
|
float scalblnf(float, long);
|
||||||
|
long double scalblnl(long double, long);
|
||||||
|
|
||||||
|
double scalbn(double, int);
|
||||||
|
float scalbnf(float, int);
|
||||||
|
long double scalbnl(long double, int);
|
||||||
|
|
||||||
|
double sin(double);
|
||||||
|
float sinf(float);
|
||||||
|
long double sinl(long double);
|
||||||
|
|
||||||
|
double sinh(double);
|
||||||
|
float sinhf(float);
|
||||||
|
long double sinhl(long double);
|
||||||
|
|
||||||
|
double sqrt(double);
|
||||||
|
float sqrtf(float);
|
||||||
|
long double sqrtl(long double);
|
||||||
|
|
||||||
|
double tan(double);
|
||||||
|
float tanf(float);
|
||||||
|
long double tanl(long double);
|
||||||
|
|
||||||
|
double tanh(double);
|
||||||
|
float tanhf(float);
|
||||||
|
long double tanhl(long double);
|
||||||
|
|
||||||
|
double tgamma(double);
|
||||||
|
float tgammaf(float);
|
||||||
|
long double tgammal(long double);
|
||||||
|
|
||||||
|
double trunc(double);
|
||||||
|
float truncf(float);
|
||||||
|
long double truncl(long double);
|
||||||
|
|
||||||
|
|
52
inc/signal.h
52
inc/signal.h
|
@ -1,26 +1,26 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef int sig_atomic_t;
|
typedef int sig_atomic_t;
|
||||||
|
|
||||||
// TODO: idk about SIG_ERR, for now this
|
// TODO: idk about SIG_ERR, for now this
|
||||||
#define SIG_ERR ((void(*)(int))0)
|
#define SIG_ERR ((void(*)(int))0)
|
||||||
#define SIG_DFL _signal_default_handler
|
#define SIG_DFL _signal_default_handler
|
||||||
#define SIG_IGN _signal_ignore_handler
|
#define SIG_IGN _signal_ignore_handler
|
||||||
|
|
||||||
// Note(bumbread): from the impl standpoint the numbers are arbitrary
|
// Note(bumbread): from the impl standpoint the numbers are arbitrary
|
||||||
#define _SIG_MIN 0
|
#define _SIG_MIN 0
|
||||||
#define SIGINT 1
|
#define SIGINT 1
|
||||||
#define SIGILL 2
|
#define SIGILL 2
|
||||||
#define SIGFPE 3
|
#define SIGFPE 3
|
||||||
#define SIGSEGV 4
|
#define SIGSEGV 4
|
||||||
#define SIGTERM 5
|
#define SIGTERM 5
|
||||||
#define SIGABRT 6
|
#define SIGABRT 6
|
||||||
// These guys are impl defined
|
// These guys are impl defined
|
||||||
#define SIGBREAK 7
|
#define SIGBREAK 7
|
||||||
#define SIGALIGN 8
|
#define SIGALIGN 8
|
||||||
#define SIGSTEP 9
|
#define SIGSTEP 9
|
||||||
#define _SIG_MAX 9
|
#define _SIG_MAX 9
|
||||||
|
|
||||||
void (*signal(int sig, void (*func)(int)))(int);
|
void (*signal(int sig, void (*func)(int)))(int);
|
||||||
int raise(int sig);
|
int raise(int sig);
|
||||||
|
|
130
inc/string.h
130
inc/string.h
|
@ -1,65 +1,65 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Technically all we should have here is typedef for size_t.
|
// Technically all we should have here is typedef for size_t.
|
||||||
// but I can't get that without macro shittery so
|
// but I can't get that without macro shittery so
|
||||||
// for now I'm just doing this, which is not quite correct
|
// for now I'm just doing this, which is not quite correct
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if !defined(NULL)
|
#if !defined(NULL)
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__STDC_LIB_EXT1__)
|
#if !defined(__STDC_LIB_EXT1__)
|
||||||
#define __STDC_LIB_EXT1__
|
#define __STDC_LIB_EXT1__
|
||||||
typedef int errno_t;
|
typedef int errno_t;
|
||||||
typedef size_t rsize_t;
|
typedef size_t rsize_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC_WANT_SECURE_LIB__ == 1
|
#if __STDC_WANT_SECURE_LIB__ == 1
|
||||||
#if !defined(__STDC_WANT_LIB_EXT1__)
|
#if !defined(__STDC_WANT_LIB_EXT1__)
|
||||||
#define __STDC_WANT_LIB_EXT1__ 1
|
#define __STDC_WANT_LIB_EXT1__ 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2);
|
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2);
|
||||||
|
|
||||||
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
|
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
|
||||||
void *memmove(void *s1, const void *s2, size_t n);
|
void *memmove(void *s1, const void *s2, size_t n);
|
||||||
char *strcpy(char *restrict s1, const char *restrict s2);
|
char *strcpy(char *restrict s1, const char *restrict s2);
|
||||||
char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
|
char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
|
||||||
char *strcat(char *restrict s1, const char *restrict s2);
|
char *strcat(char *restrict s1, const char *restrict s2);
|
||||||
char *strncat(char *restrict s1, const char *restrict s2, size_t n);
|
char *strncat(char *restrict s1, const char *restrict s2, size_t n);
|
||||||
int memcmp(const void *s1, const void *s2, size_t n);
|
int memcmp(const void *s1, const void *s2, size_t n);
|
||||||
int strcmp(const char *s1, const char *s2);
|
int strcmp(const char *s1, const char *s2);
|
||||||
int strcoll(const char *s1, const char *s2);
|
int strcoll(const char *s1, const char *s2);
|
||||||
int strncmp(const char *s1, const char *s2, size_t n);
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n);
|
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n);
|
||||||
void *memchr(const void *s, int c, size_t n);
|
void *memchr(const void *s, int c, size_t n);
|
||||||
char *strchr(const char *s, int c);
|
char *strchr(const char *s, int c);
|
||||||
size_t strcspn(const char *s1, const char *s2);
|
size_t strcspn(const char *s1, const char *s2);
|
||||||
char *strpbrk(const char *s1, const char *s2);
|
char *strpbrk(const char *s1, const char *s2);
|
||||||
char *strrchr(const char *s, int c);
|
char *strrchr(const char *s, int c);
|
||||||
size_t strspn(const char *s1, const char *s2);
|
size_t strspn(const char *s1, const char *s2);
|
||||||
char *strstr(const char *s1, const char *s2);
|
char *strstr(const char *s1, const char *s2);
|
||||||
char *strtok(char *restrict s1, const char *restrict s2);
|
char *strtok(char *restrict s1, const char *restrict s2);
|
||||||
void *memset(void *s, int c, size_t n);
|
void *memset(void *s, int c, size_t n);
|
||||||
char *strerror(int errnum);
|
char *strerror(int errnum);
|
||||||
size_t strlen(const char *s);
|
size_t strlen(const char *s);
|
||||||
|
|
||||||
// Linux extension: reentrant strtok
|
// Linux extension: reentrant strtok
|
||||||
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx);
|
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx);
|
||||||
|
|
||||||
#if __STDC_WANT_LIB_EXT1__ == 1
|
#if __STDC_WANT_LIB_EXT1__ == 1
|
||||||
errno_t memcpy_s(void *restrict s1, rsize_t s1max, const void *restrict s2, rsize_t n);
|
errno_t memcpy_s(void *restrict s1, rsize_t s1max, const void *restrict s2, rsize_t n);
|
||||||
errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n);
|
errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n);
|
||||||
errno_t strcpy_s(char *restrict s1, rsize_t s1max, const char *restrict s2);
|
errno_t strcpy_s(char *restrict s1, rsize_t s1max, const char *restrict s2);
|
||||||
errno_t strncpy_s(char *restrict s1, rsize_t s1max,const char *restrict s2, rsize_t n);
|
errno_t strncpy_s(char *restrict s1, rsize_t s1max,const char *restrict s2, rsize_t n);
|
||||||
errno_t strcat_s(char *restrict s1, rsize_t s1max, const char *restrict s2);
|
errno_t strcat_s(char *restrict s1, rsize_t s1max, const char *restrict s2);
|
||||||
errno_t strncat_s(char *restrict s1, rsize_t s1max, const char *restrict s2, rsize_t n);
|
errno_t strncat_s(char *restrict s1, rsize_t s1max, const char *restrict s2, rsize_t n);
|
||||||
char *strtok_s(char *restrict s1, rsize_t *restrict s1max, const char *restrict s2, char **restrict ptr);
|
char *strtok_s(char *restrict s1, rsize_t *restrict s1max, const char *restrict s2, char **restrict ptr);
|
||||||
errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n);
|
errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n);
|
||||||
errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum);
|
errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum);
|
||||||
size_t strerrorlen_s(errno_t errnum);
|
size_t strerrorlen_s(errno_t errnum);
|
||||||
size_t strnlen_s(const char *str, size_t strsz);
|
size_t strnlen_s(const char *str, size_t strsz);
|
||||||
#endif
|
#endif
|
||||||
|
|
132
inc/tgmath.h
132
inc/tgmath.h
|
@ -1,67 +1,67 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/*
|
/*
|
||||||
these are type generic so they're macrod and use C11's _Generic
|
these are type generic so they're macrod and use C11's _Generic
|
||||||
|
|
||||||
acos
|
acos
|
||||||
asin
|
asin
|
||||||
atan
|
atan
|
||||||
acosh
|
acosh
|
||||||
asinh
|
asinh
|
||||||
atanh
|
atanh
|
||||||
cos
|
cos
|
||||||
sin
|
sin
|
||||||
tan
|
tan
|
||||||
cosh
|
cosh
|
||||||
sinh
|
sinh
|
||||||
tanh
|
tanh
|
||||||
exp
|
exp
|
||||||
log
|
log
|
||||||
pow
|
pow
|
||||||
sqrt
|
sqrt
|
||||||
fabs
|
fabs
|
||||||
atan2
|
atan2
|
||||||
cbrt
|
cbrt
|
||||||
ceil
|
ceil
|
||||||
copysign
|
copysign
|
||||||
erf
|
erf
|
||||||
erfc
|
erfc
|
||||||
exp2
|
exp2
|
||||||
expm1
|
expm1
|
||||||
fdim
|
fdim
|
||||||
floor
|
floor
|
||||||
fma
|
fma
|
||||||
fmax
|
fmax
|
||||||
fmin
|
fmin
|
||||||
fmod
|
fmod
|
||||||
frexp
|
frexp
|
||||||
hypot
|
hypot
|
||||||
ilogb
|
ilogb
|
||||||
ldexp
|
ldexp
|
||||||
lgamma
|
lgamma
|
||||||
llrint
|
llrint
|
||||||
llround
|
llround
|
||||||
log10
|
log10
|
||||||
log1p
|
log1p
|
||||||
log2
|
log2
|
||||||
logb
|
logb
|
||||||
lrint
|
lrint
|
||||||
lround
|
lround
|
||||||
nearbyint
|
nearbyint
|
||||||
nextafter
|
nextafter
|
||||||
nexttoward
|
nexttoward
|
||||||
remainder
|
remainder
|
||||||
remquo
|
remquo
|
||||||
rint
|
rint
|
||||||
round
|
round
|
||||||
scalbn
|
scalbn
|
||||||
scalbln
|
scalbln
|
||||||
tgamma
|
tgamma
|
||||||
trunc
|
trunc
|
||||||
carg
|
carg
|
||||||
cimag
|
cimag
|
||||||
conj
|
conj
|
||||||
cproj
|
cproj
|
||||||
creal
|
creal
|
||||||
*/
|
*/
|
142
inc/threads.h
142
inc/threads.h
|
@ -1,71 +1,71 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define thread_local _Thread_local
|
#define thread_local _Thread_local
|
||||||
#define ONCE_FLAG_INIT 1
|
#define ONCE_FLAG_INIT 1
|
||||||
|
|
||||||
#define TSS_DTOR_ITERATIONS 32
|
#define TSS_DTOR_ITERATIONS 32
|
||||||
|
|
||||||
typedef struct cnd_t {
|
typedef struct cnd_t {
|
||||||
int idk_yet;
|
int idk_yet;
|
||||||
} cnd_t;
|
} cnd_t;
|
||||||
|
|
||||||
typedef struct thrd_t {
|
typedef struct thrd_t {
|
||||||
int idk_yet;
|
int idk_yet;
|
||||||
} thrd_t;
|
} thrd_t;
|
||||||
|
|
||||||
typedef struct tss_t {
|
typedef struct tss_t {
|
||||||
int idk_yet;
|
int idk_yet;
|
||||||
} tss_t;
|
} tss_t;
|
||||||
|
|
||||||
typedef struct mtx_t {
|
typedef struct mtx_t {
|
||||||
int idk_yet;
|
int idk_yet;
|
||||||
} mtx_t;
|
} mtx_t;
|
||||||
|
|
||||||
typedef void(*tss_dtor_t)(void*);
|
typedef void(*tss_dtor_t)(void*);
|
||||||
typedef int(*thrd_start_t)(void*);
|
typedef int(*thrd_start_t)(void*);
|
||||||
|
|
||||||
// TODO: change this maybe?
|
// TODO: change this maybe?
|
||||||
typedef int once_flag;
|
typedef int once_flag;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
mtx_plain = 1,
|
mtx_plain = 1,
|
||||||
mtx_recursive = 2,
|
mtx_recursive = 2,
|
||||||
mtx_timed = 4
|
mtx_timed = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
thrd_success,
|
thrd_success,
|
||||||
thrd_timedout,
|
thrd_timedout,
|
||||||
thrd_busy,
|
thrd_busy,
|
||||||
thrd_error,
|
thrd_error,
|
||||||
thrd_nomem
|
thrd_nomem
|
||||||
};
|
};
|
||||||
|
|
||||||
void call_once(once_flag *flag, void (*func)(void));
|
void call_once(once_flag *flag, void (*func)(void));
|
||||||
int cnd_broadcast(cnd_t *cond);
|
int cnd_broadcast(cnd_t *cond);
|
||||||
void cnd_destroy(cnd_t *cond);
|
void cnd_destroy(cnd_t *cond);
|
||||||
int cnd_init(cnd_t *cond);
|
int cnd_init(cnd_t *cond);
|
||||||
int cnd_signal(cnd_t *cond);
|
int cnd_signal(cnd_t *cond);
|
||||||
int cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mtx, const struct timespec *restrict ts);
|
int cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mtx, const struct timespec *restrict ts);
|
||||||
int cnd_wait(cnd_t *cond, mtx_t *mtx);
|
int cnd_wait(cnd_t *cond, mtx_t *mtx);
|
||||||
void mtx_destroy(mtx_t *mtx);
|
void mtx_destroy(mtx_t *mtx);
|
||||||
int mtx_init(mtx_t *mtx, int type);
|
int mtx_init(mtx_t *mtx, int type);
|
||||||
int mtx_lock(mtx_t *mtx);
|
int mtx_lock(mtx_t *mtx);
|
||||||
int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts);
|
int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts);
|
||||||
int mtx_trylock(mtx_t *mtx);
|
int mtx_trylock(mtx_t *mtx);
|
||||||
int mtx_unlock(mtx_t *mtx);
|
int mtx_unlock(mtx_t *mtx);
|
||||||
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
|
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
|
||||||
thrd_t thrd_current(void);
|
thrd_t thrd_current(void);
|
||||||
int thrd_detach(thrd_t thr);
|
int thrd_detach(thrd_t thr);
|
||||||
int thrd_equal(thrd_t thr0, thrd_t thr1);
|
int thrd_equal(thrd_t thr0, thrd_t thr1);
|
||||||
_Noreturn void thrd_exit(int res);
|
_Noreturn void thrd_exit(int res);
|
||||||
int thrd_join(thrd_t thr, int *res);
|
int thrd_join(thrd_t thr, int *res);
|
||||||
int thrd_sleep(const struct timespec *duration, struct timespec *remaining);
|
int thrd_sleep(const struct timespec *duration, struct timespec *remaining);
|
||||||
void thrd_yield(void);
|
void thrd_yield(void);
|
||||||
int tss_create(tss_t *key, tss_dtor_t dtor);
|
int tss_create(tss_t *key, tss_dtor_t dtor);
|
||||||
void tss_delete(tss_t key);
|
void tss_delete(tss_t key);
|
||||||
void *tss_get(tss_t key);
|
void *tss_get(tss_t key);
|
||||||
int tss_set(tss_t key, void *val);
|
int tss_set(tss_t key, void *val);
|
||||||
|
|
98
inc/time.h
98
inc/time.h
|
@ -1,49 +1,49 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if !defined(NULL)
|
#if !defined(NULL)
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The number of clock ticks per second
|
// The number of clock ticks per second
|
||||||
#define CLOCKS_PER_SEC ((clock_t)1000)
|
#define CLOCKS_PER_SEC ((clock_t)1000)
|
||||||
|
|
||||||
#define TIME_UTC 1
|
#define TIME_UTC 1
|
||||||
|
|
||||||
typedef size_t clock_t;
|
typedef size_t clock_t;
|
||||||
typedef size_t time_t;
|
typedef size_t time_t;
|
||||||
|
|
||||||
struct timespec {
|
struct timespec {
|
||||||
time_t tv_sec; // Seconds - >= 0
|
time_t tv_sec; // Seconds - >= 0
|
||||||
long tv_nsec; // Nanoseconds - [0, 999999999]
|
long tv_nsec; // Nanoseconds - [0, 999999999]
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tm {
|
struct tm {
|
||||||
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
||||||
int tm_min; // minutes after the hour - [0, 59]
|
int tm_min; // minutes after the hour - [0, 59]
|
||||||
int tm_hour; // hours since midnight - [0, 23]
|
int tm_hour; // hours since midnight - [0, 23]
|
||||||
int tm_mday; // day of the month - [1, 31]
|
int tm_mday; // day of the month - [1, 31]
|
||||||
int tm_mon; // months since January - [0, 11]
|
int tm_mon; // months since January - [0, 11]
|
||||||
int tm_year; // years since 1900
|
int tm_year; // years since 1900
|
||||||
int tm_wday; // days since Sunday - [0, 6]
|
int tm_wday; // days since Sunday - [0, 6]
|
||||||
int tm_yday; // days since January 1 - [0, 365]
|
int tm_yday; // days since January 1 - [0, 365]
|
||||||
int tm_isdst; // daylight savings time flag
|
int tm_isdst; // daylight savings time flag
|
||||||
};
|
};
|
||||||
|
|
||||||
clock_t clock(void);
|
clock_t clock(void);
|
||||||
double difftime(time_t time1, time_t time0);
|
double difftime(time_t time1, time_t time0);
|
||||||
time_t mktime(struct tm *timeptr);
|
time_t mktime(struct tm *timeptr);
|
||||||
time_t time(time_t *timer);
|
time_t time(time_t *timer);
|
||||||
int timespec_get(struct timespec *ts, int base);
|
int timespec_get(struct timespec *ts, int base);
|
||||||
char *asctime(const struct tm *timeptr);
|
char *asctime(const struct tm *timeptr);
|
||||||
char *ctime(const time_t *timer);
|
char *ctime(const time_t *timer);
|
||||||
struct tm *gmtime(const time_t *timer);
|
struct tm *gmtime(const time_t *timer);
|
||||||
struct tm *localtime(const time_t *timer);
|
struct tm *localtime(const time_t *timer);
|
||||||
size_t strftime(char * restrict s, size_t maxsize, const char * restrict format, const struct tm * restrict timeptr);
|
size_t strftime(char * restrict s, size_t maxsize, const char * restrict format, const struct tm * restrict timeptr);
|
||||||
|
|
||||||
#ifdef __STDC_WANT_LIB_EXT1__
|
#ifdef __STDC_WANT_LIB_EXT1__
|
||||||
errno_t asctime_s(char *s, rsize_t maxsize, const struct tm *timeptr);
|
errno_t asctime_s(char *s, rsize_t maxsize, const struct tm *timeptr);
|
||||||
errno_t ctime_s(char *s, rsize_t maxsize, const time_t *timer);
|
errno_t ctime_s(char *s, rsize_t maxsize, const time_t *timer);
|
||||||
struct tm *gmtime_s(const time_t * restrict timer, struct tm * restrict result);
|
struct tm *gmtime_s(const time_t * restrict timer, struct tm * restrict result);
|
||||||
struct tm *localtime_s(const time_t * restrict timer, struct tm * restrict result);
|
struct tm *localtime_s(const time_t * restrict timer, struct tm * restrict result);
|
||||||
#endif
|
#endif
|
||||||
|
|
22
inc/uchar.h
22
inc/uchar.h
|
@ -1,11 +1,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef struct mbstate_t mbstate_t;
|
typedef struct mbstate_t mbstate_t;
|
||||||
typedef uint16_t char16_t;
|
typedef uint16_t char16_t;
|
||||||
typedef uint32_t char32_t;
|
typedef uint32_t char32_t;
|
||||||
|
|
||||||
size_t mbrtoc16(char16_t * restrict pc16, const char * restrict s, size_t n, mbstate_t * restrict ps);
|
size_t mbrtoc16(char16_t * restrict pc16, const char * restrict s, size_t n, mbstate_t * restrict ps);
|
||||||
size_t c16rtomb(char * restrict s, char16_t c16, mbstate_t * restrict ps);
|
size_t c16rtomb(char * restrict s, char16_t c16, mbstate_t * restrict ps);
|
||||||
size_t mbrtoc32(char32_t * restrict pc32, const char * restrict s, size_t n, mbstate_t * restrict ps);
|
size_t mbrtoc32(char32_t * restrict pc32, const char * restrict s, size_t n, mbstate_t * restrict ps);
|
||||||
size_t c32rtomb(char * restrict s, char32_t c32, mbstate_t * restrict ps);
|
size_t c32rtomb(char * restrict s, char32_t c32, mbstate_t * restrict ps);
|
||||||
|
|
202
inc/wchar.h
202
inc/wchar.h
|
@ -1,101 +1,101 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// On linux this will be UTF-32, on windows it's UTF-16 (or maybe UCS-2?)
|
// On linux this will be UTF-32, on windows it's UTF-16 (or maybe UCS-2?)
|
||||||
typedef struct mbstate_t mbstate_t;
|
typedef struct mbstate_t mbstate_t;
|
||||||
typedef wchar_t wint_t;
|
typedef wchar_t wint_t;
|
||||||
|
|
||||||
#define WCHAR_MIN 0x0000
|
#define WCHAR_MIN 0x0000
|
||||||
#define WCHAR_MAX 0xffff
|
#define WCHAR_MAX 0xffff
|
||||||
|
|
||||||
#ifndef WEOF
|
#ifndef WEOF
|
||||||
#define WEOF 0
|
#define WEOF 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int fwprintf(FILE * restrict stream, const wchar_t * restrict format, ...);
|
int fwprintf(FILE * restrict stream, const wchar_t * restrict format, ...);
|
||||||
int fwscanf(FILE * restrict stream, const wchar_t * restrict format, ...);
|
int fwscanf(FILE * restrict stream, const wchar_t * restrict format, ...);
|
||||||
int swprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format, ...);
|
int swprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format, ...);
|
||||||
int swscanf(const wchar_t * restrict s, const wchar_t * restrict format, ...);
|
int swscanf(const wchar_t * restrict s, const wchar_t * restrict format, ...);
|
||||||
int vfwprintf(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
int vfwprintf(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
||||||
int vfwscanf(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
int vfwscanf(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
||||||
int vswprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format, va_list arg);
|
int vswprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format, va_list arg);
|
||||||
int vswscanf(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg);
|
int vswscanf(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg);
|
||||||
int vwprintf(const wchar_t * restrict format, va_list arg);
|
int vwprintf(const wchar_t * restrict format, va_list arg);
|
||||||
int vwscanf(const wchar_t * restrict format, va_list arg);
|
int vwscanf(const wchar_t * restrict format, va_list arg);
|
||||||
int wprintf(const wchar_t * restrict format, ...);
|
int wprintf(const wchar_t * restrict format, ...);
|
||||||
int wscanf(const wchar_t * restrict format, ...);
|
int wscanf(const wchar_t * restrict format, ...);
|
||||||
wint_t fgetwc(FILE *stream);
|
wint_t fgetwc(FILE *stream);
|
||||||
wchar_t *fgetws(wchar_t * restrict s, int n, FILE * restrict stream);
|
wchar_t *fgetws(wchar_t * restrict s, int n, FILE * restrict stream);
|
||||||
wint_t fputwc(wchar_t c, FILE *stream);
|
wint_t fputwc(wchar_t c, FILE *stream);
|
||||||
int fputws(const wchar_t * restrict s, FILE * restrict stream);
|
int fputws(const wchar_t * restrict s, FILE * restrict stream);
|
||||||
int fwide(FILE *stream, int mode);
|
int fwide(FILE *stream, int mode);
|
||||||
wint_t getwc(FILE *stream);
|
wint_t getwc(FILE *stream);
|
||||||
wint_t getwchar(void);
|
wint_t getwchar(void);
|
||||||
wint_t putwc(wchar_t c, FILE *stream);
|
wint_t putwc(wchar_t c, FILE *stream);
|
||||||
wint_t putwchar(wchar_t c);
|
wint_t putwchar(wchar_t c);
|
||||||
wint_t ungetwc(wint_t c, FILE *stream);
|
wint_t ungetwc(wint_t c, FILE *stream);
|
||||||
double wcstod(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
|
double wcstod(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
|
||||||
float wcstof(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 double wcstold(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
|
||||||
long int wcstol(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
long int wcstol(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
||||||
long long int wcstoll(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
long long int wcstoll(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
||||||
unsigned long int wcstoul(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
unsigned long int wcstoul(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
||||||
unsigned long long int wcstoull(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
unsigned long long int wcstoull(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
|
||||||
wchar_t *wcscpy(wchar_t * restrict s1, const wchar_t * restrict s2);
|
wchar_t *wcscpy(wchar_t * restrict s1, const wchar_t * restrict s2);
|
||||||
wchar_t *wcsncpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
wchar_t *wcsncpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
||||||
wchar_t *wmemcpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
wchar_t *wmemcpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
||||||
wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2, size_t n);
|
wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2, size_t n);
|
||||||
wchar_t *wcscat(wchar_t * restrict s1, const wchar_t * restrict s2);
|
wchar_t *wcscat(wchar_t * restrict s1, const wchar_t * restrict s2);
|
||||||
wchar_t *wcsncat(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
wchar_t *wcsncat(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
||||||
int wcscmp(const wchar_t *s1, const wchar_t *s2);
|
int wcscmp(const wchar_t *s1, const wchar_t *s2);
|
||||||
int wcscoll(const wchar_t *s1, const wchar_t *s2);
|
int wcscoll(const wchar_t *s1, const wchar_t *s2);
|
||||||
int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n);
|
int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n);
|
||||||
size_t wcsxfrm(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
size_t wcsxfrm(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
|
||||||
int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n);
|
int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n);
|
||||||
wchar_t *wcschr(const wchar_t *s, wchar_t c);
|
wchar_t *wcschr(const wchar_t *s, wchar_t c);
|
||||||
size_t wcscspn(const wchar_t *s1, const wchar_t *s2);
|
size_t wcscspn(const wchar_t *s1, const wchar_t *s2);
|
||||||
wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2);
|
wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2);
|
||||||
wchar_t *wcsrchr(const wchar_t *s, wchar_t c);
|
wchar_t *wcsrchr(const wchar_t *s, wchar_t c);
|
||||||
size_t wcsspn(const wchar_t *s1, const wchar_t *s2);
|
size_t wcsspn(const wchar_t *s1, const wchar_t *s2);
|
||||||
wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2);
|
wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2);
|
||||||
wchar_t *wcstok(wchar_t * restrict s1, const wchar_t * restrict s2, wchar_t ** restrict ptr);
|
wchar_t *wcstok(wchar_t * restrict s1, const wchar_t * restrict s2, wchar_t ** restrict ptr);
|
||||||
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n);
|
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n);
|
||||||
size_t wcslen(const wchar_t *s);
|
size_t wcslen(const wchar_t *s);
|
||||||
wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n);
|
wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n);
|
||||||
size_t wcsftime(wchar_t * restrict s, size_t maxsize, const wchar_t * restrict format, const struct tm * restrict timeptr);
|
size_t wcsftime(wchar_t * restrict s, size_t maxsize, const wchar_t * restrict format, const struct tm * restrict timeptr);
|
||||||
wint_t btowc(int c);
|
wint_t btowc(int c);
|
||||||
int wctob(wint_t c);
|
int wctob(wint_t c);
|
||||||
int mbsinit(const mbstate_t *ps);
|
int mbsinit(const mbstate_t *ps);
|
||||||
size_t mbrlen(const char * restrict s, size_t n, mbstate_t * restrict ps);
|
size_t mbrlen(const char * restrict s, size_t n, mbstate_t * restrict ps);
|
||||||
size_t mbrtowc(wchar_t * restrict pwc, const char * restrict s, size_t n, mbstate_t * restrict ps);
|
size_t mbrtowc(wchar_t * restrict pwc, const char * restrict s, size_t n, mbstate_t * restrict ps);
|
||||||
size_t wcrtomb(char * restrict s, wchar_t wc, mbstate_t * restrict ps);
|
size_t wcrtomb(char * restrict s, wchar_t wc, mbstate_t * restrict ps);
|
||||||
size_t mbsrtowcs(wchar_t * restrict dst, const char ** restrict src, size_t len, mbstate_t * restrict ps);
|
size_t mbsrtowcs(wchar_t * restrict dst, const char ** restrict src, size_t len, mbstate_t * restrict ps);
|
||||||
size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps);
|
size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps);
|
||||||
|
|
||||||
#ifdef __STDC_WANT_LIB_EXT1__
|
#ifdef __STDC_WANT_LIB_EXT1__
|
||||||
int fwprintf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
int fwprintf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
||||||
int fwscanf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
int fwscanf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
||||||
int snwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
int snwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
||||||
int swprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
int swprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
||||||
int swscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, ...);
|
int swscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, ...);
|
||||||
int vfwprintf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
int vfwprintf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
||||||
int vfwscanf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
int vfwscanf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
||||||
int vsnwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
int vsnwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
||||||
int vswprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
int vswprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
||||||
int vswscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg);
|
int vswscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg);
|
||||||
int vwprintf_s(const wchar_t * restrict format, va_list arg);
|
int vwprintf_s(const wchar_t * restrict format, va_list arg);
|
||||||
int vwscanf_s(const wchar_t * restrict format, va_list arg);
|
int vwscanf_s(const wchar_t * restrict format, va_list arg);
|
||||||
int wprintf_s(const wchar_t * restrict format, ...);
|
int wprintf_s(const wchar_t * restrict format, ...);
|
||||||
int wscanf_s(const wchar_t * restrict format, ...);
|
int wscanf_s(const wchar_t * restrict format, ...);
|
||||||
errno_t wcscpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
errno_t wcscpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
||||||
errno_t wcsncpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
errno_t wcsncpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
||||||
errno_t wmemcpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
errno_t wmemcpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
||||||
errno_t wmemmove_s(wchar_t *s1, rsize_t s1max, const wchar_t *s2, rsize_t n);
|
errno_t wmemmove_s(wchar_t *s1, rsize_t s1max, const wchar_t *s2, rsize_t n);
|
||||||
errno_t wcscat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
errno_t wcscat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
||||||
errno_t wcsncat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
errno_t wcsncat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
||||||
wchar_t *wcstok_s(wchar_t * restrict s1, rsize_t * restrict s1max, const wchar_t * restrict s2, wchar_t ** restrict ptr);
|
wchar_t *wcstok_s(wchar_t * restrict s1, rsize_t * restrict s1max, const wchar_t * restrict s2, wchar_t ** restrict ptr);
|
||||||
size_t wcsnlen_s(const wchar_t *s, size_t maxsize);
|
size_t wcsnlen_s(const wchar_t *s, size_t maxsize);
|
||||||
errno_t wcrtomb_s(size_t * restrict retval, char * restrict s, rsize_t smax, wchar_t wc, mbstate_t * restrict ps);
|
errno_t wcrtomb_s(size_t * restrict retval, char * restrict s, rsize_t smax, wchar_t wc, mbstate_t * restrict ps);
|
||||||
errno_t mbsrtowcs_s(size_t * restrict retval, wchar_t * restrict dst, rsize_t dstmax, const char ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
errno_t mbsrtowcs_s(size_t * restrict retval, wchar_t * restrict dst, rsize_t dstmax, const char ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
||||||
errno_t wcsrtombs_s(size_t * restrict retval, char * restrict dst, rsize_t dstmax, const wchar_t ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
errno_t wcsrtombs_s(size_t * restrict retval, char * restrict dst, rsize_t dstmax, const wchar_t ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
||||||
#endif
|
#endif
|
||||||
|
|
58
inc/wctype.h
58
inc/wctype.h
|
@ -1,29 +1,29 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef int wint_t;
|
typedef int wint_t;
|
||||||
wctrans_t;
|
wctrans_t;
|
||||||
wctype_t;
|
wctype_t;
|
||||||
|
|
||||||
#ifndef WEOF
|
#ifndef WEOF
|
||||||
#define WEOF 0
|
#define WEOF 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int iswalnum(wint_t wc);
|
int iswalnum(wint_t wc);
|
||||||
int iswalpha(wint_t wc);
|
int iswalpha(wint_t wc);
|
||||||
int iswblank(wint_t wc);
|
int iswblank(wint_t wc);
|
||||||
int iswcntrl(wint_t wc);
|
int iswcntrl(wint_t wc);
|
||||||
int iswdigit(wint_t wc);
|
int iswdigit(wint_t wc);
|
||||||
int iswgraph(wint_t wc);
|
int iswgraph(wint_t wc);
|
||||||
int iswlower(wint_t wc);
|
int iswlower(wint_t wc);
|
||||||
int iswprint(wint_t wc);
|
int iswprint(wint_t wc);
|
||||||
int iswpunct(wint_t wc);
|
int iswpunct(wint_t wc);
|
||||||
int iswspace(wint_t wc);
|
int iswspace(wint_t wc);
|
||||||
int iswupper(wint_t wc);
|
int iswupper(wint_t wc);
|
||||||
int iswxdigit(wint_t wc);
|
int iswxdigit(wint_t wc);
|
||||||
int iswctype(wint_t wc, wctype_t desc);
|
int iswctype(wint_t wc, wctype_t desc);
|
||||||
wctype_t wctype(const char *property);
|
wctype_t wctype(const char *property);
|
||||||
wint_t towlower(wint_t wc);
|
wint_t towlower(wint_t wc);
|
||||||
wint_t towupper(wint_t wc);
|
wint_t towupper(wint_t wc);
|
||||||
wint_t towctrans(wint_t wc, wctrans_t desc);
|
wint_t towctrans(wint_t wc, wctrans_t desc);
|
||||||
wctrans_t wctrans(const char *property);
|
wctrans_t wctrans(const char *property);
|
||||||
|
|
22
test/test5.c
22
test/test5.c
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
void test_sqrt(float f) {
|
|
||||||
float s = sqrtf(f);
|
|
||||||
printf("sqrt of %f is %f\n", f, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
test_sqrt(0.0f);
|
|
||||||
test_sqrt(1.0f);
|
|
||||||
test_sqrt(2.0f);
|
|
||||||
test_sqrt(3.0f);
|
|
||||||
test_sqrt(4.0f);
|
|
||||||
test_sqrt(7.0f);
|
|
||||||
test_sqrt(9.0f);
|
|
||||||
test_sqrt(16.0f);
|
|
||||||
test_sqrt(256.0f);
|
|
||||||
test_sqrt(257.0f);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <fenv.h>
|
||||||
|
|
||||||
|
const char *show_classification(double x) {
|
||||||
|
switch(fpclassify(x)) {
|
||||||
|
case FP_INFINITE: return "Inf";
|
||||||
|
case FP_NAN: return "NaN";
|
||||||
|
case FP_NORMAL: return "normal";
|
||||||
|
case FP_SUBNORMAL: return "subnormal";
|
||||||
|
case FP_ZERO: return "zero";
|
||||||
|
default: return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
printf("\n=== fpclassify === \n");
|
||||||
|
double zero = 0.0; // fucken msvc
|
||||||
|
printf("1.0/0.0 is %s\n", show_classification(1.0/zero));
|
||||||
|
printf("0.0/0.0 is %s\n", show_classification(0.0/zero));
|
||||||
|
printf("DBL_MIN/2 is %s\n", show_classification(DBL_MIN/2));
|
||||||
|
printf("-0.0 is %s\n", show_classification(-0.0));
|
||||||
|
printf("1.0 is %s\n", show_classification(1.0));
|
||||||
|
|
||||||
|
printf("\n\n=== signbit === \n");
|
||||||
|
printf("signbit(+0.0) = %d\n", signbit(+0.0));
|
||||||
|
printf("signbit(-0.0) = %d\n", signbit(-0.0));
|
||||||
|
|
||||||
|
printf("\n\n=== copysign === \n");
|
||||||
|
printf("copysign(1.0,+2.0) = %f\n", copysign(1.0,+2.0));
|
||||||
|
printf("copysign(1.0,-2.0) = %f\n", copysign(1.0,-2.0));
|
||||||
|
printf("copysign(INFINITY,-2.0) = %f\n", copysign(INFINITY,-2.0));
|
||||||
|
printf("copysign(NAN,-2.0) = %f\n", copysign(NAN,-2.0));
|
||||||
|
|
||||||
|
printf("\n\n=== rint === \n");
|
||||||
|
fesetround(FE_TONEAREST);
|
||||||
|
printf("rounding to nearest (halfway cases to even):\n"
|
||||||
|
"rint(+2.3) = %f ", rint(2.3));
|
||||||
|
printf("rint(+2.5) = %f ", rint(2.5));
|
||||||
|
printf("rint(+3.5) = %f\n", rint(3.5));
|
||||||
|
printf("rint(-2.3) = %f ", rint(-2.3));
|
||||||
|
printf("rint(-2.5) = %f ", rint(-2.5));
|
||||||
|
printf("rint(-3.5) = %f\n", rint(-3.5));
|
||||||
|
fesetround(FE_DOWNWARD);
|
||||||
|
printf("rounding down: \nrint(+2.3) = %f ", rint(2.3));
|
||||||
|
printf("rint(+2.5) = %f ", rint(2.5));
|
||||||
|
printf("rint(+3.5) = %f\n", rint(3.5));
|
||||||
|
printf("rint(-2.3) = %f ", rint(-2.3));
|
||||||
|
printf("rint(-2.5) = %f ", rint(-2.5));
|
||||||
|
printf("rint(-3.5) = %f\n", rint(-3.5));
|
||||||
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
printf("rint(1.1) = %f\n", rint(1.1));
|
||||||
|
if(fetestexcept(FE_INEXACT)) printf(" FE_INEXACT was raised\n");
|
||||||
|
|
||||||
|
|
||||||
|
float from1 = 0, to1 = nextafterf(from1, 1);
|
||||||
|
printf("The next representable float after %f is %f\n", from1, to1);
|
||||||
|
float from2 = 1, to2 = nextafterf(from2, 2);
|
||||||
|
printf("The next representable float after %f is %f\n", from2, to2);
|
||||||
|
{
|
||||||
|
#pragma STDC FENV_ACCESS ON
|
||||||
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
double from4 = DBL_MAX, to4 = nextafter(from4, INFINITY);
|
||||||
|
printf("The next representable double after %f is %f\n",
|
||||||
|
from4, to4);
|
||||||
|
if(fetestexcept(FE_OVERFLOW)) printf(" raised FE_OVERFLOW\n");
|
||||||
|
if(fetestexcept(FE_INEXACT)) printf(" raised FE_INEXACT\n");
|
||||||
|
}
|
||||||
|
float from5 = 0.0, to5 = nextafter(from5, -0.0);
|
||||||
|
printf("nextafter(+0.0, -0.0) gives %f (%f)\n", to5, to5);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue