Strip semicolons; Make odin strip-semicolon replace .. with ..= if used as a binary operator

This commit is contained in:
gingerBill
2021-09-06 20:15:59 +01:00
parent 3bf005bfc5
commit 0434281f73
21 changed files with 999 additions and 968 deletions

View File

@@ -11,72 +11,72 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c")
foreign libc {
// 7.3.5 Trigonometric functions
cacos :: proc(z: complex_double) -> complex_double ---;
cacosf :: proc(z: complex_float) -> complex_float ---;
casin :: proc(z: complex_double) -> complex_double ---;
casinf :: proc(z: complex_float) -> complex_float ---;
catan :: proc(z: complex_double) -> complex_double ---;
catanf :: proc(z: complex_float) -> complex_float ---;
ccos :: proc(z: complex_double) -> complex_double ---;
ccosf :: proc(z: complex_float) -> complex_float ---;
csin :: proc(z: complex_double) -> complex_double ---;
csinf :: proc(z: complex_float) -> complex_float ---;
ctan :: proc(z: complex_double) -> complex_double ---;
ctanf :: proc(z: complex_float) -> complex_float ---;
cacos :: proc(z: complex_double) -> complex_double ---
cacosf :: proc(z: complex_float) -> complex_float ---
casin :: proc(z: complex_double) -> complex_double ---
casinf :: proc(z: complex_float) -> complex_float ---
catan :: proc(z: complex_double) -> complex_double ---
catanf :: proc(z: complex_float) -> complex_float ---
ccos :: proc(z: complex_double) -> complex_double ---
ccosf :: proc(z: complex_float) -> complex_float ---
csin :: proc(z: complex_double) -> complex_double ---
csinf :: proc(z: complex_float) -> complex_float ---
ctan :: proc(z: complex_double) -> complex_double ---
ctanf :: proc(z: complex_float) -> complex_float ---
// 7.3.6 Hyperbolic functions
cacosh :: proc(z: complex_double) -> complex_double ---;
cacoshf :: proc(z: complex_float) -> complex_float ---;
casinh :: proc(z: complex_double) -> complex_double ---;
casinhf :: proc(z: complex_float) -> complex_float ---;
catanh :: proc(z: complex_double) -> complex_double ---;
catanhf :: proc(z: complex_float) -> complex_float ---;
ccosh :: proc(z: complex_double) -> complex_double ---;
ccoshf :: proc(z: complex_float) -> complex_float ---;
csinh :: proc(z: complex_double) -> complex_double ---;
csinhf :: proc(z: complex_float) -> complex_float ---;
ctanh :: proc(z: complex_double) -> complex_double ---;
ctanhf :: proc(z: complex_float) -> complex_float ---;
cacosh :: proc(z: complex_double) -> complex_double ---
cacoshf :: proc(z: complex_float) -> complex_float ---
casinh :: proc(z: complex_double) -> complex_double ---
casinhf :: proc(z: complex_float) -> complex_float ---
catanh :: proc(z: complex_double) -> complex_double ---
catanhf :: proc(z: complex_float) -> complex_float ---
ccosh :: proc(z: complex_double) -> complex_double ---
ccoshf :: proc(z: complex_float) -> complex_float ---
csinh :: proc(z: complex_double) -> complex_double ---
csinhf :: proc(z: complex_float) -> complex_float ---
ctanh :: proc(z: complex_double) -> complex_double ---
ctanhf :: proc(z: complex_float) -> complex_float ---
// 7.3.7 Exponential and logarithmic functions
cexp :: proc(z: complex_double) -> complex_double ---;
cexpf :: proc(z: complex_float) -> complex_float ---;
clog :: proc(z: complex_double) -> complex_double ---;
clogf :: proc(z: complex_float) -> complex_float ---;
cexp :: proc(z: complex_double) -> complex_double ---
cexpf :: proc(z: complex_float) -> complex_float ---
clog :: proc(z: complex_double) -> complex_double ---
clogf :: proc(z: complex_float) -> complex_float ---
// 7.3.8 Power and absolute-value functions
cabs :: proc(z: complex_double) -> complex_double ---;
cabsf :: proc(z: complex_float) -> complex_float ---;
cpow :: proc(z: complex_double) -> complex_double ---;
cpowf :: proc(z: complex_float) -> complex_float ---;
csqrt :: proc(z: complex_double) -> complex_double ---;
csqrtf :: proc(z: complex_float) -> complex_float ---;
cabs :: proc(z: complex_double) -> complex_double ---
cabsf :: proc(z: complex_float) -> complex_float ---
cpow :: proc(z: complex_double) -> complex_double ---
cpowf :: proc(z: complex_float) -> complex_float ---
csqrt :: proc(z: complex_double) -> complex_double ---
csqrtf :: proc(z: complex_float) -> complex_float ---
// 7.3.9 Manipulation functions
carg :: proc(z: complex_double) -> double ---;
cargf :: proc(z: complex_float) -> float ---;
cimag :: proc(z: complex_double) -> double ---;
cimagf :: proc(z: complex_float) -> float ---;
conj :: proc(z: complex_double) -> complex_double ---;
conjf :: proc(z: complex_float) -> complex_float ---;
cproj :: proc(z: complex_double) -> complex_double ---;
cprojf :: proc(z: complex_float) -> complex_float ---;
creal :: proc(z: complex_double) -> double ---;
crealf :: proc(z: complex_float) -> float ---;
carg :: proc(z: complex_double) -> double ---
cargf :: proc(z: complex_float) -> float ---
cimag :: proc(z: complex_double) -> double ---
cimagf :: proc(z: complex_float) -> float ---
conj :: proc(z: complex_double) -> complex_double ---
conjf :: proc(z: complex_float) -> complex_float ---
cproj :: proc(z: complex_double) -> complex_double ---
cprojf :: proc(z: complex_float) -> complex_float ---
creal :: proc(z: complex_double) -> double ---
crealf :: proc(z: complex_float) -> float ---
}
import builtin "core:builtin"
complex_float :: distinct builtin.complex64;
complex_double :: distinct builtin.complex128;
complex_float :: distinct builtin.complex64
complex_double :: distinct builtin.complex128
// Cannot implement _Complex_I or _Imaginary_I in Odin, thus
// complex and imaginary cannot be implement either.
CMPLX :: #force_inline proc(x, y: double) -> complex_double {
return builtin.complex(x, y);
return builtin.complex(x, y)
}
CMPLXF :: #force_inline proc(x, y: float) -> complex_float {
return builtin.complex(x, y);
return builtin.complex(x, y)
}

View File

@@ -11,20 +11,20 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c")
foreign libc {
// 7.4.1 Character classification functions
isalnum :: proc(c: int) -> int ---;
isalpha :: proc(c: int) -> int ---;
isblank :: proc(c: int) -> int ---;
iscntrl :: proc(c: int) -> int ---;
isdigit :: proc(c: int) -> int ---;
isgraph :: proc(c: int) -> int ---;
islower :: proc(c: int) -> int ---;
isprint :: proc(c: int) -> int ---;
ispunct :: proc(c: int) -> int ---;
isspace :: proc(c: int) -> int ---;
isupper :: proc(c: int) -> int ---;
isxdigit :: proc(c: int) -> int ---;
isalnum :: proc(c: int) -> int ---
isalpha :: proc(c: int) -> int ---
isblank :: proc(c: int) -> int ---
iscntrl :: proc(c: int) -> int ---
isdigit :: proc(c: int) -> int ---
isgraph :: proc(c: int) -> int ---
islower :: proc(c: int) -> int ---
isprint :: proc(c: int) -> int ---
ispunct :: proc(c: int) -> int ---
isspace :: proc(c: int) -> int ---
isupper :: proc(c: int) -> int ---
isxdigit :: proc(c: int) -> int ---
// 7.4.2 Character case mapping functions
tolower :: proc(c: int) -> int ---;
toupper :: proc(c: int) -> int ---;
tolower :: proc(c: int) -> int ---
toupper :: proc(c: int) -> int ---
}

View File

@@ -17,12 +17,12 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" {
@(default_calling_convention="c")
foreign libc {
@(link_name="__libc_errno_location")
_get_errno :: proc() -> ^int ---;
_get_errno :: proc() -> ^int ---
}
EDOM :: 33;
EILSEQ :: 84;
ERANGE :: 34;
EDOM :: 33
EILSEQ :: 84
ERANGE :: 34
}
when ODIN_OS == "windows" {
@@ -30,12 +30,12 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c")
foreign libc {
@(link_name="_errno")
_get_errno :: proc() -> ^int ---;
_get_errno :: proc() -> ^int ---
}
EDOM :: 33;
EILSEQ :: 42;
ERANGE :: 34;
EDOM :: 33
EILSEQ :: 42
ERANGE :: 34
}
// Odin has no way to make an identifier "errno" behave as a function call to
@@ -43,5 +43,5 @@ when ODIN_OS == "windows" {
// error value to errno. To work around this, just expose it as a function like
// it actually is.
errno :: #force_inline proc() -> ^int {
return _get_errno();
return _get_errno()
}

View File

@@ -17,210 +17,210 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c")
foreign libc {
// 7.12.4 Trigonometric functions
@(link_name="acos") libc_acos :: proc(x: double) -> double ---;
@(link_name="acosf") libc_acosf :: proc(x: float) -> float ---;
@(link_name="asin") libc_asin :: proc(x: double) -> double ---;
@(link_name="asinf") libc_asinf :: proc(x: float) -> float ---;
@(link_name="atan") libc_atan :: proc(x: double) -> double ---;
@(link_name="atanf") libc_atanf :: proc(x: float) -> float ---;
@(link_name="atan2") libc_atan2 :: proc(y: double, x: double) -> double ---;
@(link_name="atan2f") libc_atan2f :: proc(y: float, x: float) -> float ---;
@(link_name="cos") libc_cos :: proc(x: double) -> double ---;
@(link_name="cosf") libc_cosf :: proc(x: float) -> float ---;
@(link_name="sin") libc_sin :: proc(x: double) -> double ---;
@(link_name="sinf") libc_sinf :: proc(x: float) -> float ---;
@(link_name="tan") libc_tan :: proc(x: double) -> double ---;
@(link_name="tanf") libc_tanf :: proc(x: float) -> float ---;
@(link_name="acos") libc_acos :: proc(x: double) -> double ---
@(link_name="acosf") libc_acosf :: proc(x: float) -> float ---
@(link_name="asin") libc_asin :: proc(x: double) -> double ---
@(link_name="asinf") libc_asinf :: proc(x: float) -> float ---
@(link_name="atan") libc_atan :: proc(x: double) -> double ---
@(link_name="atanf") libc_atanf :: proc(x: float) -> float ---
@(link_name="atan2") libc_atan2 :: proc(y: double, x: double) -> double ---
@(link_name="atan2f") libc_atan2f :: proc(y: float, x: float) -> float ---
@(link_name="cos") libc_cos :: proc(x: double) -> double ---
@(link_name="cosf") libc_cosf :: proc(x: float) -> float ---
@(link_name="sin") libc_sin :: proc(x: double) -> double ---
@(link_name="sinf") libc_sinf :: proc(x: float) -> float ---
@(link_name="tan") libc_tan :: proc(x: double) -> double ---
@(link_name="tanf") libc_tanf :: proc(x: float) -> float ---
// 7.12.5 Hyperbolic functions
@(link_name="acosh") libc_acosh :: proc(x: double) -> double ---;
@(link_name="acoshf") libc_acoshf :: proc(x: float) -> float ---;
@(link_name="asinh") libc_asinh :: proc(x: double) -> double ---;
@(link_name="asinhf") libc_asinhf :: proc(x: float) -> float ---;
@(link_name="atanh") libc_atanh :: proc(x: double) -> double ---;
@(link_name="atanhf") libc_atanhf :: proc(x: float) -> float ---;
@(link_name="cosh") libc_cosh :: proc(x: double) -> double ---;
@(link_name="coshf") libc_coshf :: proc(x: float) -> float ---;
@(link_name="sinh") libc_sinh :: proc(x: double) -> double ---;
@(link_name="sinhf") libc_sinhf :: proc(x: float) -> float ---;
@(link_name="tanh") libc_tanh :: proc(x: double) -> double ---;
@(link_name="tanhf") libc_tanhf :: proc(x: float) -> float ---;
@(link_name="acosh") libc_acosh :: proc(x: double) -> double ---
@(link_name="acoshf") libc_acoshf :: proc(x: float) -> float ---
@(link_name="asinh") libc_asinh :: proc(x: double) -> double ---
@(link_name="asinhf") libc_asinhf :: proc(x: float) -> float ---
@(link_name="atanh") libc_atanh :: proc(x: double) -> double ---
@(link_name="atanhf") libc_atanhf :: proc(x: float) -> float ---
@(link_name="cosh") libc_cosh :: proc(x: double) -> double ---
@(link_name="coshf") libc_coshf :: proc(x: float) -> float ---
@(link_name="sinh") libc_sinh :: proc(x: double) -> double ---
@(link_name="sinhf") libc_sinhf :: proc(x: float) -> float ---
@(link_name="tanh") libc_tanh :: proc(x: double) -> double ---
@(link_name="tanhf") libc_tanhf :: proc(x: float) -> float ---
// 7.12.6 Exponential and logarithmic functions
@(link_name="exp") libc_exp :: proc(x: double) -> double ---;
@(link_name="expf") libc_expf :: proc(x: float) -> float ---;
@(link_name="exp2") libc_exp2 :: proc(x: double) -> double ---;
@(link_name="exp2f") libc_exp2f :: proc(x: float) -> float ---;
@(link_name="expm1") libc_expm1 :: proc(x: double) -> double ---;
@(link_name="expm1f") libc_expm1f :: proc(x: float) -> float ---;
@(link_name="frexp") libc_frexp :: proc(value: double, exp: ^int) -> double ---;
@(link_name="frexpf") libc_frexpf :: proc(value: float, exp: ^int) -> float ---;
@(link_name="ilogb") libc_ilogb :: proc(x: double) -> int ---;
@(link_name="ilogbf") libc_ilogbf :: proc(x: float) -> int ---;
@(link_name="ldexp") libc_ldexp :: proc(x: double, exp: int) -> double ---;
@(link_name="ldexpf") libc_ldexpf :: proc(x: float, exp: int) -> float ---;
@(link_name="log") libc_log :: proc(x: double) -> double ---;
@(link_name="logf") libc_logf :: proc(x: float) -> float ---;
@(link_name="log10") libc_log10 :: proc(x: double) -> double ---;
@(link_name="log10f") libc_log10f :: proc(x: float) -> float ---;
@(link_name="log1p") libc_log1p :: proc(x: double) -> double ---;
@(link_name="log1pf") libc_log1pf :: proc(x: float) -> float ---;
@(link_name="log2") libc_log2 :: proc(x: double) -> double ---;
@(link_name="log2f") libc_log2f :: proc(x: float) -> float ---;
@(link_name="logb") libc_logb :: proc(x: double) -> double ---;
@(link_name="logbf") libc_logbf :: proc(x: float) -> float ---;
@(link_name="modf") libc_modf :: proc(value: double, iptr: ^double) -> double ---;
@(link_name="modff") libc_modff :: proc(value: float, iptr: ^float) -> float ---;
@(link_name="scalbn") libc_scalbn :: proc(x: double, n: int) -> double ---;
@(link_name="scalbnf") libc_scalbnf :: proc(x: float, n: int) -> float ---;
@(link_name="scalbln") libc_scalbln :: proc(x: double, n: long) -> double ---;
@(link_name="scalblnf") libc_scalblnf :: proc(x: float, n: long) -> float ---;
@(link_name="exp") libc_exp :: proc(x: double) -> double ---
@(link_name="expf") libc_expf :: proc(x: float) -> float ---
@(link_name="exp2") libc_exp2 :: proc(x: double) -> double ---
@(link_name="exp2f") libc_exp2f :: proc(x: float) -> float ---
@(link_name="expm1") libc_expm1 :: proc(x: double) -> double ---
@(link_name="expm1f") libc_expm1f :: proc(x: float) -> float ---
@(link_name="frexp") libc_frexp :: proc(value: double, exp: ^int) -> double ---
@(link_name="frexpf") libc_frexpf :: proc(value: float, exp: ^int) -> float ---
@(link_name="ilogb") libc_ilogb :: proc(x: double) -> int ---
@(link_name="ilogbf") libc_ilogbf :: proc(x: float) -> int ---
@(link_name="ldexp") libc_ldexp :: proc(x: double, exp: int) -> double ---
@(link_name="ldexpf") libc_ldexpf :: proc(x: float, exp: int) -> float ---
@(link_name="log") libc_log :: proc(x: double) -> double ---
@(link_name="logf") libc_logf :: proc(x: float) -> float ---
@(link_name="log10") libc_log10 :: proc(x: double) -> double ---
@(link_name="log10f") libc_log10f :: proc(x: float) -> float ---
@(link_name="log1p") libc_log1p :: proc(x: double) -> double ---
@(link_name="log1pf") libc_log1pf :: proc(x: float) -> float ---
@(link_name="log2") libc_log2 :: proc(x: double) -> double ---
@(link_name="log2f") libc_log2f :: proc(x: float) -> float ---
@(link_name="logb") libc_logb :: proc(x: double) -> double ---
@(link_name="logbf") libc_logbf :: proc(x: float) -> float ---
@(link_name="modf") libc_modf :: proc(value: double, iptr: ^double) -> double ---
@(link_name="modff") libc_modff :: proc(value: float, iptr: ^float) -> float ---
@(link_name="scalbn") libc_scalbn :: proc(x: double, n: int) -> double ---
@(link_name="scalbnf") libc_scalbnf :: proc(x: float, n: int) -> float ---
@(link_name="scalbln") libc_scalbln :: proc(x: double, n: long) -> double ---
@(link_name="scalblnf") libc_scalblnf :: proc(x: float, n: long) -> float ---
// 7.12.7 Power and absolute-value functions
@(link_name="cbrt") libc_cbrt :: proc(x: double) -> double ---;
@(link_name="cbrtf") libc_cbrtf :: proc(x: float) -> float ---;
@(link_name="fabs") libc_fabs :: proc(x: double) -> double ---;
@(link_name="fabsf") libc_fabsf :: proc(x: float) -> float ---;
@(link_name="hypot") libc_hypot :: proc(x: double, y: double) -> double ---;
@(link_name="hypotf") libc_hypotf :: proc(x: float, y: float) -> float ---;
@(link_name="pow") libc_pow :: proc(x: double, y: double) -> double ---;
@(link_name="powf") libc_powf :: proc(x: float, y: float) -> float ---;
@(link_name="sqrt") libc_sqrt :: proc(x: double) -> double ---;
@(link_name="sqrtf") libc_sqrtf :: proc(x: float) -> float ---;
@(link_name="cbrt") libc_cbrt :: proc(x: double) -> double ---
@(link_name="cbrtf") libc_cbrtf :: proc(x: float) -> float ---
@(link_name="fabs") libc_fabs :: proc(x: double) -> double ---
@(link_name="fabsf") libc_fabsf :: proc(x: float) -> float ---
@(link_name="hypot") libc_hypot :: proc(x: double, y: double) -> double ---
@(link_name="hypotf") libc_hypotf :: proc(x: float, y: float) -> float ---
@(link_name="pow") libc_pow :: proc(x: double, y: double) -> double ---
@(link_name="powf") libc_powf :: proc(x: float, y: float) -> float ---
@(link_name="sqrt") libc_sqrt :: proc(x: double) -> double ---
@(link_name="sqrtf") libc_sqrtf :: proc(x: float) -> float ---
// 7.12.8 Error and gamma functions
@(link_name="erf") libc_erf :: proc(x: double) -> double ---;
@(link_name="erff") libc_erff :: proc(x: float) -> float ---;
@(link_name="erfc") libc_erfc :: proc(x: double) -> double ---;
@(link_name="erfcf") libc_erfcf :: proc(x: float) -> float ---;
@(link_name="lgamma") libc_lgamma :: proc(x: double) -> double ---;
@(link_name="lgammaf") libc_lgammaf :: proc(x: float) -> float ---;
@(link_name="tgamma") libc_tgamma :: proc(x: double) -> double ---;
@(link_name="tgammaf") libc_tgammaf :: proc(x: float) -> float ---;
@(link_name="erf") libc_erf :: proc(x: double) -> double ---
@(link_name="erff") libc_erff :: proc(x: float) -> float ---
@(link_name="erfc") libc_erfc :: proc(x: double) -> double ---
@(link_name="erfcf") libc_erfcf :: proc(x: float) -> float ---
@(link_name="lgamma") libc_lgamma :: proc(x: double) -> double ---
@(link_name="lgammaf") libc_lgammaf :: proc(x: float) -> float ---
@(link_name="tgamma") libc_tgamma :: proc(x: double) -> double ---
@(link_name="tgammaf") libc_tgammaf :: proc(x: float) -> float ---
// 7.12.9 Nearest integer functions
@(link_name="ceil") libc_ceil :: proc(x: double) -> double ---;
@(link_name="ceilf") libc_ceilf :: proc(x: float) -> float ---;
@(link_name="floor") libc_floor :: proc(x: double) -> double ---;
@(link_name="floorf") libc_floorf :: proc(x: float) -> float ---;
@(link_name="nearbyint") libc_nearbyint :: proc(x: double) -> double ---;
@(link_name="nearbyintf") libc_nearbyintf :: proc(x: float) -> float ---;
@(link_name="rint") libc_rint :: proc(x: double) -> double ---;
@(link_name="rintf") libc_rintf :: proc(x: float) -> float ---;
@(link_name="lrint") libc_lrint :: proc(x: double) -> long ---;
@(link_name="lrintf") libc_lrintf :: proc(x: float) -> long ---;
@(link_name="llrint") libc_llrint :: proc(x: double) -> longlong ---;
@(link_name="llrintf") libc_llrintf :: proc(x: float) -> longlong ---;
@(link_name="round") libc_round :: proc(x: double) -> double ---;
@(link_name="roundf") libc_roundf :: proc(x: float) -> float ---;
@(link_name="lround") libc_lround :: proc(x: double) -> long ---;
@(link_name="lroundf") libc_lroundf :: proc(x: float) -> long ---;
@(link_name="llround") libc_llround :: proc(x: double) -> longlong ---;
@(link_name="llroundf") libc_llroundf :: proc(x: float) -> longlong ---;
@(link_name="trunc") libc_trunc :: proc(x: double) -> double ---;
@(link_name="truncf") libc_truncf :: proc(x: float) -> float ---;
@(link_name="ceil") libc_ceil :: proc(x: double) -> double ---
@(link_name="ceilf") libc_ceilf :: proc(x: float) -> float ---
@(link_name="floor") libc_floor :: proc(x: double) -> double ---
@(link_name="floorf") libc_floorf :: proc(x: float) -> float ---
@(link_name="nearbyint") libc_nearbyint :: proc(x: double) -> double ---
@(link_name="nearbyintf") libc_nearbyintf :: proc(x: float) -> float ---
@(link_name="rint") libc_rint :: proc(x: double) -> double ---
@(link_name="rintf") libc_rintf :: proc(x: float) -> float ---
@(link_name="lrint") libc_lrint :: proc(x: double) -> long ---
@(link_name="lrintf") libc_lrintf :: proc(x: float) -> long ---
@(link_name="llrint") libc_llrint :: proc(x: double) -> longlong ---
@(link_name="llrintf") libc_llrintf :: proc(x: float) -> longlong ---
@(link_name="round") libc_round :: proc(x: double) -> double ---
@(link_name="roundf") libc_roundf :: proc(x: float) -> float ---
@(link_name="lround") libc_lround :: proc(x: double) -> long ---
@(link_name="lroundf") libc_lroundf :: proc(x: float) -> long ---
@(link_name="llround") libc_llround :: proc(x: double) -> longlong ---
@(link_name="llroundf") libc_llroundf :: proc(x: float) -> longlong ---
@(link_name="trunc") libc_trunc :: proc(x: double) -> double ---
@(link_name="truncf") libc_truncf :: proc(x: float) -> float ---
// 7.12.10 Remainder functions
@(link_name="fmod") libc_fmod :: proc(x: double, y: double) -> double ---;
@(link_name="fmodf") libc_fmodf :: proc(x: float, y: float) -> float ---;
@(link_name="remainder") libc_remainder :: proc(x: double, y: double) -> double ---;
@(link_name="remainderf") libc_remainderf :: proc(x: float, y: float) -> float ---;
@(link_name="remquo") libc_remquo :: proc(x: double, y: double, quo: ^int) -> double ---;
@(link_name="remquof") libc_remquof :: proc(x: float, y: float, quo: ^int) -> float ---;
@(link_name="fmod") libc_fmod :: proc(x: double, y: double) -> double ---
@(link_name="fmodf") libc_fmodf :: proc(x: float, y: float) -> float ---
@(link_name="remainder") libc_remainder :: proc(x: double, y: double) -> double ---
@(link_name="remainderf") libc_remainderf :: proc(x: float, y: float) -> float ---
@(link_name="remquo") libc_remquo :: proc(x: double, y: double, quo: ^int) -> double ---
@(link_name="remquof") libc_remquof :: proc(x: float, y: float, quo: ^int) -> float ---
// 7.12.11 Manipulation functions
@(link_name="copysign") libc_copysign :: proc(x: double, y: double) -> double ---;
@(link_name="copysignf") libc_copysignf :: proc(x: float, y: float) -> float ---;
@(link_name="nan") libc_nan :: proc(tagp: cstring) -> double ---;
@(link_name="nanf") libc_nanf :: proc(tagp: cstring) -> float ---;
@(link_name="nextafter") libc_nextafter :: proc(x: double, y: double) -> double ---;
@(link_name="nextafterf") libc_nextafterf :: proc(x: float, y: float) -> float ---;
@(link_name="copysign") libc_copysign :: proc(x: double, y: double) -> double ---
@(link_name="copysignf") libc_copysignf :: proc(x: float, y: float) -> float ---
@(link_name="nan") libc_nan :: proc(tagp: cstring) -> double ---
@(link_name="nanf") libc_nanf :: proc(tagp: cstring) -> float ---
@(link_name="nextafter") libc_nextafter :: proc(x: double, y: double) -> double ---
@(link_name="nextafterf") libc_nextafterf :: proc(x: float, y: float) -> float ---
// 7.12.12 Maximum, minimum, and positive difference functions
@(link_name="fdim") libc_fdim :: proc(x: double, y: double) -> double ---;
@(link_name="fdimf") libc_fdimf :: proc(x: float, y: float) -> float ---;
@(link_name="fmax") libc_fmax :: proc(x: double, y: double) -> double ---;
@(link_name="fmaxf") libc_fmaxf :: proc(x: float, y: float) -> float ---;
@(link_name="fmin") libc_fmin :: proc(x: double, y: double) -> double ---;
@(link_name="fminf") libc_fminf :: proc(x: float, y: float) -> float ---;
@(link_name="fma") libc_fma :: proc(x, y, z: double) -> double ---;
@(link_name="fmaf") libc_fmaf :: proc(x, y, z: float) -> float ---;
@(link_name="fdim") libc_fdim :: proc(x: double, y: double) -> double ---
@(link_name="fdimf") libc_fdimf :: proc(x: float, y: float) -> float ---
@(link_name="fmax") libc_fmax :: proc(x: double, y: double) -> double ---
@(link_name="fmaxf") libc_fmaxf :: proc(x: float, y: float) -> float ---
@(link_name="fmin") libc_fmin :: proc(x: double, y: double) -> double ---
@(link_name="fminf") libc_fminf :: proc(x: float, y: float) -> float ---
@(link_name="fma") libc_fma :: proc(x, y, z: double) -> double ---
@(link_name="fmaf") libc_fmaf :: proc(x, y, z: float) -> float ---
}
@(private="file")
_nan_bit_pattern := ~u64(0);
_nan_bit_pattern := ~u64(0)
// On amd64 Windows and Linux, float_t and double_t are respectively both
// their usual types. On x86 it's not possible to define these types correctly
// since they would be long double which Odin does have support for.
float_t :: float;
double_t :: double;
float_t :: float
double_t :: double
NAN := transmute(double)(_nan_bit_pattern);
INFINITY :: 1e5000;
NAN := transmute(double)(_nan_bit_pattern)
INFINITY :: 1e5000
HUGE_VALF :: INFINITY;
HUGE_VAL :: double(INFINITY);
HUGE_VALF :: INFINITY
HUGE_VAL :: double(INFINITY)
MATH_ERRNO :: 1;
MATH_ERREXCEPT :: 2;
MATH_ERRNO :: 1
MATH_ERREXCEPT :: 2
math_errhandling :: 2; // Windows, Linux, macOS all use this mode.
math_errhandling :: 2 // Windows, Linux, macOS all use this mode.
FP_ILOGBNAN :: -1 - int((~uint(0)) >> 1);
FP_ILOGB0 :: FP_ILOGBNAN;
FP_ILOGBNAN :: -1 - int((~uint(0)) >> 1)
FP_ILOGB0 :: FP_ILOGBNAN
// Number classification constants. These do not have to match libc since we
// implement our own classification functions as libc requires they be macros,
// which means libc does not export standard functions for them.
FP_NAN :: 0;
FP_INFINITE :: 1;
FP_ZERO :: 2;
FP_NORMAL :: 3;
FP_SUBNORMAL :: 4;
FP_NAN :: 0
FP_INFINITE :: 1
FP_ZERO :: 2
FP_NORMAL :: 3
FP_SUBNORMAL :: 4
@(private)
_fpclassify :: #force_inline proc(x: double) -> int {
u := transmute(uint64_t)x;
e := u >> 52 & 0x7ff;
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO;
if e == 0x7ff do return FP_NAN if (u << 12) != 0 else FP_INFINITE;
return FP_NORMAL;
u := transmute(uint64_t)x
e := u >> 52 & 0x7ff
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO
if e == 0x7ff do return FP_NAN if (u << 12) != 0 else FP_INFINITE
return FP_NORMAL
}
@(private)
_fpclassifyf :: #force_inline proc(x: float) -> int {
u := transmute(uint32_t)x;
e := u >> 23 & 0xff;
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO;
if e == 0xff do return FP_NAN if (u << 9) != 0 else FP_INFINITE;
return FP_NORMAL;
u := transmute(uint32_t)x
e := u >> 23 & 0xff
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO
if e == 0xff do return FP_NAN if (u << 9) != 0 else FP_INFINITE
return FP_NORMAL
}
@(private)
_signbit :: #force_inline proc(x: double) -> int {
return int(transmute(uint64_t)x >> 63);
return int(transmute(uint64_t)x >> 63)
}
@(private)
_signbitf :: #force_inline proc(x: float) -> int {
return int(transmute(uint32_t)x >> 31);
return int(transmute(uint32_t)x >> 31)
}
isfinite :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_INFINITE;
return fpclassify(x) == FP_INFINITE
}
isinf :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) > FP_INFINITE;
return fpclassify(x) > FP_INFINITE
}
isnan :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_NAN;
return fpclassify(x) == FP_NAN
}
isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_NORMAL;
return fpclassify(x) == FP_NORMAL
}
// These are special in that they avoid float exceptions. They cannot just be
@@ -228,173 +228,173 @@ isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
// "sticky" state that propagates and affects maths results. These need
// to be implemented natively in Odin assuming isunordered to prevent that.
isgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x > y;
return !isunordered(x, y) && x > y
}
isgreaterequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x >= y;
return !isunordered(x, y) && x >= y
}
isless :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x < y;
return !isunordered(x, y) && x < y
}
islessequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x <= y;
return !isunordered(x, y) && x <= y
}
islessgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x <= y;
return !isunordered(x, y) && x <= y
}
isunordered :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
if isnan(x) {
// Force evaluation of y to propagate exceptions for ordering semantics.
// To ensure correct semantics of IEEE 754 this cannot be compiled away.
sink: T;
intrinsics.volatile_store(&sink, intrinsics.volatile_load(&y));
return true;
sink: T
intrinsics.volatile_store(&sink, intrinsics.volatile_load(&y))
return true
}
return isnan(y);
return isnan(y)
}
fpclassify :: proc{_fpclassify, _fpclassifyf};
signbit :: proc{_signbit, _signbitf};
fpclassify :: proc{_fpclassify, _fpclassifyf}
signbit :: proc{_signbit, _signbitf}
// Emulate tgmath.h behavior with explicit procedure overloading here.
acos :: proc{libc_acos, libc_acosf, cacos, cacosf};
asin :: proc{libc_asin, libc_asinf, casin, casinf};
atan :: proc{libc_atan, libc_atanf, catan, catanf};
atan2 :: proc{libc_atan2, libc_atan2f};
cos :: proc{libc_cos, libc_cosf, ccos, ccosf};
sin :: proc{libc_sin, libc_sinf, csin, csinf};
tan :: proc{libc_tan, libc_tanf, ctan, ctanf};
acos :: proc{libc_acos, libc_acosf, cacos, cacosf}
asin :: proc{libc_asin, libc_asinf, casin, casinf}
atan :: proc{libc_atan, libc_atanf, catan, catanf}
atan2 :: proc{libc_atan2, libc_atan2f}
cos :: proc{libc_cos, libc_cosf, ccos, ccosf}
sin :: proc{libc_sin, libc_sinf, csin, csinf}
tan :: proc{libc_tan, libc_tanf, ctan, ctanf}
acosh :: proc{libc_acosh, libc_acoshf, cacosh, cacoshf};
asinh :: proc{libc_asinh, libc_asinhf, casinh, casinhf};
atanh :: proc{libc_atanh, libc_atanhf, catanh, catanhf};
cosh :: proc{libc_cosh, libc_coshf, ccosh, ccoshf};
sinh :: proc{libc_sinh, libc_sinhf, csinh, csinhf};
tanh :: proc{libc_tanh, libc_tanhf, ctanh, ctanhf};
acosh :: proc{libc_acosh, libc_acoshf, cacosh, cacoshf}
asinh :: proc{libc_asinh, libc_asinhf, casinh, casinhf}
atanh :: proc{libc_atanh, libc_atanhf, catanh, catanhf}
cosh :: proc{libc_cosh, libc_coshf, ccosh, ccoshf}
sinh :: proc{libc_sinh, libc_sinhf, csinh, csinhf}
tanh :: proc{libc_tanh, libc_tanhf, ctanh, ctanhf}
exp :: proc{libc_exp, libc_expf, cexp, cexpf};
exp2 :: proc{libc_exp2, libc_exp2f};
expm1 :: proc{libc_expm1, libc_expm1f};
frexp :: proc{libc_frexp, libc_frexpf};
ilogb :: proc{libc_ilogb, libc_ilogbf};
ldexp :: proc{libc_ldexp, libc_ldexpf};
log :: proc{libc_log, libc_logf, clog, clogf};
log10 :: proc{libc_log10, libc_log10f};
log1p :: proc{libc_log1p, libc_log1pf};
log2 :: proc{libc_log2, libc_log2f};
logb :: proc{libc_logb, libc_logbf};
modf :: proc{libc_modf, libc_modff};
scalbn :: proc{libc_scalbn, libc_scalbnf};
scalbln :: proc{libc_scalbln, libc_scalblnf};
exp :: proc{libc_exp, libc_expf, cexp, cexpf}
exp2 :: proc{libc_exp2, libc_exp2f}
expm1 :: proc{libc_expm1, libc_expm1f}
frexp :: proc{libc_frexp, libc_frexpf}
ilogb :: proc{libc_ilogb, libc_ilogbf}
ldexp :: proc{libc_ldexp, libc_ldexpf}
log :: proc{libc_log, libc_logf, clog, clogf}
log10 :: proc{libc_log10, libc_log10f}
log1p :: proc{libc_log1p, libc_log1pf}
log2 :: proc{libc_log2, libc_log2f}
logb :: proc{libc_logb, libc_logbf}
modf :: proc{libc_modf, libc_modff}
scalbn :: proc{libc_scalbn, libc_scalbnf}
scalbln :: proc{libc_scalbln, libc_scalblnf}
cbrt :: proc{libc_cbrt, libc_cbrtf};
fabs :: proc{libc_fabs, libc_fabsf, cabs, cabsf};
hypot :: proc{libc_hypot, libc_hypotf};
pow :: proc{libc_pow, libc_powf, cpow, cpowf};
sqrt :: proc{libc_sqrt, libc_sqrtf, csqrt, csqrtf};
cbrt :: proc{libc_cbrt, libc_cbrtf}
fabs :: proc{libc_fabs, libc_fabsf, cabs, cabsf}
hypot :: proc{libc_hypot, libc_hypotf}
pow :: proc{libc_pow, libc_powf, cpow, cpowf}
sqrt :: proc{libc_sqrt, libc_sqrtf, csqrt, csqrtf}
erf :: proc{libc_erf, libc_erff};
erfc :: proc{libc_erfc, libc_erfcf};
lgamma :: proc{libc_lgamma, libc_lgammaf};
tgamma :: proc{libc_tgamma, libc_tgammaf};
erf :: proc{libc_erf, libc_erff}
erfc :: proc{libc_erfc, libc_erfcf}
lgamma :: proc{libc_lgamma, libc_lgammaf}
tgamma :: proc{libc_tgamma, libc_tgammaf}
ceil :: proc{libc_ceil, libc_ceilf};
floor :: proc{libc_floor, libc_floorf};
nearbyint :: proc{libc_nearbyint, libc_nearbyintf};
rint :: proc{libc_rint, libc_rintf};
lrint :: proc{libc_lrint, libc_lrintf};
llrint :: proc{libc_llrint, libc_llrintf};
round :: proc{libc_round, libc_roundf};
lround :: proc{libc_lround, libc_lroundf};
llround :: proc{libc_llround, libc_llroundf};
trunc :: proc{libc_trunc, libc_truncf};
ceil :: proc{libc_ceil, libc_ceilf}
floor :: proc{libc_floor, libc_floorf}
nearbyint :: proc{libc_nearbyint, libc_nearbyintf}
rint :: proc{libc_rint, libc_rintf}
lrint :: proc{libc_lrint, libc_lrintf}
llrint :: proc{libc_llrint, libc_llrintf}
round :: proc{libc_round, libc_roundf}
lround :: proc{libc_lround, libc_lroundf}
llround :: proc{libc_llround, libc_llroundf}
trunc :: proc{libc_trunc, libc_truncf}
fmod :: proc{libc_fmod, libc_fmodf};
remainder :: proc{libc_remainder, libc_remainderf};
remquo :: proc{libc_remquo, libc_remquof};
fmod :: proc{libc_fmod, libc_fmodf}
remainder :: proc{libc_remainder, libc_remainderf}
remquo :: proc{libc_remquo, libc_remquof}
copysign :: proc{libc_copysign, libc_copysignf};
nextafter :: proc{libc_nextafter, libc_nextafterf};
copysign :: proc{libc_copysign, libc_copysignf}
nextafter :: proc{libc_nextafter, libc_nextafterf}
fdim :: proc{libc_fdim, libc_fdimf};
fmax :: proc{libc_fmax, libc_fmaxf};
fmin :: proc{libc_fmin, libc_fminf};
fma :: proc{libc_fma, libc_fmaf};
fdim :: proc{libc_fdim, libc_fdimf}
fmax :: proc{libc_fmax, libc_fmaxf}
fmin :: proc{libc_fmin, libc_fminf}
fma :: proc{libc_fma, libc_fmaf}
// But retain the 'f' suffix-variant functions as well so they can be used,
// a trick is used here where we use explicit procedrual overloading of one
// procedure. This is done because the foreign block is marked @(private) and
// aliasing functions does not remove privateness from the entity.
acosf :: proc{libc_acosf};
asinf :: proc{libc_asinf};
atanf :: proc{libc_atanf};
atan2f :: proc{libc_atan2f};
cosf :: proc{libc_cosf};
sinf :: proc{libc_sinf};
tanf :: proc{libc_tanf};
acosf :: proc{libc_acosf}
asinf :: proc{libc_asinf}
atanf :: proc{libc_atanf}
atan2f :: proc{libc_atan2f}
cosf :: proc{libc_cosf}
sinf :: proc{libc_sinf}
tanf :: proc{libc_tanf}
acoshf :: proc{libc_acoshf};
asinhf :: proc{libc_asinhf};
atanhf :: proc{libc_atanhf};
coshf :: proc{libc_coshf};
sinhf :: proc{libc_sinhf};
tanhf :: proc{libc_tanhf};
acoshf :: proc{libc_acoshf}
asinhf :: proc{libc_asinhf}
atanhf :: proc{libc_atanhf}
coshf :: proc{libc_coshf}
sinhf :: proc{libc_sinhf}
tanhf :: proc{libc_tanhf}
expf :: proc{libc_expf};
exp2f :: proc{libc_exp2f};
expm1f :: proc{libc_expm1f};
frexpf :: proc{libc_frexpf};
ilogbf :: proc{libc_ilogbf};
ldexpf :: proc{libc_ldexpf};
logf :: proc{libc_logf};
log10f :: proc{libc_log10f};
log1pf :: proc{libc_log1pf};
log2f :: proc{libc_log2f};
logbf :: proc{libc_logbf};
modff :: proc{libc_modff};
scalbnf :: proc{libc_scalbnf};
scalblnf :: proc{libc_scalblnf};
expf :: proc{libc_expf}
exp2f :: proc{libc_exp2f}
expm1f :: proc{libc_expm1f}
frexpf :: proc{libc_frexpf}
ilogbf :: proc{libc_ilogbf}
ldexpf :: proc{libc_ldexpf}
logf :: proc{libc_logf}
log10f :: proc{libc_log10f}
log1pf :: proc{libc_log1pf}
log2f :: proc{libc_log2f}
logbf :: proc{libc_logbf}
modff :: proc{libc_modff}
scalbnf :: proc{libc_scalbnf}
scalblnf :: proc{libc_scalblnf}
cbrtf :: proc{libc_cbrtf};
fabsf :: proc{libc_fabsf};
hypotf :: proc{libc_hypotf};
powf :: proc{libc_powf};
sqrtf :: proc{libc_sqrtf};
cbrtf :: proc{libc_cbrtf}
fabsf :: proc{libc_fabsf}
hypotf :: proc{libc_hypotf}
powf :: proc{libc_powf}
sqrtf :: proc{libc_sqrtf}
erff :: proc{libc_erff};
erfcf :: proc{libc_erfcf};
lgammaf :: proc{libc_lgammaf};
tgammaf :: proc{libc_tgammaf};
erff :: proc{libc_erff}
erfcf :: proc{libc_erfcf}
lgammaf :: proc{libc_lgammaf}
tgammaf :: proc{libc_tgammaf}
ceilf :: proc{libc_ceilf};
floorf :: proc{libc_floorf};
nearbyintf :: proc{libc_nearbyintf};
rintf :: proc{libc_rintf};
lrintf :: proc{libc_lrintf};
llrintf :: proc{libc_llrintf};
roundf :: proc{libc_roundf};
lroundf :: proc{libc_lroundf};
llroundf :: proc{libc_llroundf};
truncf :: proc{libc_truncf};
ceilf :: proc{libc_ceilf}
floorf :: proc{libc_floorf}
nearbyintf :: proc{libc_nearbyintf}
rintf :: proc{libc_rintf}
lrintf :: proc{libc_lrintf}
llrintf :: proc{libc_llrintf}
roundf :: proc{libc_roundf}
lroundf :: proc{libc_lroundf}
llroundf :: proc{libc_llroundf}
truncf :: proc{libc_truncf}
fmodf :: proc{libc_fmodf};
remainderf :: proc{libc_remainderf};
remquof :: proc{libc_remquof};
fmodf :: proc{libc_fmodf}
remainderf :: proc{libc_remainderf}
remquof :: proc{libc_remquof}
copysignf :: proc{libc_copysignf};
nextafterf :: proc{libc_nextafterf};
copysignf :: proc{libc_copysignf}
nextafterf :: proc{libc_nextafterf}
fdimf :: proc{libc_fdimf};
fmaxf :: proc{libc_fmaxf};
fminf :: proc{libc_fminf};
fmaf :: proc{libc_fmaf};
fdimf :: proc{libc_fdimf}
fmaxf :: proc{libc_fmaxf}
fminf :: proc{libc_fminf}
fmaf :: proc{libc_fmaf}
// These two functions are special and not made type generic in tgmath.h since
// they only differ by their return type.
nan :: proc{libc_nan};
nanf :: proc{libc_nanf};
nan :: proc{libc_nan}
nanf :: proc{libc_nanf}

View File

@@ -31,7 +31,7 @@ when ODIN_OS == "windows" {
// the RDX register will contain zero and correctly set the flag to disable
// stack unwinding.
@(link_name="_setjmp")
setjmp :: proc(env: ^jmp_buf, hack: rawptr = nil) -> int ---;
setjmp :: proc(env: ^jmp_buf, hack: rawptr = nil) -> int ---
}
} else {
@(default_calling_convention="c")
@@ -42,14 +42,14 @@ when ODIN_OS == "windows" {
// necessarily export a symbol named setjmp but rather _setjmp in the case
// of musl, glibc, BSD libc, and msvcrt.
@(link_name="_setjmp")
setjmp :: proc(env: ^jmp_buf) -> int ---;
setjmp :: proc(env: ^jmp_buf) -> int ---
}
}
@(default_calling_convention="c")
foreign libc {
// 7.13.2 Restore calling environment
longjmp :: proc(env: ^jmp_buf, val: int) -> ! ---;
longjmp :: proc(env: ^jmp_buf, val: int) -> ! ---
}
// The C99 Rationale describes jmp_buf as being an array type for backward
@@ -62,4 +62,4 @@ foreign libc {
// strictly conformant C implementation is 16 on the platforms we care about.
// The choice of 4096 bytes for storage of this type is more than enough on all
// relevant platforms.
jmp_buf :: struct #align 16 { _: [4096]char, };
jmp_buf :: struct #align 16 { _: [4096]char, }

View File

@@ -8,36 +8,36 @@ when ODIN_OS == "windows" {
foreign import libc "system:c"
}
sig_atomic_t :: distinct atomic_int;
sig_atomic_t :: distinct atomic_int
@(default_calling_convention="c")
foreign libc {
signal :: proc(sig: int, func: proc "c" (int)) -> proc "c" (int) ---;
raise :: proc(sig: int) -> int ---;
signal :: proc(sig: int, func: proc "c" (int)) -> proc "c" (int) ---
raise :: proc(sig: int) -> int ---
}
when ODIN_OS == "windows" {
SIG_ERR :: rawptr(~uintptr(0));
SIG_DFL :: rawptr(uintptr(0));
SIG_IGN :: rawptr(uintptr(1));
SIG_ERR :: rawptr(~uintptr(0))
SIG_DFL :: rawptr(uintptr(0))
SIG_IGN :: rawptr(uintptr(1))
SIGABRT :: 22;
SIGFPE :: 8;
SIGILL :: 4;
SIGINT :: 2;
SIGSEGV :: 11;
SIGTERM :: 15;
SIGABRT :: 22
SIGFPE :: 8
SIGILL :: 4
SIGINT :: 2
SIGSEGV :: 11
SIGTERM :: 15
}
when ODIN_OS == "linux" || ODIN_OS == "freebsd" || ODIN_OS == "darwin" {
SIG_ERR :: rawptr(~uintptr(0));
SIG_DFL :: rawptr(uintptr(0));
SIG_IGN :: rawptr(uintptr(1));
SIG_ERR :: rawptr(~uintptr(0))
SIG_DFL :: rawptr(uintptr(0))
SIG_IGN :: rawptr(uintptr(1))
SIGABRT :: 6;
SIGFPE :: 8;
SIGILL :: 4;
SIGINT :: 2;
SIGSEGV :: 11;
SIGTERM :: 15;
SIGABRT :: 6
SIGFPE :: 8
SIGILL :: 4
SIGINT :: 2
SIGSEGV :: 11
SIGTERM :: 15
}

View File

@@ -9,9 +9,9 @@ import "core:mem"
@(private="file")
@(default_calling_convention="none")
foreign _ {
@(link_name="llvm.va_start") _va_start :: proc(arglist: ^i8) ---;
@(link_name="llvm.va_end") _va_end :: proc(arglist: ^i8) ---;
@(link_name="llvm.va_copy") _va_copy :: proc(dst, src: ^i8) ---;
@(link_name="llvm.va_start") _va_start :: proc(arglist: ^i8) ---
@(link_name="llvm.va_end") _va_end :: proc(arglist: ^i8) ---
@(link_name="llvm.va_copy") _va_copy :: proc(dst, src: ^i8) ---
}
// Since there are no types in C with an alignment larger than that of
@@ -22,18 +22,18 @@ foreign _ {
// relevant platforms.
va_list :: struct #align 16 {
_: [4096]u8,
};
}
va_start :: #force_inline proc(ap: ^va_list, _: any) {
_va_start(cast(^i8)ap);
_va_start(cast(^i8)ap)
}
va_end :: #force_inline proc(ap: ^va_list) {
_va_end(cast(^i8)ap);
_va_end(cast(^i8)ap)
}
va_copy :: #force_inline proc(dst, src: ^va_list) {
_va_copy(cast(^i8)dst, cast(^i8)src);
_va_copy(cast(^i8)dst, cast(^i8)src)
}
// We cannot provide va_arg as there is no way to create "C" style procedures

View File

@@ -4,16 +4,16 @@ package libc
import "core:intrinsics"
ATOMIC_BOOL_LOCK_FREE :: true;
ATOMIC_CHAR_LOCK_FREE :: true;
ATOMIC_CHAR16_T_LOCK_FREE :: true;
ATOMIC_CHAR32_T_LOCK_FREE :: true;
ATOMIC_WCHAR_T_LOCK_FREE :: true;
ATOMIC_SHORT_LOCK_FREE :: true;
ATOMIC_INT_LOCK_FREE :: true;
ATOMIC_LONG_LOCK_FREE :: true;
ATOMIC_LLONG_LOCK_FREE :: true;
ATOMIC_POINTER_LOCK_FREE :: true;
ATOMIC_BOOL_LOCK_FREE :: true
ATOMIC_CHAR_LOCK_FREE :: true
ATOMIC_CHAR16_T_LOCK_FREE :: true
ATOMIC_CHAR32_T_LOCK_FREE :: true
ATOMIC_WCHAR_T_LOCK_FREE :: true
ATOMIC_SHORT_LOCK_FREE :: true
ATOMIC_INT_LOCK_FREE :: true
ATOMIC_LONG_LOCK_FREE :: true
ATOMIC_LLONG_LOCK_FREE :: true
ATOMIC_POINTER_LOCK_FREE :: true
// 7.17.3 Order and consistency
memory_order :: enum int {
@@ -25,152 +25,152 @@ memory_order :: enum int {
seq_cst,
}
memory_order_relaxed :: memory_order.relaxed;
memory_order_consume :: memory_order.consume;
memory_order_acquire :: memory_order.acquire;
memory_order_release :: memory_order.release;
memory_order_acq_rel :: memory_order.acq_rel;
memory_order_seq_cst :: memory_order.seq_cst;
memory_order_relaxed :: memory_order.relaxed
memory_order_consume :: memory_order.consume
memory_order_acquire :: memory_order.acquire
memory_order_release :: memory_order.release
memory_order_acq_rel :: memory_order.acq_rel
memory_order_seq_cst :: memory_order.seq_cst
// 7.17.2 Initialization
ATOMIC_VAR_INIT :: #force_inline proc(value: $T) -> T {
return value;
return value
}
atomic_init :: #force_inline proc(obj: ^$T, value: T) {
intrinsics.atomic_store(obj, value);
intrinsics.atomic_store(obj, value)
}
kill_dependency :: #force_inline proc(value: $T) -> T {
return value;
return value
}
// 7.17.4 Fences
atomic_thread_fence :: #force_inline proc(order: memory_order) {
switch (order) {
case .relaxed:
return;
return
case .consume:
intrinsics.atomic_fence_acq();
intrinsics.atomic_fence_acq()
case .acquire:
intrinsics.atomic_fence_acq();
intrinsics.atomic_fence_acq()
case .release:
intrinsics.atomic_fence_rel();
intrinsics.atomic_fence_rel()
case .acq_rel:
intrinsics.atomic_fence_acqrel();
intrinsics.atomic_fence_acqrel()
case .seq_cst:
intrinsics.atomic_fence_acqrel();
intrinsics.atomic_fence_acqrel()
}
}
atomic_signal_fence :: #force_inline proc(order: memory_order) {
atomic_thread_fence(order);
atomic_thread_fence(order)
}
// 7.17.5 Lock-free property
atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool {
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T));
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T))
}
// 7.17.6 Atomic integer types
atomic_bool :: distinct bool;
atomic_char :: distinct char;
atomic_schar :: distinct char;
atomic_uchar :: distinct uchar;
atomic_short :: distinct short;
atomic_ushort :: distinct ushort;
atomic_int :: distinct int;
atomic_uint :: distinct uint;
atomic_long :: distinct long;
atomic_ulong :: distinct ulong;
atomic_llong :: distinct longlong;
atomic_ullong :: distinct ulonglong;
atomic_char16_t :: distinct char16_t;
atomic_char32_t :: distinct char32_t;
atomic_wchar_t :: distinct wchar_t;
atomic_int_least8_t :: distinct int_least8_t;
atomic_uint_least8_t :: distinct uint_least8_t;
atomic_int_least16_t :: distinct int_least16_t;
atomic_uint_least16_t :: distinct uint_least16_t;
atomic_int_least32_t :: distinct int_least32_t;
atomic_uint_least32_t :: distinct uint_least32_t;
atomic_int_least64_t :: distinct int_least64_t;
atomic_uint_least64_t :: distinct uint_least64_t;
atomic_int_fast8_t :: distinct int_fast8_t;
atomic_uint_fast8_t :: distinct uint_fast8_t;
atomic_int_fast16_t :: distinct int_fast16_t;
atomic_uint_fast16_t :: distinct uint_fast16_t;
atomic_int_fast32_t :: distinct int_fast32_t;
atomic_uint_fast32_t :: distinct uint_fast32_t;
atomic_int_fast64_t :: distinct int_fast64_t;
atomic_uint_fast64_t :: distinct uint_fast64_t;
atomic_intptr_t :: distinct intptr_t;
atomic_uintptr_t :: distinct uintptr_t;
atomic_size_t :: distinct size_t;
atomic_ptrdiff_t :: distinct ptrdiff_t;
atomic_intmax_t :: distinct intmax_t;
atomic_uintmax_t :: distinct uintmax_t;
atomic_bool :: distinct bool
atomic_char :: distinct char
atomic_schar :: distinct char
atomic_uchar :: distinct uchar
atomic_short :: distinct short
atomic_ushort :: distinct ushort
atomic_int :: distinct int
atomic_uint :: distinct uint
atomic_long :: distinct long
atomic_ulong :: distinct ulong
atomic_llong :: distinct longlong
atomic_ullong :: distinct ulonglong
atomic_char16_t :: distinct char16_t
atomic_char32_t :: distinct char32_t
atomic_wchar_t :: distinct wchar_t
atomic_int_least8_t :: distinct int_least8_t
atomic_uint_least8_t :: distinct uint_least8_t
atomic_int_least16_t :: distinct int_least16_t
atomic_uint_least16_t :: distinct uint_least16_t
atomic_int_least32_t :: distinct int_least32_t
atomic_uint_least32_t :: distinct uint_least32_t
atomic_int_least64_t :: distinct int_least64_t
atomic_uint_least64_t :: distinct uint_least64_t
atomic_int_fast8_t :: distinct int_fast8_t
atomic_uint_fast8_t :: distinct uint_fast8_t
atomic_int_fast16_t :: distinct int_fast16_t
atomic_uint_fast16_t :: distinct uint_fast16_t
atomic_int_fast32_t :: distinct int_fast32_t
atomic_uint_fast32_t :: distinct uint_fast32_t
atomic_int_fast64_t :: distinct int_fast64_t
atomic_uint_fast64_t :: distinct uint_fast64_t
atomic_intptr_t :: distinct intptr_t
atomic_uintptr_t :: distinct uintptr_t
atomic_size_t :: distinct size_t
atomic_ptrdiff_t :: distinct ptrdiff_t
atomic_intmax_t :: distinct intmax_t
atomic_uintmax_t :: distinct uintmax_t
// 7.17.7 Operations on atomic types
atomic_store :: #force_inline proc(object: ^$T, desired: T) {
intrinsics.atomic_store(object, desired);
intrinsics.atomic_store(object, desired)
}
atomic_store_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) {
assert(order != .consume);
assert(order != .acquire);
assert(order != .acq_rel);
assert(order != .consume)
assert(order != .acquire)
assert(order != .acq_rel)
#partial switch (order) {
case .relaxed:
intrinsics.atomic_store_relaxed(object, desired);
intrinsics.atomic_store_relaxed(object, desired)
case .release:
intrinsics.atomic_store_rel(object, desired);
intrinsics.atomic_store_rel(object, desired)
case .seq_cst:
intrinsics.atomic_store(object, desired);
intrinsics.atomic_store(object, desired)
}
}
atomic_load :: #force_inline proc(object: ^$T) -> T {
return intrinsics.atomic_load(object);
return intrinsics.atomic_load(object)
}
atomic_load_explicit :: #force_inline proc(object: ^$T, order: memory_order) {
assert(order != .release);
assert(order != .acq_rel);
assert(order != .release)
assert(order != .acq_rel)
#partial switch (order) {
case .relaxed:
return intrinsics.atomic_load_relaxed(object);
return intrinsics.atomic_load_relaxed(object)
case .consume:
return intrinsics.atomic_load_acq(object);
return intrinsics.atomic_load_acq(object)
case .acquire:
return intrinsics.atomic_load_acq(object);
return intrinsics.atomic_load_acq(object)
case .seq_cst:
return intrinsics.atomic_load(object);
return intrinsics.atomic_load(object)
}
}
atomic_exchange :: #force_inline proc(object: ^$T, desired: T) -> T {
return intrinsics.atomic_xchg(object, desired);
return intrinsics.atomic_xchg(object, desired)
}
atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_xchg_relaxed(object, desired);
return intrinsics.atomic_xchg_relaxed(object, desired)
case .consume:
return intrinsics.atomic_xchg_acq(object, desired);
return intrinsics.atomic_xchg_acq(object, desired)
case .acquire:
return intrinsics.atomic_xchg_acq(object, desired);
return intrinsics.atomic_xchg_acq(object, desired)
case .release:
return intrinsics.atomic_xchg_rel(object, desired);
return intrinsics.atomic_xchg_rel(object, desired)
case .acq_rel:
return intrinsics.atomic_xchg_acqrel(object, desired);
return intrinsics.atomic_xchg_acqrel(object, desired)
case .seq_cst:
return intrinsics.atomic_xchg(object, desired);
return intrinsics.atomic_xchg(object, desired)
}
return false;
return false
}
// C does not allow failure memory order to be order_release or acq_rel.
@@ -190,227 +190,227 @@ atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: m
// [success = acquire, failure = relaxed] => acq_failrelaxed
// [success = acq_rel, failure = relaxed] => acqrel_failrelaxed
atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) {
value, ok := intrinsics.atomic_cxchg(object, expected^, desired);
if !ok do expected^ = value;
return ok;
value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
if !ok do expected^ = value
return ok
}
atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) {
assert(failure != .release);
assert(failure != .acq_rel);
assert(failure != .release)
assert(failure != .acq_rel)
value: T; ok: bool;
value: T; ok: bool
#partial switch (failure) {
case .seq_cst:
assert(success != .relaxed);
assert(success != .relaxed)
#partial switch (success) {
case .seq_cst:
value, ok := intrinsics.atomic_cxchg(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
case .acquire:
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
case .consume:
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
case .release:
value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired)
case .acq_rel:
value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired)
}
case .relaxed:
assert(success != .release);
assert(success != .release)
#partial switch (success) {
case .relaxed:
value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired)
case .seq_cst:
value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired)
case .acquire:
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
case .consume:
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
case .acq_rel:
value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired)
}
case .consume:
fallthrough;
fallthrough
case .acquire:
assert(success == .seq_cst);
value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired);
assert(success == .seq_cst)
value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired)
}
if !ok do expected^ = value;
return ok;
if !ok do expected^ = value
return ok
}
atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) {
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired);
if !ok do expected^ = value;
return ok;
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
if !ok do expected^ = value
return ok
}
atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) {
assert(failure != .release);
assert(failure != .acq_rel);
assert(failure != .release)
assert(failure != .acq_rel)
value: T; ok: bool;
value: T; ok: bool
#partial switch (failure) {
case .seq_cst:
assert(success != .relaxed);
assert(success != .relaxed)
#partial switch (success) {
case .seq_cst:
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
case .acquire:
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
case .consume:
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
case .release:
value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired)
case .acq_rel:
value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired)
}
case .relaxed:
assert(success != .release);
assert(success != .release)
#partial switch (success) {
case .relaxed:
value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired)
case .seq_cst:
value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired)
case .acquire:
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
case .consume:
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
case .acq_rel:
value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired);
value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired)
}
case .consume:
fallthrough;
fallthrough
case .acquire:
assert(success == .seq_cst);
value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired);
assert(success == .seq_cst)
value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired)
}
if !ok do expected^ = value;
return ok;
if !ok do expected^ = value
return ok
}
// 7.17.7.5 The atomic_fetch and modify generic functions
atomic_fetch_add :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_add(object, operand);
return intrinsics.atomic_add(object, operand)
}
atomic_fetch_add_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_add_relaxed(object, operand);
return intrinsics.atomic_add_relaxed(object, operand)
case .consume:
return intrinsics.atomic_add_acq(object, operand);
return intrinsics.atomic_add_acq(object, operand)
case .acquire:
return intrinsics.atomic_add_acq(object, operand);
return intrinsics.atomic_add_acq(object, operand)
case .release:
return intrinsics.atomic_add_rel(object, operand);
return intrinsics.atomic_add_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_add_acqrel(object, operand);
return intrinsics.atomic_add_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_add(object, operand);
return intrinsics.atomic_add(object, operand)
}
}
atomic_fetch_sub :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_sub(object, operand);
return intrinsics.atomic_sub(object, operand)
}
atomic_fetch_sub_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_sub_relaxed(object, operand);
return intrinsics.atomic_sub_relaxed(object, operand)
case .consume:
return intrinsics.atomic_sub_acq(object, operand);
return intrinsics.atomic_sub_acq(object, operand)
case .acquire:
return intrinsics.atomic_sub_acq(object, operand);
return intrinsics.atomic_sub_acq(object, operand)
case .release:
return intrinsics.atomic_sub_rel(object, operand);
return intrinsics.atomic_sub_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_sub_acqrel(object, operand);
return intrinsics.atomic_sub_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_sub(object, operand);
return intrinsics.atomic_sub(object, operand)
}
}
atomic_fetch_or :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_or(object, operand);
return intrinsics.atomic_or(object, operand)
}
atomic_fetch_or_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_or_relaxed(object, operand);
return intrinsics.atomic_or_relaxed(object, operand)
case .consume:
return intrinsics.atomic_or_acq(object, operand);
return intrinsics.atomic_or_acq(object, operand)
case .acquire:
return intrinsics.atomic_or_acq(object, operand);
return intrinsics.atomic_or_acq(object, operand)
case .release:
return intrinsics.atomic_or_rel(object, operand);
return intrinsics.atomic_or_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_or_acqrel(object, operand);
return intrinsics.atomic_or_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_or(object, operand);
return intrinsics.atomic_or(object, operand)
}
}
atomic_fetch_xor :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_xor(object, operand);
return intrinsics.atomic_xor(object, operand)
}
atomic_fetch_xor_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_xor_relaxed(object, operand);
return intrinsics.atomic_xor_relaxed(object, operand)
case .consume:
return intrinsics.atomic_xor_acq(object, operand);
return intrinsics.atomic_xor_acq(object, operand)
case .acquire:
return intrinsics.atomic_xor_acq(object, operand);
return intrinsics.atomic_xor_acq(object, operand)
case .release:
return intrinsics.atomic_xor_rel(object, operand);
return intrinsics.atomic_xor_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_xor_acqrel(object, operand);
return intrinsics.atomic_xor_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_xor(object, operand);
return intrinsics.atomic_xor(object, operand)
}
}
atomic_fetch_and :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_and(object, operand);
return intrinsics.atomic_and(object, operand)
}
atomic_fetch_and_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_and_relaxed(object, operand);
return intrinsics.atomic_and_relaxed(object, operand)
case .consume:
return intrinsics.atomic_and_acq(object, operand);
return intrinsics.atomic_and_acq(object, operand)
case .acquire:
return intrinsics.atomic_and_acq(object, operand);
return intrinsics.atomic_and_acq(object, operand)
case .release:
return intrinsics.atomic_and_rel(object, operand);
return intrinsics.atomic_and_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_and_acqrel(object, operand);
return intrinsics.atomic_and_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_and(object, operand);
return intrinsics.atomic_and(object, operand)
}
}
// 7.17.8 Atomic flag type and operations
atomic_flag :: distinct atomic_bool;
atomic_flag :: distinct atomic_bool
atomic_flag_test_and_set :: #force_inline proc(flag: ^atomic_flag) -> bool {
return bool(atomic_exchange(flag, atomic_flag(true)));
return bool(atomic_exchange(flag, atomic_flag(true)))
}
atomic_flag_test_and_set_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) -> bool {
return bool(atomic_exchange_explicit(flag, atomic_flag(true), order));
return bool(atomic_exchange_explicit(flag, atomic_flag(true), order))
}
atomic_flag_clear :: #force_inline proc(flag: ^atomic_flag) {
atomic_store(flag, atomic_flag(false));
atomic_store(flag, atomic_flag(false))
}
atomic_flag_clear_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) {
atomic_store_explicit(flag, atomic_flag(false), order);
atomic_store_explicit(flag, atomic_flag(false), order)
}

View File

@@ -8,128 +8,128 @@ when ODIN_OS == "windows" {
// 7.21 Input/output
FILE :: struct {};
FILE :: struct {}
// MSVCRT compatible.
when ODIN_OS == "windows" {
_IOFBF :: 0x0000;
_IONBF :: 0x0004;
_IOLBF :: 0x0040;
_IOFBF :: 0x0000
_IONBF :: 0x0004
_IOLBF :: 0x0040
BUFSIZ :: 512;
BUFSIZ :: 512
EOF :: int(-1);
EOF :: int(-1)
FOPEN_MAX :: 20;
FOPEN_MAX :: 20
FILENAME_MAX :: 260;
FILENAME_MAX :: 260
L_tmpnam :: 15; // "\\" + 12 + NUL
L_tmpnam :: 15 // "\\" + 12 + NUL
SEEK_SET :: 0;
SEEK_CUR :: 1;
SEEK_END :: 2;
SEEK_SET :: 0
SEEK_CUR :: 1
SEEK_END :: 2
TMP_MAX :: 32767; // SHRT_MAX
TMP_MAX :: 32767 // SHRT_MAX
fpos_t :: distinct i64;
fpos_t :: distinct i64
@(private="file")
@(default_calling_convention="c")
foreign libc {
__acrt_iob_func :: proc (index: uint) -> ^FILE ---;
__acrt_iob_func :: proc (index: uint) -> ^FILE ---
}
stdin := __acrt_iob_func(0);
stdout := __acrt_iob_func(1);
stderr := __acrt_iob_func(2);
stdin := __acrt_iob_func(0)
stdout := __acrt_iob_func(1)
stderr := __acrt_iob_func(2)
}
// GLIBC and MUSL compatible.
when ODIN_OS == "linux" {
fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, };
fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, }
_IOFBF :: 0;
_IOLBF :: 1;
_IONBF :: 2;
_IOFBF :: 0
_IOLBF :: 1
_IONBF :: 2
BUFSIZ :: 1024;
BUFSIZ :: 1024
EOF :: int(-1);
EOF :: int(-1)
FOPEN_MAX :: 1000;
FOPEN_MAX :: 1000
FILENAME_MAX :: 4096;
FILENAME_MAX :: 4096
L_tmpnam :: 20;
L_tmpnam :: 20
SEEK_SET :: 0;
SEEK_CUR :: 1;
SEEK_END :: 2;
SEEK_SET :: 0
SEEK_CUR :: 1
SEEK_END :: 2
TMP_MAX :: 10000;
TMP_MAX :: 10000
foreign libc {
stderr: ^FILE;
stdin: ^FILE;
stdout: ^FILE;
stderr: ^FILE
stdin: ^FILE
stdout: ^FILE
}
}
@(default_calling_convention="c")
foreign libc {
// 7.21.4 Operations on files
remove :: proc(filename: cstring) -> int ---;
rename :: proc(old, new: cstring) -> int ---;
tmpfile :: proc() -> ^FILE ---;
tmpnam :: proc(s: ^char) -> ^char ---;
remove :: proc(filename: cstring) -> int ---
rename :: proc(old, new: cstring) -> int ---
tmpfile :: proc() -> ^FILE ---
tmpnam :: proc(s: ^char) -> ^char ---
// 7.21.5 File access functions
fclose :: proc(stream: ^FILE) -> int ---;
fflush :: proc(stream: ^FILE) -> int ---;
fopen :: proc(filename, mode: cstring) -> ^FILE ---;
freopen :: proc(filename, mode: cstring, stream: ^FILE) -> ^FILE ---;
setbuf :: proc(stream: ^FILE, buf: ^char) ---;
setvbuf :: proc(stream: ^FILE, buf: ^char, mode: int, size: size_t) -> int ---;
fclose :: proc(stream: ^FILE) -> int ---
fflush :: proc(stream: ^FILE) -> int ---
fopen :: proc(filename, mode: cstring) -> ^FILE ---
freopen :: proc(filename, mode: cstring, stream: ^FILE) -> ^FILE ---
setbuf :: proc(stream: ^FILE, buf: ^char) ---
setvbuf :: proc(stream: ^FILE, buf: ^char, mode: int, size: size_t) -> int ---
// 7.21.6 Formatted input/output functions
fprintf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---;
fscanf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---;
printf :: proc(format: cstring, #c_vararg args: ..any) -> int ---;
scanf :: proc(format: cstring, #c_vararg args: ..any) -> int ---;
snprintf :: proc(s: ^char, format: cstring, #c_vararg args: ..any) -> int ---;
sscanf :: proc(s, format: cstring, #c_vararg args: ..any) -> int ---;
vfprintf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---;
vfscanf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---;
vprintf :: proc(format: cstring, arg: ^va_list) -> int ---;
vscanf :: proc(format: cstring, arg: ^va_list) -> int ---;
vsnprintf :: proc(s: ^char, n: size_t, format: cstring, arg: ^va_list) -> int ---;
vsprintf :: proc(s: ^char, format: cstring, arg: ^va_list) -> int ---;
vsscanf :: proc(s, format: cstring, arg: ^va_list) -> int ---;
fprintf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---
fscanf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---
printf :: proc(format: cstring, #c_vararg args: ..any) -> int ---
scanf :: proc(format: cstring, #c_vararg args: ..any) -> int ---
snprintf :: proc(s: ^char, format: cstring, #c_vararg args: ..any) -> int ---
sscanf :: proc(s, format: cstring, #c_vararg args: ..any) -> int ---
vfprintf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---
vfscanf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---
vprintf :: proc(format: cstring, arg: ^va_list) -> int ---
vscanf :: proc(format: cstring, arg: ^va_list) -> int ---
vsnprintf :: proc(s: ^char, n: size_t, format: cstring, arg: ^va_list) -> int ---
vsprintf :: proc(s: ^char, format: cstring, arg: ^va_list) -> int ---
vsscanf :: proc(s, format: cstring, arg: ^va_list) -> int ---
// 7.21.7 Character input/output functions
fgetc :: proc(stream: ^FILE) -> int ---;
fgets :: proc(s: ^char, n: int, stream: ^FILE) -> ^char ---;
fputc :: proc(s: cstring, stream: ^FILE) -> int ---;
getc :: proc(stream: ^FILE) -> int ---;
getchar :: proc() -> int ---;
putc :: proc(c: int, stream: ^FILE) -> int ---;
putchar :: proc() -> int ---;
puts :: proc(s: cstring) -> int ---;
ungetc :: proc(c: int, stream: ^FILE) -> int ---;
fread :: proc(ptr: rawptr, size: size_t, stream: ^FILE) -> size_t ---;
fwrite :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t ---;
fgetc :: proc(stream: ^FILE) -> int ---
fgets :: proc(s: ^char, n: int, stream: ^FILE) -> ^char ---
fputc :: proc(s: cstring, stream: ^FILE) -> int ---
getc :: proc(stream: ^FILE) -> int ---
getchar :: proc() -> int ---
putc :: proc(c: int, stream: ^FILE) -> int ---
putchar :: proc() -> int ---
puts :: proc(s: cstring) -> int ---
ungetc :: proc(c: int, stream: ^FILE) -> int ---
fread :: proc(ptr: rawptr, size: size_t, stream: ^FILE) -> size_t ---
fwrite :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t ---
// 7.21.9 File positioning functions
fgetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---;
fseek :: proc(stream: ^FILE, offset: long, whence: int) -> int ---;
fsetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---;
ftell :: proc(stream: ^FILE) -> long ---;
rewind :: proc(stream: ^FILE) ---;
fgetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---
fseek :: proc(stream: ^FILE, offset: long, whence: int) -> int ---
fsetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---
ftell :: proc(stream: ^FILE) -> long ---
rewind :: proc(stream: ^FILE) ---
// 7.21.10 Error-handling functions
clearerr :: proc(stream: ^FILE) ---;
feof :: proc(stream: ^FILE) -> int ---;
ferror :: proc(stream: ^FILE) -> int ---;
perror :: proc(s: cstring) ---;
clearerr :: proc(stream: ^FILE) ---
feof :: proc(stream: ^FILE) -> int ---
ferror :: proc(stream: ^FILE) -> int ---
perror :: proc(s: cstring) ---
}

View File

@@ -9,31 +9,31 @@ when ODIN_OS == "windows" {
}
when ODIN_OS == "windows" {
RAND_MAX :: 0x7fff;
RAND_MAX :: 0x7fff
@(private="file")
@(default_calling_convention="c")
foreign libc {
___mb_cur_max_func :: proc() -> int ---;
___mb_cur_max_func :: proc() -> int ---
}
MB_CUR_MAX :: #force_inline proc() -> size_t {
return size_t(___mb_cur_max_func());
return size_t(___mb_cur_max_func())
}
}
when ODIN_OS == "linux" {
RAND_MAX :: 0x7fffffff;
RAND_MAX :: 0x7fffffff
// GLIBC and MUSL only
@(private="file")
@(default_calling_convention="c")
foreign libc {
__ctype_get_mb_cur_max :: proc() -> size_t ---;
__ctype_get_mb_cur_max :: proc() -> size_t ---
}
MB_CUR_MAX :: #force_inline proc() -> size_t {
return __ctype_get_mb_cur_max();
return __ctype_get_mb_cur_max()
}
}
@@ -41,8 +41,8 @@ when ODIN_OS == "linux" {
// to use any two distinct values it wants to indicate success or failure.
// However, nobody actually does and everyone appears to have agreed upon these
// values.
EXIT_SUCCESS :: 0;
EXIT_FAILURE :: 1;
EXIT_SUCCESS :: 0
EXIT_FAILURE :: 1
// C does not declare which order 'quot' and 'rem' should be for the divide
// structures. An implementation could put 'rem' first. However, nobody actually
@@ -54,56 +54,56 @@ lldiv_t :: struct { quot, rem: longlong, }
@(default_calling_convention="c")
foreign libc {
// 7.22.1 Numeric conversion functions
atof :: proc(nptr: cstring) -> double ---;
atoi :: proc(nptr: cstring) -> int ---;
atol :: proc(nptr: cstring) -> long ---;
atoll :: proc(nptr: cstring) -> longlong ---;
strtod :: proc(nptr: cstring, endptr: ^^char) -> double ---;
strtof :: proc(nptr: cstring, endptr: ^^char) -> float ---;
strtol :: proc(nptr: cstring, endptr: ^^char, base: int) -> long ---;
strtoll :: proc(nptr: cstring, endptr: ^^char, base: int) -> longlong ---;
strtoul :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulong ---;
strtoull :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulonglong ---;
atof :: proc(nptr: cstring) -> double ---
atoi :: proc(nptr: cstring) -> int ---
atol :: proc(nptr: cstring) -> long ---
atoll :: proc(nptr: cstring) -> longlong ---
strtod :: proc(nptr: cstring, endptr: ^^char) -> double ---
strtof :: proc(nptr: cstring, endptr: ^^char) -> float ---
strtol :: proc(nptr: cstring, endptr: ^^char, base: int) -> long ---
strtoll :: proc(nptr: cstring, endptr: ^^char, base: int) -> longlong ---
strtoul :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulong ---
strtoull :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulonglong ---
// 7.22.2 Pseudo-random sequence generation functions
rand :: proc() -> int ---;
srand :: proc(seed: uint) ---;
rand :: proc() -> int ---
srand :: proc(seed: uint) ---
// 7.22.3 Memory management functions
aligned_alloc :: proc(aligment, size: size_t) -> rawptr ---;
calloc :: proc(nmemb, size: size_t) -> rawptr ---;
free :: proc(ptr: rawptr) ---;
malloc :: proc(size: size_t) -> rawptr ---;
realloc :: proc(ptr: rawptr, size: size_t) -> rawptr ---;
aligned_alloc :: proc(aligment, size: size_t) -> rawptr ---
calloc :: proc(nmemb, size: size_t) -> rawptr ---
free :: proc(ptr: rawptr) ---
malloc :: proc(size: size_t) -> rawptr ---
realloc :: proc(ptr: rawptr, size: size_t) -> rawptr ---
// 7.22.4 Communication with the environment
abort :: proc() -> ! ---;
atexit :: proc(func: proc "c" ()) -> int ---;
at_quick_exit :: proc(func: proc "c" ()) -> int ---;
exit :: proc(status: int) -> ! ---;
_Exit :: proc(status: int) -> ! ---;
getenv :: proc(name: cstring) -> ^char ---;
quick_exit :: proc(status: int) -> ! ---;
system :: proc(cmd: cstring) -> int ---;
abort :: proc() -> ! ---
atexit :: proc(func: proc "c" ()) -> int ---
at_quick_exit :: proc(func: proc "c" ()) -> int ---
exit :: proc(status: int) -> ! ---
_Exit :: proc(status: int) -> ! ---
getenv :: proc(name: cstring) -> ^char ---
quick_exit :: proc(status: int) -> ! ---
system :: proc(cmd: cstring) -> int ---
// 7.22.5 Searching and sorting utilities
bsearch :: proc(key, base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) -> rawptr ---;
qsort :: proc(base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) ---;
bsearch :: proc(key, base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) -> rawptr ---
qsort :: proc(base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) ---
// 7.22.6 Integer arithmetic functions
abs :: proc(j: int) -> int ---;
labs :: proc(j: long) -> long ---;
llabs :: proc(j: longlong) -> longlong ---;
div :: proc(numer, denom: int) -> div_t ---;
ldiv :: proc(numer, denom: long) -> ldiv_t ---;
lldiv :: proc(numer, denom: longlong) -> lldiv_t ---;
abs :: proc(j: int) -> int ---
labs :: proc(j: long) -> long ---
llabs :: proc(j: longlong) -> longlong ---
div :: proc(numer, denom: int) -> div_t ---
ldiv :: proc(numer, denom: long) -> ldiv_t ---
lldiv :: proc(numer, denom: longlong) -> lldiv_t ---
// 7.22.7 Multibyte/wide character conversion functions
mblen :: proc(s: cstring, n: size_t) -> int ---;
mbtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t) -> int ---;
wctomb :: proc(s: ^char, wc: wchar_t) -> int ---;
mblen :: proc(s: cstring, n: size_t) -> int ---
mbtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t) -> int ---
wctomb :: proc(s: ^char, wc: wchar_t) -> int ---
// 7.22.8 Multibyte/wide string conversion functions
mbstowcs :: proc(pwcs: ^wchar_t, s: cstring, n: size_t) -> size_t ---;
wcstombs :: proc(s: ^char, pwcs: ^wchar_t, n: size_t) -> size_t ---;
mbstowcs :: proc(pwcs: ^wchar_t, s: cstring, n: size_t) -> size_t ---
wcstombs :: proc(s: ^char, pwcs: ^wchar_t, n: size_t) -> size_t ---
}

View File

@@ -11,33 +11,33 @@ when ODIN_OS == "windows" {
foreign libc {
// 7.24.2 Copying functions
memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---;
memmove :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---;
strcpy :: proc(s1: ^char, s2: cstring) -> ^char ---;
strncpy :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---;
memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---
memmove :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---
strcpy :: proc(s1: ^char, s2: cstring) -> ^char ---
strncpy :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---
// 7.24.3 Concatenation functions
strcat :: proc(s1: ^char, s2: cstring) -> ^char ---;
strncat :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---;
strcat :: proc(s1: ^char, s2: cstring) -> ^char ---
strncat :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---
// 7.24.4 Comparison functions
memcmp :: proc(s1, s2: rawptr, n: size_t) -> int ---;
strcmp :: proc(s1, s2: cstring) -> int ---;
strcoll :: proc(s1, s2: cstring) -> int ---;
strncmp :: proc(s1, s2: cstring, n: size_t) -> int ---;
strxfrm :: proc(s1: ^char, s2: cstring, n: size_t) -> size_t ---;
memcmp :: proc(s1, s2: rawptr, n: size_t) -> int ---
strcmp :: proc(s1, s2: cstring) -> int ---
strcoll :: proc(s1, s2: cstring) -> int ---
strncmp :: proc(s1, s2: cstring, n: size_t) -> int ---
strxfrm :: proc(s1: ^char, s2: cstring, n: size_t) -> size_t ---
// 7.24.5 Search functions
memchr :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---;
strchr :: proc(s: cstring, c: int) -> ^char ---;
strcspn :: proc(s1, s2: cstring) -> size_t ---;
strpbrk :: proc(s1, s2: cstring) -> ^char ---;
strrchr :: proc(s: ^char, c: int) -> ^char ---;
strcpn :: proc(s1, s2: cstring) -> ^char ---;
strtok :: proc(s1: ^char, s2: cstring) -> ^char ---;
memchr :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---
strchr :: proc(s: cstring, c: int) -> ^char ---
strcspn :: proc(s1, s2: cstring) -> size_t ---
strpbrk :: proc(s1, s2: cstring) -> ^char ---
strrchr :: proc(s: ^char, c: int) -> ^char ---
strcpn :: proc(s1, s2: cstring) -> ^char ---
strtok :: proc(s1: ^char, s2: cstring) -> ^char ---
// 7.24.6 Miscellaneous functions
memset :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---;
strerror :: proc(errnum: int) -> ^char ---;
strlen :: proc(s: cstring) -> size_t ---;
memset :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---
strerror :: proc(errnum: int) -> ^char ---
strlen :: proc(s: cstring) -> size_t ---
}

View File

@@ -2,8 +2,8 @@ package libc
// 7.26 Threads
thrd_start_t :: proc "c" (rawptr) -> int;
tss_dtor_t :: proc "c" (rawptr);
thrd_start_t :: proc "c" (rawptr) -> int
tss_dtor_t :: proc "c" (rawptr)
when ODIN_OS == "windows" {
foreign import libc {
@@ -11,23 +11,23 @@ when ODIN_OS == "windows" {
"system:msvcprt.lib"
}
thrd_success :: 0; // _Thrd_success
thrd_nomem :: 1; // _Thrd_nomem
thrd_timedout :: 2; // _Thrd_timedout
thrd_busy :: 3; // _Thrd_busy
thrd_error :: 4; // _Thrd_error
thrd_success :: 0 // _Thrd_success
thrd_nomem :: 1 // _Thrd_nomem
thrd_timedout :: 2 // _Thrd_timedout
thrd_busy :: 3 // _Thrd_busy
thrd_error :: 4 // _Thrd_error
mtx_plain :: 1; // _Mtx_plain
mtx_recursive :: 0x100; // _Mtx_recursive
mtx_timed :: 4; // _Mtx_timed
mtx_plain :: 1 // _Mtx_plain
mtx_recursive :: 0x100 // _Mtx_recursive
mtx_timed :: 4 // _Mtx_timed
TSS_DTOR_ITERATIONS :: 4; // _TSS_DTOR_ITERATIONS_IMP
TSS_DTOR_ITERATIONS :: 4 // _TSS_DTOR_ITERATIONS_IMP
once_flag :: distinct i8; // _Once_flag_imp_t
once_flag :: distinct i8 // _Once_flag_imp_t
thrd_t :: struct { _: rawptr, _: uint, } // _Thrd_t
tss_t :: distinct int; // _Tss_imp_t
cnd_t :: distinct rawptr; // _Cnd_imp_t
mtx_t :: distinct rawptr; // _Mtx_imp_t
tss_t :: distinct int // _Tss_imp_t
cnd_t :: distinct rawptr // _Cnd_imp_t
mtx_t :: distinct rawptr // _Mtx_imp_t
// MSVCRT does not expose the C11 symbol names as what they are in C11
// because they held off implementing <threads.h> and C11 support for so
@@ -38,38 +38,38 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c")
foreign libc {
// 7.26.2 Initialization functions
@(link_name="_Call_once") call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---;
@(link_name="_Call_once") call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---
// 7.26.3 Condition variable functions
@(link_name="_Cnd_broadcast") cnd_broadcast :: proc(cond: ^cnd_t) -> int ---;
@(link_name="_Cnd_destroy") cnd_destroy :: proc(cond: ^cnd_t) ---;
@(link_name="_Cnd_init") cnd_init :: proc(cond: ^cnd_t) -> int ---;
@(link_name="_Cnd_signal") cnd_signal :: proc(cond: ^cnd_t) -> int ---;
@(link_name="_Cnd_timedwait") cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---;
@(link_name="_Cnd_wait") cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---;
@(link_name="_Cnd_broadcast") cnd_broadcast :: proc(cond: ^cnd_t) -> int ---
@(link_name="_Cnd_destroy") cnd_destroy :: proc(cond: ^cnd_t) ---
@(link_name="_Cnd_init") cnd_init :: proc(cond: ^cnd_t) -> int ---
@(link_name="_Cnd_signal") cnd_signal :: proc(cond: ^cnd_t) -> int ---
@(link_name="_Cnd_timedwait") cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---
@(link_name="_Cnd_wait") cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---
// 7.26.4 Mutex functions
@(link_name="_Mtx_destroy") mtx_destroy :: proc(mtx: ^mtx_t) ---;
@(link_name="_Mtx_init") mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---;
@(link_name="_Mtx_lock") mtx_lock :: proc(mtx: ^mtx_t) -> int ---;
@(link_name="_Mtx_timedlock") mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---;
@(link_name="_Mtx_trylock") mtx_trylock :: proc(mtx: ^mtx_t) -> int ---;
@(link_name="_Mtx_unlock") mtx_unlock :: proc(mtx: ^mtx_t) -> int ---;
@(link_name="_Mtx_destroy") mtx_destroy :: proc(mtx: ^mtx_t) ---
@(link_name="_Mtx_init") mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---
@(link_name="_Mtx_lock") mtx_lock :: proc(mtx: ^mtx_t) -> int ---
@(link_name="_Mtx_timedlock") mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---
@(link_name="_Mtx_trylock") mtx_trylock :: proc(mtx: ^mtx_t) -> int ---
@(link_name="_Mtx_unlock") mtx_unlock :: proc(mtx: ^mtx_t) -> int ---
// 7.26.5 Thread functions
@(link_name="_Thrd_create") thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---;
@(link_name="_Thrd_current") thrd_current :: proc() -> thrd_t ---;
@(link_name="_Thrd_detach") thrd_detach :: proc(thr: thrd_t) -> int ---;
@(link_name="_Thrd_equal") thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---;
@(link_name="_Thrd_exit") thrd_exit :: proc(res: int) -> ! ---;
@(link_name="_Thrd_join") thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---;
@(link_name="_Thrd_sleep") thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---;
@(link_name="_Thrd_yield") thrd_yield :: proc() ---;
@(link_name="_Thrd_create") thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---
@(link_name="_Thrd_current") thrd_current :: proc() -> thrd_t ---
@(link_name="_Thrd_detach") thrd_detach :: proc(thr: thrd_t) -> int ---
@(link_name="_Thrd_equal") thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---
@(link_name="_Thrd_exit") thrd_exit :: proc(res: int) -> ! ---
@(link_name="_Thrd_join") thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---
@(link_name="_Thrd_sleep") thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---
@(link_name="_Thrd_yield") thrd_yield :: proc() ---
// 7.26.6 Thread-specific storage functions
@(link_name="_Tss_create") tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---;
@(link_name="_Tss_delete") tss_delete :: proc(key: tss_t) ---;
@(link_name="_Tss_get") tss_get :: proc(key: tss_t) -> rawptr ---;
@(link_name="_Tss_set") tss_set :: proc(key: tss_t, val: rawptr) -> int ---;
@(link_name="_Tss_create") tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---
@(link_name="_Tss_delete") tss_delete :: proc(key: tss_t) ---
@(link_name="_Tss_get") tss_get :: proc(key: tss_t) -> rawptr ---
@(link_name="_Tss_set") tss_set :: proc(key: tss_t, val: rawptr) -> int ---
}
}
@@ -80,59 +80,59 @@ when ODIN_OS == "linux" {
"system:pthread"
}
thrd_success :: 0;
thrd_busy :: 1;
thrd_error :: 2;
thrd_nomem :: 3;
thrd_timedout :: 4;
thrd_success :: 0
thrd_busy :: 1
thrd_error :: 2
thrd_nomem :: 3
thrd_timedout :: 4
mtx_plain :: 0;
mtx_recursive :: 1;
mtx_timed :: 2;
mtx_plain :: 0
mtx_recursive :: 1
mtx_timed :: 2
TSS_DTOR_ITERATIONS :: 4;
TSS_DTOR_ITERATIONS :: 4
once_flag :: distinct int;
thrd_t :: distinct ulong;
tss_t :: distinct uint;
cnd_t :: struct #raw_union { _: [12]int, _: [12 * size_of(int) / size_of(rawptr)]rawptr, };
mtx_t :: struct #raw_union { _: [10 when size_of(long) == 8 else 6]int, _: [5 when size_of(long) == 8 else 6]rawptr, };
once_flag :: distinct int
thrd_t :: distinct ulong
tss_t :: distinct uint
cnd_t :: struct #raw_union { _: [12]int, _: [12 * size_of(int) / size_of(rawptr)]rawptr, }
mtx_t :: struct #raw_union { _: [10 when size_of(long) == 8 else 6]int, _: [5 when size_of(long) == 8 else 6]rawptr, }
@(default_calling_convention="c")
foreign libc {
// 7.26.2 Initialization functions
call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---;
call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---
// 7.26.3 Condition variable functions
cnd_broadcast :: proc(cond: ^cnd_t) -> int ---;
cnd_destroy :: proc(cond: ^cnd_t) ---;
cnd_init :: proc(cond: ^cnd_t) -> int ---;
cnd_signal :: proc(cond: ^cnd_t) -> int ---;
cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---;
cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---;
cnd_broadcast :: proc(cond: ^cnd_t) -> int ---
cnd_destroy :: proc(cond: ^cnd_t) ---
cnd_init :: proc(cond: ^cnd_t) -> int ---
cnd_signal :: proc(cond: ^cnd_t) -> int ---
cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---
cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---
// 7.26.4 Mutex functions
mtx_destroy :: proc(mtx: ^mtx_t) ---;
mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---;
mtx_lock :: proc(mtx: ^mtx_t) -> int ---;
mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---;
mtx_trylock :: proc(mtx: ^mtx_t) -> int ---;
mtx_unlock :: proc(mtx: ^mtx_t) -> int ---;
mtx_destroy :: proc(mtx: ^mtx_t) ---
mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---
mtx_lock :: proc(mtx: ^mtx_t) -> int ---
mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---
mtx_trylock :: proc(mtx: ^mtx_t) -> int ---
mtx_unlock :: proc(mtx: ^mtx_t) -> int ---
// 7.26.5 Thread functions
thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---;
thrd_current :: proc() -> thrd_t ---;
thrd_detach :: proc(thr: thrd_t) -> int ---;
thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---;
thrd_exit :: proc(res: int) -> ! ---;
thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---;
thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---;
thrd_yield :: proc() ---;
thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---
thrd_current :: proc() -> thrd_t ---
thrd_detach :: proc(thr: thrd_t) -> int ---
thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---
thrd_exit :: proc(res: int) -> ! ---
thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---
thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---
thrd_yield :: proc() ---
// 7.26.6 Thread-specific storage functions
tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---;
tss_delete :: proc(key: tss_t) ---;
tss_get :: proc(key: tss_t) -> rawptr ---;
tss_set :: proc(key: tss_t, val: rawptr) -> int ---;
tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---
tss_delete :: proc(key: tss_t) ---
tss_get :: proc(key: tss_t) -> rawptr ---
tss_set :: proc(key: tss_t, val: rawptr) -> int ---
}
}

View File

@@ -13,25 +13,25 @@ when ODIN_OS == "windows" {
when ODIN_OS == "windows" {
foreign libc {
// 7.27.2 Time manipulation functions
clock :: proc() -> clock_t ---;
@(link_name="_difftime64") difftime :: proc(time1, time2: time_t) -> double ---;
mktime :: proc(timeptr: ^tm) -> time_t ---;
@(link_name="_time64") time :: proc(timer: ^time_t) -> time_t ---;
@(link_name="_timespec64_get") timespec_get :: proc(ts: ^timespec, base: int) -> int ---;
clock :: proc() -> clock_t ---
@(link_name="_difftime64") difftime :: proc(time1, time2: time_t) -> double ---
mktime :: proc(timeptr: ^tm) -> time_t ---
@(link_name="_time64") time :: proc(timer: ^time_t) -> time_t ---
@(link_name="_timespec64_get") timespec_get :: proc(ts: ^timespec, base: int) -> int ---
// 7.27.3 Time conversion functions
asctime :: proc(timeptr: ^tm) -> ^char ---;
@(link_name="_ctime64") ctime :: proc(timer: ^time_t) -> ^char ---;
@(link_name="_gmtime64") gmtime :: proc(timer: ^time_t) -> ^tm ---;
@(link_name="_localtime64") localtime :: proc(timer: ^time_t) -> ^tm ---;
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---;
asctime :: proc(timeptr: ^tm) -> ^char ---
@(link_name="_ctime64") ctime :: proc(timer: ^time_t) -> ^char ---
@(link_name="_gmtime64") gmtime :: proc(timer: ^time_t) -> ^tm ---
@(link_name="_localtime64") localtime :: proc(timer: ^time_t) -> ^tm ---
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---
}
CLOCKS_PER_SEC :: 1000;
TIME_UTC :: 1;
CLOCKS_PER_SEC :: 1000
TIME_UTC :: 1
clock_t :: distinct long;
time_t :: distinct i64;
clock_t :: distinct long
time_t :: distinct i64
timespec :: struct #align 8 {
tv_sec: time_t,
@@ -47,26 +47,26 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" {
@(default_calling_convention="c")
foreign libc {
// 7.27.2 Time manipulation functions
clock :: proc() -> clock_t ---;
difftime :: proc(time1, time2: time_t) -> double ---;
mktime :: proc(timeptr: ^tm) -> time_t ---;
time :: proc(timer: ^time_t) -> time_t ---;
timespec_get :: proc(ts: ^timespec, base: int) -> int ---;
clock :: proc() -> clock_t ---
difftime :: proc(time1, time2: time_t) -> double ---
mktime :: proc(timeptr: ^tm) -> time_t ---
time :: proc(timer: ^time_t) -> time_t ---
timespec_get :: proc(ts: ^timespec, base: int) -> int ---
// 7.27.3 Time conversion functions
asctime :: proc(timeptr: ^tm) -> ^char ---;
ctime :: proc(timer: ^time_t) -> ^char ---;
gmtime :: proc(timer: ^time_t) -> ^tm ---;
localtime :: proc(timer: ^time_t) -> ^tm ---;
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---;
asctime :: proc(timeptr: ^tm) -> ^char ---
ctime :: proc(timer: ^time_t) -> ^char ---
gmtime :: proc(timer: ^time_t) -> ^tm ---
localtime :: proc(timer: ^time_t) -> ^tm ---
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---
}
CLOCKS_PER_SEC :: 1000000;
TIME_UTC :: 1;
CLOCKS_PER_SEC :: 1000000
TIME_UTC :: 1
time_t :: distinct i64;
time_t :: distinct i64
clock_t :: long;
clock_t :: long
timespec :: struct {
tv_sec: time_t,

View File

@@ -2,81 +2,81 @@ package libc
import builtin "core:builtin"
char :: builtin.u8; // assuming -funsigned-char
short :: builtin.i16;
int :: builtin.i32;
long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64;
longlong :: builtin.i64;
char :: builtin.u8 // assuming -funsigned-char
short :: builtin.i16
int :: builtin.i32
long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64
longlong :: builtin.i64
uchar :: builtin.u8;
ushort :: builtin.u16;
uint :: builtin.u32;
ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64;
ulonglong :: builtin.u64;
uchar :: builtin.u8
ushort :: builtin.u16
uint :: builtin.u32
ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64
ulonglong :: builtin.u64
bool :: distinct builtin.b8;
bool :: distinct builtin.b8
size_t :: builtin.uint;
wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32;
size_t :: builtin.uint
wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32
float :: builtin.f32;
double :: builtin.f64;
float :: builtin.f32
double :: builtin.f64
// 7.20.1 Integer types
int8_t :: builtin.i8;
uint8_t :: builtin.u8;
int16_t :: builtin.i16;
uint16_t :: builtin.u16;
int32_t :: builtin.i32;
uint32_t :: builtin.u32;
int64_t :: builtin.i64;
uint64_t :: builtin.u64;
int8_t :: builtin.i8
uint8_t :: builtin.u8
int16_t :: builtin.i16
uint16_t :: builtin.u16
int32_t :: builtin.i32
uint32_t :: builtin.u32
int64_t :: builtin.i64
uint64_t :: builtin.u64
// These are all the same in multiple libc's for multiple architectures.
int_least8_t :: builtin.i8;
uint_least8_t :: builtin.u8;
int_least16_t :: builtin.i16;
uint_least16_t :: builtin.u16;
int_least32_t :: builtin.i32;
uint_least32_t :: builtin.u32;
int_least64_t :: builtin.i64;
uint_least64_t :: builtin.u64;
int_least8_t :: builtin.i8
uint_least8_t :: builtin.u8
int_least16_t :: builtin.i16
uint_least16_t :: builtin.u16
int_least32_t :: builtin.i32
uint_least32_t :: builtin.u32
int_least64_t :: builtin.i64
uint_least64_t :: builtin.u64
// Same on Windows, Linux, and FreeBSD
when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" {
int_fast8_t :: builtin.i8;
uint_fast8_t :: builtin.u8;
int_fast16_t :: builtin.i32;
uint_fast16_t :: builtin.u32;
int_fast32_t :: builtin.i32;
uint_fast32_t :: builtin.u32;
int_fast64_t :: builtin.i64;
uint_fast64_t :: builtin.u64;
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
int_fast64_t :: builtin.i64
uint_fast64_t :: builtin.u64
}
intptr_t :: builtin.int;
uintptr_t :: builtin.uintptr;
ptrdiff_t :: distinct intptr_t;
intptr_t :: builtin.int
uintptr_t :: builtin.uintptr
ptrdiff_t :: distinct intptr_t
intmax_t :: builtin.i64;
uintmax_t :: builtin.u64;
intmax_t :: builtin.i64
uintmax_t :: builtin.u64
// Copy C's rules for type promotion here by forcing the type on the literals.
INT8_MAX :: int(0x7f);
INT16_MAX :: int(0x7fff);
INT32_MAX :: int(0x7fffffff);
INT64_MAX :: longlong(0x7fffffffffffffff);
INT8_MAX :: int(0x7f)
INT16_MAX :: int(0x7fff)
INT32_MAX :: int(0x7fffffff)
INT64_MAX :: longlong(0x7fffffffffffffff)
UINT8_MAX :: int(0xff);
UINT16_MAX :: int(0xffff);
UINT32_MAX :: uint(0xffffffff);
UINT64_MAX :: ulonglong(0xffffffffffffffff);
UINT8_MAX :: int(0xff)
UINT16_MAX :: int(0xffff)
UINT32_MAX :: uint(0xffffffff)
UINT64_MAX :: ulonglong(0xffffffffffffffff)
INT8_MIN :: ~INT8_MAX;
INT16_MIN :: ~INT16_MAX;
INT32_MIN :: ~INT32_MAX;
INT64_MIN :: ~INT64_MAX;
INT8_MIN :: ~INT8_MAX
INT16_MIN :: ~INT16_MAX
INT32_MIN :: ~INT32_MAX
INT64_MIN :: ~INT64_MAX
NULL :: rawptr(uintptr(0));
NULL :: rawptr(uintptr(0))
NDEBUG :: !ODIN_DEBUG;
NDEBUG :: !ODIN_DEBUG

View File

@@ -11,11 +11,11 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c")
foreign libc {
// 7.28.1 Restartable multibyte/wide character conversion functions
mbrtoc16 :: proc(pc16: ^char16_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
c16rtomb :: proc(s: ^char, c16: char16_t, ps: ^mbstate_t) -> size_t ---;
mbrtoc32 :: proc(pc32: ^char32_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
c32rtomb :: proc(s: ^char, c32: char32_t, ps: ^mbstate_t) -> size_t ---;
mbrtoc16 :: proc(pc16: ^char16_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
c16rtomb :: proc(s: ^char, c16: char16_t, ps: ^mbstate_t) -> size_t ---
mbrtoc32 :: proc(pc32: ^char32_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
c32rtomb :: proc(s: ^char, c32: char32_t, ps: ^mbstate_t) -> size_t ---
}
char16_t :: uint_least16_t;
char32_t :: uint_least32_t;
char16_t :: uint_least16_t
char32_t :: uint_least32_t

View File

@@ -11,88 +11,88 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c")
foreign libc {
// 7.29.2 Formatted wide character input/output functions
fwprintf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
fwscanf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
swprintf :: proc(stream: ^FILE, n: size_t, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
swscanf :: proc(s, format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
vfwprintf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---;
vfwscanf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---;
vswprintf :: proc(s: ^wchar_t, n: size_t, format: ^wchar_t, arg: va_list) -> int ---;
vswscanf :: proc(s, format: ^wchar_t, arg: va_list) -> int ---;
vwprintf :: proc(format: ^wchar_t, arg: va_list) -> int ---;
vwscanf :: proc(format: ^wchar_t, arg: va_list) -> int ---;
wprintf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
wscanf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---;
fwprintf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
fwscanf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
swprintf :: proc(stream: ^FILE, n: size_t, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
swscanf :: proc(s, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
vfwprintf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---
vfwscanf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---
vswprintf :: proc(s: ^wchar_t, n: size_t, format: ^wchar_t, arg: va_list) -> int ---
vswscanf :: proc(s, format: ^wchar_t, arg: va_list) -> int ---
vwprintf :: proc(format: ^wchar_t, arg: va_list) -> int ---
vwscanf :: proc(format: ^wchar_t, arg: va_list) -> int ---
wprintf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---
wscanf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---
// 7.29.3 Wide character input/output functions
fwgetc :: proc(stream: ^FILE) -> wint_t ---;
fgetws :: proc(s: ^wchar_t, n: int, stream: ^FILE) -> wchar_t ---;
fputwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---;
fputws :: proc(s: ^wchar_t, stream: ^FILE) -> int ---;
fwide :: proc(stream: ^FILE, mode: int) -> int ---;
getwc :: proc(stream: ^FILE) -> wint_t ---;
getwchar :: proc() -> wint_t ---;
putwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---;
putwchar :: proc(c: wchar_t) -> wint_t ---;
ungetwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---;
fwgetc :: proc(stream: ^FILE) -> wint_t ---
fgetws :: proc(s: ^wchar_t, n: int, stream: ^FILE) -> wchar_t ---
fputwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
fputws :: proc(s: ^wchar_t, stream: ^FILE) -> int ---
fwide :: proc(stream: ^FILE, mode: int) -> int ---
getwc :: proc(stream: ^FILE) -> wint_t ---
getwchar :: proc() -> wint_t ---
putwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
putwchar :: proc(c: wchar_t) -> wint_t ---
ungetwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
// 7.29.4 General wide string utilities
wcstod :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> double ---;
wcstof :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> float ---;
wcstol :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> long ---;
wcstoll :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> longlong ---;
wcstoul :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulong ---;
wcstoull :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulonglong ---;
wcstod :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> double ---
wcstof :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> float ---
wcstol :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> long ---
wcstoll :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> longlong ---
wcstoul :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulong ---
wcstoull :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulonglong ---
// 7.29.4.2 Wide string copying functions
wcscpy :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
wcsncpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
wmemcpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
wmemmove :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
wcscpy :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcsncpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
wmemcpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
wmemmove :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.4.3 Wide string concatenation functions
wcscat :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
wcsncat :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---;
wcscat :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcsncat :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.4.4 Wide string comparison functions
wcscmp :: proc(s1, s2: ^wchar_t) -> int ---;
wcscoll :: proc(s1, s2: ^wchar_t) -> int ---;
wcsncmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---;
wcsxfrm :: proc(s1, s2: ^wchar_t, n: size_t) -> size_t ---;
wmemcmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---;
wcscmp :: proc(s1, s2: ^wchar_t) -> int ---
wcscoll :: proc(s1, s2: ^wchar_t) -> int ---
wcsncmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---
wcsxfrm :: proc(s1, s2: ^wchar_t, n: size_t) -> size_t ---
wmemcmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---
// 7.29.4.5 Wide string search functions
wcschr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---;
wcscspn :: proc(s1, s2: ^wchar_t) -> size_t ---;
wcspbrk :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
wcsrchr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---;
wcsspn :: proc(s1, s2: ^wchar_t) -> size_t ---;
wcsstr :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---;
wcstok :: proc(s1, s2: ^wchar_t, ptr: ^^wchar_t) -> ^wchar_t ---;
wmemchr :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---;
wcschr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---
wcscspn :: proc(s1, s2: ^wchar_t) -> size_t ---
wcspbrk :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcsrchr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---
wcsspn :: proc(s1, s2: ^wchar_t) -> size_t ---
wcsstr :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcstok :: proc(s1, s2: ^wchar_t, ptr: ^^wchar_t) -> ^wchar_t ---
wmemchr :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.4.6 Miscellaneous functions
wcslen :: proc(s: ^wchar_t) -> size_t ---;
wmemset :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---;
wcslen :: proc(s: ^wchar_t) -> size_t ---
wmemset :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.5 Wide character time conversion functions
wcsftime :: proc(s: ^wchar_t, maxsize: size_t, format: ^wchar_t, timeptr: ^tm) -> size_t ---;
wcsftime :: proc(s: ^wchar_t, maxsize: size_t, format: ^wchar_t, timeptr: ^tm) -> size_t ---
// 7.29.6.1 Single-byte/wide character conversion functions
btowc :: proc(c: int) -> wint_t ---;
wctob :: proc(c: wint_t) -> int ---;
btowc :: proc(c: int) -> wint_t ---
wctob :: proc(c: wint_t) -> int ---
// 7.29.6.2 Conversion state functions
mbsinit :: proc(ps: ^mbstate_t) -> int ---;
mbsinit :: proc(ps: ^mbstate_t) -> int ---
// 7.29.6.3 Restartable multibyte/wide character conversion functions
mbrlen :: proc(s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
mbrtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---;
wcrtomb :: proc(s: ^char, wc: wchar_t, ps: ^mbstate_t) -> size_t ---;
mbrlen :: proc(s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
mbrtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
wcrtomb :: proc(s: ^char, wc: wchar_t, ps: ^mbstate_t) -> size_t ---
// 7.29.6.4 Restartable multibyte/wide string conversion functions
mbsrtowcs :: proc(dst: ^wchar_t, src: ^cstring, len: size_t, ps: ^mbstate_t) -> size_t ---;
wcsrtombs :: proc(dst: ^char, src: ^^wchar_t, len: size_t, ps: ^mbstate_t) -> size_t ---;
mbsrtowcs :: proc(dst: ^wchar_t, src: ^cstring, len: size_t, ps: ^mbstate_t) -> size_t ---
wcsrtombs :: proc(dst: ^char, src: ^^wchar_t, len: size_t, ps: ^mbstate_t) -> size_t ---
}
// Large enough and aligned enough for any wide-spread in-use libc.
@@ -100,9 +100,9 @@ mbstate_t :: struct #align 16 { _: [32]char, }
// Odin does not have default argument promotion so the need for a separate type
// here isn't necessary, though make it distinct just to be safe.
wint_t :: distinct wchar_t;
wint_t :: distinct wchar_t
// Calculate these values correctly regardless of what type wchar_t actually is.
WINT_MIN :: 0;
WINT_MAX :: 1 << (size_of(wint_t) * 8);
WEOF :: ~wint_t(0);
WINT_MIN :: 0
WINT_MAX :: 1 << (size_of(wint_t) * 8)
WEOF :: ~wint_t(0)

View File

@@ -9,40 +9,40 @@ when ODIN_OS == "windows" {
}
when ODIN_OS == "windows" {
wctrans_t :: distinct wchar_t;
wctype_t :: distinct ushort;
wctrans_t :: distinct wchar_t
wctype_t :: distinct ushort
}
when ODIN_OS == "linux" {
wctrans_t :: distinct rawptr;
wctype_t :: distinct ulong;
wctrans_t :: distinct rawptr
wctype_t :: distinct ulong
}
@(default_calling_convention="c")
foreign libc {
// 7.30.2.1 Wide character classification functions
iswalnum :: proc(wc: wint_t) -> int ---;
iswalpha :: proc(wc: wint_t) -> int ---;
iswblank :: proc(wc: wint_t) -> int ---;
iswcntrl :: proc(wc: wint_t) -> int ---;
iswdigit :: proc(wc: wint_t) -> int ---;
iswgraph :: proc(wc: wint_t) -> int ---;
iswlower :: proc(wc: wint_t) -> int ---;
iswprint :: proc(wc: wint_t) -> int ---;
iswpunct :: proc(wc: wint_t) -> int ---;
iswspace :: proc(wc: wint_t) -> int ---;
iswupper :: proc(wc: wint_t) -> int ---;
iswxdigit :: proc(wc: wint_t) -> int ---;
iswalnum :: proc(wc: wint_t) -> int ---
iswalpha :: proc(wc: wint_t) -> int ---
iswblank :: proc(wc: wint_t) -> int ---
iswcntrl :: proc(wc: wint_t) -> int ---
iswdigit :: proc(wc: wint_t) -> int ---
iswgraph :: proc(wc: wint_t) -> int ---
iswlower :: proc(wc: wint_t) -> int ---
iswprint :: proc(wc: wint_t) -> int ---
iswpunct :: proc(wc: wint_t) -> int ---
iswspace :: proc(wc: wint_t) -> int ---
iswupper :: proc(wc: wint_t) -> int ---
iswxdigit :: proc(wc: wint_t) -> int ---
// 7.30.2.2 Extensible wide character classification functions
iswctype :: proc(wc: wint_t, desc: wctype_t) -> int ---;
wctype :: proc(property: cstring) -> wctype_t ---;
iswctype :: proc(wc: wint_t, desc: wctype_t) -> int ---
wctype :: proc(property: cstring) -> wctype_t ---
// 7.30.3 Wide character case mapping utilities
towlower :: proc(wc: wint_t) -> wint_t ---;
towupper :: proc(wc: wint_t) -> wint_t ---;
towlower :: proc(wc: wint_t) -> wint_t ---
towupper :: proc(wc: wint_t) -> wint_t ---
// 7.30.3.2 Extensible wide character case mapping functions
towctrans :: proc(wc: wint_t, desc: wctrans_t) -> wint_t ---;
wctrans :: proc(property: cstring) -> wctrans_t ---;
towctrans :: proc(wc: wint_t, desc: wctrans_t) -> wint_t ---
wctrans :: proc(property: cstring) -> wctrans_t ---
}

View File

@@ -41,17 +41,17 @@ accept_ranges := [5]Accept_Range{
}
accept_sizes := [256]u8{
0x00..0x7f = 0xf0,
0x80..0xc1 = 0xf1,
0xc2..0xdf = 0x02,
0xe0 = 0x13,
0xe1..0xec = 0x03,
0xed = 0x23,
0xee..0xef = 0x03,
0xf0 = 0x34,
0xf1..0xf3 = 0x04,
0xf4 = 0x44,
0xf5..0xff = 0xf1,
0x00..=0x7f = 0xf0,
0x80..=0xc1 = 0xf1,
0xc2..=0xdf = 0x02,
0xe0 = 0x13,
0xe1..=0xec = 0x03,
0xed = 0x23,
0xee..=0xef = 0x03,
0xf0 = 0x34,
0xf1..=0xf3 = 0x04,
0xf4 = 0x44,
0xf5..=0xff = 0xf1,
}
encode_rune :: proc(c: rune) -> ([4]u8, int) {
@@ -379,15 +379,15 @@ full_rune_in_string :: proc(s: string) -> bool {
_first := [256]u8{
0x00..0x7f = 0xf0, // ascii, size 1
0x80..0xc1 = 0xf1, // invalid, size 1
0xc2..0xdf = 0x02, // accept 1, size 2
0xe0 = 0x13, // accept 1, size 3
0xe1..0xec = 0x03, // accept 0, size 3
0xed = 0x23, // accept 2, size 3
0xee..0xef = 0x03, // accept 0, size 3
0xf0 = 0x34, // accept 3, size 4
0xf1..0xf3 = 0x04, // accept 0, size 4
0xf4 = 0x44, // accept 4, size 4
0xf5..0xff = 0xf1, // ascii, size 1
0x00..=0x7f = 0xf0, // ascii, size 1
0x80..=0xc1 = 0xf1, // invalid, size 1
0xc2..=0xdf = 0x02, // accept 1, size 2
0xe0 = 0x13, // accept 1, size 3
0xe1..=0xec = 0x03, // accept 0, size 3
0xed = 0x23, // accept 2, size 3
0xee..=0xef = 0x03, // accept 0, size 3
0xf0 = 0x34, // accept 3, size 4
0xf1..=0xf3 = 0x04, // accept 0, size 4
0xf4 = 0x44, // accept 4, size 4
0xf5..=0xff = 0xf1, // ascii, size 1
}

View File

@@ -2026,7 +2026,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
i32 const end_offset = cast(i32)(file->tokenizer.end - file->tokenizer.start);
for_array(i, file->tokens) {
Token *token = &file->tokens[i];
if (token->flags & TokenFlag_Remove) {
if (token->flags & (TokenFlag_Remove|TokenFlag_Replace)) {
i32 offset = token->pos.offset;
i32 to_write = offset-prev_offset;
if (!gb_file_write(f, file_data+prev_offset, to_write)) {
@@ -2034,6 +2034,16 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
}
written += to_write;
prev_offset = token_pos_end(*token).offset;
}
if (token->flags & TokenFlag_Replace) {
if (token->kind == Token_Ellipsis) {
if (!gb_file_write(f, "..=", 3)) {
return gbFileError_Invalid;
}
written += 3;
} else {
return gbFileError_Invalid;
}
}
}
if (end_offset > prev_offset) {
@@ -2054,7 +2064,6 @@ int strip_semicolons(Parser *parser) {
AstPackage *pkg = parser->packages[i];
file_count += pkg->files.count;
}
gb_printf_err("File count to be stripped of unneeded tokens: %td\n", file_count);
auto generated_files = array_make<StripSemicolonFile>(permanent_allocator(), 0, file_count);
@@ -2062,6 +2071,20 @@ int strip_semicolons(Parser *parser) {
AstPackage *pkg = parser->packages[i];
for_array(j, pkg->files) {
AstFile *file = pkg->files[j];
bool nothing_to_change = true;
for_array(i, file->tokens) {
Token *token = &file->tokens[i];
if (token->flags) {
nothing_to_change = false;
break;
}
}
if (nothing_to_change) {
continue;
}
String old_fullpath = copy_string(permanent_allocator(), file->fullpath);
// assumes .odin extension
@@ -2074,6 +2097,9 @@ int strip_semicolons(Parser *parser) {
}
}
gb_printf_err("File count to be stripped of unneeded tokens: %td\n", generated_files.count);
isize generated_count = 0;
bool failed = false;
@@ -2169,7 +2195,7 @@ int strip_semicolons(Parser *parser) {
}
}
gb_printf_err("Files stripped of unneeded token: %td\n", file_count);
gb_printf_err("Files stripped of unneeded token: %td\n", generated_files.count);
return cast(int)failed;

View File

@@ -1376,6 +1376,10 @@ Token expect_operator(AstFile *f) {
syntax_error(f->curr_token, "Expected an non-range operator, got '%.*s'",
LIT(p));
}
if (f->curr_token.kind == Token_Ellipsis) {
f->tokens[f->curr_token_index].flags |= TokenFlag_Replace;
}
advance_token(f);
return prev;
}

View File

@@ -236,7 +236,8 @@ TokenPos token_pos_add_column(TokenPos pos) {
}
enum TokenFlag : u8 {
TokenFlag_Remove = 1<<1,
TokenFlag_Remove = 1<<1,
TokenFlag_Replace = 1<<2,
};
struct Token {