Steal some math funcs

This commit is contained in:
bumbread 2022-06-11 15:49:07 +11:00
parent 6f57efcaa9
commit 2320a22706
29 changed files with 1616 additions and 1508 deletions

109
bake.cmd
View File

@ -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

View File

@ -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

View File

View File

264
code/math/ieee754.c Normal file
View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

View File

@ -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);
}

View File

View File

View File

View File

@ -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;
}

View File

@ -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);
} }

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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
*/ */

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}

76
test/test_math.c Normal file
View File

@ -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;
}