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
setlocal enabledelayedexpansion
:: 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
:: in that case I recommend you removing the 'echo y' part.
:: although you will have to confirm termination of the script twice
if "%~1" neq "_start_" (
pushd %~pd0
echo y | cmd /c "%~f0" _start_ %*
popd
exit /b
)
shift /1
set CIABATTA_OPTIONS=-Iinc -Wall -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS
set PLATFORM=win
if "%1"=="test" (
goto :skip_crt_compilation
)
:: 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
:: that file (set ok=0). Otherwise we compile it.
:: 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
:: im gonna be seriously disappointed :kekw:
del ciabatta.lib 2> nul
for /R code %%F in (*.c) do (
set ok=1
set os_dependent=0
set is_cur_os=0
echo %%F | findstr /c:"%~pd0code\os" > nul
if !errorlevel! neq 1 (
set os_dependent=1
)
echo %%F | findstr /c:"%~pd0code\os\%PLATFORM%" > nul
if !errorlevel! neq 1 (
set is_cur_os=1
)
if "!os_dependent!"=="1" if "!is_cur_os!"=="0" (
set ok=0
)
if "!ok!"=="1" (
echo %%F
clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS%
)
)
llvm-ar rc ciabatta.lib build\*.obj
del build\*.obj
:skip_crt_compilation
echo Compiling test..
clang test\test6.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%
@echo off
setlocal enabledelayedexpansion
:: 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
:: in that case I recommend you removing the 'echo y' part.
:: although you will have to confirm termination of the script twice
if "%~1" neq "_start_" (
pushd %~pd0
echo y | cmd /c "%~f0" _start_ %*
popd
exit /b
)
shift /1
set CIABATTA_OPTIONS=-Iinc -Wall -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS
set PLATFORM=win
if "%1"=="test" (
goto :skip_crt_compilation
)
:: 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
:: that file (set ok=0). Otherwise we compile it.
:: 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
:: im gonna be seriously disappointed :kekw:
del ciabatta.lib 2> nul
for /R code %%F in (*.c) do (
set ok=1
set os_dependent=0
set is_cur_os=0
echo %%F | findstr /c:"%~pd0code\os" > nul
if !errorlevel! neq 1 (
set os_dependent=1
)
echo %%F | findstr /c:"%~pd0code\os\%PLATFORM%" > nul
if !errorlevel! neq 1 (
set is_cur_os=1
)
if "!os_dependent!"=="1" if "!is_cur_os!"=="0" (
set ok=0
)
if "!ok!"=="1" (
echo %%F
clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS%
)
)
llvm-ar rc ciabatta.lib build\*.obj
del build\*.obj
:skip_crt_compilation
echo Compiling test..
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
setlocal enabledelayedexpansion
set PLATFORM=win
set CIABATTA_OPTIONS=--crt none -I %% -I inc
del ciabatta.lib
cuik %CIABATTA_OPTIONS% code\*.c code\os\%PLATFORM%\*.c -c -o ciabatta.obj
lib /out:ciabatta.lib ciabatta.obj
cuik test\test.c --lib ciabatta.lib,kernel32.lib,user32.lib,shell32.lib %CIABATTA_OPTIONS%
del ciabatta.obj
@echo off
setlocal enabledelayedexpansion
set PLATFORM=win
set CIABATTA_OPTIONS=--crt none -I %% -I inc
del ciabatta.lib
cuik %CIABATTA_OPTIONS% code\*.c code\os\%PLATFORM%\*.c -c -o ciabatta.obj
lib /out:ciabatta.lib ciabatta.obj
cuik test\test.c --lib ciabatta.lib,kernel32.lib,user32.lib,shell32.lib %CIABATTA_OPTIONS%
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
// an empty string.
// NOTE: this file doesn't exist in a vacuum, it's a template for generating
// 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) {
size_t full_length = 0;
while (*fmt) {
// skip any normal non percent text
const FMT_CHAR_TYPE *start = fmt;
while (*fmt && *fmt != '%') fmt++;
// print all those non percent text
out(ctx, fmt - start, start);
full_length += (fmt - start);
// null terminated
if (*fmt == '\0') break;
fmt += 1;
if (*fmt == '%') {
out(ctx, 1, "%");
fmt++;
continue;
}
unsigned int precision = 0;
if (*fmt == '.') {
// custom precision
fmt++;
if (isdigit(*fmt)) {
// just a small atoi
// TODO: handle overflow, just in case(?)
while (isdigit(*fmt)) {
precision *= 10u;
precision += (*fmt - '0');
fmt++;
}
} else if (*fmt == '*') {
int p = va_arg(args, int);
precision = p >= 0 ? ((unsigned int)p) : 0;
fmt++;
}
}
// integer length specifiers
enum {
CHAR,
SHORT,
INT,
LONG,
LLONG
} int_length = INT;
if (*fmt == 'l') {
fmt++;
if (*fmt == 'l') {
int_length = LLONG;
fmt++;
} else {
int_length = LONG;
}
} else if (*fmt == 'h') {
fmt++;
if (*fmt == 'h') {
int_length = CHAR;
fmt++;
} else {
int_length = SHORT;
}
} else if (*fmt == 'z') {
fmt++;
int_length = _Generic((size_t)0,
unsigned char: CHAR,
unsigned short: SHORT,
unsigned int: INT,
unsigned long: LONG,
unsigned long long: LLONG);
}
FMT_CHAR_TYPE ch = *fmt++;
const char* characters = "0123456789abcdef";
if (ch == 'X') characters = "0123456789ABCDEF";
switch (ch) {
case 'c': {
const char chr = va_arg(args, int);
out(ctx, 1, &chr);
full_length ++;
break;
}
case 'f':
case 'L': {
double d = va_arg(args, double);
if(isinf(d)) {
out(ctx, sizeof"inf"-1, "inf");
break;
}
else if(isnan(d)) {
out(ctx, sizeof"nan"-1, "nan");
break;
}
if(d < 0) { // TODO: negative zero
out(ctx, 1, "-");
d = -d;
}
uint64_t w = (uint64_t)d;
d -= w;
FMT_CHAR_TYPE buffer[20];
size_t len = sizeof(buffer);
do {
buffer[--len] = characters[w % 10];
w /= 10;
} while(w != 0);
out(ctx, sizeof(buffer) - (len * sizeof(FMT_CHAR_TYPE)), buffer + len);
char dot = '.';
out(ctx, 1, &dot);
for(int i = 0; i != 6; ++i) {
d *= 10;
int dv = (int)d;
d -= dv;
char digit = characters[dv];
out(ctx, 1, &digit);
}
} break;
case 's': {
const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*);
size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX);
out(ctx, len, str);
full_length += len;
break;
}
case 'b':
case 'o':
case 'i':
case 'u':
case 'd':
case 'x':
case 'X': {
int base = 10;
switch (ch) {
case 'X': case 'x': base = 16; 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;
switch (int_length) {
case CHAR: num = (char) va_arg(args, int); break;
case SHORT: num = (short) va_arg(args, int); break;
case INT: num = va_arg(args, int); 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;
full_length += 1;
} else {
i = num;
}
} else {
switch (int_length) {
case CHAR: i = (char) va_arg(args, int); break;
case SHORT: i = (short) va_arg(args, int); break;
case INT: i = va_arg(args, int); 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;
} else {
FMT_CHAR_TYPE buffer[20];
size_t len = sizeof(buffer);
// we build the number in reverse
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);
}
break;
}
default: break;
}
}
return full_length;
}
#include <math.h>
//TODO: verify printf("%d", 0). From the code it looked like it would print
// an empty string.
// NOTE: this file doesn't exist in a vacuum, it's a template for generating
// 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) {
size_t full_length = 0;
while (*fmt) {
// skip any normal non percent text
const FMT_CHAR_TYPE *start = fmt;
while (*fmt && *fmt != '%') fmt++;
// print all those non percent text
out(ctx, fmt - start, start);
full_length += (fmt - start);
// null terminated
if (*fmt == '\0') break;
fmt += 1;
if (*fmt == '%') {
out(ctx, 1, "%");
fmt++;
continue;
}
unsigned int precision = 0;
if (*fmt == '.') {
// custom precision
fmt++;
if (isdigit(*fmt)) {
// just a small atoi
// TODO: handle overflow, just in case(?)
while (isdigit(*fmt)) {
precision *= 10u;
precision += (*fmt - '0');
fmt++;
}
} else if (*fmt == '*') {
int p = va_arg(args, int);
precision = p >= 0 ? ((unsigned int)p) : 0;
fmt++;
}
}
// integer length specifiers
enum {
CHAR,
SHORT,
INT,
LONG,
LLONG
} int_length = INT;
if (*fmt == 'l') {
fmt++;
if (*fmt == 'l') {
int_length = LLONG;
fmt++;
} else {
int_length = LONG;
}
} else if (*fmt == 'h') {
fmt++;
if (*fmt == 'h') {
int_length = CHAR;
fmt++;
} else {
int_length = SHORT;
}
} else if (*fmt == 'z') {
fmt++;
int_length = _Generic((size_t)0,
unsigned char: CHAR,
unsigned short: SHORT,
unsigned int: INT,
unsigned long: LONG,
unsigned long long: LLONG);
}
FMT_CHAR_TYPE ch = *fmt++;
const char* characters = "0123456789abcdef";
if (ch == 'X') characters = "0123456789ABCDEF";
switch (ch) {
case 'c': {
const char chr = va_arg(args, int);
out(ctx, 1, &chr);
full_length ++;
break;
}
case 'f':
case 'L': {
double d = va_arg(args, double);
if(signbit(d)) { // TODO: negative zero
out(ctx, 1, "-");
d = -d;
}
if(isinf(d)) {
out(ctx, sizeof"inf"-1, "inf");
break;
}
else if(isnan(d)) {
out(ctx, sizeof"nan"-1, "nan");
break;
}
uint64_t w = (uint64_t)d;
d -= w;
FMT_CHAR_TYPE buffer[20];
size_t len = sizeof(buffer);
do {
buffer[--len] = characters[w % 10];
w /= 10;
} while(w != 0);
out(ctx, sizeof(buffer) - (len * sizeof(FMT_CHAR_TYPE)), buffer + len);
char dot = '.';
out(ctx, 1, &dot);
for(int i = 0; i != 6; ++i) {
d *= 10;
int dv = (int)d;
d -= dv;
char digit = characters[dv];
out(ctx, 1, &digit);
}
} break;
case 's': {
const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*);
size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX);
out(ctx, len, str);
full_length += len;
break;
}
case 'b':
case 'o':
case 'i':
case 'u':
case 'd':
case 'x':
case 'X': {
int base = 10;
switch (ch) {
case 'X': case 'x': base = 16; 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;
switch (int_length) {
case CHAR: num = (char) va_arg(args, int); break;
case SHORT: num = (short) va_arg(args, int); break;
case INT: num = va_arg(args, int); 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;
full_length += 1;
} else {
i = num;
}
} else {
switch (int_length) {
case CHAR: i = (char) va_arg(args, int); break;
case SHORT: i = (short) va_arg(args, int); break;
case INT: i = va_arg(args, int); 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;
} else {
FMT_CHAR_TYPE buffer[20];
size_t len = sizeof(buffer);
// we build the number in reverse
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);
}
break;
}
default: break;
}
}
return full_length;
}

View File

@ -1,139 +1,139 @@
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdbool.h>
#include <math.h>
#include <_os.h>
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
int remove(const char *filename)
{
return _os_del_file(filename);
}
int rename(const char *old, const char *new)
{
return _os_mov_file(old, new);
}
char *tmpnam(char *s)
{
static char static_buffer[L_tmpnam];
char *buffer = s;
if(s == NULL) buffer = static_buffer;
return _os_tmpname(buffer);
}
FILE *fopen(const char *restrict filename, const char *restrict mode)
{
// Basically defined UB here by introducing missing modes
// It is simpler to implement that way I think.
int base_mode = mode[0];
int binary = 0;
int exclusive = 0;
int update = 0;
for(; *mode != 0; ++mode) {
if(*mode == 'x') exclusive = 1;
if(*mode == 'b') binary = 1;
if(*mode == '+') update = 1;
}
if(base_mode == 'r' && exclusive) return NULL;
if(base_mode == 'a' && exclusive) return NULL;
_OS_ModeFlags mode_flags = {
.base_mode = base_mode,
.binary = binary,
.update = update,
.exclusive = exclusive,
};
return _os_fopen(filename, mode_flags);
}
int fclose(FILE *stream)
{
return _os_fclose(stream);
}
// TODO:kekw:
FILE *freopen(
const char *restrict filename,
const char *restrict mode,
FILE *restrict stream)
{
fclose(stream);
return NULL;
}
typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]);
///////////////////////////////////////////////
// Instantiate formatted print functions
///////////////////////////////////////////////
// TODO: instantiate wide char variants of print
#define FMT_FUNC_NAME fmt_print_char
#define FMT_CHAR_TYPE char
#define FMT_STRLEN_S(s, maxsize) strnlen_s(s, maxsize)
#include "printf.h"
typedef struct {
size_t used, capacity;
char* string;
} StrPrintCtx;
FILE *stdout, *stderr, *stdin;
#define CALL_PRINTF(fmt_func, ctx, out, fmt) \
va_list args; \
va_start(args, fmt); \
int result = fmt_func(ctx, out, fmt, args); \
va_end(args)
static void string_write(void *ctx, size_t n, const char *restrict str) {
StrPrintCtx *c = ctx;
memcpy(c->string + c->used, str, n);
c->used += n;
}
int fprintf(FILE *file, const char *restrict fmt, ...) {
CALL_PRINTF(fmt_print_char, file, _os_file_write, fmt);
return result;
}
int printf(const char *restrict fmt, ...) {
CALL_PRINTF(fmt_print_char, stdout, _os_file_write, fmt);
return result;
}
int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) {
StrPrintCtx ctx = { 0, n, s };
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
return result;
}
int sprintf(char *restrict s, const char *restrict fmt, ...) {
StrPrintCtx ctx = { 0, SIZE_MAX, s };
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
return result;
}
int vfprintf(FILE *file, const char *restrict fmt, va_list args) {
return fmt_print_char(file, _os_file_write, fmt, args);
}
int vprintf(const char *restrict fmt, va_list 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) {
StrPrintCtx ctx = { 0, n, s };
return fmt_print_char(&ctx, string_write, fmt, args);
}
int vsprintf(char *restrict s, const char *restrict fmt, va_list args) {
StrPrintCtx ctx = { 0, SIZE_MAX, s };
return fmt_print_char(&ctx, string_write, fmt, args);
}
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdbool.h>
#include <math.h>
#include <_os.h>
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
int remove(const char *filename)
{
return _os_del_file(filename);
}
int rename(const char *old, const char *new)
{
return _os_mov_file(old, new);
}
char *tmpnam(char *s)
{
static char static_buffer[L_tmpnam];
char *buffer = s;
if(s == NULL) buffer = static_buffer;
return _os_tmpname(buffer);
}
FILE *fopen(const char *restrict filename, const char *restrict mode)
{
// Basically defined UB here by introducing missing modes
// It is simpler to implement that way I think.
int base_mode = mode[0];
int binary = 0;
int exclusive = 0;
int update = 0;
for(; *mode != 0; ++mode) {
if(*mode == 'x') exclusive = 1;
if(*mode == 'b') binary = 1;
if(*mode == '+') update = 1;
}
if(base_mode == 'r' && exclusive) return NULL;
if(base_mode == 'a' && exclusive) return NULL;
_OS_ModeFlags mode_flags = {
.base_mode = base_mode,
.binary = binary,
.update = update,
.exclusive = exclusive,
};
return _os_fopen(filename, mode_flags);
}
int fclose(FILE *stream)
{
return _os_fclose(stream);
}
// TODO:kekw:
FILE *freopen(
const char *restrict filename,
const char *restrict mode,
FILE *restrict stream)
{
fclose(stream);
return NULL;
}
typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]);
///////////////////////////////////////////////
// Instantiate formatted print functions
///////////////////////////////////////////////
// TODO: instantiate wide char variants of print
#define FMT_FUNC_NAME fmt_print_char
#define FMT_CHAR_TYPE char
#define FMT_STRLEN_S(s, maxsize) strnlen_s(s, maxsize)
#include "printf.h"
typedef struct {
size_t used, capacity;
char* string;
} StrPrintCtx;
FILE *stdout, *stderr, *stdin;
#define CALL_PRINTF(fmt_func, ctx, out, fmt) \
va_list args; \
va_start(args, fmt); \
int result = fmt_func(ctx, out, fmt, args); \
va_end(args)
static void string_write(void *ctx, size_t n, const char *restrict str) {
StrPrintCtx *c = ctx;
memcpy(c->string + c->used, str, n);
c->used += n;
}
int fprintf(FILE *file, const char *restrict fmt, ...) {
CALL_PRINTF(fmt_print_char, file, _os_file_write, fmt);
return result;
}
int printf(const char *restrict fmt, ...) {
CALL_PRINTF(fmt_print_char, stdout, _os_file_write, fmt);
return result;
}
int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) {
StrPrintCtx ctx = { 0, n, s };
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
return result;
}
int sprintf(char *restrict s, const char *restrict fmt, ...) {
StrPrintCtx ctx = { 0, SIZE_MAX, s };
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
return result;
}
int vfprintf(FILE *file, const char *restrict fmt, va_list args) {
return fmt_print_char(file, _os_file_write, fmt, args);
}
int vprintf(const char *restrict fmt, va_list 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) {
StrPrintCtx ctx = { 0, n, s };
return fmt_print_char(&ctx, string_write, fmt, args);
}
int vsprintf(char *restrict s, const char *restrict fmt, va_list args) {
StrPrintCtx ctx = { 0, SIZE_MAX, s };
return fmt_print_char(&ctx, string_write, fmt, args);
}

View File

@ -1,16 +1,16 @@
#pragma once
int isalnum(int c);
int isalpha(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
int tolower(int c);
int toupper(int c);
#pragma once
int isalnum(int c);
int isalpha(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
int tolower(int c);
int toupper(int c);

View File

@ -1,9 +1,9 @@
#pragma once
#define EDOM 1
#define EILSEQ 2
#define ERANGE 3
// TODO: make it thread-local
extern int errno;
#pragma once
#define EDOM 1
#define EILSEQ 2
#define ERANGE 3
// TODO: make it thread-local
extern int errno;

View File

@ -1,61 +1,61 @@
#pragma once
typedef unsigned fexcept_t;
typedef unsigned fenv_t;
#define FE_INVALID (1 << 0)
#define FE_DIVBYZERO (1 << 2)
#define FE_OVERFLOW (1 << 3)
#define FE_UNDERFLOW (1 << 4)
#define FE_INEXACT (1 << 5)
// Implementation-defined flags
#define FE_DENORM (1 << 1)
#define FE_DAZ (1 << 6)
#define FE_ALL_EXCEPT \
( FE_INVALID \
| FE_DIVBYZERO \
| FE_OVERFLOW \
| FE_UNDERFLOW \
| FE_INEXACT \
| FE_DENORM \
| FE_DAZ )
#define FE_TONEAREST 0x00
#define FE_DOWNWARD 0x01
#define FE_UPWARD 0x02
#define FE_TOWARDZERO 0x03
extern fenv_t _fe_dfl_env;
#define FE_DFL_ENV (&_fe_dfl_env)
// Exceptions
int feclearexcept(int excepts);
int fegetexceptflag(fexcept_t *flagp, int excepts);
int feraiseexcept(int excepts);
int fesetexceptflag(const fexcept_t *flagp, int excepts);
int fetestexcept(int excepts);
// Rounding behaviour
int fegetround(void);
int fesetround(int round);
// Environment
int fegetenv(fenv_t *env);
int fesetenv(fenv_t *env);
int feholdexcept(fenv_t *envp);
int feupdateenv(fenv_t const *envp);
// Non-standard functions
int _feenabletraps(int excepts);
int _fedisabletraps(int excepts);
#if defined(_CIABATTA_EXT)
#define feenabletraps _feenabletraps
#define _fedisabletraps _fedisabletraps
#pragma once
typedef unsigned fexcept_t;
typedef unsigned fenv_t;
#define FE_INVALID (1 << 0)
#define FE_DIVBYZERO (1 << 2)
#define FE_OVERFLOW (1 << 3)
#define FE_UNDERFLOW (1 << 4)
#define FE_INEXACT (1 << 5)
// Implementation-defined flags
#define FE_DENORM (1 << 1)
#define FE_DAZ (1 << 6)
#define FE_ALL_EXCEPT \
( FE_INVALID \
| FE_DIVBYZERO \
| FE_OVERFLOW \
| FE_UNDERFLOW \
| FE_INEXACT \
| FE_DENORM \
| FE_DAZ )
#define FE_TONEAREST 0x00
#define FE_DOWNWARD 0x01
#define FE_UPWARD 0x02
#define FE_TOWARDZERO 0x03
extern fenv_t _fe_dfl_env;
#define FE_DFL_ENV (&_fe_dfl_env)
// Exceptions
int feclearexcept(int excepts);
int fegetexceptflag(fexcept_t *flagp, int excepts);
int feraiseexcept(int excepts);
int fesetexceptflag(const fexcept_t *flagp, int excepts);
int fetestexcept(int excepts);
// Rounding behaviour
int fegetround(void);
int fesetround(int round);
// Environment
int fegetenv(fenv_t *env);
int fesetenv(fenv_t *env);
int feholdexcept(fenv_t *envp);
int feupdateenv(fenv_t const *envp);
// Non-standard functions
int _feenabletraps(int excepts);
int _fedisabletraps(int excepts);
#if defined(_CIABATTA_EXT)
#define feenabletraps _feenabletraps
#define _fedisabletraps _fedisabletraps
#endif

View File

@ -1,45 +1,45 @@
#pragma once
#define _COL_IGNORE_SPACE 0x1
#define _COL_IGNORE_SYMBOL 0x2
struct lconv {
// LC_NUMERIC
char *decimal_point; // "."
char *thousands_sep; // ""
char *grouping; // ""
// LC_MONETARY
char *mon_decimal_point; // ""
char *mon_thousands_sep; // ""
char *mon_grouping; // ""
char *positive_sign; // ""
char *negative_sign; // ""
char *currency_symbol; // ""
char frac_digits; // CHAR_MAX
char p_cs_precedes; // CHAR_MAX
char n_cs_precedes; // CHAR_MAX
char p_sep_by_space; // CHAR_MAX
char n_sep_by_space; // CHAR_MAX
char p_sign_posn; // CHAR_MAX
char n_sign_posn; // CHAR_MAX
char *int_curr_symbol; // ""
char int_frac_digits; // CHAR_MAX
char int_p_cs_precedes; // CHAR_MAX
char int_n_cs_precedes; // CHAR_MAX
char int_p_sep_by_space; // CHAR_MAX
char int_n_sep_by_space; // CHAR_MAX
char int_p_sign_posn; // CHAR_MAX
char int_n_sign_posn; // CHAR_MAX
};
// Locale categories
#define LC_ALL 0
#define LC_COLLATE 1
#define LC_CTYPE 2
#define LC_MONETARY 3
#define LC_NUMERIC 4
#define LC_TIME 5
char *setlocale(int category, const char *locale);
struct lconv *localeconv(void);
#pragma once
#define _COL_IGNORE_SPACE 0x1
#define _COL_IGNORE_SYMBOL 0x2
struct lconv {
// LC_NUMERIC
char *decimal_point; // "."
char *thousands_sep; // ""
char *grouping; // ""
// LC_MONETARY
char *mon_decimal_point; // ""
char *mon_thousands_sep; // ""
char *mon_grouping; // ""
char *positive_sign; // ""
char *negative_sign; // ""
char *currency_symbol; // ""
char frac_digits; // CHAR_MAX
char p_cs_precedes; // CHAR_MAX
char n_cs_precedes; // CHAR_MAX
char p_sep_by_space; // CHAR_MAX
char n_sep_by_space; // CHAR_MAX
char p_sign_posn; // CHAR_MAX
char n_sign_posn; // CHAR_MAX
char *int_curr_symbol; // ""
char int_frac_digits; // CHAR_MAX
char int_p_cs_precedes; // CHAR_MAX
char int_n_cs_precedes; // CHAR_MAX
char int_p_sep_by_space; // CHAR_MAX
char int_n_sep_by_space; // CHAR_MAX
char int_p_sign_posn; // CHAR_MAX
char int_n_sign_posn; // CHAR_MAX
};
// Locale categories
#define LC_ALL 0
#define LC_COLLATE 1
#define LC_CTYPE 2
#define LC_MONETARY 3
#define LC_NUMERIC 4
#define LC_TIME 5
char *setlocale(int category, const char *locale);
struct lconv *localeconv(void);

View File

@ -1,220 +1,302 @@
#pragma once
typedef float float_t;
typedef double double_t;
#ifndef _HUGE_ENUF
#define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow
#endif
#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
#define HUGE_VAL ((double)INFINITY)
#define HUGE_VALF ((float)INFINITY)
#define NAN (-(float)(INFINITY * 0.0F))
// FP_ILOGB0
// FP_ILOGBNAN
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
#define math_errhandling MATH_ERRNO
// Classification
#define FP_INFINITE 0
#define FP_NAN 1
#define FP_NORMAL 2
#define FP_SUBNORMAL 3
#define FP_ZERO 4
int _fpclassify(double f);
int _fpclassifyf(float f);
#define fpclassify(x) (sizeof(x)==4?_fpclassifyf(x):_fpclassify(x))
#define isfinite(x) (fpclassify(x) != FP_INFINITE && fpclassify(x) != FP_NAN)
#define isinf(x) (fpclassify(x) == FP_INFINITE)
#define isnan(x) (fpclassify(x) == FP_NAN)
#define isnormal(x) (fpclassify(x) == FP_NORMAL)
// Sign bit shit
int _signbit(double f);
int _signbitf(float f);
#define signbit(x) (sizeof(x)==4?_signbitf(x):signbit(x))
float copysignf(float x, float y);
// Ordering
#define isgreater(x) (sizeof(x)==4?_isgrtf(x):_isgrt(x))
#define isgreaterequal(x) (sizeof(x)==4?_isgeqf(x):_isgeq(x))
#define isless(x) (sizeof(x)==4?_islesf(x):_isles(x))
#define islessequal(x) (sizeof(x)==4?_isleqf(x):_isleq(x))
#define islessgreater(x) (sizeof(x)==4?_islegf(x):_isleg(x))
#define isunordered(x) (sizeof(x)==4?_isunof(x):_isuno(x))
double acos(double x);
float acosf(float x);
double asin(double x);
float asinf(float x);
double atan(double x);
float atanf(float x);
double atan2(double y, double x);
float atan2f(float y, float x);
double cos(double x);
float cosf(float x);
double sin(double x);
float sinf(float x);
double tan(double x);
float tanf(float x);
double acosh(double x);
float acoshf(float x);
double asinh(double x);
float asinhf(float x);
double atanh(double x);
float atanhf(float x);
double cosh(double x);
float coshf(float x);
double sinh(double x);
float sinhf(float x);
double tanh(double x);
float tanhf(float x);
double exp(double x);
float expf(float x);
double exp2(double x);
float exp2f(float x);
double expm1(double x);
float expm1f(float x);
double frexp(double value, int *exp);
float frexpf(float value, int *exp);
int ilogb(double x);
int ilogbf(float x);
double ldexp(double x, int exp);
float ldexpf(float x, int exp);
double log(double x);
float logf(float x);
double log10(double x);
float log10f(float x);
double log1p(double x);
float log1pf(float x);
double log2(double x);
float log2f(float x);
double logb(double x);
float logbf(float x);
double modf(double value, double *iptr);
float modff(float value, float *iptr);
double scalbn(double x, int n);
float scalbnf(float x, int n);
double scalbln(double x, long int n);
float scalblnf(float x, long int n);
double cbrt(double x);
float cbrtf(float x);
double fabs(double x);
float fabsf(float x);
double hypot(double x, double y);
float hypotf(float x, float y);
double pow(double x, double y);
float powf(float x, float y);
double sqrt(double x);
float sqrtf(float x);
double erf(double x);
float erff(float x);
double erfc(double x);
float erfcf(float x);
double lgamma(double x);
float lgammaf(float x);
double tgamma(double x);
float tgammaf(float x);
double ceil(double x);
float ceilf(float x);
double floor(double x);
float floorf(float x);
double nearbyint(double x);
float nearbyintf(float x);
double rint(double x);
float rintf(float x);
long int lrint(double x);
long int lrintf(float x);
long long int llrint(double x);
long long int llrintf(float x);
double round(double x);
float roundf(float x);
long int lround(double x);
long int lroundf(float x);
long long int llround(double x);
long long int llroundf(float x);
double trunc(double x);
float truncf(float x);
double fmod(double x, double y);
float fmodf(float x, float y);
double remainder(double x, double y);
float remainderf(float x, float y);
double remquo(double x, double y, int *quo);
float remquof(float x, float y, int *quo);
double copysign(double x, double y);
float copysignf(float x, float y);
double nan(const char *tagp);
float nanf(const char *tagp);
double nextafter(double x, double y);
float nextafterf(float x, float y);
double fdim(double x, double y);
float fdimf(float x, float y);
double fmax(double x, double y);
float fmaxf(float x, float y);
double fmin(double x, double y);
float fminf(float x, float y);
double fma(double x, double y, double z);
float fmaf(float x, float y, float z);
#pragma once
typedef float float_t;
typedef double double_t;
#ifndef _HUGE_ENUF
#define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow
#endif
#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
#define HUGE_VAL ((double)INFINITY)
#define HUGE_VALF ((float)INFINITY)
#define NAN (-(float)(INFINITY * 0.0F))
#define FP_ILOGBNAN (-1-0x7fffffff)
#define FP_ILOGB0 FP_ILOGBNAN
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
#define math_errhandling MATH_ERRNO
// Classification
#define FP_INFINITE 0
#define FP_NAN 1
#define FP_NORMAL 2
#define FP_SUBNORMAL 3
#define FP_ZERO 4
int _fpclassify(double);
int _fpclassifyf(float);
int _fpclassifyl(long double);
#define fpclassify(x) (sizeof(x)==4?_fpclassifyf(x)\
:sizeof(x)==8?_fpclassify(x) \
: _fpclassifyl(x))
#define isfinite(x) (fpclassify(x) != FP_INFINITE && fpclassify(x) != FP_NAN)
#define isinf(x) (fpclassify(x) == FP_INFINITE)
#define isnan(x) (fpclassify(x) == FP_NAN)
#define isnormal(x) (fpclassify(x) == FP_NORMAL)
// signbit shit
int _signbit(double);
int _signbitf(float);
int _signbitl(long double);
#define signbit(x) (sizeof(x) == sizeof(float) ? _signbitf(x) \
:sizeof(x) == sizeof(double) ? _signbit(x) \
: _signbitl(x))
// Ordering
#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y)))
#define isgreater(x,y) (!isunordered(x,y) && ((x) > (y)))
#define isgreaterequal(x,y) (!isunordered(x,y) && ((x) >= (y)))
#define isless(x,y) (!isunordered(x,y) && ((x) < (y)))
#define islessequal(x,y) (!isunordered(x,y) && ((x) <= (y)))
#define islessgreater(x,y) (!isunordered(x,y) && ((x) != (y)))
#if defined(_USE_MATH_DEFINES)
#define M_E 2.7182818284590452354
#define M_LOG2E 1.4426950408889634074
#define M_LOG10E 0.43429448190325182765
#define M_LN2 0.69314718055994530942
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.78539816339744830962
#define M_1_PI 0.31830988618379067154
#define M_2_PI 0.63661977236758134308
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT1_2 0.70710678118654752440
#endif
// Floating-point function prototypes
double acos(double);
float acosf(float);
long double acosl(long double);
double acosh(double);
float acoshf(float);
long double acoshl(long double);
double asin(double);
float asinf(float);
long double asinl(long double);
double asinh(double);
float asinhf(float);
long double asinhl(long double);
double atan(double);
float atanf(float);
long double atanl(long double);
double atan2(double, double);
float atan2f(float, float);
long double atan2l(long double, long double);
double atanh(double);
float atanhf(float);
long double atanhl(long double);
double cbrt(double);
float cbrtf(float);
long double cbrtl(long double);
double ceil(double);
float ceilf(float);
long double ceill(long double);
double copysign(double, double);
float copysignf(float, float);
long double copysignl(long double, long double);
double cos(double);
float cosf(float);
long double cosl(long double);
double cosh(double);
float coshf(float);
long double coshl(long double);
double erf(double);
float erff(float);
long double erfl(long double);
double erfc(double);
float erfcf(float);
long double erfcl(long double);
double exp(double);
float expf(float);
long double expl(long double);
double exp2(double);
float exp2f(float);
long double exp2l(long double);
double expm1(double);
float expm1f(float);
long double expm1l(long double);
double fabs(double);
float fabsf(float);
long double fabsl(long double);
double fdim(double, double);
float fdimf(float, float);
long double fdiml(long double, long double);
double floor(double);
float floorf(float);
long double floorl(long double);
double fma(double, double, double);
float fmaf(float, float, float);
long double fmal(long double, long double, long double);
double fmax(double, double);
float fmaxf(float, float);
long double fmaxl(long double, long double);
double fmin(double, double);
float fminf(float, float);
long double fminl(long double, long double);
double fmod(double, double);
float fmodf(float, float);
long double fmodl(long double, long double);
double frexp(double, int *);
float frexpf(float, int *);
long double frexpl(long double, int *);
double hypot(double, double);
float hypotf(float, float);
long double hypotl(long double, long double);
int ilogb(double);
int ilogbf(float);
int ilogbl(long double);
double ldexp(double, int);
float ldexpf(float, int);
long double ldexpl(long double, int);
double lgamma(double);
float lgammaf(float);
long double lgammal(long double);
long long llrint(double);
long long llrintf(float);
long long llrintl(long double);
long long llround(double);
long long llroundf(float);
long long llroundl(long double);
double log(double);
float logf(float);
long double logl(long double);
double log10(double);
float log10f(float);
long double log10l(long double);
double log1p(double);
float log1pf(float);
long double log1pl(long double);
double log2(double);
float log2f(float);
long double log2l(long double);
double logb(double);
float logbf(float);
long double logbl(long double);
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
typedef int sig_atomic_t;
// TODO: idk about SIG_ERR, for now this
#define SIG_ERR ((void(*)(int))0)
#define SIG_DFL _signal_default_handler
#define SIG_IGN _signal_ignore_handler
// Note(bumbread): from the impl standpoint the numbers are arbitrary
#define _SIG_MIN 0
#define SIGINT 1
#define SIGILL 2
#define SIGFPE 3
#define SIGSEGV 4
#define SIGTERM 5
#define SIGABRT 6
// These guys are impl defined
#define SIGBREAK 7
#define SIGALIGN 8
#define SIGSTEP 9
#define _SIG_MAX 9
void (*signal(int sig, void (*func)(int)))(int);
int raise(int sig);
#pragma once
typedef int sig_atomic_t;
// TODO: idk about SIG_ERR, for now this
#define SIG_ERR ((void(*)(int))0)
#define SIG_DFL _signal_default_handler
#define SIG_IGN _signal_ignore_handler
// Note(bumbread): from the impl standpoint the numbers are arbitrary
#define _SIG_MIN 0
#define SIGINT 1
#define SIGILL 2
#define SIGFPE 3
#define SIGSEGV 4
#define SIGTERM 5
#define SIGABRT 6
// These guys are impl defined
#define SIGBREAK 7
#define SIGALIGN 8
#define SIGSTEP 9
#define _SIG_MAX 9
void (*signal(int sig, void (*func)(int)))(int);
int raise(int sig);

View File

@ -1,65 +1,65 @@
#pragma once
// Technically all we should have here is typedef for size_t.
// but I can't get that without macro shittery so
// for now I'm just doing this, which is not quite correct
#include <stddef.h>
#if !defined(NULL)
#define NULL ((void *)0)
#endif
#if !defined(__STDC_LIB_EXT1__)
#define __STDC_LIB_EXT1__
typedef int errno_t;
typedef size_t rsize_t;
#endif
#if __STDC_WANT_SECURE_LIB__ == 1
#if !defined(__STDC_WANT_LIB_EXT1__)
#define __STDC_WANT_LIB_EXT1__ 1
#endif
#endif
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2);
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
char *strcpy(char *restrict s1, const char *restrict s2);
char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
char *strcat(char *restrict s1, const char *restrict s2);
char *strncat(char *restrict s1, const char *restrict s2, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(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);
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n);
void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c);
size_t strcspn(const char *s1, const char *s2);
char *strpbrk(const char *s1, const char *s2);
char *strrchr(const char *s, int c);
size_t strspn(const char *s1, const char *s2);
char *strstr(const char *s1, const char *s2);
char *strtok(char *restrict s1, const char *restrict s2);
void *memset(void *s, int c, size_t n);
char *strerror(int errnum);
size_t strlen(const char *s);
// Linux extension: reentrant strtok
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx);
#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 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 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 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);
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);
size_t strerrorlen_s(errno_t errnum);
size_t strnlen_s(const char *str, size_t strsz);
#endif
#pragma once
// Technically all we should have here is typedef for size_t.
// but I can't get that without macro shittery so
// for now I'm just doing this, which is not quite correct
#include <stddef.h>
#if !defined(NULL)
#define NULL ((void *)0)
#endif
#if !defined(__STDC_LIB_EXT1__)
#define __STDC_LIB_EXT1__
typedef int errno_t;
typedef size_t rsize_t;
#endif
#if __STDC_WANT_SECURE_LIB__ == 1
#if !defined(__STDC_WANT_LIB_EXT1__)
#define __STDC_WANT_LIB_EXT1__ 1
#endif
#endif
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2);
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
char *strcpy(char *restrict s1, const char *restrict s2);
char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
char *strcat(char *restrict s1, const char *restrict s2);
char *strncat(char *restrict s1, const char *restrict s2, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(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);
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n);
void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c);
size_t strcspn(const char *s1, const char *s2);
char *strpbrk(const char *s1, const char *s2);
char *strrchr(const char *s, int c);
size_t strspn(const char *s1, const char *s2);
char *strstr(const char *s1, const char *s2);
char *strtok(char *restrict s1, const char *restrict s2);
void *memset(void *s, int c, size_t n);
char *strerror(int errnum);
size_t strlen(const char *s);
// Linux extension: reentrant strtok
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx);
#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 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 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 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);
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);
size_t strerrorlen_s(errno_t errnum);
size_t strnlen_s(const char *str, size_t strsz);
#endif

View File

@ -1,67 +1,67 @@
#pragma once
/*
these are type generic so they're macrod and use C11's _Generic
acos
asin
atan
acosh
asinh
atanh
cos
sin
tan
cosh
sinh
tanh
exp
log
pow
sqrt
fabs
atan2
cbrt
ceil
copysign
erf
erfc
exp2
expm1
fdim
floor
fma
fmax
fmin
fmod
frexp
hypot
ilogb
ldexp
lgamma
llrint
llround
log10
log1p
log2
logb
lrint
lround
nearbyint
nextafter
nexttoward
remainder
remquo
rint
round
scalbn
scalbln
tgamma
trunc
carg
cimag
conj
cproj
creal
#pragma once
/*
these are type generic so they're macrod and use C11's _Generic
acos
asin
atan
acosh
asinh
atanh
cos
sin
tan
cosh
sinh
tanh
exp
log
pow
sqrt
fabs
atan2
cbrt
ceil
copysign
erf
erfc
exp2
expm1
fdim
floor
fma
fmax
fmin
fmod
frexp
hypot
ilogb
ldexp
lgamma
llrint
llround
log10
log1p
log2
logb
lrint
lround
nearbyint
nextafter
nexttoward
remainder
remquo
rint
round
scalbn
scalbln
tgamma
trunc
carg
cimag
conj
cproj
creal
*/

View File

@ -1,71 +1,71 @@
#pragma once
#include <time.h>
#define thread_local _Thread_local
#define ONCE_FLAG_INIT 1
#define TSS_DTOR_ITERATIONS 32
typedef struct cnd_t {
int idk_yet;
} cnd_t;
typedef struct thrd_t {
int idk_yet;
} thrd_t;
typedef struct tss_t {
int idk_yet;
} tss_t;
typedef struct mtx_t {
int idk_yet;
} mtx_t;
typedef void(*tss_dtor_t)(void*);
typedef int(*thrd_start_t)(void*);
// TODO: change this maybe?
typedef int once_flag;
enum {
mtx_plain = 1,
mtx_recursive = 2,
mtx_timed = 4
};
enum {
thrd_success,
thrd_timedout,
thrd_busy,
thrd_error,
thrd_nomem
};
void call_once(once_flag *flag, void (*func)(void));
int cnd_broadcast(cnd_t *cond);
void cnd_destroy(cnd_t *cond);
int cnd_init(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_wait(cnd_t *cond, mtx_t *mtx);
void mtx_destroy(mtx_t *mtx);
int mtx_init(mtx_t *mtx, int type);
int mtx_lock(mtx_t *mtx);
int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts);
int mtx_trylock(mtx_t *mtx);
int mtx_unlock(mtx_t *mtx);
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
thrd_t thrd_current(void);
int thrd_detach(thrd_t thr);
int thrd_equal(thrd_t thr0, thrd_t thr1);
_Noreturn void thrd_exit(int res);
int thrd_join(thrd_t thr, int *res);
int thrd_sleep(const struct timespec *duration, struct timespec *remaining);
void thrd_yield(void);
int tss_create(tss_t *key, tss_dtor_t dtor);
void tss_delete(tss_t key);
void *tss_get(tss_t key);
int tss_set(tss_t key, void *val);
#pragma once
#include <time.h>
#define thread_local _Thread_local
#define ONCE_FLAG_INIT 1
#define TSS_DTOR_ITERATIONS 32
typedef struct cnd_t {
int idk_yet;
} cnd_t;
typedef struct thrd_t {
int idk_yet;
} thrd_t;
typedef struct tss_t {
int idk_yet;
} tss_t;
typedef struct mtx_t {
int idk_yet;
} mtx_t;
typedef void(*tss_dtor_t)(void*);
typedef int(*thrd_start_t)(void*);
// TODO: change this maybe?
typedef int once_flag;
enum {
mtx_plain = 1,
mtx_recursive = 2,
mtx_timed = 4
};
enum {
thrd_success,
thrd_timedout,
thrd_busy,
thrd_error,
thrd_nomem
};
void call_once(once_flag *flag, void (*func)(void));
int cnd_broadcast(cnd_t *cond);
void cnd_destroy(cnd_t *cond);
int cnd_init(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_wait(cnd_t *cond, mtx_t *mtx);
void mtx_destroy(mtx_t *mtx);
int mtx_init(mtx_t *mtx, int type);
int mtx_lock(mtx_t *mtx);
int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts);
int mtx_trylock(mtx_t *mtx);
int mtx_unlock(mtx_t *mtx);
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
thrd_t thrd_current(void);
int thrd_detach(thrd_t thr);
int thrd_equal(thrd_t thr0, thrd_t thr1);
_Noreturn void thrd_exit(int res);
int thrd_join(thrd_t thr, int *res);
int thrd_sleep(const struct timespec *duration, struct timespec *remaining);
void thrd_yield(void);
int tss_create(tss_t *key, tss_dtor_t dtor);
void tss_delete(tss_t key);
void *tss_get(tss_t key);
int tss_set(tss_t key, void *val);

View File

@ -1,49 +1,49 @@
#pragma once
#include <stddef.h>
#if !defined(NULL)
#define NULL ((void *)0)
#endif
// The number of clock ticks per second
#define CLOCKS_PER_SEC ((clock_t)1000)
#define TIME_UTC 1
typedef size_t clock_t;
typedef size_t time_t;
struct timespec {
time_t tv_sec; // Seconds - >= 0
long tv_nsec; // Nanoseconds - [0, 999999999]
};
struct tm {
int tm_sec; // seconds after the minute - [0, 60] including leap second
int tm_min; // minutes after the hour - [0, 59]
int tm_hour; // hours since midnight - [0, 23]
int tm_mday; // day of the month - [1, 31]
int tm_mon; // months since January - [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday - [0, 6]
int tm_yday; // days since January 1 - [0, 365]
int tm_isdst; // daylight savings time flag
};
clock_t clock(void);
double difftime(time_t time1, time_t time0);
time_t mktime(struct tm *timeptr);
time_t time(time_t *timer);
int timespec_get(struct timespec *ts, int base);
char *asctime(const struct tm *timeptr);
char *ctime(const time_t *timer);
struct tm *gmtime(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);
#ifdef __STDC_WANT_LIB_EXT1__
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);
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);
#endif
#pragma once
#include <stddef.h>
#if !defined(NULL)
#define NULL ((void *)0)
#endif
// The number of clock ticks per second
#define CLOCKS_PER_SEC ((clock_t)1000)
#define TIME_UTC 1
typedef size_t clock_t;
typedef size_t time_t;
struct timespec {
time_t tv_sec; // Seconds - >= 0
long tv_nsec; // Nanoseconds - [0, 999999999]
};
struct tm {
int tm_sec; // seconds after the minute - [0, 60] including leap second
int tm_min; // minutes after the hour - [0, 59]
int tm_hour; // hours since midnight - [0, 23]
int tm_mday; // day of the month - [1, 31]
int tm_mon; // months since January - [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday - [0, 6]
int tm_yday; // days since January 1 - [0, 365]
int tm_isdst; // daylight savings time flag
};
clock_t clock(void);
double difftime(time_t time1, time_t time0);
time_t mktime(struct tm *timeptr);
time_t time(time_t *timer);
int timespec_get(struct timespec *ts, int base);
char *asctime(const struct tm *timeptr);
char *ctime(const time_t *timer);
struct tm *gmtime(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);
#ifdef __STDC_WANT_LIB_EXT1__
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);
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);
#endif

View File

@ -1,11 +1,11 @@
#pragma once
typedef struct mbstate_t mbstate_t;
typedef uint16_t char16_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 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 c32rtomb(char * restrict s, char32_t c32, mbstate_t * restrict ps);
#pragma once
typedef struct mbstate_t mbstate_t;
typedef uint16_t char16_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 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 c32rtomb(char * restrict s, char32_t c32, mbstate_t * restrict ps);

View File

@ -1,101 +1,101 @@
#pragma once
// On linux this will be UTF-32, on windows it's UTF-16 (or maybe UCS-2?)
typedef struct mbstate_t mbstate_t;
typedef wchar_t wint_t;
#define WCHAR_MIN 0x0000
#define WCHAR_MAX 0xffff
#ifndef WEOF
#define WEOF 0
#endif
int fwprintf(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 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 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 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 vwscanf(const wchar_t * restrict format, va_list arg);
int wprintf(const wchar_t * restrict format, ...);
int wscanf(const wchar_t * restrict format, ...);
wint_t fgetwc(FILE *stream);
wchar_t *fgetws(wchar_t * restrict s, int n, FILE * restrict stream);
wint_t fputwc(wchar_t c, FILE *stream);
int fputws(const wchar_t * restrict s, FILE * restrict stream);
int fwide(FILE *stream, int mode);
wint_t getwc(FILE *stream);
wint_t getwchar(void);
wint_t putwc(wchar_t c, FILE *stream);
wint_t putwchar(wchar_t c);
wint_t ungetwc(wint_t c, FILE *stream);
double wcstod(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
float wcstof(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
long double wcstold(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
long 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);
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);
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 *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 *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);
int wcscmp(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);
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);
wchar_t *wcschr(const wchar_t *s, wchar_t c);
size_t wcscspn(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);
size_t wcsspn(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 *wmemchr(const wchar_t *s, wchar_t c, size_t n);
size_t wcslen(const wchar_t *s);
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);
wint_t btowc(int c);
int wctob(wint_t c);
int mbsinit(const mbstate_t *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 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 wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps);
#ifdef __STDC_WANT_LIB_EXT1__
int fwprintf_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 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 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 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 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 vwscanf_s(const wchar_t * restrict format, va_list arg);
int wprintf_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 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 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 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);
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 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);
#endif
#pragma once
// On linux this will be UTF-32, on windows it's UTF-16 (or maybe UCS-2?)
typedef struct mbstate_t mbstate_t;
typedef wchar_t wint_t;
#define WCHAR_MIN 0x0000
#define WCHAR_MAX 0xffff
#ifndef WEOF
#define WEOF 0
#endif
int fwprintf(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 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 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 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 vwscanf(const wchar_t * restrict format, va_list arg);
int wprintf(const wchar_t * restrict format, ...);
int wscanf(const wchar_t * restrict format, ...);
wint_t fgetwc(FILE *stream);
wchar_t *fgetws(wchar_t * restrict s, int n, FILE * restrict stream);
wint_t fputwc(wchar_t c, FILE *stream);
int fputws(const wchar_t * restrict s, FILE * restrict stream);
int fwide(FILE *stream, int mode);
wint_t getwc(FILE *stream);
wint_t getwchar(void);
wint_t putwc(wchar_t c, FILE *stream);
wint_t putwchar(wchar_t c);
wint_t ungetwc(wint_t c, FILE *stream);
double wcstod(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
float wcstof(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
long double wcstold(const wchar_t * restrict nptr, wchar_t ** restrict endptr);
long 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);
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);
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 *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 *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);
int wcscmp(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);
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);
wchar_t *wcschr(const wchar_t *s, wchar_t c);
size_t wcscspn(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);
size_t wcsspn(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 *wmemchr(const wchar_t *s, wchar_t c, size_t n);
size_t wcslen(const wchar_t *s);
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);
wint_t btowc(int c);
int wctob(wint_t c);
int mbsinit(const mbstate_t *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 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 wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps);
#ifdef __STDC_WANT_LIB_EXT1__
int fwprintf_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 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 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 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 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 vwscanf_s(const wchar_t * restrict format, va_list arg);
int wprintf_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 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 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 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);
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 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);
#endif

View File

@ -1,29 +1,29 @@
#pragma once
typedef int wint_t;
wctrans_t;
wctype_t;
#ifndef WEOF
#define WEOF 0
#endif
int iswalnum(wint_t wc);
int iswalpha(wint_t wc);
int iswblank(wint_t wc);
int iswcntrl(wint_t wc);
int iswdigit(wint_t wc);
int iswgraph(wint_t wc);
int iswlower(wint_t wc);
int iswprint(wint_t wc);
int iswpunct(wint_t wc);
int iswspace(wint_t wc);
int iswupper(wint_t wc);
int iswxdigit(wint_t wc);
int iswctype(wint_t wc, wctype_t desc);
wctype_t wctype(const char *property);
wint_t towlower(wint_t wc);
wint_t towupper(wint_t wc);
wint_t towctrans(wint_t wc, wctrans_t desc);
wctrans_t wctrans(const char *property);
#pragma once
typedef int wint_t;
wctrans_t;
wctype_t;
#ifndef WEOF
#define WEOF 0
#endif
int iswalnum(wint_t wc);
int iswalpha(wint_t wc);
int iswblank(wint_t wc);
int iswcntrl(wint_t wc);
int iswdigit(wint_t wc);
int iswgraph(wint_t wc);
int iswlower(wint_t wc);
int iswprint(wint_t wc);
int iswpunct(wint_t wc);
int iswspace(wint_t wc);
int iswupper(wint_t wc);
int iswxdigit(wint_t wc);
int iswctype(wint_t wc, wctype_t desc);
wctype_t wctype(const char *property);
wint_t towlower(wint_t wc);
wint_t towupper(wint_t wc);
wint_t towctrans(wint_t wc, wctrans_t desc);
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;
}