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