mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-15 07:43:13 +00:00
Strip semicolons; Make odin strip-semicolon replace .. with ..= if used as a binary operator
This commit is contained in:
@@ -11,72 +11,72 @@ when ODIN_OS == "windows" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.3.5 Trigonometric functions
|
||||
cacos :: proc(z: complex_double) -> complex_double ---;
|
||||
cacosf :: proc(z: complex_float) -> complex_float ---;
|
||||
casin :: proc(z: complex_double) -> complex_double ---;
|
||||
casinf :: proc(z: complex_float) -> complex_float ---;
|
||||
catan :: proc(z: complex_double) -> complex_double ---;
|
||||
catanf :: proc(z: complex_float) -> complex_float ---;
|
||||
ccos :: proc(z: complex_double) -> complex_double ---;
|
||||
ccosf :: proc(z: complex_float) -> complex_float ---;
|
||||
csin :: proc(z: complex_double) -> complex_double ---;
|
||||
csinf :: proc(z: complex_float) -> complex_float ---;
|
||||
ctan :: proc(z: complex_double) -> complex_double ---;
|
||||
ctanf :: proc(z: complex_float) -> complex_float ---;
|
||||
cacos :: proc(z: complex_double) -> complex_double ---
|
||||
cacosf :: proc(z: complex_float) -> complex_float ---
|
||||
casin :: proc(z: complex_double) -> complex_double ---
|
||||
casinf :: proc(z: complex_float) -> complex_float ---
|
||||
catan :: proc(z: complex_double) -> complex_double ---
|
||||
catanf :: proc(z: complex_float) -> complex_float ---
|
||||
ccos :: proc(z: complex_double) -> complex_double ---
|
||||
ccosf :: proc(z: complex_float) -> complex_float ---
|
||||
csin :: proc(z: complex_double) -> complex_double ---
|
||||
csinf :: proc(z: complex_float) -> complex_float ---
|
||||
ctan :: proc(z: complex_double) -> complex_double ---
|
||||
ctanf :: proc(z: complex_float) -> complex_float ---
|
||||
|
||||
// 7.3.6 Hyperbolic functions
|
||||
cacosh :: proc(z: complex_double) -> complex_double ---;
|
||||
cacoshf :: proc(z: complex_float) -> complex_float ---;
|
||||
casinh :: proc(z: complex_double) -> complex_double ---;
|
||||
casinhf :: proc(z: complex_float) -> complex_float ---;
|
||||
catanh :: proc(z: complex_double) -> complex_double ---;
|
||||
catanhf :: proc(z: complex_float) -> complex_float ---;
|
||||
ccosh :: proc(z: complex_double) -> complex_double ---;
|
||||
ccoshf :: proc(z: complex_float) -> complex_float ---;
|
||||
csinh :: proc(z: complex_double) -> complex_double ---;
|
||||
csinhf :: proc(z: complex_float) -> complex_float ---;
|
||||
ctanh :: proc(z: complex_double) -> complex_double ---;
|
||||
ctanhf :: proc(z: complex_float) -> complex_float ---;
|
||||
cacosh :: proc(z: complex_double) -> complex_double ---
|
||||
cacoshf :: proc(z: complex_float) -> complex_float ---
|
||||
casinh :: proc(z: complex_double) -> complex_double ---
|
||||
casinhf :: proc(z: complex_float) -> complex_float ---
|
||||
catanh :: proc(z: complex_double) -> complex_double ---
|
||||
catanhf :: proc(z: complex_float) -> complex_float ---
|
||||
ccosh :: proc(z: complex_double) -> complex_double ---
|
||||
ccoshf :: proc(z: complex_float) -> complex_float ---
|
||||
csinh :: proc(z: complex_double) -> complex_double ---
|
||||
csinhf :: proc(z: complex_float) -> complex_float ---
|
||||
ctanh :: proc(z: complex_double) -> complex_double ---
|
||||
ctanhf :: proc(z: complex_float) -> complex_float ---
|
||||
|
||||
// 7.3.7 Exponential and logarithmic functions
|
||||
cexp :: proc(z: complex_double) -> complex_double ---;
|
||||
cexpf :: proc(z: complex_float) -> complex_float ---;
|
||||
clog :: proc(z: complex_double) -> complex_double ---;
|
||||
clogf :: proc(z: complex_float) -> complex_float ---;
|
||||
cexp :: proc(z: complex_double) -> complex_double ---
|
||||
cexpf :: proc(z: complex_float) -> complex_float ---
|
||||
clog :: proc(z: complex_double) -> complex_double ---
|
||||
clogf :: proc(z: complex_float) -> complex_float ---
|
||||
|
||||
// 7.3.8 Power and absolute-value functions
|
||||
cabs :: proc(z: complex_double) -> complex_double ---;
|
||||
cabsf :: proc(z: complex_float) -> complex_float ---;
|
||||
cpow :: proc(z: complex_double) -> complex_double ---;
|
||||
cpowf :: proc(z: complex_float) -> complex_float ---;
|
||||
csqrt :: proc(z: complex_double) -> complex_double ---;
|
||||
csqrtf :: proc(z: complex_float) -> complex_float ---;
|
||||
cabs :: proc(z: complex_double) -> complex_double ---
|
||||
cabsf :: proc(z: complex_float) -> complex_float ---
|
||||
cpow :: proc(z: complex_double) -> complex_double ---
|
||||
cpowf :: proc(z: complex_float) -> complex_float ---
|
||||
csqrt :: proc(z: complex_double) -> complex_double ---
|
||||
csqrtf :: proc(z: complex_float) -> complex_float ---
|
||||
|
||||
// 7.3.9 Manipulation functions
|
||||
carg :: proc(z: complex_double) -> double ---;
|
||||
cargf :: proc(z: complex_float) -> float ---;
|
||||
cimag :: proc(z: complex_double) -> double ---;
|
||||
cimagf :: proc(z: complex_float) -> float ---;
|
||||
conj :: proc(z: complex_double) -> complex_double ---;
|
||||
conjf :: proc(z: complex_float) -> complex_float ---;
|
||||
cproj :: proc(z: complex_double) -> complex_double ---;
|
||||
cprojf :: proc(z: complex_float) -> complex_float ---;
|
||||
creal :: proc(z: complex_double) -> double ---;
|
||||
crealf :: proc(z: complex_float) -> float ---;
|
||||
carg :: proc(z: complex_double) -> double ---
|
||||
cargf :: proc(z: complex_float) -> float ---
|
||||
cimag :: proc(z: complex_double) -> double ---
|
||||
cimagf :: proc(z: complex_float) -> float ---
|
||||
conj :: proc(z: complex_double) -> complex_double ---
|
||||
conjf :: proc(z: complex_float) -> complex_float ---
|
||||
cproj :: proc(z: complex_double) -> complex_double ---
|
||||
cprojf :: proc(z: complex_float) -> complex_float ---
|
||||
creal :: proc(z: complex_double) -> double ---
|
||||
crealf :: proc(z: complex_float) -> float ---
|
||||
}
|
||||
|
||||
import builtin "core:builtin"
|
||||
|
||||
complex_float :: distinct builtin.complex64;
|
||||
complex_double :: distinct builtin.complex128;
|
||||
complex_float :: distinct builtin.complex64
|
||||
complex_double :: distinct builtin.complex128
|
||||
|
||||
// Cannot implement _Complex_I or _Imaginary_I in Odin, thus
|
||||
// complex and imaginary cannot be implement either.
|
||||
|
||||
CMPLX :: #force_inline proc(x, y: double) -> complex_double {
|
||||
return builtin.complex(x, y);
|
||||
return builtin.complex(x, y)
|
||||
}
|
||||
|
||||
CMPLXF :: #force_inline proc(x, y: float) -> complex_float {
|
||||
return builtin.complex(x, y);
|
||||
return builtin.complex(x, y)
|
||||
}
|
||||
|
||||
@@ -11,20 +11,20 @@ when ODIN_OS == "windows" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.4.1 Character classification functions
|
||||
isalnum :: proc(c: int) -> int ---;
|
||||
isalpha :: proc(c: int) -> int ---;
|
||||
isblank :: proc(c: int) -> int ---;
|
||||
iscntrl :: proc(c: int) -> int ---;
|
||||
isdigit :: proc(c: int) -> int ---;
|
||||
isgraph :: proc(c: int) -> int ---;
|
||||
islower :: proc(c: int) -> int ---;
|
||||
isprint :: proc(c: int) -> int ---;
|
||||
ispunct :: proc(c: int) -> int ---;
|
||||
isspace :: proc(c: int) -> int ---;
|
||||
isupper :: proc(c: int) -> int ---;
|
||||
isxdigit :: proc(c: int) -> int ---;
|
||||
isalnum :: proc(c: int) -> int ---
|
||||
isalpha :: proc(c: int) -> int ---
|
||||
isblank :: proc(c: int) -> int ---
|
||||
iscntrl :: proc(c: int) -> int ---
|
||||
isdigit :: proc(c: int) -> int ---
|
||||
isgraph :: proc(c: int) -> int ---
|
||||
islower :: proc(c: int) -> int ---
|
||||
isprint :: proc(c: int) -> int ---
|
||||
ispunct :: proc(c: int) -> int ---
|
||||
isspace :: proc(c: int) -> int ---
|
||||
isupper :: proc(c: int) -> int ---
|
||||
isxdigit :: proc(c: int) -> int ---
|
||||
|
||||
// 7.4.2 Character case mapping functions
|
||||
tolower :: proc(c: int) -> int ---;
|
||||
toupper :: proc(c: int) -> int ---;
|
||||
tolower :: proc(c: int) -> int ---
|
||||
toupper :: proc(c: int) -> int ---
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
@(link_name="__libc_errno_location")
|
||||
_get_errno :: proc() -> ^int ---;
|
||||
_get_errno :: proc() -> ^int ---
|
||||
}
|
||||
|
||||
EDOM :: 33;
|
||||
EILSEQ :: 84;
|
||||
ERANGE :: 34;
|
||||
EDOM :: 33
|
||||
EILSEQ :: 84
|
||||
ERANGE :: 34
|
||||
}
|
||||
|
||||
when ODIN_OS == "windows" {
|
||||
@@ -30,12 +30,12 @@ when ODIN_OS == "windows" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
@(link_name="_errno")
|
||||
_get_errno :: proc() -> ^int ---;
|
||||
_get_errno :: proc() -> ^int ---
|
||||
}
|
||||
|
||||
EDOM :: 33;
|
||||
EILSEQ :: 42;
|
||||
ERANGE :: 34;
|
||||
EDOM :: 33
|
||||
EILSEQ :: 42
|
||||
ERANGE :: 34
|
||||
}
|
||||
|
||||
// Odin has no way to make an identifier "errno" behave as a function call to
|
||||
@@ -43,5 +43,5 @@ when ODIN_OS == "windows" {
|
||||
// error value to errno. To work around this, just expose it as a function like
|
||||
// it actually is.
|
||||
errno :: #force_inline proc() -> ^int {
|
||||
return _get_errno();
|
||||
return _get_errno()
|
||||
}
|
||||
|
||||
@@ -17,210 +17,210 @@ when ODIN_OS == "windows" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.12.4 Trigonometric functions
|
||||
@(link_name="acos") libc_acos :: proc(x: double) -> double ---;
|
||||
@(link_name="acosf") libc_acosf :: proc(x: float) -> float ---;
|
||||
@(link_name="asin") libc_asin :: proc(x: double) -> double ---;
|
||||
@(link_name="asinf") libc_asinf :: proc(x: float) -> float ---;
|
||||
@(link_name="atan") libc_atan :: proc(x: double) -> double ---;
|
||||
@(link_name="atanf") libc_atanf :: proc(x: float) -> float ---;
|
||||
@(link_name="atan2") libc_atan2 :: proc(y: double, x: double) -> double ---;
|
||||
@(link_name="atan2f") libc_atan2f :: proc(y: float, x: float) -> float ---;
|
||||
@(link_name="cos") libc_cos :: proc(x: double) -> double ---;
|
||||
@(link_name="cosf") libc_cosf :: proc(x: float) -> float ---;
|
||||
@(link_name="sin") libc_sin :: proc(x: double) -> double ---;
|
||||
@(link_name="sinf") libc_sinf :: proc(x: float) -> float ---;
|
||||
@(link_name="tan") libc_tan :: proc(x: double) -> double ---;
|
||||
@(link_name="tanf") libc_tanf :: proc(x: float) -> float ---;
|
||||
@(link_name="acos") libc_acos :: proc(x: double) -> double ---
|
||||
@(link_name="acosf") libc_acosf :: proc(x: float) -> float ---
|
||||
@(link_name="asin") libc_asin :: proc(x: double) -> double ---
|
||||
@(link_name="asinf") libc_asinf :: proc(x: float) -> float ---
|
||||
@(link_name="atan") libc_atan :: proc(x: double) -> double ---
|
||||
@(link_name="atanf") libc_atanf :: proc(x: float) -> float ---
|
||||
@(link_name="atan2") libc_atan2 :: proc(y: double, x: double) -> double ---
|
||||
@(link_name="atan2f") libc_atan2f :: proc(y: float, x: float) -> float ---
|
||||
@(link_name="cos") libc_cos :: proc(x: double) -> double ---
|
||||
@(link_name="cosf") libc_cosf :: proc(x: float) -> float ---
|
||||
@(link_name="sin") libc_sin :: proc(x: double) -> double ---
|
||||
@(link_name="sinf") libc_sinf :: proc(x: float) -> float ---
|
||||
@(link_name="tan") libc_tan :: proc(x: double) -> double ---
|
||||
@(link_name="tanf") libc_tanf :: proc(x: float) -> float ---
|
||||
|
||||
// 7.12.5 Hyperbolic functions
|
||||
@(link_name="acosh") libc_acosh :: proc(x: double) -> double ---;
|
||||
@(link_name="acoshf") libc_acoshf :: proc(x: float) -> float ---;
|
||||
@(link_name="asinh") libc_asinh :: proc(x: double) -> double ---;
|
||||
@(link_name="asinhf") libc_asinhf :: proc(x: float) -> float ---;
|
||||
@(link_name="atanh") libc_atanh :: proc(x: double) -> double ---;
|
||||
@(link_name="atanhf") libc_atanhf :: proc(x: float) -> float ---;
|
||||
@(link_name="cosh") libc_cosh :: proc(x: double) -> double ---;
|
||||
@(link_name="coshf") libc_coshf :: proc(x: float) -> float ---;
|
||||
@(link_name="sinh") libc_sinh :: proc(x: double) -> double ---;
|
||||
@(link_name="sinhf") libc_sinhf :: proc(x: float) -> float ---;
|
||||
@(link_name="tanh") libc_tanh :: proc(x: double) -> double ---;
|
||||
@(link_name="tanhf") libc_tanhf :: proc(x: float) -> float ---;
|
||||
@(link_name="acosh") libc_acosh :: proc(x: double) -> double ---
|
||||
@(link_name="acoshf") libc_acoshf :: proc(x: float) -> float ---
|
||||
@(link_name="asinh") libc_asinh :: proc(x: double) -> double ---
|
||||
@(link_name="asinhf") libc_asinhf :: proc(x: float) -> float ---
|
||||
@(link_name="atanh") libc_atanh :: proc(x: double) -> double ---
|
||||
@(link_name="atanhf") libc_atanhf :: proc(x: float) -> float ---
|
||||
@(link_name="cosh") libc_cosh :: proc(x: double) -> double ---
|
||||
@(link_name="coshf") libc_coshf :: proc(x: float) -> float ---
|
||||
@(link_name="sinh") libc_sinh :: proc(x: double) -> double ---
|
||||
@(link_name="sinhf") libc_sinhf :: proc(x: float) -> float ---
|
||||
@(link_name="tanh") libc_tanh :: proc(x: double) -> double ---
|
||||
@(link_name="tanhf") libc_tanhf :: proc(x: float) -> float ---
|
||||
|
||||
// 7.12.6 Exponential and logarithmic functions
|
||||
@(link_name="exp") libc_exp :: proc(x: double) -> double ---;
|
||||
@(link_name="expf") libc_expf :: proc(x: float) -> float ---;
|
||||
@(link_name="exp2") libc_exp2 :: proc(x: double) -> double ---;
|
||||
@(link_name="exp2f") libc_exp2f :: proc(x: float) -> float ---;
|
||||
@(link_name="expm1") libc_expm1 :: proc(x: double) -> double ---;
|
||||
@(link_name="expm1f") libc_expm1f :: proc(x: float) -> float ---;
|
||||
@(link_name="frexp") libc_frexp :: proc(value: double, exp: ^int) -> double ---;
|
||||
@(link_name="frexpf") libc_frexpf :: proc(value: float, exp: ^int) -> float ---;
|
||||
@(link_name="ilogb") libc_ilogb :: proc(x: double) -> int ---;
|
||||
@(link_name="ilogbf") libc_ilogbf :: proc(x: float) -> int ---;
|
||||
@(link_name="ldexp") libc_ldexp :: proc(x: double, exp: int) -> double ---;
|
||||
@(link_name="ldexpf") libc_ldexpf :: proc(x: float, exp: int) -> float ---;
|
||||
@(link_name="log") libc_log :: proc(x: double) -> double ---;
|
||||
@(link_name="logf") libc_logf :: proc(x: float) -> float ---;
|
||||
@(link_name="log10") libc_log10 :: proc(x: double) -> double ---;
|
||||
@(link_name="log10f") libc_log10f :: proc(x: float) -> float ---;
|
||||
@(link_name="log1p") libc_log1p :: proc(x: double) -> double ---;
|
||||
@(link_name="log1pf") libc_log1pf :: proc(x: float) -> float ---;
|
||||
@(link_name="log2") libc_log2 :: proc(x: double) -> double ---;
|
||||
@(link_name="log2f") libc_log2f :: proc(x: float) -> float ---;
|
||||
@(link_name="logb") libc_logb :: proc(x: double) -> double ---;
|
||||
@(link_name="logbf") libc_logbf :: proc(x: float) -> float ---;
|
||||
@(link_name="modf") libc_modf :: proc(value: double, iptr: ^double) -> double ---;
|
||||
@(link_name="modff") libc_modff :: proc(value: float, iptr: ^float) -> float ---;
|
||||
@(link_name="scalbn") libc_scalbn :: proc(x: double, n: int) -> double ---;
|
||||
@(link_name="scalbnf") libc_scalbnf :: proc(x: float, n: int) -> float ---;
|
||||
@(link_name="scalbln") libc_scalbln :: proc(x: double, n: long) -> double ---;
|
||||
@(link_name="scalblnf") libc_scalblnf :: proc(x: float, n: long) -> float ---;
|
||||
@(link_name="exp") libc_exp :: proc(x: double) -> double ---
|
||||
@(link_name="expf") libc_expf :: proc(x: float) -> float ---
|
||||
@(link_name="exp2") libc_exp2 :: proc(x: double) -> double ---
|
||||
@(link_name="exp2f") libc_exp2f :: proc(x: float) -> float ---
|
||||
@(link_name="expm1") libc_expm1 :: proc(x: double) -> double ---
|
||||
@(link_name="expm1f") libc_expm1f :: proc(x: float) -> float ---
|
||||
@(link_name="frexp") libc_frexp :: proc(value: double, exp: ^int) -> double ---
|
||||
@(link_name="frexpf") libc_frexpf :: proc(value: float, exp: ^int) -> float ---
|
||||
@(link_name="ilogb") libc_ilogb :: proc(x: double) -> int ---
|
||||
@(link_name="ilogbf") libc_ilogbf :: proc(x: float) -> int ---
|
||||
@(link_name="ldexp") libc_ldexp :: proc(x: double, exp: int) -> double ---
|
||||
@(link_name="ldexpf") libc_ldexpf :: proc(x: float, exp: int) -> float ---
|
||||
@(link_name="log") libc_log :: proc(x: double) -> double ---
|
||||
@(link_name="logf") libc_logf :: proc(x: float) -> float ---
|
||||
@(link_name="log10") libc_log10 :: proc(x: double) -> double ---
|
||||
@(link_name="log10f") libc_log10f :: proc(x: float) -> float ---
|
||||
@(link_name="log1p") libc_log1p :: proc(x: double) -> double ---
|
||||
@(link_name="log1pf") libc_log1pf :: proc(x: float) -> float ---
|
||||
@(link_name="log2") libc_log2 :: proc(x: double) -> double ---
|
||||
@(link_name="log2f") libc_log2f :: proc(x: float) -> float ---
|
||||
@(link_name="logb") libc_logb :: proc(x: double) -> double ---
|
||||
@(link_name="logbf") libc_logbf :: proc(x: float) -> float ---
|
||||
@(link_name="modf") libc_modf :: proc(value: double, iptr: ^double) -> double ---
|
||||
@(link_name="modff") libc_modff :: proc(value: float, iptr: ^float) -> float ---
|
||||
@(link_name="scalbn") libc_scalbn :: proc(x: double, n: int) -> double ---
|
||||
@(link_name="scalbnf") libc_scalbnf :: proc(x: float, n: int) -> float ---
|
||||
@(link_name="scalbln") libc_scalbln :: proc(x: double, n: long) -> double ---
|
||||
@(link_name="scalblnf") libc_scalblnf :: proc(x: float, n: long) -> float ---
|
||||
|
||||
// 7.12.7 Power and absolute-value functions
|
||||
@(link_name="cbrt") libc_cbrt :: proc(x: double) -> double ---;
|
||||
@(link_name="cbrtf") libc_cbrtf :: proc(x: float) -> float ---;
|
||||
@(link_name="fabs") libc_fabs :: proc(x: double) -> double ---;
|
||||
@(link_name="fabsf") libc_fabsf :: proc(x: float) -> float ---;
|
||||
@(link_name="hypot") libc_hypot :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="hypotf") libc_hypotf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="pow") libc_pow :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="powf") libc_powf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="sqrt") libc_sqrt :: proc(x: double) -> double ---;
|
||||
@(link_name="sqrtf") libc_sqrtf :: proc(x: float) -> float ---;
|
||||
@(link_name="cbrt") libc_cbrt :: proc(x: double) -> double ---
|
||||
@(link_name="cbrtf") libc_cbrtf :: proc(x: float) -> float ---
|
||||
@(link_name="fabs") libc_fabs :: proc(x: double) -> double ---
|
||||
@(link_name="fabsf") libc_fabsf :: proc(x: float) -> float ---
|
||||
@(link_name="hypot") libc_hypot :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="hypotf") libc_hypotf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="pow") libc_pow :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="powf") libc_powf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="sqrt") libc_sqrt :: proc(x: double) -> double ---
|
||||
@(link_name="sqrtf") libc_sqrtf :: proc(x: float) -> float ---
|
||||
|
||||
// 7.12.8 Error and gamma functions
|
||||
@(link_name="erf") libc_erf :: proc(x: double) -> double ---;
|
||||
@(link_name="erff") libc_erff :: proc(x: float) -> float ---;
|
||||
@(link_name="erfc") libc_erfc :: proc(x: double) -> double ---;
|
||||
@(link_name="erfcf") libc_erfcf :: proc(x: float) -> float ---;
|
||||
@(link_name="lgamma") libc_lgamma :: proc(x: double) -> double ---;
|
||||
@(link_name="lgammaf") libc_lgammaf :: proc(x: float) -> float ---;
|
||||
@(link_name="tgamma") libc_tgamma :: proc(x: double) -> double ---;
|
||||
@(link_name="tgammaf") libc_tgammaf :: proc(x: float) -> float ---;
|
||||
@(link_name="erf") libc_erf :: proc(x: double) -> double ---
|
||||
@(link_name="erff") libc_erff :: proc(x: float) -> float ---
|
||||
@(link_name="erfc") libc_erfc :: proc(x: double) -> double ---
|
||||
@(link_name="erfcf") libc_erfcf :: proc(x: float) -> float ---
|
||||
@(link_name="lgamma") libc_lgamma :: proc(x: double) -> double ---
|
||||
@(link_name="lgammaf") libc_lgammaf :: proc(x: float) -> float ---
|
||||
@(link_name="tgamma") libc_tgamma :: proc(x: double) -> double ---
|
||||
@(link_name="tgammaf") libc_tgammaf :: proc(x: float) -> float ---
|
||||
|
||||
// 7.12.9 Nearest integer functions
|
||||
@(link_name="ceil") libc_ceil :: proc(x: double) -> double ---;
|
||||
@(link_name="ceilf") libc_ceilf :: proc(x: float) -> float ---;
|
||||
@(link_name="floor") libc_floor :: proc(x: double) -> double ---;
|
||||
@(link_name="floorf") libc_floorf :: proc(x: float) -> float ---;
|
||||
@(link_name="nearbyint") libc_nearbyint :: proc(x: double) -> double ---;
|
||||
@(link_name="nearbyintf") libc_nearbyintf :: proc(x: float) -> float ---;
|
||||
@(link_name="rint") libc_rint :: proc(x: double) -> double ---;
|
||||
@(link_name="rintf") libc_rintf :: proc(x: float) -> float ---;
|
||||
@(link_name="lrint") libc_lrint :: proc(x: double) -> long ---;
|
||||
@(link_name="lrintf") libc_lrintf :: proc(x: float) -> long ---;
|
||||
@(link_name="llrint") libc_llrint :: proc(x: double) -> longlong ---;
|
||||
@(link_name="llrintf") libc_llrintf :: proc(x: float) -> longlong ---;
|
||||
@(link_name="round") libc_round :: proc(x: double) -> double ---;
|
||||
@(link_name="roundf") libc_roundf :: proc(x: float) -> float ---;
|
||||
@(link_name="lround") libc_lround :: proc(x: double) -> long ---;
|
||||
@(link_name="lroundf") libc_lroundf :: proc(x: float) -> long ---;
|
||||
@(link_name="llround") libc_llround :: proc(x: double) -> longlong ---;
|
||||
@(link_name="llroundf") libc_llroundf :: proc(x: float) -> longlong ---;
|
||||
@(link_name="trunc") libc_trunc :: proc(x: double) -> double ---;
|
||||
@(link_name="truncf") libc_truncf :: proc(x: float) -> float ---;
|
||||
@(link_name="ceil") libc_ceil :: proc(x: double) -> double ---
|
||||
@(link_name="ceilf") libc_ceilf :: proc(x: float) -> float ---
|
||||
@(link_name="floor") libc_floor :: proc(x: double) -> double ---
|
||||
@(link_name="floorf") libc_floorf :: proc(x: float) -> float ---
|
||||
@(link_name="nearbyint") libc_nearbyint :: proc(x: double) -> double ---
|
||||
@(link_name="nearbyintf") libc_nearbyintf :: proc(x: float) -> float ---
|
||||
@(link_name="rint") libc_rint :: proc(x: double) -> double ---
|
||||
@(link_name="rintf") libc_rintf :: proc(x: float) -> float ---
|
||||
@(link_name="lrint") libc_lrint :: proc(x: double) -> long ---
|
||||
@(link_name="lrintf") libc_lrintf :: proc(x: float) -> long ---
|
||||
@(link_name="llrint") libc_llrint :: proc(x: double) -> longlong ---
|
||||
@(link_name="llrintf") libc_llrintf :: proc(x: float) -> longlong ---
|
||||
@(link_name="round") libc_round :: proc(x: double) -> double ---
|
||||
@(link_name="roundf") libc_roundf :: proc(x: float) -> float ---
|
||||
@(link_name="lround") libc_lround :: proc(x: double) -> long ---
|
||||
@(link_name="lroundf") libc_lroundf :: proc(x: float) -> long ---
|
||||
@(link_name="llround") libc_llround :: proc(x: double) -> longlong ---
|
||||
@(link_name="llroundf") libc_llroundf :: proc(x: float) -> longlong ---
|
||||
@(link_name="trunc") libc_trunc :: proc(x: double) -> double ---
|
||||
@(link_name="truncf") libc_truncf :: proc(x: float) -> float ---
|
||||
|
||||
// 7.12.10 Remainder functions
|
||||
@(link_name="fmod") libc_fmod :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="fmodf") libc_fmodf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="remainder") libc_remainder :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="remainderf") libc_remainderf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="remquo") libc_remquo :: proc(x: double, y: double, quo: ^int) -> double ---;
|
||||
@(link_name="remquof") libc_remquof :: proc(x: float, y: float, quo: ^int) -> float ---;
|
||||
@(link_name="fmod") libc_fmod :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="fmodf") libc_fmodf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="remainder") libc_remainder :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="remainderf") libc_remainderf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="remquo") libc_remquo :: proc(x: double, y: double, quo: ^int) -> double ---
|
||||
@(link_name="remquof") libc_remquof :: proc(x: float, y: float, quo: ^int) -> float ---
|
||||
|
||||
// 7.12.11 Manipulation functions
|
||||
@(link_name="copysign") libc_copysign :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="copysignf") libc_copysignf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="nan") libc_nan :: proc(tagp: cstring) -> double ---;
|
||||
@(link_name="nanf") libc_nanf :: proc(tagp: cstring) -> float ---;
|
||||
@(link_name="nextafter") libc_nextafter :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="nextafterf") libc_nextafterf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="copysign") libc_copysign :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="copysignf") libc_copysignf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="nan") libc_nan :: proc(tagp: cstring) -> double ---
|
||||
@(link_name="nanf") libc_nanf :: proc(tagp: cstring) -> float ---
|
||||
@(link_name="nextafter") libc_nextafter :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="nextafterf") libc_nextafterf :: proc(x: float, y: float) -> float ---
|
||||
|
||||
// 7.12.12 Maximum, minimum, and positive difference functions
|
||||
@(link_name="fdim") libc_fdim :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="fdimf") libc_fdimf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="fmax") libc_fmax :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="fmaxf") libc_fmaxf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="fmin") libc_fmin :: proc(x: double, y: double) -> double ---;
|
||||
@(link_name="fminf") libc_fminf :: proc(x: float, y: float) -> float ---;
|
||||
@(link_name="fma") libc_fma :: proc(x, y, z: double) -> double ---;
|
||||
@(link_name="fmaf") libc_fmaf :: proc(x, y, z: float) -> float ---;
|
||||
@(link_name="fdim") libc_fdim :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="fdimf") libc_fdimf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="fmax") libc_fmax :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="fmaxf") libc_fmaxf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="fmin") libc_fmin :: proc(x: double, y: double) -> double ---
|
||||
@(link_name="fminf") libc_fminf :: proc(x: float, y: float) -> float ---
|
||||
@(link_name="fma") libc_fma :: proc(x, y, z: double) -> double ---
|
||||
@(link_name="fmaf") libc_fmaf :: proc(x, y, z: float) -> float ---
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
_nan_bit_pattern := ~u64(0);
|
||||
_nan_bit_pattern := ~u64(0)
|
||||
|
||||
// On amd64 Windows and Linux, float_t and double_t are respectively both
|
||||
// their usual types. On x86 it's not possible to define these types correctly
|
||||
// since they would be long double which Odin does have support for.
|
||||
float_t :: float;
|
||||
double_t :: double;
|
||||
float_t :: float
|
||||
double_t :: double
|
||||
|
||||
NAN := transmute(double)(_nan_bit_pattern);
|
||||
INFINITY :: 1e5000;
|
||||
NAN := transmute(double)(_nan_bit_pattern)
|
||||
INFINITY :: 1e5000
|
||||
|
||||
HUGE_VALF :: INFINITY;
|
||||
HUGE_VAL :: double(INFINITY);
|
||||
HUGE_VALF :: INFINITY
|
||||
HUGE_VAL :: double(INFINITY)
|
||||
|
||||
MATH_ERRNO :: 1;
|
||||
MATH_ERREXCEPT :: 2;
|
||||
MATH_ERRNO :: 1
|
||||
MATH_ERREXCEPT :: 2
|
||||
|
||||
math_errhandling :: 2; // Windows, Linux, macOS all use this mode.
|
||||
math_errhandling :: 2 // Windows, Linux, macOS all use this mode.
|
||||
|
||||
FP_ILOGBNAN :: -1 - int((~uint(0)) >> 1);
|
||||
FP_ILOGB0 :: FP_ILOGBNAN;
|
||||
FP_ILOGBNAN :: -1 - int((~uint(0)) >> 1)
|
||||
FP_ILOGB0 :: FP_ILOGBNAN
|
||||
|
||||
// Number classification constants. These do not have to match libc since we
|
||||
// implement our own classification functions as libc requires they be macros,
|
||||
// which means libc does not export standard functions for them.
|
||||
FP_NAN :: 0;
|
||||
FP_INFINITE :: 1;
|
||||
FP_ZERO :: 2;
|
||||
FP_NORMAL :: 3;
|
||||
FP_SUBNORMAL :: 4;
|
||||
FP_NAN :: 0
|
||||
FP_INFINITE :: 1
|
||||
FP_ZERO :: 2
|
||||
FP_NORMAL :: 3
|
||||
FP_SUBNORMAL :: 4
|
||||
|
||||
@(private)
|
||||
_fpclassify :: #force_inline proc(x: double) -> int {
|
||||
u := transmute(uint64_t)x;
|
||||
e := u >> 52 & 0x7ff;
|
||||
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO;
|
||||
if e == 0x7ff do return FP_NAN if (u << 12) != 0 else FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
u := transmute(uint64_t)x
|
||||
e := u >> 52 & 0x7ff
|
||||
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO
|
||||
if e == 0x7ff do return FP_NAN if (u << 12) != 0 else FP_INFINITE
|
||||
return FP_NORMAL
|
||||
}
|
||||
|
||||
@(private)
|
||||
_fpclassifyf :: #force_inline proc(x: float) -> int {
|
||||
u := transmute(uint32_t)x;
|
||||
e := u >> 23 & 0xff;
|
||||
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO;
|
||||
if e == 0xff do return FP_NAN if (u << 9) != 0 else FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
u := transmute(uint32_t)x
|
||||
e := u >> 23 & 0xff
|
||||
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO
|
||||
if e == 0xff do return FP_NAN if (u << 9) != 0 else FP_INFINITE
|
||||
return FP_NORMAL
|
||||
}
|
||||
|
||||
@(private)
|
||||
_signbit :: #force_inline proc(x: double) -> int {
|
||||
return int(transmute(uint64_t)x >> 63);
|
||||
return int(transmute(uint64_t)x >> 63)
|
||||
}
|
||||
|
||||
@(private)
|
||||
_signbitf :: #force_inline proc(x: float) -> int {
|
||||
return int(transmute(uint32_t)x >> 31);
|
||||
return int(transmute(uint32_t)x >> 31)
|
||||
}
|
||||
|
||||
isfinite :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) == FP_INFINITE;
|
||||
return fpclassify(x) == FP_INFINITE
|
||||
}
|
||||
|
||||
isinf :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) > FP_INFINITE;
|
||||
return fpclassify(x) > FP_INFINITE
|
||||
}
|
||||
|
||||
isnan :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) == FP_NAN;
|
||||
return fpclassify(x) == FP_NAN
|
||||
}
|
||||
|
||||
isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) == FP_NORMAL;
|
||||
return fpclassify(x) == FP_NORMAL
|
||||
}
|
||||
|
||||
// These are special in that they avoid float exceptions. They cannot just be
|
||||
@@ -228,173 +228,173 @@ isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
// "sticky" state that propagates and affects maths results. These need
|
||||
// to be implemented natively in Odin assuming isunordered to prevent that.
|
||||
isgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x > y;
|
||||
return !isunordered(x, y) && x > y
|
||||
}
|
||||
|
||||
isgreaterequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x >= y;
|
||||
return !isunordered(x, y) && x >= y
|
||||
}
|
||||
|
||||
isless :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x < y;
|
||||
return !isunordered(x, y) && x < y
|
||||
}
|
||||
|
||||
islessequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x <= y;
|
||||
return !isunordered(x, y) && x <= y
|
||||
}
|
||||
|
||||
islessgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x <= y;
|
||||
return !isunordered(x, y) && x <= y
|
||||
}
|
||||
|
||||
isunordered :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
if isnan(x) {
|
||||
// Force evaluation of y to propagate exceptions for ordering semantics.
|
||||
// To ensure correct semantics of IEEE 754 this cannot be compiled away.
|
||||
sink: T;
|
||||
intrinsics.volatile_store(&sink, intrinsics.volatile_load(&y));
|
||||
return true;
|
||||
sink: T
|
||||
intrinsics.volatile_store(&sink, intrinsics.volatile_load(&y))
|
||||
return true
|
||||
}
|
||||
return isnan(y);
|
||||
return isnan(y)
|
||||
}
|
||||
|
||||
fpclassify :: proc{_fpclassify, _fpclassifyf};
|
||||
signbit :: proc{_signbit, _signbitf};
|
||||
fpclassify :: proc{_fpclassify, _fpclassifyf}
|
||||
signbit :: proc{_signbit, _signbitf}
|
||||
|
||||
// Emulate tgmath.h behavior with explicit procedure overloading here.
|
||||
acos :: proc{libc_acos, libc_acosf, cacos, cacosf};
|
||||
asin :: proc{libc_asin, libc_asinf, casin, casinf};
|
||||
atan :: proc{libc_atan, libc_atanf, catan, catanf};
|
||||
atan2 :: proc{libc_atan2, libc_atan2f};
|
||||
cos :: proc{libc_cos, libc_cosf, ccos, ccosf};
|
||||
sin :: proc{libc_sin, libc_sinf, csin, csinf};
|
||||
tan :: proc{libc_tan, libc_tanf, ctan, ctanf};
|
||||
acos :: proc{libc_acos, libc_acosf, cacos, cacosf}
|
||||
asin :: proc{libc_asin, libc_asinf, casin, casinf}
|
||||
atan :: proc{libc_atan, libc_atanf, catan, catanf}
|
||||
atan2 :: proc{libc_atan2, libc_atan2f}
|
||||
cos :: proc{libc_cos, libc_cosf, ccos, ccosf}
|
||||
sin :: proc{libc_sin, libc_sinf, csin, csinf}
|
||||
tan :: proc{libc_tan, libc_tanf, ctan, ctanf}
|
||||
|
||||
acosh :: proc{libc_acosh, libc_acoshf, cacosh, cacoshf};
|
||||
asinh :: proc{libc_asinh, libc_asinhf, casinh, casinhf};
|
||||
atanh :: proc{libc_atanh, libc_atanhf, catanh, catanhf};
|
||||
cosh :: proc{libc_cosh, libc_coshf, ccosh, ccoshf};
|
||||
sinh :: proc{libc_sinh, libc_sinhf, csinh, csinhf};
|
||||
tanh :: proc{libc_tanh, libc_tanhf, ctanh, ctanhf};
|
||||
acosh :: proc{libc_acosh, libc_acoshf, cacosh, cacoshf}
|
||||
asinh :: proc{libc_asinh, libc_asinhf, casinh, casinhf}
|
||||
atanh :: proc{libc_atanh, libc_atanhf, catanh, catanhf}
|
||||
cosh :: proc{libc_cosh, libc_coshf, ccosh, ccoshf}
|
||||
sinh :: proc{libc_sinh, libc_sinhf, csinh, csinhf}
|
||||
tanh :: proc{libc_tanh, libc_tanhf, ctanh, ctanhf}
|
||||
|
||||
exp :: proc{libc_exp, libc_expf, cexp, cexpf};
|
||||
exp2 :: proc{libc_exp2, libc_exp2f};
|
||||
expm1 :: proc{libc_expm1, libc_expm1f};
|
||||
frexp :: proc{libc_frexp, libc_frexpf};
|
||||
ilogb :: proc{libc_ilogb, libc_ilogbf};
|
||||
ldexp :: proc{libc_ldexp, libc_ldexpf};
|
||||
log :: proc{libc_log, libc_logf, clog, clogf};
|
||||
log10 :: proc{libc_log10, libc_log10f};
|
||||
log1p :: proc{libc_log1p, libc_log1pf};
|
||||
log2 :: proc{libc_log2, libc_log2f};
|
||||
logb :: proc{libc_logb, libc_logbf};
|
||||
modf :: proc{libc_modf, libc_modff};
|
||||
scalbn :: proc{libc_scalbn, libc_scalbnf};
|
||||
scalbln :: proc{libc_scalbln, libc_scalblnf};
|
||||
exp :: proc{libc_exp, libc_expf, cexp, cexpf}
|
||||
exp2 :: proc{libc_exp2, libc_exp2f}
|
||||
expm1 :: proc{libc_expm1, libc_expm1f}
|
||||
frexp :: proc{libc_frexp, libc_frexpf}
|
||||
ilogb :: proc{libc_ilogb, libc_ilogbf}
|
||||
ldexp :: proc{libc_ldexp, libc_ldexpf}
|
||||
log :: proc{libc_log, libc_logf, clog, clogf}
|
||||
log10 :: proc{libc_log10, libc_log10f}
|
||||
log1p :: proc{libc_log1p, libc_log1pf}
|
||||
log2 :: proc{libc_log2, libc_log2f}
|
||||
logb :: proc{libc_logb, libc_logbf}
|
||||
modf :: proc{libc_modf, libc_modff}
|
||||
scalbn :: proc{libc_scalbn, libc_scalbnf}
|
||||
scalbln :: proc{libc_scalbln, libc_scalblnf}
|
||||
|
||||
cbrt :: proc{libc_cbrt, libc_cbrtf};
|
||||
fabs :: proc{libc_fabs, libc_fabsf, cabs, cabsf};
|
||||
hypot :: proc{libc_hypot, libc_hypotf};
|
||||
pow :: proc{libc_pow, libc_powf, cpow, cpowf};
|
||||
sqrt :: proc{libc_sqrt, libc_sqrtf, csqrt, csqrtf};
|
||||
cbrt :: proc{libc_cbrt, libc_cbrtf}
|
||||
fabs :: proc{libc_fabs, libc_fabsf, cabs, cabsf}
|
||||
hypot :: proc{libc_hypot, libc_hypotf}
|
||||
pow :: proc{libc_pow, libc_powf, cpow, cpowf}
|
||||
sqrt :: proc{libc_sqrt, libc_sqrtf, csqrt, csqrtf}
|
||||
|
||||
erf :: proc{libc_erf, libc_erff};
|
||||
erfc :: proc{libc_erfc, libc_erfcf};
|
||||
lgamma :: proc{libc_lgamma, libc_lgammaf};
|
||||
tgamma :: proc{libc_tgamma, libc_tgammaf};
|
||||
erf :: proc{libc_erf, libc_erff}
|
||||
erfc :: proc{libc_erfc, libc_erfcf}
|
||||
lgamma :: proc{libc_lgamma, libc_lgammaf}
|
||||
tgamma :: proc{libc_tgamma, libc_tgammaf}
|
||||
|
||||
ceil :: proc{libc_ceil, libc_ceilf};
|
||||
floor :: proc{libc_floor, libc_floorf};
|
||||
nearbyint :: proc{libc_nearbyint, libc_nearbyintf};
|
||||
rint :: proc{libc_rint, libc_rintf};
|
||||
lrint :: proc{libc_lrint, libc_lrintf};
|
||||
llrint :: proc{libc_llrint, libc_llrintf};
|
||||
round :: proc{libc_round, libc_roundf};
|
||||
lround :: proc{libc_lround, libc_lroundf};
|
||||
llround :: proc{libc_llround, libc_llroundf};
|
||||
trunc :: proc{libc_trunc, libc_truncf};
|
||||
ceil :: proc{libc_ceil, libc_ceilf}
|
||||
floor :: proc{libc_floor, libc_floorf}
|
||||
nearbyint :: proc{libc_nearbyint, libc_nearbyintf}
|
||||
rint :: proc{libc_rint, libc_rintf}
|
||||
lrint :: proc{libc_lrint, libc_lrintf}
|
||||
llrint :: proc{libc_llrint, libc_llrintf}
|
||||
round :: proc{libc_round, libc_roundf}
|
||||
lround :: proc{libc_lround, libc_lroundf}
|
||||
llround :: proc{libc_llround, libc_llroundf}
|
||||
trunc :: proc{libc_trunc, libc_truncf}
|
||||
|
||||
fmod :: proc{libc_fmod, libc_fmodf};
|
||||
remainder :: proc{libc_remainder, libc_remainderf};
|
||||
remquo :: proc{libc_remquo, libc_remquof};
|
||||
fmod :: proc{libc_fmod, libc_fmodf}
|
||||
remainder :: proc{libc_remainder, libc_remainderf}
|
||||
remquo :: proc{libc_remquo, libc_remquof}
|
||||
|
||||
copysign :: proc{libc_copysign, libc_copysignf};
|
||||
nextafter :: proc{libc_nextafter, libc_nextafterf};
|
||||
copysign :: proc{libc_copysign, libc_copysignf}
|
||||
nextafter :: proc{libc_nextafter, libc_nextafterf}
|
||||
|
||||
fdim :: proc{libc_fdim, libc_fdimf};
|
||||
fmax :: proc{libc_fmax, libc_fmaxf};
|
||||
fmin :: proc{libc_fmin, libc_fminf};
|
||||
fma :: proc{libc_fma, libc_fmaf};
|
||||
fdim :: proc{libc_fdim, libc_fdimf}
|
||||
fmax :: proc{libc_fmax, libc_fmaxf}
|
||||
fmin :: proc{libc_fmin, libc_fminf}
|
||||
fma :: proc{libc_fma, libc_fmaf}
|
||||
|
||||
// But retain the 'f' suffix-variant functions as well so they can be used,
|
||||
// a trick is used here where we use explicit procedrual overloading of one
|
||||
// procedure. This is done because the foreign block is marked @(private) and
|
||||
// aliasing functions does not remove privateness from the entity.
|
||||
acosf :: proc{libc_acosf};
|
||||
asinf :: proc{libc_asinf};
|
||||
atanf :: proc{libc_atanf};
|
||||
atan2f :: proc{libc_atan2f};
|
||||
cosf :: proc{libc_cosf};
|
||||
sinf :: proc{libc_sinf};
|
||||
tanf :: proc{libc_tanf};
|
||||
acosf :: proc{libc_acosf}
|
||||
asinf :: proc{libc_asinf}
|
||||
atanf :: proc{libc_atanf}
|
||||
atan2f :: proc{libc_atan2f}
|
||||
cosf :: proc{libc_cosf}
|
||||
sinf :: proc{libc_sinf}
|
||||
tanf :: proc{libc_tanf}
|
||||
|
||||
acoshf :: proc{libc_acoshf};
|
||||
asinhf :: proc{libc_asinhf};
|
||||
atanhf :: proc{libc_atanhf};
|
||||
coshf :: proc{libc_coshf};
|
||||
sinhf :: proc{libc_sinhf};
|
||||
tanhf :: proc{libc_tanhf};
|
||||
acoshf :: proc{libc_acoshf}
|
||||
asinhf :: proc{libc_asinhf}
|
||||
atanhf :: proc{libc_atanhf}
|
||||
coshf :: proc{libc_coshf}
|
||||
sinhf :: proc{libc_sinhf}
|
||||
tanhf :: proc{libc_tanhf}
|
||||
|
||||
expf :: proc{libc_expf};
|
||||
exp2f :: proc{libc_exp2f};
|
||||
expm1f :: proc{libc_expm1f};
|
||||
frexpf :: proc{libc_frexpf};
|
||||
ilogbf :: proc{libc_ilogbf};
|
||||
ldexpf :: proc{libc_ldexpf};
|
||||
logf :: proc{libc_logf};
|
||||
log10f :: proc{libc_log10f};
|
||||
log1pf :: proc{libc_log1pf};
|
||||
log2f :: proc{libc_log2f};
|
||||
logbf :: proc{libc_logbf};
|
||||
modff :: proc{libc_modff};
|
||||
scalbnf :: proc{libc_scalbnf};
|
||||
scalblnf :: proc{libc_scalblnf};
|
||||
expf :: proc{libc_expf}
|
||||
exp2f :: proc{libc_exp2f}
|
||||
expm1f :: proc{libc_expm1f}
|
||||
frexpf :: proc{libc_frexpf}
|
||||
ilogbf :: proc{libc_ilogbf}
|
||||
ldexpf :: proc{libc_ldexpf}
|
||||
logf :: proc{libc_logf}
|
||||
log10f :: proc{libc_log10f}
|
||||
log1pf :: proc{libc_log1pf}
|
||||
log2f :: proc{libc_log2f}
|
||||
logbf :: proc{libc_logbf}
|
||||
modff :: proc{libc_modff}
|
||||
scalbnf :: proc{libc_scalbnf}
|
||||
scalblnf :: proc{libc_scalblnf}
|
||||
|
||||
cbrtf :: proc{libc_cbrtf};
|
||||
fabsf :: proc{libc_fabsf};
|
||||
hypotf :: proc{libc_hypotf};
|
||||
powf :: proc{libc_powf};
|
||||
sqrtf :: proc{libc_sqrtf};
|
||||
cbrtf :: proc{libc_cbrtf}
|
||||
fabsf :: proc{libc_fabsf}
|
||||
hypotf :: proc{libc_hypotf}
|
||||
powf :: proc{libc_powf}
|
||||
sqrtf :: proc{libc_sqrtf}
|
||||
|
||||
erff :: proc{libc_erff};
|
||||
erfcf :: proc{libc_erfcf};
|
||||
lgammaf :: proc{libc_lgammaf};
|
||||
tgammaf :: proc{libc_tgammaf};
|
||||
erff :: proc{libc_erff}
|
||||
erfcf :: proc{libc_erfcf}
|
||||
lgammaf :: proc{libc_lgammaf}
|
||||
tgammaf :: proc{libc_tgammaf}
|
||||
|
||||
ceilf :: proc{libc_ceilf};
|
||||
floorf :: proc{libc_floorf};
|
||||
nearbyintf :: proc{libc_nearbyintf};
|
||||
rintf :: proc{libc_rintf};
|
||||
lrintf :: proc{libc_lrintf};
|
||||
llrintf :: proc{libc_llrintf};
|
||||
roundf :: proc{libc_roundf};
|
||||
lroundf :: proc{libc_lroundf};
|
||||
llroundf :: proc{libc_llroundf};
|
||||
truncf :: proc{libc_truncf};
|
||||
ceilf :: proc{libc_ceilf}
|
||||
floorf :: proc{libc_floorf}
|
||||
nearbyintf :: proc{libc_nearbyintf}
|
||||
rintf :: proc{libc_rintf}
|
||||
lrintf :: proc{libc_lrintf}
|
||||
llrintf :: proc{libc_llrintf}
|
||||
roundf :: proc{libc_roundf}
|
||||
lroundf :: proc{libc_lroundf}
|
||||
llroundf :: proc{libc_llroundf}
|
||||
truncf :: proc{libc_truncf}
|
||||
|
||||
fmodf :: proc{libc_fmodf};
|
||||
remainderf :: proc{libc_remainderf};
|
||||
remquof :: proc{libc_remquof};
|
||||
fmodf :: proc{libc_fmodf}
|
||||
remainderf :: proc{libc_remainderf}
|
||||
remquof :: proc{libc_remquof}
|
||||
|
||||
copysignf :: proc{libc_copysignf};
|
||||
nextafterf :: proc{libc_nextafterf};
|
||||
copysignf :: proc{libc_copysignf}
|
||||
nextafterf :: proc{libc_nextafterf}
|
||||
|
||||
fdimf :: proc{libc_fdimf};
|
||||
fmaxf :: proc{libc_fmaxf};
|
||||
fminf :: proc{libc_fminf};
|
||||
fmaf :: proc{libc_fmaf};
|
||||
fdimf :: proc{libc_fdimf}
|
||||
fmaxf :: proc{libc_fmaxf}
|
||||
fminf :: proc{libc_fminf}
|
||||
fmaf :: proc{libc_fmaf}
|
||||
|
||||
// These two functions are special and not made type generic in tgmath.h since
|
||||
// they only differ by their return type.
|
||||
nan :: proc{libc_nan};
|
||||
nanf :: proc{libc_nanf};
|
||||
nan :: proc{libc_nan}
|
||||
nanf :: proc{libc_nanf}
|
||||
|
||||
@@ -31,7 +31,7 @@ when ODIN_OS == "windows" {
|
||||
// the RDX register will contain zero and correctly set the flag to disable
|
||||
// stack unwinding.
|
||||
@(link_name="_setjmp")
|
||||
setjmp :: proc(env: ^jmp_buf, hack: rawptr = nil) -> int ---;
|
||||
setjmp :: proc(env: ^jmp_buf, hack: rawptr = nil) -> int ---
|
||||
}
|
||||
} else {
|
||||
@(default_calling_convention="c")
|
||||
@@ -42,14 +42,14 @@ when ODIN_OS == "windows" {
|
||||
// necessarily export a symbol named setjmp but rather _setjmp in the case
|
||||
// of musl, glibc, BSD libc, and msvcrt.
|
||||
@(link_name="_setjmp")
|
||||
setjmp :: proc(env: ^jmp_buf) -> int ---;
|
||||
setjmp :: proc(env: ^jmp_buf) -> int ---
|
||||
}
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.13.2 Restore calling environment
|
||||
longjmp :: proc(env: ^jmp_buf, val: int) -> ! ---;
|
||||
longjmp :: proc(env: ^jmp_buf, val: int) -> ! ---
|
||||
}
|
||||
|
||||
// The C99 Rationale describes jmp_buf as being an array type for backward
|
||||
@@ -62,4 +62,4 @@ foreign libc {
|
||||
// strictly conformant C implementation is 16 on the platforms we care about.
|
||||
// The choice of 4096 bytes for storage of this type is more than enough on all
|
||||
// relevant platforms.
|
||||
jmp_buf :: struct #align 16 { _: [4096]char, };
|
||||
jmp_buf :: struct #align 16 { _: [4096]char, }
|
||||
|
||||
@@ -8,36 +8,36 @@ when ODIN_OS == "windows" {
|
||||
foreign import libc "system:c"
|
||||
}
|
||||
|
||||
sig_atomic_t :: distinct atomic_int;
|
||||
sig_atomic_t :: distinct atomic_int
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
signal :: proc(sig: int, func: proc "c" (int)) -> proc "c" (int) ---;
|
||||
raise :: proc(sig: int) -> int ---;
|
||||
signal :: proc(sig: int, func: proc "c" (int)) -> proc "c" (int) ---
|
||||
raise :: proc(sig: int) -> int ---
|
||||
}
|
||||
|
||||
when ODIN_OS == "windows" {
|
||||
SIG_ERR :: rawptr(~uintptr(0));
|
||||
SIG_DFL :: rawptr(uintptr(0));
|
||||
SIG_IGN :: rawptr(uintptr(1));
|
||||
SIG_ERR :: rawptr(~uintptr(0))
|
||||
SIG_DFL :: rawptr(uintptr(0))
|
||||
SIG_IGN :: rawptr(uintptr(1))
|
||||
|
||||
SIGABRT :: 22;
|
||||
SIGFPE :: 8;
|
||||
SIGILL :: 4;
|
||||
SIGINT :: 2;
|
||||
SIGSEGV :: 11;
|
||||
SIGTERM :: 15;
|
||||
SIGABRT :: 22
|
||||
SIGFPE :: 8
|
||||
SIGILL :: 4
|
||||
SIGINT :: 2
|
||||
SIGSEGV :: 11
|
||||
SIGTERM :: 15
|
||||
}
|
||||
|
||||
when ODIN_OS == "linux" || ODIN_OS == "freebsd" || ODIN_OS == "darwin" {
|
||||
SIG_ERR :: rawptr(~uintptr(0));
|
||||
SIG_DFL :: rawptr(uintptr(0));
|
||||
SIG_IGN :: rawptr(uintptr(1));
|
||||
SIG_ERR :: rawptr(~uintptr(0))
|
||||
SIG_DFL :: rawptr(uintptr(0))
|
||||
SIG_IGN :: rawptr(uintptr(1))
|
||||
|
||||
SIGABRT :: 6;
|
||||
SIGFPE :: 8;
|
||||
SIGILL :: 4;
|
||||
SIGINT :: 2;
|
||||
SIGSEGV :: 11;
|
||||
SIGTERM :: 15;
|
||||
SIGABRT :: 6
|
||||
SIGFPE :: 8
|
||||
SIGILL :: 4
|
||||
SIGINT :: 2
|
||||
SIGSEGV :: 11
|
||||
SIGTERM :: 15
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ import "core:mem"
|
||||
@(private="file")
|
||||
@(default_calling_convention="none")
|
||||
foreign _ {
|
||||
@(link_name="llvm.va_start") _va_start :: proc(arglist: ^i8) ---;
|
||||
@(link_name="llvm.va_end") _va_end :: proc(arglist: ^i8) ---;
|
||||
@(link_name="llvm.va_copy") _va_copy :: proc(dst, src: ^i8) ---;
|
||||
@(link_name="llvm.va_start") _va_start :: proc(arglist: ^i8) ---
|
||||
@(link_name="llvm.va_end") _va_end :: proc(arglist: ^i8) ---
|
||||
@(link_name="llvm.va_copy") _va_copy :: proc(dst, src: ^i8) ---
|
||||
}
|
||||
|
||||
// Since there are no types in C with an alignment larger than that of
|
||||
@@ -22,18 +22,18 @@ foreign _ {
|
||||
// relevant platforms.
|
||||
va_list :: struct #align 16 {
|
||||
_: [4096]u8,
|
||||
};
|
||||
}
|
||||
|
||||
va_start :: #force_inline proc(ap: ^va_list, _: any) {
|
||||
_va_start(cast(^i8)ap);
|
||||
_va_start(cast(^i8)ap)
|
||||
}
|
||||
|
||||
va_end :: #force_inline proc(ap: ^va_list) {
|
||||
_va_end(cast(^i8)ap);
|
||||
_va_end(cast(^i8)ap)
|
||||
}
|
||||
|
||||
va_copy :: #force_inline proc(dst, src: ^va_list) {
|
||||
_va_copy(cast(^i8)dst, cast(^i8)src);
|
||||
_va_copy(cast(^i8)dst, cast(^i8)src)
|
||||
}
|
||||
|
||||
// We cannot provide va_arg as there is no way to create "C" style procedures
|
||||
|
||||
@@ -4,16 +4,16 @@ package libc
|
||||
|
||||
import "core:intrinsics"
|
||||
|
||||
ATOMIC_BOOL_LOCK_FREE :: true;
|
||||
ATOMIC_CHAR_LOCK_FREE :: true;
|
||||
ATOMIC_CHAR16_T_LOCK_FREE :: true;
|
||||
ATOMIC_CHAR32_T_LOCK_FREE :: true;
|
||||
ATOMIC_WCHAR_T_LOCK_FREE :: true;
|
||||
ATOMIC_SHORT_LOCK_FREE :: true;
|
||||
ATOMIC_INT_LOCK_FREE :: true;
|
||||
ATOMIC_LONG_LOCK_FREE :: true;
|
||||
ATOMIC_LLONG_LOCK_FREE :: true;
|
||||
ATOMIC_POINTER_LOCK_FREE :: true;
|
||||
ATOMIC_BOOL_LOCK_FREE :: true
|
||||
ATOMIC_CHAR_LOCK_FREE :: true
|
||||
ATOMIC_CHAR16_T_LOCK_FREE :: true
|
||||
ATOMIC_CHAR32_T_LOCK_FREE :: true
|
||||
ATOMIC_WCHAR_T_LOCK_FREE :: true
|
||||
ATOMIC_SHORT_LOCK_FREE :: true
|
||||
ATOMIC_INT_LOCK_FREE :: true
|
||||
ATOMIC_LONG_LOCK_FREE :: true
|
||||
ATOMIC_LLONG_LOCK_FREE :: true
|
||||
ATOMIC_POINTER_LOCK_FREE :: true
|
||||
|
||||
// 7.17.3 Order and consistency
|
||||
memory_order :: enum int {
|
||||
@@ -25,152 +25,152 @@ memory_order :: enum int {
|
||||
seq_cst,
|
||||
}
|
||||
|
||||
memory_order_relaxed :: memory_order.relaxed;
|
||||
memory_order_consume :: memory_order.consume;
|
||||
memory_order_acquire :: memory_order.acquire;
|
||||
memory_order_release :: memory_order.release;
|
||||
memory_order_acq_rel :: memory_order.acq_rel;
|
||||
memory_order_seq_cst :: memory_order.seq_cst;
|
||||
memory_order_relaxed :: memory_order.relaxed
|
||||
memory_order_consume :: memory_order.consume
|
||||
memory_order_acquire :: memory_order.acquire
|
||||
memory_order_release :: memory_order.release
|
||||
memory_order_acq_rel :: memory_order.acq_rel
|
||||
memory_order_seq_cst :: memory_order.seq_cst
|
||||
|
||||
// 7.17.2 Initialization
|
||||
ATOMIC_VAR_INIT :: #force_inline proc(value: $T) -> T {
|
||||
return value;
|
||||
return value
|
||||
}
|
||||
|
||||
atomic_init :: #force_inline proc(obj: ^$T, value: T) {
|
||||
intrinsics.atomic_store(obj, value);
|
||||
intrinsics.atomic_store(obj, value)
|
||||
}
|
||||
|
||||
kill_dependency :: #force_inline proc(value: $T) -> T {
|
||||
return value;
|
||||
return value
|
||||
}
|
||||
|
||||
// 7.17.4 Fences
|
||||
atomic_thread_fence :: #force_inline proc(order: memory_order) {
|
||||
switch (order) {
|
||||
case .relaxed:
|
||||
return;
|
||||
return
|
||||
case .consume:
|
||||
intrinsics.atomic_fence_acq();
|
||||
intrinsics.atomic_fence_acq()
|
||||
case .acquire:
|
||||
intrinsics.atomic_fence_acq();
|
||||
intrinsics.atomic_fence_acq()
|
||||
case .release:
|
||||
intrinsics.atomic_fence_rel();
|
||||
intrinsics.atomic_fence_rel()
|
||||
case .acq_rel:
|
||||
intrinsics.atomic_fence_acqrel();
|
||||
intrinsics.atomic_fence_acqrel()
|
||||
case .seq_cst:
|
||||
intrinsics.atomic_fence_acqrel();
|
||||
intrinsics.atomic_fence_acqrel()
|
||||
}
|
||||
}
|
||||
|
||||
atomic_signal_fence :: #force_inline proc(order: memory_order) {
|
||||
atomic_thread_fence(order);
|
||||
atomic_thread_fence(order)
|
||||
}
|
||||
|
||||
// 7.17.5 Lock-free property
|
||||
atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool {
|
||||
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T));
|
||||
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T))
|
||||
}
|
||||
|
||||
// 7.17.6 Atomic integer types
|
||||
atomic_bool :: distinct bool;
|
||||
atomic_char :: distinct char;
|
||||
atomic_schar :: distinct char;
|
||||
atomic_uchar :: distinct uchar;
|
||||
atomic_short :: distinct short;
|
||||
atomic_ushort :: distinct ushort;
|
||||
atomic_int :: distinct int;
|
||||
atomic_uint :: distinct uint;
|
||||
atomic_long :: distinct long;
|
||||
atomic_ulong :: distinct ulong;
|
||||
atomic_llong :: distinct longlong;
|
||||
atomic_ullong :: distinct ulonglong;
|
||||
atomic_char16_t :: distinct char16_t;
|
||||
atomic_char32_t :: distinct char32_t;
|
||||
atomic_wchar_t :: distinct wchar_t;
|
||||
atomic_int_least8_t :: distinct int_least8_t;
|
||||
atomic_uint_least8_t :: distinct uint_least8_t;
|
||||
atomic_int_least16_t :: distinct int_least16_t;
|
||||
atomic_uint_least16_t :: distinct uint_least16_t;
|
||||
atomic_int_least32_t :: distinct int_least32_t;
|
||||
atomic_uint_least32_t :: distinct uint_least32_t;
|
||||
atomic_int_least64_t :: distinct int_least64_t;
|
||||
atomic_uint_least64_t :: distinct uint_least64_t;
|
||||
atomic_int_fast8_t :: distinct int_fast8_t;
|
||||
atomic_uint_fast8_t :: distinct uint_fast8_t;
|
||||
atomic_int_fast16_t :: distinct int_fast16_t;
|
||||
atomic_uint_fast16_t :: distinct uint_fast16_t;
|
||||
atomic_int_fast32_t :: distinct int_fast32_t;
|
||||
atomic_uint_fast32_t :: distinct uint_fast32_t;
|
||||
atomic_int_fast64_t :: distinct int_fast64_t;
|
||||
atomic_uint_fast64_t :: distinct uint_fast64_t;
|
||||
atomic_intptr_t :: distinct intptr_t;
|
||||
atomic_uintptr_t :: distinct uintptr_t;
|
||||
atomic_size_t :: distinct size_t;
|
||||
atomic_ptrdiff_t :: distinct ptrdiff_t;
|
||||
atomic_intmax_t :: distinct intmax_t;
|
||||
atomic_uintmax_t :: distinct uintmax_t;
|
||||
atomic_bool :: distinct bool
|
||||
atomic_char :: distinct char
|
||||
atomic_schar :: distinct char
|
||||
atomic_uchar :: distinct uchar
|
||||
atomic_short :: distinct short
|
||||
atomic_ushort :: distinct ushort
|
||||
atomic_int :: distinct int
|
||||
atomic_uint :: distinct uint
|
||||
atomic_long :: distinct long
|
||||
atomic_ulong :: distinct ulong
|
||||
atomic_llong :: distinct longlong
|
||||
atomic_ullong :: distinct ulonglong
|
||||
atomic_char16_t :: distinct char16_t
|
||||
atomic_char32_t :: distinct char32_t
|
||||
atomic_wchar_t :: distinct wchar_t
|
||||
atomic_int_least8_t :: distinct int_least8_t
|
||||
atomic_uint_least8_t :: distinct uint_least8_t
|
||||
atomic_int_least16_t :: distinct int_least16_t
|
||||
atomic_uint_least16_t :: distinct uint_least16_t
|
||||
atomic_int_least32_t :: distinct int_least32_t
|
||||
atomic_uint_least32_t :: distinct uint_least32_t
|
||||
atomic_int_least64_t :: distinct int_least64_t
|
||||
atomic_uint_least64_t :: distinct uint_least64_t
|
||||
atomic_int_fast8_t :: distinct int_fast8_t
|
||||
atomic_uint_fast8_t :: distinct uint_fast8_t
|
||||
atomic_int_fast16_t :: distinct int_fast16_t
|
||||
atomic_uint_fast16_t :: distinct uint_fast16_t
|
||||
atomic_int_fast32_t :: distinct int_fast32_t
|
||||
atomic_uint_fast32_t :: distinct uint_fast32_t
|
||||
atomic_int_fast64_t :: distinct int_fast64_t
|
||||
atomic_uint_fast64_t :: distinct uint_fast64_t
|
||||
atomic_intptr_t :: distinct intptr_t
|
||||
atomic_uintptr_t :: distinct uintptr_t
|
||||
atomic_size_t :: distinct size_t
|
||||
atomic_ptrdiff_t :: distinct ptrdiff_t
|
||||
atomic_intmax_t :: distinct intmax_t
|
||||
atomic_uintmax_t :: distinct uintmax_t
|
||||
|
||||
// 7.17.7 Operations on atomic types
|
||||
atomic_store :: #force_inline proc(object: ^$T, desired: T) {
|
||||
intrinsics.atomic_store(object, desired);
|
||||
intrinsics.atomic_store(object, desired)
|
||||
}
|
||||
|
||||
atomic_store_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) {
|
||||
assert(order != .consume);
|
||||
assert(order != .acquire);
|
||||
assert(order != .acq_rel);
|
||||
assert(order != .consume)
|
||||
assert(order != .acquire)
|
||||
assert(order != .acq_rel)
|
||||
|
||||
#partial switch (order) {
|
||||
case .relaxed:
|
||||
intrinsics.atomic_store_relaxed(object, desired);
|
||||
intrinsics.atomic_store_relaxed(object, desired)
|
||||
case .release:
|
||||
intrinsics.atomic_store_rel(object, desired);
|
||||
intrinsics.atomic_store_rel(object, desired)
|
||||
case .seq_cst:
|
||||
intrinsics.atomic_store(object, desired);
|
||||
intrinsics.atomic_store(object, desired)
|
||||
}
|
||||
}
|
||||
|
||||
atomic_load :: #force_inline proc(object: ^$T) -> T {
|
||||
return intrinsics.atomic_load(object);
|
||||
return intrinsics.atomic_load(object)
|
||||
}
|
||||
|
||||
atomic_load_explicit :: #force_inline proc(object: ^$T, order: memory_order) {
|
||||
assert(order != .release);
|
||||
assert(order != .acq_rel);
|
||||
assert(order != .release)
|
||||
assert(order != .acq_rel)
|
||||
|
||||
#partial switch (order) {
|
||||
case .relaxed:
|
||||
return intrinsics.atomic_load_relaxed(object);
|
||||
return intrinsics.atomic_load_relaxed(object)
|
||||
case .consume:
|
||||
return intrinsics.atomic_load_acq(object);
|
||||
return intrinsics.atomic_load_acq(object)
|
||||
case .acquire:
|
||||
return intrinsics.atomic_load_acq(object);
|
||||
return intrinsics.atomic_load_acq(object)
|
||||
case .seq_cst:
|
||||
return intrinsics.atomic_load(object);
|
||||
return intrinsics.atomic_load(object)
|
||||
}
|
||||
}
|
||||
|
||||
atomic_exchange :: #force_inline proc(object: ^$T, desired: T) -> T {
|
||||
return intrinsics.atomic_xchg(object, desired);
|
||||
return intrinsics.atomic_xchg(object, desired)
|
||||
}
|
||||
|
||||
atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) -> T {
|
||||
switch (order) {
|
||||
case .relaxed:
|
||||
return intrinsics.atomic_xchg_relaxed(object, desired);
|
||||
return intrinsics.atomic_xchg_relaxed(object, desired)
|
||||
case .consume:
|
||||
return intrinsics.atomic_xchg_acq(object, desired);
|
||||
return intrinsics.atomic_xchg_acq(object, desired)
|
||||
case .acquire:
|
||||
return intrinsics.atomic_xchg_acq(object, desired);
|
||||
return intrinsics.atomic_xchg_acq(object, desired)
|
||||
case .release:
|
||||
return intrinsics.atomic_xchg_rel(object, desired);
|
||||
return intrinsics.atomic_xchg_rel(object, desired)
|
||||
case .acq_rel:
|
||||
return intrinsics.atomic_xchg_acqrel(object, desired);
|
||||
return intrinsics.atomic_xchg_acqrel(object, desired)
|
||||
case .seq_cst:
|
||||
return intrinsics.atomic_xchg(object, desired);
|
||||
return intrinsics.atomic_xchg(object, desired)
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
// C does not allow failure memory order to be order_release or acq_rel.
|
||||
@@ -190,227 +190,227 @@ atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: m
|
||||
// [success = acquire, failure = relaxed] => acq_failrelaxed
|
||||
// [success = acq_rel, failure = relaxed] => acqrel_failrelaxed
|
||||
atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) {
|
||||
value, ok := intrinsics.atomic_cxchg(object, expected^, desired);
|
||||
if !ok do expected^ = value;
|
||||
return ok;
|
||||
value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
|
||||
if !ok do expected^ = value
|
||||
return ok
|
||||
}
|
||||
|
||||
atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) {
|
||||
assert(failure != .release);
|
||||
assert(failure != .acq_rel);
|
||||
assert(failure != .release)
|
||||
assert(failure != .acq_rel)
|
||||
|
||||
value: T; ok: bool;
|
||||
value: T; ok: bool
|
||||
#partial switch (failure) {
|
||||
case .seq_cst:
|
||||
assert(success != .relaxed);
|
||||
assert(success != .relaxed)
|
||||
#partial switch (success) {
|
||||
case .seq_cst:
|
||||
value, ok := intrinsics.atomic_cxchg(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
|
||||
case .acquire:
|
||||
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
|
||||
case .consume:
|
||||
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
|
||||
case .release:
|
||||
value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired)
|
||||
case .acq_rel:
|
||||
value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired)
|
||||
}
|
||||
case .relaxed:
|
||||
assert(success != .release);
|
||||
assert(success != .release)
|
||||
#partial switch (success) {
|
||||
case .relaxed:
|
||||
value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired)
|
||||
case .seq_cst:
|
||||
value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired)
|
||||
case .acquire:
|
||||
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
|
||||
case .consume:
|
||||
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
|
||||
case .acq_rel:
|
||||
value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired)
|
||||
}
|
||||
case .consume:
|
||||
fallthrough;
|
||||
fallthrough
|
||||
case .acquire:
|
||||
assert(success == .seq_cst);
|
||||
value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired);
|
||||
assert(success == .seq_cst)
|
||||
value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired)
|
||||
|
||||
}
|
||||
if !ok do expected^ = value;
|
||||
return ok;
|
||||
if !ok do expected^ = value
|
||||
return ok
|
||||
}
|
||||
|
||||
atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) {
|
||||
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired);
|
||||
if !ok do expected^ = value;
|
||||
return ok;
|
||||
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
|
||||
if !ok do expected^ = value
|
||||
return ok
|
||||
}
|
||||
|
||||
atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) {
|
||||
assert(failure != .release);
|
||||
assert(failure != .acq_rel);
|
||||
assert(failure != .release)
|
||||
assert(failure != .acq_rel)
|
||||
|
||||
value: T; ok: bool;
|
||||
value: T; ok: bool
|
||||
#partial switch (failure) {
|
||||
case .seq_cst:
|
||||
assert(success != .relaxed);
|
||||
assert(success != .relaxed)
|
||||
#partial switch (success) {
|
||||
case .seq_cst:
|
||||
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
|
||||
case .acquire:
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
|
||||
case .consume:
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
|
||||
case .release:
|
||||
value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired)
|
||||
case .acq_rel:
|
||||
value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired)
|
||||
}
|
||||
case .relaxed:
|
||||
assert(success != .release);
|
||||
assert(success != .release)
|
||||
#partial switch (success) {
|
||||
case .relaxed:
|
||||
value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired)
|
||||
case .seq_cst:
|
||||
value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired)
|
||||
case .acquire:
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
|
||||
case .consume:
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
|
||||
case .acq_rel:
|
||||
value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired);
|
||||
value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired)
|
||||
}
|
||||
case .consume:
|
||||
fallthrough;
|
||||
fallthrough
|
||||
case .acquire:
|
||||
assert(success == .seq_cst);
|
||||
value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired);
|
||||
assert(success == .seq_cst)
|
||||
value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired)
|
||||
|
||||
}
|
||||
if !ok do expected^ = value;
|
||||
return ok;
|
||||
if !ok do expected^ = value
|
||||
return ok
|
||||
}
|
||||
|
||||
// 7.17.7.5 The atomic_fetch and modify generic functions
|
||||
atomic_fetch_add :: #force_inline proc(object: ^$T, operand: T) -> T {
|
||||
return intrinsics.atomic_add(object, operand);
|
||||
return intrinsics.atomic_add(object, operand)
|
||||
}
|
||||
|
||||
atomic_fetch_add_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
|
||||
switch (order) {
|
||||
case .relaxed:
|
||||
return intrinsics.atomic_add_relaxed(object, operand);
|
||||
return intrinsics.atomic_add_relaxed(object, operand)
|
||||
case .consume:
|
||||
return intrinsics.atomic_add_acq(object, operand);
|
||||
return intrinsics.atomic_add_acq(object, operand)
|
||||
case .acquire:
|
||||
return intrinsics.atomic_add_acq(object, operand);
|
||||
return intrinsics.atomic_add_acq(object, operand)
|
||||
case .release:
|
||||
return intrinsics.atomic_add_rel(object, operand);
|
||||
return intrinsics.atomic_add_rel(object, operand)
|
||||
case .acq_rel:
|
||||
return intrinsics.atomic_add_acqrel(object, operand);
|
||||
return intrinsics.atomic_add_acqrel(object, operand)
|
||||
case .seq_cst:
|
||||
return intrinsics.atomic_add(object, operand);
|
||||
return intrinsics.atomic_add(object, operand)
|
||||
}
|
||||
}
|
||||
|
||||
atomic_fetch_sub :: #force_inline proc(object: ^$T, operand: T) -> T {
|
||||
return intrinsics.atomic_sub(object, operand);
|
||||
return intrinsics.atomic_sub(object, operand)
|
||||
}
|
||||
|
||||
atomic_fetch_sub_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
|
||||
switch (order) {
|
||||
case .relaxed:
|
||||
return intrinsics.atomic_sub_relaxed(object, operand);
|
||||
return intrinsics.atomic_sub_relaxed(object, operand)
|
||||
case .consume:
|
||||
return intrinsics.atomic_sub_acq(object, operand);
|
||||
return intrinsics.atomic_sub_acq(object, operand)
|
||||
case .acquire:
|
||||
return intrinsics.atomic_sub_acq(object, operand);
|
||||
return intrinsics.atomic_sub_acq(object, operand)
|
||||
case .release:
|
||||
return intrinsics.atomic_sub_rel(object, operand);
|
||||
return intrinsics.atomic_sub_rel(object, operand)
|
||||
case .acq_rel:
|
||||
return intrinsics.atomic_sub_acqrel(object, operand);
|
||||
return intrinsics.atomic_sub_acqrel(object, operand)
|
||||
case .seq_cst:
|
||||
return intrinsics.atomic_sub(object, operand);
|
||||
return intrinsics.atomic_sub(object, operand)
|
||||
}
|
||||
}
|
||||
|
||||
atomic_fetch_or :: #force_inline proc(object: ^$T, operand: T) -> T {
|
||||
return intrinsics.atomic_or(object, operand);
|
||||
return intrinsics.atomic_or(object, operand)
|
||||
}
|
||||
|
||||
atomic_fetch_or_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
|
||||
switch (order) {
|
||||
case .relaxed:
|
||||
return intrinsics.atomic_or_relaxed(object, operand);
|
||||
return intrinsics.atomic_or_relaxed(object, operand)
|
||||
case .consume:
|
||||
return intrinsics.atomic_or_acq(object, operand);
|
||||
return intrinsics.atomic_or_acq(object, operand)
|
||||
case .acquire:
|
||||
return intrinsics.atomic_or_acq(object, operand);
|
||||
return intrinsics.atomic_or_acq(object, operand)
|
||||
case .release:
|
||||
return intrinsics.atomic_or_rel(object, operand);
|
||||
return intrinsics.atomic_or_rel(object, operand)
|
||||
case .acq_rel:
|
||||
return intrinsics.atomic_or_acqrel(object, operand);
|
||||
return intrinsics.atomic_or_acqrel(object, operand)
|
||||
case .seq_cst:
|
||||
return intrinsics.atomic_or(object, operand);
|
||||
return intrinsics.atomic_or(object, operand)
|
||||
}
|
||||
}
|
||||
|
||||
atomic_fetch_xor :: #force_inline proc(object: ^$T, operand: T) -> T {
|
||||
return intrinsics.atomic_xor(object, operand);
|
||||
return intrinsics.atomic_xor(object, operand)
|
||||
}
|
||||
|
||||
atomic_fetch_xor_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
|
||||
switch (order) {
|
||||
case .relaxed:
|
||||
return intrinsics.atomic_xor_relaxed(object, operand);
|
||||
return intrinsics.atomic_xor_relaxed(object, operand)
|
||||
case .consume:
|
||||
return intrinsics.atomic_xor_acq(object, operand);
|
||||
return intrinsics.atomic_xor_acq(object, operand)
|
||||
case .acquire:
|
||||
return intrinsics.atomic_xor_acq(object, operand);
|
||||
return intrinsics.atomic_xor_acq(object, operand)
|
||||
case .release:
|
||||
return intrinsics.atomic_xor_rel(object, operand);
|
||||
return intrinsics.atomic_xor_rel(object, operand)
|
||||
case .acq_rel:
|
||||
return intrinsics.atomic_xor_acqrel(object, operand);
|
||||
return intrinsics.atomic_xor_acqrel(object, operand)
|
||||
case .seq_cst:
|
||||
return intrinsics.atomic_xor(object, operand);
|
||||
return intrinsics.atomic_xor(object, operand)
|
||||
}
|
||||
}
|
||||
|
||||
atomic_fetch_and :: #force_inline proc(object: ^$T, operand: T) -> T {
|
||||
return intrinsics.atomic_and(object, operand);
|
||||
return intrinsics.atomic_and(object, operand)
|
||||
}
|
||||
atomic_fetch_and_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
|
||||
switch (order) {
|
||||
case .relaxed:
|
||||
return intrinsics.atomic_and_relaxed(object, operand);
|
||||
return intrinsics.atomic_and_relaxed(object, operand)
|
||||
case .consume:
|
||||
return intrinsics.atomic_and_acq(object, operand);
|
||||
return intrinsics.atomic_and_acq(object, operand)
|
||||
case .acquire:
|
||||
return intrinsics.atomic_and_acq(object, operand);
|
||||
return intrinsics.atomic_and_acq(object, operand)
|
||||
case .release:
|
||||
return intrinsics.atomic_and_rel(object, operand);
|
||||
return intrinsics.atomic_and_rel(object, operand)
|
||||
case .acq_rel:
|
||||
return intrinsics.atomic_and_acqrel(object, operand);
|
||||
return intrinsics.atomic_and_acqrel(object, operand)
|
||||
case .seq_cst:
|
||||
return intrinsics.atomic_and(object, operand);
|
||||
return intrinsics.atomic_and(object, operand)
|
||||
}
|
||||
}
|
||||
|
||||
// 7.17.8 Atomic flag type and operations
|
||||
atomic_flag :: distinct atomic_bool;
|
||||
atomic_flag :: distinct atomic_bool
|
||||
|
||||
atomic_flag_test_and_set :: #force_inline proc(flag: ^atomic_flag) -> bool {
|
||||
return bool(atomic_exchange(flag, atomic_flag(true)));
|
||||
return bool(atomic_exchange(flag, atomic_flag(true)))
|
||||
}
|
||||
|
||||
atomic_flag_test_and_set_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) -> bool {
|
||||
return bool(atomic_exchange_explicit(flag, atomic_flag(true), order));
|
||||
return bool(atomic_exchange_explicit(flag, atomic_flag(true), order))
|
||||
}
|
||||
|
||||
atomic_flag_clear :: #force_inline proc(flag: ^atomic_flag) {
|
||||
atomic_store(flag, atomic_flag(false));
|
||||
atomic_store(flag, atomic_flag(false))
|
||||
}
|
||||
|
||||
atomic_flag_clear_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) {
|
||||
atomic_store_explicit(flag, atomic_flag(false), order);
|
||||
atomic_store_explicit(flag, atomic_flag(false), order)
|
||||
}
|
||||
|
||||
@@ -8,128 +8,128 @@ when ODIN_OS == "windows" {
|
||||
|
||||
// 7.21 Input/output
|
||||
|
||||
FILE :: struct {};
|
||||
FILE :: struct {}
|
||||
|
||||
// MSVCRT compatible.
|
||||
when ODIN_OS == "windows" {
|
||||
_IOFBF :: 0x0000;
|
||||
_IONBF :: 0x0004;
|
||||
_IOLBF :: 0x0040;
|
||||
_IOFBF :: 0x0000
|
||||
_IONBF :: 0x0004
|
||||
_IOLBF :: 0x0040
|
||||
|
||||
BUFSIZ :: 512;
|
||||
BUFSIZ :: 512
|
||||
|
||||
EOF :: int(-1);
|
||||
EOF :: int(-1)
|
||||
|
||||
FOPEN_MAX :: 20;
|
||||
FOPEN_MAX :: 20
|
||||
|
||||
FILENAME_MAX :: 260;
|
||||
FILENAME_MAX :: 260
|
||||
|
||||
L_tmpnam :: 15; // "\\" + 12 + NUL
|
||||
L_tmpnam :: 15 // "\\" + 12 + NUL
|
||||
|
||||
SEEK_SET :: 0;
|
||||
SEEK_CUR :: 1;
|
||||
SEEK_END :: 2;
|
||||
SEEK_SET :: 0
|
||||
SEEK_CUR :: 1
|
||||
SEEK_END :: 2
|
||||
|
||||
TMP_MAX :: 32767; // SHRT_MAX
|
||||
TMP_MAX :: 32767 // SHRT_MAX
|
||||
|
||||
fpos_t :: distinct i64;
|
||||
fpos_t :: distinct i64
|
||||
|
||||
@(private="file")
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
__acrt_iob_func :: proc (index: uint) -> ^FILE ---;
|
||||
__acrt_iob_func :: proc (index: uint) -> ^FILE ---
|
||||
}
|
||||
|
||||
stdin := __acrt_iob_func(0);
|
||||
stdout := __acrt_iob_func(1);
|
||||
stderr := __acrt_iob_func(2);
|
||||
stdin := __acrt_iob_func(0)
|
||||
stdout := __acrt_iob_func(1)
|
||||
stderr := __acrt_iob_func(2)
|
||||
}
|
||||
|
||||
// GLIBC and MUSL compatible.
|
||||
when ODIN_OS == "linux" {
|
||||
fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, };
|
||||
fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, }
|
||||
|
||||
_IOFBF :: 0;
|
||||
_IOLBF :: 1;
|
||||
_IONBF :: 2;
|
||||
_IOFBF :: 0
|
||||
_IOLBF :: 1
|
||||
_IONBF :: 2
|
||||
|
||||
BUFSIZ :: 1024;
|
||||
BUFSIZ :: 1024
|
||||
|
||||
EOF :: int(-1);
|
||||
EOF :: int(-1)
|
||||
|
||||
FOPEN_MAX :: 1000;
|
||||
FOPEN_MAX :: 1000
|
||||
|
||||
FILENAME_MAX :: 4096;
|
||||
FILENAME_MAX :: 4096
|
||||
|
||||
L_tmpnam :: 20;
|
||||
L_tmpnam :: 20
|
||||
|
||||
SEEK_SET :: 0;
|
||||
SEEK_CUR :: 1;
|
||||
SEEK_END :: 2;
|
||||
SEEK_SET :: 0
|
||||
SEEK_CUR :: 1
|
||||
SEEK_END :: 2
|
||||
|
||||
TMP_MAX :: 10000;
|
||||
TMP_MAX :: 10000
|
||||
|
||||
foreign libc {
|
||||
stderr: ^FILE;
|
||||
stdin: ^FILE;
|
||||
stdout: ^FILE;
|
||||
stderr: ^FILE
|
||||
stdin: ^FILE
|
||||
stdout: ^FILE
|
||||
}
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.21.4 Operations on files
|
||||
remove :: proc(filename: cstring) -> int ---;
|
||||
rename :: proc(old, new: cstring) -> int ---;
|
||||
tmpfile :: proc() -> ^FILE ---;
|
||||
tmpnam :: proc(s: ^char) -> ^char ---;
|
||||
remove :: proc(filename: cstring) -> int ---
|
||||
rename :: proc(old, new: cstring) -> int ---
|
||||
tmpfile :: proc() -> ^FILE ---
|
||||
tmpnam :: proc(s: ^char) -> ^char ---
|
||||
|
||||
// 7.21.5 File access functions
|
||||
fclose :: proc(stream: ^FILE) -> int ---;
|
||||
fflush :: proc(stream: ^FILE) -> int ---;
|
||||
fopen :: proc(filename, mode: cstring) -> ^FILE ---;
|
||||
freopen :: proc(filename, mode: cstring, stream: ^FILE) -> ^FILE ---;
|
||||
setbuf :: proc(stream: ^FILE, buf: ^char) ---;
|
||||
setvbuf :: proc(stream: ^FILE, buf: ^char, mode: int, size: size_t) -> int ---;
|
||||
fclose :: proc(stream: ^FILE) -> int ---
|
||||
fflush :: proc(stream: ^FILE) -> int ---
|
||||
fopen :: proc(filename, mode: cstring) -> ^FILE ---
|
||||
freopen :: proc(filename, mode: cstring, stream: ^FILE) -> ^FILE ---
|
||||
setbuf :: proc(stream: ^FILE, buf: ^char) ---
|
||||
setvbuf :: proc(stream: ^FILE, buf: ^char, mode: int, size: size_t) -> int ---
|
||||
|
||||
// 7.21.6 Formatted input/output functions
|
||||
fprintf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---;
|
||||
fscanf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---;
|
||||
printf :: proc(format: cstring, #c_vararg args: ..any) -> int ---;
|
||||
scanf :: proc(format: cstring, #c_vararg args: ..any) -> int ---;
|
||||
snprintf :: proc(s: ^char, format: cstring, #c_vararg args: ..any) -> int ---;
|
||||
sscanf :: proc(s, format: cstring, #c_vararg args: ..any) -> int ---;
|
||||
vfprintf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---;
|
||||
vfscanf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---;
|
||||
vprintf :: proc(format: cstring, arg: ^va_list) -> int ---;
|
||||
vscanf :: proc(format: cstring, arg: ^va_list) -> int ---;
|
||||
vsnprintf :: proc(s: ^char, n: size_t, format: cstring, arg: ^va_list) -> int ---;
|
||||
vsprintf :: proc(s: ^char, format: cstring, arg: ^va_list) -> int ---;
|
||||
vsscanf :: proc(s, format: cstring, arg: ^va_list) -> int ---;
|
||||
fprintf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---
|
||||
fscanf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---
|
||||
printf :: proc(format: cstring, #c_vararg args: ..any) -> int ---
|
||||
scanf :: proc(format: cstring, #c_vararg args: ..any) -> int ---
|
||||
snprintf :: proc(s: ^char, format: cstring, #c_vararg args: ..any) -> int ---
|
||||
sscanf :: proc(s, format: cstring, #c_vararg args: ..any) -> int ---
|
||||
vfprintf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---
|
||||
vfscanf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---
|
||||
vprintf :: proc(format: cstring, arg: ^va_list) -> int ---
|
||||
vscanf :: proc(format: cstring, arg: ^va_list) -> int ---
|
||||
vsnprintf :: proc(s: ^char, n: size_t, format: cstring, arg: ^va_list) -> int ---
|
||||
vsprintf :: proc(s: ^char, format: cstring, arg: ^va_list) -> int ---
|
||||
vsscanf :: proc(s, format: cstring, arg: ^va_list) -> int ---
|
||||
|
||||
// 7.21.7 Character input/output functions
|
||||
fgetc :: proc(stream: ^FILE) -> int ---;
|
||||
fgets :: proc(s: ^char, n: int, stream: ^FILE) -> ^char ---;
|
||||
fputc :: proc(s: cstring, stream: ^FILE) -> int ---;
|
||||
getc :: proc(stream: ^FILE) -> int ---;
|
||||
getchar :: proc() -> int ---;
|
||||
putc :: proc(c: int, stream: ^FILE) -> int ---;
|
||||
putchar :: proc() -> int ---;
|
||||
puts :: proc(s: cstring) -> int ---;
|
||||
ungetc :: proc(c: int, stream: ^FILE) -> int ---;
|
||||
fread :: proc(ptr: rawptr, size: size_t, stream: ^FILE) -> size_t ---;
|
||||
fwrite :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t ---;
|
||||
fgetc :: proc(stream: ^FILE) -> int ---
|
||||
fgets :: proc(s: ^char, n: int, stream: ^FILE) -> ^char ---
|
||||
fputc :: proc(s: cstring, stream: ^FILE) -> int ---
|
||||
getc :: proc(stream: ^FILE) -> int ---
|
||||
getchar :: proc() -> int ---
|
||||
putc :: proc(c: int, stream: ^FILE) -> int ---
|
||||
putchar :: proc() -> int ---
|
||||
puts :: proc(s: cstring) -> int ---
|
||||
ungetc :: proc(c: int, stream: ^FILE) -> int ---
|
||||
fread :: proc(ptr: rawptr, size: size_t, stream: ^FILE) -> size_t ---
|
||||
fwrite :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t ---
|
||||
|
||||
// 7.21.9 File positioning functions
|
||||
fgetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---;
|
||||
fseek :: proc(stream: ^FILE, offset: long, whence: int) -> int ---;
|
||||
fsetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---;
|
||||
ftell :: proc(stream: ^FILE) -> long ---;
|
||||
rewind :: proc(stream: ^FILE) ---;
|
||||
fgetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---
|
||||
fseek :: proc(stream: ^FILE, offset: long, whence: int) -> int ---
|
||||
fsetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---
|
||||
ftell :: proc(stream: ^FILE) -> long ---
|
||||
rewind :: proc(stream: ^FILE) ---
|
||||
|
||||
// 7.21.10 Error-handling functions
|
||||
clearerr :: proc(stream: ^FILE) ---;
|
||||
feof :: proc(stream: ^FILE) -> int ---;
|
||||
ferror :: proc(stream: ^FILE) -> int ---;
|
||||
perror :: proc(s: cstring) ---;
|
||||
clearerr :: proc(stream: ^FILE) ---
|
||||
feof :: proc(stream: ^FILE) -> int ---
|
||||
ferror :: proc(stream: ^FILE) -> int ---
|
||||
perror :: proc(s: cstring) ---
|
||||
}
|
||||
|
||||
@@ -9,31 +9,31 @@ when ODIN_OS == "windows" {
|
||||
}
|
||||
|
||||
when ODIN_OS == "windows" {
|
||||
RAND_MAX :: 0x7fff;
|
||||
RAND_MAX :: 0x7fff
|
||||
|
||||
@(private="file")
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
___mb_cur_max_func :: proc() -> int ---;
|
||||
___mb_cur_max_func :: proc() -> int ---
|
||||
}
|
||||
|
||||
MB_CUR_MAX :: #force_inline proc() -> size_t {
|
||||
return size_t(___mb_cur_max_func());
|
||||
return size_t(___mb_cur_max_func())
|
||||
}
|
||||
}
|
||||
|
||||
when ODIN_OS == "linux" {
|
||||
RAND_MAX :: 0x7fffffff;
|
||||
RAND_MAX :: 0x7fffffff
|
||||
|
||||
// GLIBC and MUSL only
|
||||
@(private="file")
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
__ctype_get_mb_cur_max :: proc() -> size_t ---;
|
||||
__ctype_get_mb_cur_max :: proc() -> size_t ---
|
||||
}
|
||||
|
||||
MB_CUR_MAX :: #force_inline proc() -> size_t {
|
||||
return __ctype_get_mb_cur_max();
|
||||
return __ctype_get_mb_cur_max()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ when ODIN_OS == "linux" {
|
||||
// to use any two distinct values it wants to indicate success or failure.
|
||||
// However, nobody actually does and everyone appears to have agreed upon these
|
||||
// values.
|
||||
EXIT_SUCCESS :: 0;
|
||||
EXIT_FAILURE :: 1;
|
||||
EXIT_SUCCESS :: 0
|
||||
EXIT_FAILURE :: 1
|
||||
|
||||
// C does not declare which order 'quot' and 'rem' should be for the divide
|
||||
// structures. An implementation could put 'rem' first. However, nobody actually
|
||||
@@ -54,56 +54,56 @@ lldiv_t :: struct { quot, rem: longlong, }
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.22.1 Numeric conversion functions
|
||||
atof :: proc(nptr: cstring) -> double ---;
|
||||
atoi :: proc(nptr: cstring) -> int ---;
|
||||
atol :: proc(nptr: cstring) -> long ---;
|
||||
atoll :: proc(nptr: cstring) -> longlong ---;
|
||||
strtod :: proc(nptr: cstring, endptr: ^^char) -> double ---;
|
||||
strtof :: proc(nptr: cstring, endptr: ^^char) -> float ---;
|
||||
strtol :: proc(nptr: cstring, endptr: ^^char, base: int) -> long ---;
|
||||
strtoll :: proc(nptr: cstring, endptr: ^^char, base: int) -> longlong ---;
|
||||
strtoul :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulong ---;
|
||||
strtoull :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulonglong ---;
|
||||
atof :: proc(nptr: cstring) -> double ---
|
||||
atoi :: proc(nptr: cstring) -> int ---
|
||||
atol :: proc(nptr: cstring) -> long ---
|
||||
atoll :: proc(nptr: cstring) -> longlong ---
|
||||
strtod :: proc(nptr: cstring, endptr: ^^char) -> double ---
|
||||
strtof :: proc(nptr: cstring, endptr: ^^char) -> float ---
|
||||
strtol :: proc(nptr: cstring, endptr: ^^char, base: int) -> long ---
|
||||
strtoll :: proc(nptr: cstring, endptr: ^^char, base: int) -> longlong ---
|
||||
strtoul :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulong ---
|
||||
strtoull :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulonglong ---
|
||||
|
||||
// 7.22.2 Pseudo-random sequence generation functions
|
||||
rand :: proc() -> int ---;
|
||||
srand :: proc(seed: uint) ---;
|
||||
rand :: proc() -> int ---
|
||||
srand :: proc(seed: uint) ---
|
||||
|
||||
// 7.22.3 Memory management functions
|
||||
aligned_alloc :: proc(aligment, size: size_t) -> rawptr ---;
|
||||
calloc :: proc(nmemb, size: size_t) -> rawptr ---;
|
||||
free :: proc(ptr: rawptr) ---;
|
||||
malloc :: proc(size: size_t) -> rawptr ---;
|
||||
realloc :: proc(ptr: rawptr, size: size_t) -> rawptr ---;
|
||||
aligned_alloc :: proc(aligment, size: size_t) -> rawptr ---
|
||||
calloc :: proc(nmemb, size: size_t) -> rawptr ---
|
||||
free :: proc(ptr: rawptr) ---
|
||||
malloc :: proc(size: size_t) -> rawptr ---
|
||||
realloc :: proc(ptr: rawptr, size: size_t) -> rawptr ---
|
||||
|
||||
// 7.22.4 Communication with the environment
|
||||
abort :: proc() -> ! ---;
|
||||
atexit :: proc(func: proc "c" ()) -> int ---;
|
||||
at_quick_exit :: proc(func: proc "c" ()) -> int ---;
|
||||
exit :: proc(status: int) -> ! ---;
|
||||
_Exit :: proc(status: int) -> ! ---;
|
||||
getenv :: proc(name: cstring) -> ^char ---;
|
||||
quick_exit :: proc(status: int) -> ! ---;
|
||||
system :: proc(cmd: cstring) -> int ---;
|
||||
abort :: proc() -> ! ---
|
||||
atexit :: proc(func: proc "c" ()) -> int ---
|
||||
at_quick_exit :: proc(func: proc "c" ()) -> int ---
|
||||
exit :: proc(status: int) -> ! ---
|
||||
_Exit :: proc(status: int) -> ! ---
|
||||
getenv :: proc(name: cstring) -> ^char ---
|
||||
quick_exit :: proc(status: int) -> ! ---
|
||||
system :: proc(cmd: cstring) -> int ---
|
||||
|
||||
// 7.22.5 Searching and sorting utilities
|
||||
bsearch :: proc(key, base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) -> rawptr ---;
|
||||
qsort :: proc(base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) ---;
|
||||
bsearch :: proc(key, base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) -> rawptr ---
|
||||
qsort :: proc(base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) ---
|
||||
|
||||
// 7.22.6 Integer arithmetic functions
|
||||
abs :: proc(j: int) -> int ---;
|
||||
labs :: proc(j: long) -> long ---;
|
||||
llabs :: proc(j: longlong) -> longlong ---;
|
||||
div :: proc(numer, denom: int) -> div_t ---;
|
||||
ldiv :: proc(numer, denom: long) -> ldiv_t ---;
|
||||
lldiv :: proc(numer, denom: longlong) -> lldiv_t ---;
|
||||
abs :: proc(j: int) -> int ---
|
||||
labs :: proc(j: long) -> long ---
|
||||
llabs :: proc(j: longlong) -> longlong ---
|
||||
div :: proc(numer, denom: int) -> div_t ---
|
||||
ldiv :: proc(numer, denom: long) -> ldiv_t ---
|
||||
lldiv :: proc(numer, denom: longlong) -> lldiv_t ---
|
||||
|
||||
// 7.22.7 Multibyte/wide character conversion functions
|
||||
mblen :: proc(s: cstring, n: size_t) -> int ---;
|
||||
mbtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t) -> int ---;
|
||||
wctomb :: proc(s: ^char, wc: wchar_t) -> int ---;
|
||||
mblen :: proc(s: cstring, n: size_t) -> int ---
|
||||
mbtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t) -> int ---
|
||||
wctomb :: proc(s: ^char, wc: wchar_t) -> int ---
|
||||
|
||||
// 7.22.8 Multibyte/wide string conversion functions
|
||||
mbstowcs :: proc(pwcs: ^wchar_t, s: cstring, n: size_t) -> size_t ---;
|
||||
wcstombs :: proc(s: ^char, pwcs: ^wchar_t, n: size_t) -> size_t ---;
|
||||
mbstowcs :: proc(pwcs: ^wchar_t, s: cstring, n: size_t) -> size_t ---
|
||||
wcstombs :: proc(s: ^char, pwcs: ^wchar_t, n: size_t) -> size_t ---
|
||||
}
|
||||
|
||||
@@ -11,33 +11,33 @@ when ODIN_OS == "windows" {
|
||||
|
||||
foreign libc {
|
||||
// 7.24.2 Copying functions
|
||||
memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---;
|
||||
memmove :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---;
|
||||
strcpy :: proc(s1: ^char, s2: cstring) -> ^char ---;
|
||||
strncpy :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---;
|
||||
memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---
|
||||
memmove :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---
|
||||
strcpy :: proc(s1: ^char, s2: cstring) -> ^char ---
|
||||
strncpy :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---
|
||||
|
||||
// 7.24.3 Concatenation functions
|
||||
strcat :: proc(s1: ^char, s2: cstring) -> ^char ---;
|
||||
strncat :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---;
|
||||
strcat :: proc(s1: ^char, s2: cstring) -> ^char ---
|
||||
strncat :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---
|
||||
|
||||
// 7.24.4 Comparison functions
|
||||
memcmp :: proc(s1, s2: rawptr, n: size_t) -> int ---;
|
||||
strcmp :: proc(s1, s2: cstring) -> int ---;
|
||||
strcoll :: proc(s1, s2: cstring) -> int ---;
|
||||
strncmp :: proc(s1, s2: cstring, n: size_t) -> int ---;
|
||||
strxfrm :: proc(s1: ^char, s2: cstring, n: size_t) -> size_t ---;
|
||||
memcmp :: proc(s1, s2: rawptr, n: size_t) -> int ---
|
||||
strcmp :: proc(s1, s2: cstring) -> int ---
|
||||
strcoll :: proc(s1, s2: cstring) -> int ---
|
||||
strncmp :: proc(s1, s2: cstring, n: size_t) -> int ---
|
||||
strxfrm :: proc(s1: ^char, s2: cstring, n: size_t) -> size_t ---
|
||||
|
||||
// 7.24.5 Search functions
|
||||
memchr :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---;
|
||||
strchr :: proc(s: cstring, c: int) -> ^char ---;
|
||||
strcspn :: proc(s1, s2: cstring) -> size_t ---;
|
||||
strpbrk :: proc(s1, s2: cstring) -> ^char ---;
|
||||
strrchr :: proc(s: ^char, c: int) -> ^char ---;
|
||||
strcpn :: proc(s1, s2: cstring) -> ^char ---;
|
||||
strtok :: proc(s1: ^char, s2: cstring) -> ^char ---;
|
||||
memchr :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---
|
||||
strchr :: proc(s: cstring, c: int) -> ^char ---
|
||||
strcspn :: proc(s1, s2: cstring) -> size_t ---
|
||||
strpbrk :: proc(s1, s2: cstring) -> ^char ---
|
||||
strrchr :: proc(s: ^char, c: int) -> ^char ---
|
||||
strcpn :: proc(s1, s2: cstring) -> ^char ---
|
||||
strtok :: proc(s1: ^char, s2: cstring) -> ^char ---
|
||||
|
||||
// 7.24.6 Miscellaneous functions
|
||||
memset :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---;
|
||||
strerror :: proc(errnum: int) -> ^char ---;
|
||||
strlen :: proc(s: cstring) -> size_t ---;
|
||||
memset :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---
|
||||
strerror :: proc(errnum: int) -> ^char ---
|
||||
strlen :: proc(s: cstring) -> size_t ---
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package libc
|
||||
|
||||
// 7.26 Threads
|
||||
|
||||
thrd_start_t :: proc "c" (rawptr) -> int;
|
||||
tss_dtor_t :: proc "c" (rawptr);
|
||||
thrd_start_t :: proc "c" (rawptr) -> int
|
||||
tss_dtor_t :: proc "c" (rawptr)
|
||||
|
||||
when ODIN_OS == "windows" {
|
||||
foreign import libc {
|
||||
@@ -11,23 +11,23 @@ when ODIN_OS == "windows" {
|
||||
"system:msvcprt.lib"
|
||||
}
|
||||
|
||||
thrd_success :: 0; // _Thrd_success
|
||||
thrd_nomem :: 1; // _Thrd_nomem
|
||||
thrd_timedout :: 2; // _Thrd_timedout
|
||||
thrd_busy :: 3; // _Thrd_busy
|
||||
thrd_error :: 4; // _Thrd_error
|
||||
thrd_success :: 0 // _Thrd_success
|
||||
thrd_nomem :: 1 // _Thrd_nomem
|
||||
thrd_timedout :: 2 // _Thrd_timedout
|
||||
thrd_busy :: 3 // _Thrd_busy
|
||||
thrd_error :: 4 // _Thrd_error
|
||||
|
||||
mtx_plain :: 1; // _Mtx_plain
|
||||
mtx_recursive :: 0x100; // _Mtx_recursive
|
||||
mtx_timed :: 4; // _Mtx_timed
|
||||
mtx_plain :: 1 // _Mtx_plain
|
||||
mtx_recursive :: 0x100 // _Mtx_recursive
|
||||
mtx_timed :: 4 // _Mtx_timed
|
||||
|
||||
TSS_DTOR_ITERATIONS :: 4; // _TSS_DTOR_ITERATIONS_IMP
|
||||
TSS_DTOR_ITERATIONS :: 4 // _TSS_DTOR_ITERATIONS_IMP
|
||||
|
||||
once_flag :: distinct i8; // _Once_flag_imp_t
|
||||
once_flag :: distinct i8 // _Once_flag_imp_t
|
||||
thrd_t :: struct { _: rawptr, _: uint, } // _Thrd_t
|
||||
tss_t :: distinct int; // _Tss_imp_t
|
||||
cnd_t :: distinct rawptr; // _Cnd_imp_t
|
||||
mtx_t :: distinct rawptr; // _Mtx_imp_t
|
||||
tss_t :: distinct int // _Tss_imp_t
|
||||
cnd_t :: distinct rawptr // _Cnd_imp_t
|
||||
mtx_t :: distinct rawptr // _Mtx_imp_t
|
||||
|
||||
// MSVCRT does not expose the C11 symbol names as what they are in C11
|
||||
// because they held off implementing <threads.h> and C11 support for so
|
||||
@@ -38,38 +38,38 @@ when ODIN_OS == "windows" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.26.2 Initialization functions
|
||||
@(link_name="_Call_once") call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---;
|
||||
@(link_name="_Call_once") call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---
|
||||
// 7.26.3 Condition variable functions
|
||||
@(link_name="_Cnd_broadcast") cnd_broadcast :: proc(cond: ^cnd_t) -> int ---;
|
||||
@(link_name="_Cnd_destroy") cnd_destroy :: proc(cond: ^cnd_t) ---;
|
||||
@(link_name="_Cnd_init") cnd_init :: proc(cond: ^cnd_t) -> int ---;
|
||||
@(link_name="_Cnd_signal") cnd_signal :: proc(cond: ^cnd_t) -> int ---;
|
||||
@(link_name="_Cnd_timedwait") cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---;
|
||||
@(link_name="_Cnd_wait") cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---;
|
||||
@(link_name="_Cnd_broadcast") cnd_broadcast :: proc(cond: ^cnd_t) -> int ---
|
||||
@(link_name="_Cnd_destroy") cnd_destroy :: proc(cond: ^cnd_t) ---
|
||||
@(link_name="_Cnd_init") cnd_init :: proc(cond: ^cnd_t) -> int ---
|
||||
@(link_name="_Cnd_signal") cnd_signal :: proc(cond: ^cnd_t) -> int ---
|
||||
@(link_name="_Cnd_timedwait") cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---
|
||||
@(link_name="_Cnd_wait") cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---
|
||||
|
||||
// 7.26.4 Mutex functions
|
||||
@(link_name="_Mtx_destroy") mtx_destroy :: proc(mtx: ^mtx_t) ---;
|
||||
@(link_name="_Mtx_init") mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---;
|
||||
@(link_name="_Mtx_lock") mtx_lock :: proc(mtx: ^mtx_t) -> int ---;
|
||||
@(link_name="_Mtx_timedlock") mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---;
|
||||
@(link_name="_Mtx_trylock") mtx_trylock :: proc(mtx: ^mtx_t) -> int ---;
|
||||
@(link_name="_Mtx_unlock") mtx_unlock :: proc(mtx: ^mtx_t) -> int ---;
|
||||
@(link_name="_Mtx_destroy") mtx_destroy :: proc(mtx: ^mtx_t) ---
|
||||
@(link_name="_Mtx_init") mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---
|
||||
@(link_name="_Mtx_lock") mtx_lock :: proc(mtx: ^mtx_t) -> int ---
|
||||
@(link_name="_Mtx_timedlock") mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---
|
||||
@(link_name="_Mtx_trylock") mtx_trylock :: proc(mtx: ^mtx_t) -> int ---
|
||||
@(link_name="_Mtx_unlock") mtx_unlock :: proc(mtx: ^mtx_t) -> int ---
|
||||
|
||||
// 7.26.5 Thread functions
|
||||
@(link_name="_Thrd_create") thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---;
|
||||
@(link_name="_Thrd_current") thrd_current :: proc() -> thrd_t ---;
|
||||
@(link_name="_Thrd_detach") thrd_detach :: proc(thr: thrd_t) -> int ---;
|
||||
@(link_name="_Thrd_equal") thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---;
|
||||
@(link_name="_Thrd_exit") thrd_exit :: proc(res: int) -> ! ---;
|
||||
@(link_name="_Thrd_join") thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---;
|
||||
@(link_name="_Thrd_sleep") thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---;
|
||||
@(link_name="_Thrd_yield") thrd_yield :: proc() ---;
|
||||
@(link_name="_Thrd_create") thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---
|
||||
@(link_name="_Thrd_current") thrd_current :: proc() -> thrd_t ---
|
||||
@(link_name="_Thrd_detach") thrd_detach :: proc(thr: thrd_t) -> int ---
|
||||
@(link_name="_Thrd_equal") thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---
|
||||
@(link_name="_Thrd_exit") thrd_exit :: proc(res: int) -> ! ---
|
||||
@(link_name="_Thrd_join") thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---
|
||||
@(link_name="_Thrd_sleep") thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---
|
||||
@(link_name="_Thrd_yield") thrd_yield :: proc() ---
|
||||
|
||||
// 7.26.6 Thread-specific storage functions
|
||||
@(link_name="_Tss_create") tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---;
|
||||
@(link_name="_Tss_delete") tss_delete :: proc(key: tss_t) ---;
|
||||
@(link_name="_Tss_get") tss_get :: proc(key: tss_t) -> rawptr ---;
|
||||
@(link_name="_Tss_set") tss_set :: proc(key: tss_t, val: rawptr) -> int ---;
|
||||
@(link_name="_Tss_create") tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---
|
||||
@(link_name="_Tss_delete") tss_delete :: proc(key: tss_t) ---
|
||||
@(link_name="_Tss_get") tss_get :: proc(key: tss_t) -> rawptr ---
|
||||
@(link_name="_Tss_set") tss_set :: proc(key: tss_t, val: rawptr) -> int ---
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,59 +80,59 @@ when ODIN_OS == "linux" {
|
||||
"system:pthread"
|
||||
}
|
||||
|
||||
thrd_success :: 0;
|
||||
thrd_busy :: 1;
|
||||
thrd_error :: 2;
|
||||
thrd_nomem :: 3;
|
||||
thrd_timedout :: 4;
|
||||
thrd_success :: 0
|
||||
thrd_busy :: 1
|
||||
thrd_error :: 2
|
||||
thrd_nomem :: 3
|
||||
thrd_timedout :: 4
|
||||
|
||||
mtx_plain :: 0;
|
||||
mtx_recursive :: 1;
|
||||
mtx_timed :: 2;
|
||||
mtx_plain :: 0
|
||||
mtx_recursive :: 1
|
||||
mtx_timed :: 2
|
||||
|
||||
TSS_DTOR_ITERATIONS :: 4;
|
||||
TSS_DTOR_ITERATIONS :: 4
|
||||
|
||||
once_flag :: distinct int;
|
||||
thrd_t :: distinct ulong;
|
||||
tss_t :: distinct uint;
|
||||
cnd_t :: struct #raw_union { _: [12]int, _: [12 * size_of(int) / size_of(rawptr)]rawptr, };
|
||||
mtx_t :: struct #raw_union { _: [10 when size_of(long) == 8 else 6]int, _: [5 when size_of(long) == 8 else 6]rawptr, };
|
||||
once_flag :: distinct int
|
||||
thrd_t :: distinct ulong
|
||||
tss_t :: distinct uint
|
||||
cnd_t :: struct #raw_union { _: [12]int, _: [12 * size_of(int) / size_of(rawptr)]rawptr, }
|
||||
mtx_t :: struct #raw_union { _: [10 when size_of(long) == 8 else 6]int, _: [5 when size_of(long) == 8 else 6]rawptr, }
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.26.2 Initialization functions
|
||||
call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---;
|
||||
call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---
|
||||
|
||||
// 7.26.3 Condition variable functions
|
||||
cnd_broadcast :: proc(cond: ^cnd_t) -> int ---;
|
||||
cnd_destroy :: proc(cond: ^cnd_t) ---;
|
||||
cnd_init :: proc(cond: ^cnd_t) -> int ---;
|
||||
cnd_signal :: proc(cond: ^cnd_t) -> int ---;
|
||||
cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---;
|
||||
cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---;
|
||||
cnd_broadcast :: proc(cond: ^cnd_t) -> int ---
|
||||
cnd_destroy :: proc(cond: ^cnd_t) ---
|
||||
cnd_init :: proc(cond: ^cnd_t) -> int ---
|
||||
cnd_signal :: proc(cond: ^cnd_t) -> int ---
|
||||
cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---
|
||||
cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---
|
||||
|
||||
// 7.26.4 Mutex functions
|
||||
mtx_destroy :: proc(mtx: ^mtx_t) ---;
|
||||
mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---;
|
||||
mtx_lock :: proc(mtx: ^mtx_t) -> int ---;
|
||||
mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---;
|
||||
mtx_trylock :: proc(mtx: ^mtx_t) -> int ---;
|
||||
mtx_unlock :: proc(mtx: ^mtx_t) -> int ---;
|
||||
mtx_destroy :: proc(mtx: ^mtx_t) ---
|
||||
mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---
|
||||
mtx_lock :: proc(mtx: ^mtx_t) -> int ---
|
||||
mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---
|
||||
mtx_trylock :: proc(mtx: ^mtx_t) -> int ---
|
||||
mtx_unlock :: proc(mtx: ^mtx_t) -> int ---
|
||||
|
||||
// 7.26.5 Thread functions
|
||||
thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---;
|
||||
thrd_current :: proc() -> thrd_t ---;
|
||||
thrd_detach :: proc(thr: thrd_t) -> int ---;
|
||||
thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---;
|
||||
thrd_exit :: proc(res: int) -> ! ---;
|
||||
thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---;
|
||||
thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---;
|
||||
thrd_yield :: proc() ---;
|
||||
thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---
|
||||
thrd_current :: proc() -> thrd_t ---
|
||||
thrd_detach :: proc(thr: thrd_t) -> int ---
|
||||
thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---
|
||||
thrd_exit :: proc(res: int) -> ! ---
|
||||
thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---
|
||||
thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---
|
||||
thrd_yield :: proc() ---
|
||||
|
||||
// 7.26.6 Thread-specific storage functions
|
||||
tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---;
|
||||
tss_delete :: proc(key: tss_t) ---;
|
||||
tss_get :: proc(key: tss_t) -> rawptr ---;
|
||||
tss_set :: proc(key: tss_t, val: rawptr) -> int ---;
|
||||
tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---
|
||||
tss_delete :: proc(key: tss_t) ---
|
||||
tss_get :: proc(key: tss_t) -> rawptr ---
|
||||
tss_set :: proc(key: tss_t, val: rawptr) -> int ---
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,25 +13,25 @@ when ODIN_OS == "windows" {
|
||||
when ODIN_OS == "windows" {
|
||||
foreign libc {
|
||||
// 7.27.2 Time manipulation functions
|
||||
clock :: proc() -> clock_t ---;
|
||||
@(link_name="_difftime64") difftime :: proc(time1, time2: time_t) -> double ---;
|
||||
mktime :: proc(timeptr: ^tm) -> time_t ---;
|
||||
@(link_name="_time64") time :: proc(timer: ^time_t) -> time_t ---;
|
||||
@(link_name="_timespec64_get") timespec_get :: proc(ts: ^timespec, base: int) -> int ---;
|
||||
clock :: proc() -> clock_t ---
|
||||
@(link_name="_difftime64") difftime :: proc(time1, time2: time_t) -> double ---
|
||||
mktime :: proc(timeptr: ^tm) -> time_t ---
|
||||
@(link_name="_time64") time :: proc(timer: ^time_t) -> time_t ---
|
||||
@(link_name="_timespec64_get") timespec_get :: proc(ts: ^timespec, base: int) -> int ---
|
||||
|
||||
// 7.27.3 Time conversion functions
|
||||
asctime :: proc(timeptr: ^tm) -> ^char ---;
|
||||
@(link_name="_ctime64") ctime :: proc(timer: ^time_t) -> ^char ---;
|
||||
@(link_name="_gmtime64") gmtime :: proc(timer: ^time_t) -> ^tm ---;
|
||||
@(link_name="_localtime64") localtime :: proc(timer: ^time_t) -> ^tm ---;
|
||||
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---;
|
||||
asctime :: proc(timeptr: ^tm) -> ^char ---
|
||||
@(link_name="_ctime64") ctime :: proc(timer: ^time_t) -> ^char ---
|
||||
@(link_name="_gmtime64") gmtime :: proc(timer: ^time_t) -> ^tm ---
|
||||
@(link_name="_localtime64") localtime :: proc(timer: ^time_t) -> ^tm ---
|
||||
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---
|
||||
}
|
||||
|
||||
CLOCKS_PER_SEC :: 1000;
|
||||
TIME_UTC :: 1;
|
||||
CLOCKS_PER_SEC :: 1000
|
||||
TIME_UTC :: 1
|
||||
|
||||
clock_t :: distinct long;
|
||||
time_t :: distinct i64;
|
||||
clock_t :: distinct long
|
||||
time_t :: distinct i64
|
||||
|
||||
timespec :: struct #align 8 {
|
||||
tv_sec: time_t,
|
||||
@@ -47,26 +47,26 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.27.2 Time manipulation functions
|
||||
clock :: proc() -> clock_t ---;
|
||||
difftime :: proc(time1, time2: time_t) -> double ---;
|
||||
mktime :: proc(timeptr: ^tm) -> time_t ---;
|
||||
time :: proc(timer: ^time_t) -> time_t ---;
|
||||
timespec_get :: proc(ts: ^timespec, base: int) -> int ---;
|
||||
clock :: proc() -> clock_t ---
|
||||
difftime :: proc(time1, time2: time_t) -> double ---
|
||||
mktime :: proc(timeptr: ^tm) -> time_t ---
|
||||
time :: proc(timer: ^time_t) -> time_t ---
|
||||
timespec_get :: proc(ts: ^timespec, base: int) -> int ---
|
||||
|
||||
// 7.27.3 Time conversion functions
|
||||
asctime :: proc(timeptr: ^tm) -> ^char ---;
|
||||
ctime :: proc(timer: ^time_t) -> ^char ---;
|
||||
gmtime :: proc(timer: ^time_t) -> ^tm ---;
|
||||
localtime :: proc(timer: ^time_t) -> ^tm ---;
|
||||
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---;
|
||||
asctime :: proc(timeptr: ^tm) -> ^char ---
|
||||
ctime :: proc(timer: ^time_t) -> ^char ---
|
||||
gmtime :: proc(timer: ^time_t) -> ^tm ---
|
||||
localtime :: proc(timer: ^time_t) -> ^tm ---
|
||||
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---
|
||||
}
|
||||
|
||||
CLOCKS_PER_SEC :: 1000000;
|
||||
TIME_UTC :: 1;
|
||||
CLOCKS_PER_SEC :: 1000000
|
||||
TIME_UTC :: 1
|
||||
|
||||
time_t :: distinct i64;
|
||||
time_t :: distinct i64
|
||||
|
||||
clock_t :: long;
|
||||
clock_t :: long
|
||||
|
||||
timespec :: struct {
|
||||
tv_sec: time_t,
|
||||
|
||||
@@ -2,81 +2,81 @@ package libc
|
||||
|
||||
import builtin "core:builtin"
|
||||
|
||||
char :: builtin.u8; // assuming -funsigned-char
|
||||
short :: builtin.i16;
|
||||
int :: builtin.i32;
|
||||
long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64;
|
||||
longlong :: builtin.i64;
|
||||
char :: builtin.u8 // assuming -funsigned-char
|
||||
short :: builtin.i16
|
||||
int :: builtin.i32
|
||||
long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64
|
||||
longlong :: builtin.i64
|
||||
|
||||
uchar :: builtin.u8;
|
||||
ushort :: builtin.u16;
|
||||
uint :: builtin.u32;
|
||||
ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64;
|
||||
ulonglong :: builtin.u64;
|
||||
uchar :: builtin.u8
|
||||
ushort :: builtin.u16
|
||||
uint :: builtin.u32
|
||||
ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64
|
||||
ulonglong :: builtin.u64
|
||||
|
||||
bool :: distinct builtin.b8;
|
||||
bool :: distinct builtin.b8
|
||||
|
||||
size_t :: builtin.uint;
|
||||
wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32;
|
||||
size_t :: builtin.uint
|
||||
wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32
|
||||
|
||||
float :: builtin.f32;
|
||||
double :: builtin.f64;
|
||||
float :: builtin.f32
|
||||
double :: builtin.f64
|
||||
|
||||
// 7.20.1 Integer types
|
||||
int8_t :: builtin.i8;
|
||||
uint8_t :: builtin.u8;
|
||||
int16_t :: builtin.i16;
|
||||
uint16_t :: builtin.u16;
|
||||
int32_t :: builtin.i32;
|
||||
uint32_t :: builtin.u32;
|
||||
int64_t :: builtin.i64;
|
||||
uint64_t :: builtin.u64;
|
||||
int8_t :: builtin.i8
|
||||
uint8_t :: builtin.u8
|
||||
int16_t :: builtin.i16
|
||||
uint16_t :: builtin.u16
|
||||
int32_t :: builtin.i32
|
||||
uint32_t :: builtin.u32
|
||||
int64_t :: builtin.i64
|
||||
uint64_t :: builtin.u64
|
||||
|
||||
// These are all the same in multiple libc's for multiple architectures.
|
||||
int_least8_t :: builtin.i8;
|
||||
uint_least8_t :: builtin.u8;
|
||||
int_least16_t :: builtin.i16;
|
||||
uint_least16_t :: builtin.u16;
|
||||
int_least32_t :: builtin.i32;
|
||||
uint_least32_t :: builtin.u32;
|
||||
int_least64_t :: builtin.i64;
|
||||
uint_least64_t :: builtin.u64;
|
||||
int_least8_t :: builtin.i8
|
||||
uint_least8_t :: builtin.u8
|
||||
int_least16_t :: builtin.i16
|
||||
uint_least16_t :: builtin.u16
|
||||
int_least32_t :: builtin.i32
|
||||
uint_least32_t :: builtin.u32
|
||||
int_least64_t :: builtin.i64
|
||||
uint_least64_t :: builtin.u64
|
||||
|
||||
// Same on Windows, Linux, and FreeBSD
|
||||
when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" {
|
||||
int_fast8_t :: builtin.i8;
|
||||
uint_fast8_t :: builtin.u8;
|
||||
int_fast16_t :: builtin.i32;
|
||||
uint_fast16_t :: builtin.u32;
|
||||
int_fast32_t :: builtin.i32;
|
||||
uint_fast32_t :: builtin.u32;
|
||||
int_fast64_t :: builtin.i64;
|
||||
uint_fast64_t :: builtin.u64;
|
||||
int_fast8_t :: builtin.i8
|
||||
uint_fast8_t :: builtin.u8
|
||||
int_fast16_t :: builtin.i32
|
||||
uint_fast16_t :: builtin.u32
|
||||
int_fast32_t :: builtin.i32
|
||||
uint_fast32_t :: builtin.u32
|
||||
int_fast64_t :: builtin.i64
|
||||
uint_fast64_t :: builtin.u64
|
||||
}
|
||||
|
||||
intptr_t :: builtin.int;
|
||||
uintptr_t :: builtin.uintptr;
|
||||
ptrdiff_t :: distinct intptr_t;
|
||||
intptr_t :: builtin.int
|
||||
uintptr_t :: builtin.uintptr
|
||||
ptrdiff_t :: distinct intptr_t
|
||||
|
||||
intmax_t :: builtin.i64;
|
||||
uintmax_t :: builtin.u64;
|
||||
intmax_t :: builtin.i64
|
||||
uintmax_t :: builtin.u64
|
||||
|
||||
// Copy C's rules for type promotion here by forcing the type on the literals.
|
||||
INT8_MAX :: int(0x7f);
|
||||
INT16_MAX :: int(0x7fff);
|
||||
INT32_MAX :: int(0x7fffffff);
|
||||
INT64_MAX :: longlong(0x7fffffffffffffff);
|
||||
INT8_MAX :: int(0x7f)
|
||||
INT16_MAX :: int(0x7fff)
|
||||
INT32_MAX :: int(0x7fffffff)
|
||||
INT64_MAX :: longlong(0x7fffffffffffffff)
|
||||
|
||||
UINT8_MAX :: int(0xff);
|
||||
UINT16_MAX :: int(0xffff);
|
||||
UINT32_MAX :: uint(0xffffffff);
|
||||
UINT64_MAX :: ulonglong(0xffffffffffffffff);
|
||||
UINT8_MAX :: int(0xff)
|
||||
UINT16_MAX :: int(0xffff)
|
||||
UINT32_MAX :: uint(0xffffffff)
|
||||
UINT64_MAX :: ulonglong(0xffffffffffffffff)
|
||||
|
||||
INT8_MIN :: ~INT8_MAX;
|
||||
INT16_MIN :: ~INT16_MAX;
|
||||
INT32_MIN :: ~INT32_MAX;
|
||||
INT64_MIN :: ~INT64_MAX;
|
||||
INT8_MIN :: ~INT8_MAX
|
||||
INT16_MIN :: ~INT16_MAX
|
||||
INT32_MIN :: ~INT32_MAX
|
||||
INT64_MIN :: ~INT64_MAX
|
||||
|
||||
NULL :: rawptr(uintptr(0));
|
||||
NULL :: rawptr(uintptr(0))
|
||||
|
||||
NDEBUG :: !ODIN_DEBUG;
|
||||
NDEBUG :: !ODIN_DEBUG
|
||||
|
||||
@@ -11,11 +11,11 @@ when ODIN_OS == "windows" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.28.1 Restartable multibyte/wide character conversion functions
|
||||
mbrtoc16 :: proc(pc16: ^char16_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
|
||||
c16rtomb :: proc(s: ^char, c16: char16_t, ps: ^mbstate_t) -> size_t ---;
|
||||
mbrtoc32 :: proc(pc32: ^char32_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
|
||||
c32rtomb :: proc(s: ^char, c32: char32_t, ps: ^mbstate_t) -> size_t ---;
|
||||
mbrtoc16 :: proc(pc16: ^char16_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
|
||||
c16rtomb :: proc(s: ^char, c16: char16_t, ps: ^mbstate_t) -> size_t ---
|
||||
mbrtoc32 :: proc(pc32: ^char32_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
|
||||
c32rtomb :: proc(s: ^char, c32: char32_t, ps: ^mbstate_t) -> size_t ---
|
||||
}
|
||||
|
||||
char16_t :: uint_least16_t;
|
||||
char32_t :: uint_least32_t;
|
||||
char16_t :: uint_least16_t
|
||||
char32_t :: uint_least32_t
|
||||
|
||||
@@ -11,88 +11,88 @@ when ODIN_OS == "windows" {
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.29.2 Formatted wide character input/output functions
|
||||
fwprintf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
|
||||
fwscanf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
|
||||
swprintf :: proc(stream: ^FILE, n: size_t, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
|
||||
swscanf :: proc(s, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
|
||||
vfwprintf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---;
|
||||
vfwscanf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---;
|
||||
vswprintf :: proc(s: ^wchar_t, n: size_t, format: ^wchar_t, arg: va_list) -> int ---;
|
||||
vswscanf :: proc(s, format: ^wchar_t, arg: va_list) -> int ---;
|
||||
vwprintf :: proc(format: ^wchar_t, arg: va_list) -> int ---;
|
||||
vwscanf :: proc(format: ^wchar_t, arg: va_list) -> int ---;
|
||||
wprintf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
|
||||
wscanf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
|
||||
fwprintf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
|
||||
fwscanf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
|
||||
swprintf :: proc(stream: ^FILE, n: size_t, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
|
||||
swscanf :: proc(s, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
|
||||
vfwprintf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---
|
||||
vfwscanf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---
|
||||
vswprintf :: proc(s: ^wchar_t, n: size_t, format: ^wchar_t, arg: va_list) -> int ---
|
||||
vswscanf :: proc(s, format: ^wchar_t, arg: va_list) -> int ---
|
||||
vwprintf :: proc(format: ^wchar_t, arg: va_list) -> int ---
|
||||
vwscanf :: proc(format: ^wchar_t, arg: va_list) -> int ---
|
||||
wprintf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---
|
||||
wscanf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---
|
||||
|
||||
// 7.29.3 Wide character input/output functions
|
||||
fwgetc :: proc(stream: ^FILE) -> wint_t ---;
|
||||
fgetws :: proc(s: ^wchar_t, n: int, stream: ^FILE) -> wchar_t ---;
|
||||
fputwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---;
|
||||
fputws :: proc(s: ^wchar_t, stream: ^FILE) -> int ---;
|
||||
fwide :: proc(stream: ^FILE, mode: int) -> int ---;
|
||||
getwc :: proc(stream: ^FILE) -> wint_t ---;
|
||||
getwchar :: proc() -> wint_t ---;
|
||||
putwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---;
|
||||
putwchar :: proc(c: wchar_t) -> wint_t ---;
|
||||
ungetwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---;
|
||||
fwgetc :: proc(stream: ^FILE) -> wint_t ---
|
||||
fgetws :: proc(s: ^wchar_t, n: int, stream: ^FILE) -> wchar_t ---
|
||||
fputwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
|
||||
fputws :: proc(s: ^wchar_t, stream: ^FILE) -> int ---
|
||||
fwide :: proc(stream: ^FILE, mode: int) -> int ---
|
||||
getwc :: proc(stream: ^FILE) -> wint_t ---
|
||||
getwchar :: proc() -> wint_t ---
|
||||
putwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
|
||||
putwchar :: proc(c: wchar_t) -> wint_t ---
|
||||
ungetwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
|
||||
|
||||
// 7.29.4 General wide string utilities
|
||||
wcstod :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> double ---;
|
||||
wcstof :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> float ---;
|
||||
wcstol :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> long ---;
|
||||
wcstoll :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> longlong ---;
|
||||
wcstoul :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulong ---;
|
||||
wcstoull :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulonglong ---;
|
||||
wcstod :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> double ---
|
||||
wcstof :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> float ---
|
||||
wcstol :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> long ---
|
||||
wcstoll :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> longlong ---
|
||||
wcstoul :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulong ---
|
||||
wcstoull :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulonglong ---
|
||||
|
||||
// 7.29.4.2 Wide string copying functions
|
||||
wcscpy :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
|
||||
wcsncpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
|
||||
wmemcpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
|
||||
wmemmove :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
|
||||
wcscpy :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
|
||||
wcsncpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
|
||||
wmemcpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
|
||||
wmemmove :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
|
||||
|
||||
// 7.29.4.3 Wide string concatenation functions
|
||||
wcscat :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
|
||||
wcsncat :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
|
||||
wcscat :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
|
||||
wcsncat :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
|
||||
|
||||
// 7.29.4.4 Wide string comparison functions
|
||||
wcscmp :: proc(s1, s2: ^wchar_t) -> int ---;
|
||||
wcscoll :: proc(s1, s2: ^wchar_t) -> int ---;
|
||||
wcsncmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---;
|
||||
wcsxfrm :: proc(s1, s2: ^wchar_t, n: size_t) -> size_t ---;
|
||||
wmemcmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---;
|
||||
wcscmp :: proc(s1, s2: ^wchar_t) -> int ---
|
||||
wcscoll :: proc(s1, s2: ^wchar_t) -> int ---
|
||||
wcsncmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---
|
||||
wcsxfrm :: proc(s1, s2: ^wchar_t, n: size_t) -> size_t ---
|
||||
wmemcmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---
|
||||
|
||||
// 7.29.4.5 Wide string search functions
|
||||
wcschr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---;
|
||||
wcscspn :: proc(s1, s2: ^wchar_t) -> size_t ---;
|
||||
wcspbrk :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
|
||||
wcsrchr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---;
|
||||
wcsspn :: proc(s1, s2: ^wchar_t) -> size_t ---;
|
||||
wcsstr :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
|
||||
wcstok :: proc(s1, s2: ^wchar_t, ptr: ^^wchar_t) -> ^wchar_t ---;
|
||||
wmemchr :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---;
|
||||
wcschr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---
|
||||
wcscspn :: proc(s1, s2: ^wchar_t) -> size_t ---
|
||||
wcspbrk :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
|
||||
wcsrchr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---
|
||||
wcsspn :: proc(s1, s2: ^wchar_t) -> size_t ---
|
||||
wcsstr :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
|
||||
wcstok :: proc(s1, s2: ^wchar_t, ptr: ^^wchar_t) -> ^wchar_t ---
|
||||
wmemchr :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---
|
||||
|
||||
// 7.29.4.6 Miscellaneous functions
|
||||
wcslen :: proc(s: ^wchar_t) -> size_t ---;
|
||||
wmemset :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---;
|
||||
wcslen :: proc(s: ^wchar_t) -> size_t ---
|
||||
wmemset :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---
|
||||
|
||||
// 7.29.5 Wide character time conversion functions
|
||||
wcsftime :: proc(s: ^wchar_t, maxsize: size_t, format: ^wchar_t, timeptr: ^tm) -> size_t ---;
|
||||
wcsftime :: proc(s: ^wchar_t, maxsize: size_t, format: ^wchar_t, timeptr: ^tm) -> size_t ---
|
||||
|
||||
// 7.29.6.1 Single-byte/wide character conversion functions
|
||||
btowc :: proc(c: int) -> wint_t ---;
|
||||
wctob :: proc(c: wint_t) -> int ---;
|
||||
btowc :: proc(c: int) -> wint_t ---
|
||||
wctob :: proc(c: wint_t) -> int ---
|
||||
|
||||
// 7.29.6.2 Conversion state functions
|
||||
mbsinit :: proc(ps: ^mbstate_t) -> int ---;
|
||||
mbsinit :: proc(ps: ^mbstate_t) -> int ---
|
||||
|
||||
// 7.29.6.3 Restartable multibyte/wide character conversion functions
|
||||
mbrlen :: proc(s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
|
||||
mbrtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
|
||||
wcrtomb :: proc(s: ^char, wc: wchar_t, ps: ^mbstate_t) -> size_t ---;
|
||||
mbrlen :: proc(s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
|
||||
mbrtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
|
||||
wcrtomb :: proc(s: ^char, wc: wchar_t, ps: ^mbstate_t) -> size_t ---
|
||||
|
||||
// 7.29.6.4 Restartable multibyte/wide string conversion functions
|
||||
mbsrtowcs :: proc(dst: ^wchar_t, src: ^cstring, len: size_t, ps: ^mbstate_t) -> size_t ---;
|
||||
wcsrtombs :: proc(dst: ^char, src: ^^wchar_t, len: size_t, ps: ^mbstate_t) -> size_t ---;
|
||||
mbsrtowcs :: proc(dst: ^wchar_t, src: ^cstring, len: size_t, ps: ^mbstate_t) -> size_t ---
|
||||
wcsrtombs :: proc(dst: ^char, src: ^^wchar_t, len: size_t, ps: ^mbstate_t) -> size_t ---
|
||||
}
|
||||
|
||||
// Large enough and aligned enough for any wide-spread in-use libc.
|
||||
@@ -100,9 +100,9 @@ mbstate_t :: struct #align 16 { _: [32]char, }
|
||||
|
||||
// Odin does not have default argument promotion so the need for a separate type
|
||||
// here isn't necessary, though make it distinct just to be safe.
|
||||
wint_t :: distinct wchar_t;
|
||||
wint_t :: distinct wchar_t
|
||||
|
||||
// Calculate these values correctly regardless of what type wchar_t actually is.
|
||||
WINT_MIN :: 0;
|
||||
WINT_MAX :: 1 << (size_of(wint_t) * 8);
|
||||
WEOF :: ~wint_t(0);
|
||||
WINT_MIN :: 0
|
||||
WINT_MAX :: 1 << (size_of(wint_t) * 8)
|
||||
WEOF :: ~wint_t(0)
|
||||
|
||||
@@ -9,40 +9,40 @@ when ODIN_OS == "windows" {
|
||||
}
|
||||
|
||||
when ODIN_OS == "windows" {
|
||||
wctrans_t :: distinct wchar_t;
|
||||
wctype_t :: distinct ushort;
|
||||
wctrans_t :: distinct wchar_t
|
||||
wctype_t :: distinct ushort
|
||||
}
|
||||
|
||||
when ODIN_OS == "linux" {
|
||||
wctrans_t :: distinct rawptr;
|
||||
wctype_t :: distinct ulong;
|
||||
wctrans_t :: distinct rawptr
|
||||
wctype_t :: distinct ulong
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
// 7.30.2.1 Wide character classification functions
|
||||
iswalnum :: proc(wc: wint_t) -> int ---;
|
||||
iswalpha :: proc(wc: wint_t) -> int ---;
|
||||
iswblank :: proc(wc: wint_t) -> int ---;
|
||||
iswcntrl :: proc(wc: wint_t) -> int ---;
|
||||
iswdigit :: proc(wc: wint_t) -> int ---;
|
||||
iswgraph :: proc(wc: wint_t) -> int ---;
|
||||
iswlower :: proc(wc: wint_t) -> int ---;
|
||||
iswprint :: proc(wc: wint_t) -> int ---;
|
||||
iswpunct :: proc(wc: wint_t) -> int ---;
|
||||
iswspace :: proc(wc: wint_t) -> int ---;
|
||||
iswupper :: proc(wc: wint_t) -> int ---;
|
||||
iswxdigit :: proc(wc: wint_t) -> int ---;
|
||||
iswalnum :: proc(wc: wint_t) -> int ---
|
||||
iswalpha :: proc(wc: wint_t) -> int ---
|
||||
iswblank :: proc(wc: wint_t) -> int ---
|
||||
iswcntrl :: proc(wc: wint_t) -> int ---
|
||||
iswdigit :: proc(wc: wint_t) -> int ---
|
||||
iswgraph :: proc(wc: wint_t) -> int ---
|
||||
iswlower :: proc(wc: wint_t) -> int ---
|
||||
iswprint :: proc(wc: wint_t) -> int ---
|
||||
iswpunct :: proc(wc: wint_t) -> int ---
|
||||
iswspace :: proc(wc: wint_t) -> int ---
|
||||
iswupper :: proc(wc: wint_t) -> int ---
|
||||
iswxdigit :: proc(wc: wint_t) -> int ---
|
||||
|
||||
// 7.30.2.2 Extensible wide character classification functions
|
||||
iswctype :: proc(wc: wint_t, desc: wctype_t) -> int ---;
|
||||
wctype :: proc(property: cstring) -> wctype_t ---;
|
||||
iswctype :: proc(wc: wint_t, desc: wctype_t) -> int ---
|
||||
wctype :: proc(property: cstring) -> wctype_t ---
|
||||
|
||||
// 7.30.3 Wide character case mapping utilities
|
||||
towlower :: proc(wc: wint_t) -> wint_t ---;
|
||||
towupper :: proc(wc: wint_t) -> wint_t ---;
|
||||
towlower :: proc(wc: wint_t) -> wint_t ---
|
||||
towupper :: proc(wc: wint_t) -> wint_t ---
|
||||
|
||||
// 7.30.3.2 Extensible wide character case mapping functions
|
||||
towctrans :: proc(wc: wint_t, desc: wctrans_t) -> wint_t ---;
|
||||
wctrans :: proc(property: cstring) -> wctrans_t ---;
|
||||
towctrans :: proc(wc: wint_t, desc: wctrans_t) -> wint_t ---
|
||||
wctrans :: proc(property: cstring) -> wctrans_t ---
|
||||
}
|
||||
|
||||
@@ -41,17 +41,17 @@ accept_ranges := [5]Accept_Range{
|
||||
}
|
||||
|
||||
accept_sizes := [256]u8{
|
||||
0x00..0x7f = 0xf0,
|
||||
0x80..0xc1 = 0xf1,
|
||||
0xc2..0xdf = 0x02,
|
||||
0xe0 = 0x13,
|
||||
0xe1..0xec = 0x03,
|
||||
0xed = 0x23,
|
||||
0xee..0xef = 0x03,
|
||||
0xf0 = 0x34,
|
||||
0xf1..0xf3 = 0x04,
|
||||
0xf4 = 0x44,
|
||||
0xf5..0xff = 0xf1,
|
||||
0x00..=0x7f = 0xf0,
|
||||
0x80..=0xc1 = 0xf1,
|
||||
0xc2..=0xdf = 0x02,
|
||||
0xe0 = 0x13,
|
||||
0xe1..=0xec = 0x03,
|
||||
0xed = 0x23,
|
||||
0xee..=0xef = 0x03,
|
||||
0xf0 = 0x34,
|
||||
0xf1..=0xf3 = 0x04,
|
||||
0xf4 = 0x44,
|
||||
0xf5..=0xff = 0xf1,
|
||||
}
|
||||
|
||||
encode_rune :: proc(c: rune) -> ([4]u8, int) {
|
||||
@@ -379,15 +379,15 @@ full_rune_in_string :: proc(s: string) -> bool {
|
||||
|
||||
|
||||
_first := [256]u8{
|
||||
0x00..0x7f = 0xf0, // ascii, size 1
|
||||
0x80..0xc1 = 0xf1, // invalid, size 1
|
||||
0xc2..0xdf = 0x02, // accept 1, size 2
|
||||
0xe0 = 0x13, // accept 1, size 3
|
||||
0xe1..0xec = 0x03, // accept 0, size 3
|
||||
0xed = 0x23, // accept 2, size 3
|
||||
0xee..0xef = 0x03, // accept 0, size 3
|
||||
0xf0 = 0x34, // accept 3, size 4
|
||||
0xf1..0xf3 = 0x04, // accept 0, size 4
|
||||
0xf4 = 0x44, // accept 4, size 4
|
||||
0xf5..0xff = 0xf1, // ascii, size 1
|
||||
0x00..=0x7f = 0xf0, // ascii, size 1
|
||||
0x80..=0xc1 = 0xf1, // invalid, size 1
|
||||
0xc2..=0xdf = 0x02, // accept 1, size 2
|
||||
0xe0 = 0x13, // accept 1, size 3
|
||||
0xe1..=0xec = 0x03, // accept 0, size 3
|
||||
0xed = 0x23, // accept 2, size 3
|
||||
0xee..=0xef = 0x03, // accept 0, size 3
|
||||
0xf0 = 0x34, // accept 3, size 4
|
||||
0xf1..=0xf3 = 0x04, // accept 0, size 4
|
||||
0xf4 = 0x44, // accept 4, size 4
|
||||
0xf5..=0xff = 0xf1, // ascii, size 1
|
||||
}
|
||||
|
||||
32
src/main.cpp
32
src/main.cpp
@@ -2026,7 +2026,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
|
||||
i32 const end_offset = cast(i32)(file->tokenizer.end - file->tokenizer.start);
|
||||
for_array(i, file->tokens) {
|
||||
Token *token = &file->tokens[i];
|
||||
if (token->flags & TokenFlag_Remove) {
|
||||
if (token->flags & (TokenFlag_Remove|TokenFlag_Replace)) {
|
||||
i32 offset = token->pos.offset;
|
||||
i32 to_write = offset-prev_offset;
|
||||
if (!gb_file_write(f, file_data+prev_offset, to_write)) {
|
||||
@@ -2034,6 +2034,16 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
|
||||
}
|
||||
written += to_write;
|
||||
prev_offset = token_pos_end(*token).offset;
|
||||
}
|
||||
if (token->flags & TokenFlag_Replace) {
|
||||
if (token->kind == Token_Ellipsis) {
|
||||
if (!gb_file_write(f, "..=", 3)) {
|
||||
return gbFileError_Invalid;
|
||||
}
|
||||
written += 3;
|
||||
} else {
|
||||
return gbFileError_Invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (end_offset > prev_offset) {
|
||||
@@ -2054,7 +2064,6 @@ int strip_semicolons(Parser *parser) {
|
||||
AstPackage *pkg = parser->packages[i];
|
||||
file_count += pkg->files.count;
|
||||
}
|
||||
gb_printf_err("File count to be stripped of unneeded tokens: %td\n", file_count);
|
||||
|
||||
auto generated_files = array_make<StripSemicolonFile>(permanent_allocator(), 0, file_count);
|
||||
|
||||
@@ -2062,6 +2071,20 @@ int strip_semicolons(Parser *parser) {
|
||||
AstPackage *pkg = parser->packages[i];
|
||||
for_array(j, pkg->files) {
|
||||
AstFile *file = pkg->files[j];
|
||||
|
||||
bool nothing_to_change = true;
|
||||
for_array(i, file->tokens) {
|
||||
Token *token = &file->tokens[i];
|
||||
if (token->flags) {
|
||||
nothing_to_change = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nothing_to_change) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String old_fullpath = copy_string(permanent_allocator(), file->fullpath);
|
||||
|
||||
// assumes .odin extension
|
||||
@@ -2074,6 +2097,9 @@ int strip_semicolons(Parser *parser) {
|
||||
}
|
||||
}
|
||||
|
||||
gb_printf_err("File count to be stripped of unneeded tokens: %td\n", generated_files.count);
|
||||
|
||||
|
||||
isize generated_count = 0;
|
||||
bool failed = false;
|
||||
|
||||
@@ -2169,7 +2195,7 @@ int strip_semicolons(Parser *parser) {
|
||||
}
|
||||
}
|
||||
|
||||
gb_printf_err("Files stripped of unneeded token: %td\n", file_count);
|
||||
gb_printf_err("Files stripped of unneeded token: %td\n", generated_files.count);
|
||||
|
||||
|
||||
return cast(int)failed;
|
||||
|
||||
@@ -1376,6 +1376,10 @@ Token expect_operator(AstFile *f) {
|
||||
syntax_error(f->curr_token, "Expected an non-range operator, got '%.*s'",
|
||||
LIT(p));
|
||||
}
|
||||
if (f->curr_token.kind == Token_Ellipsis) {
|
||||
f->tokens[f->curr_token_index].flags |= TokenFlag_Replace;
|
||||
}
|
||||
|
||||
advance_token(f);
|
||||
return prev;
|
||||
}
|
||||
|
||||
@@ -236,7 +236,8 @@ TokenPos token_pos_add_column(TokenPos pos) {
|
||||
}
|
||||
|
||||
enum TokenFlag : u8 {
|
||||
TokenFlag_Remove = 1<<1,
|
||||
TokenFlag_Remove = 1<<1,
|
||||
TokenFlag_Replace = 1<<2,
|
||||
};
|
||||
|
||||
struct Token {
|
||||
|
||||
Reference in New Issue
Block a user