mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-09 13:01:38 -07:00
Merge branch 'master' of https://github.com/odin-lang/Odin
This commit is contained in:
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build, Check, and Test
|
||||
timeout-minutes: 25
|
||||
timeout-minutes: 15
|
||||
uses: vmactions/netbsd-vm@v1
|
||||
with:
|
||||
release: "10.0"
|
||||
@@ -31,6 +31,7 @@ jobs:
|
||||
./odin version
|
||||
./odin report
|
||||
./odin check examples/all -vet -strict-style -target:netbsd_amd64
|
||||
./odin check examples/all -vet -strict-style -target:netbsd_arm64
|
||||
(cd tests/core; gmake all_bsd)
|
||||
(cd tests/internal; gmake all_bsd)
|
||||
(cd tests/issues; ./run.sh)
|
||||
|
||||
@@ -5,7 +5,6 @@ foreign import libc "system:c"
|
||||
|
||||
import "base:runtime"
|
||||
import "core:strings"
|
||||
import "core:sys/unix"
|
||||
import "core:c"
|
||||
|
||||
Handle :: distinct i32
|
||||
@@ -328,6 +327,11 @@ foreign dl {
|
||||
@(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---
|
||||
}
|
||||
|
||||
@(private)
|
||||
foreign libc {
|
||||
_lwp_self :: proc() -> i32 ---
|
||||
}
|
||||
|
||||
// NOTE(phix): Perhaps share the following functions with FreeBSD if they turn out to be the same in the end.
|
||||
|
||||
is_path_separator :: proc(r: rune) -> bool {
|
||||
@@ -721,7 +725,7 @@ exit :: proc "contextless" (code: int) -> ! {
|
||||
}
|
||||
|
||||
current_thread_id :: proc "contextless" () -> int {
|
||||
return cast(int) unix.pthread_self()
|
||||
return int(_lwp_self())
|
||||
}
|
||||
|
||||
dlopen :: proc(filename: string, flags: int) -> rawptr {
|
||||
|
||||
@@ -882,13 +882,16 @@ parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
|
||||
s = s[1:]
|
||||
fallthrough
|
||||
case 'i', 'I':
|
||||
n = common_prefix_len_ignore_case(s, "infinity")
|
||||
if 3 < n && n < 8 { // "inf" or "infinity"
|
||||
n = 3
|
||||
}
|
||||
if n == 3 || n == 8 {
|
||||
m := common_prefix_len_ignore_case(s, "infinity")
|
||||
if 3 <= m && m < 9 { // "inf" to "infinity"
|
||||
f = 0h7ff00000_00000000 if sign == 1 else 0hfff00000_00000000
|
||||
n = nsign + 3
|
||||
if m == 8 {
|
||||
// We only count the entire prefix if it is precisely "infinity".
|
||||
n = nsign + m
|
||||
} else {
|
||||
// The string was either only "inf" or incomplete.
|
||||
n = nsign + 3
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
//+private
|
||||
package sync
|
||||
|
||||
import "core:sys/unix"
|
||||
foreign import libc "system:c"
|
||||
|
||||
foreign libc {
|
||||
_lwp_self :: proc "c" () -> i32 ---
|
||||
}
|
||||
|
||||
_current_thread_id :: proc "contextless" () -> int {
|
||||
return cast(int) unix.pthread_self()
|
||||
return int(_lwp_self())
|
||||
}
|
||||
|
||||
+15
-2
@@ -1039,6 +1039,13 @@ gb_global TargetMetrics target_netbsd_amd64 = {
|
||||
str_lit("x86_64-unknown-netbsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_netbsd_arm64 = {
|
||||
TargetOs_netbsd,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16, 16,
|
||||
str_lit("aarch64-unknown-netbsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_haiku_amd64 = {
|
||||
TargetOs_haiku,
|
||||
TargetArch_amd64,
|
||||
@@ -1154,8 +1161,10 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ str_lit("freebsd_amd64"), &target_freebsd_amd64 },
|
||||
{ str_lit("freebsd_arm64"), &target_freebsd_arm64 },
|
||||
|
||||
{ str_lit("openbsd_amd64"), &target_openbsd_amd64 },
|
||||
{ str_lit("netbsd_amd64"), &target_netbsd_amd64 },
|
||||
{ str_lit("netbsd_arm64"), &target_netbsd_arm64 },
|
||||
|
||||
{ str_lit("openbsd_amd64"), &target_openbsd_amd64 },
|
||||
{ str_lit("haiku_amd64"), &target_haiku_amd64 },
|
||||
|
||||
{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
|
||||
@@ -1916,7 +1925,11 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
#elif defined(GB_SYSTEM_OPENBSD)
|
||||
metrics = &target_openbsd_amd64;
|
||||
#elif defined(GB_SYSTEM_NETBSD)
|
||||
metrics = &target_netbsd_amd64;
|
||||
#if defined(GB_CPU_ARM)
|
||||
metrics = &target_netbsd_arm64;
|
||||
#else
|
||||
metrics = &target_netbsd_amd64;
|
||||
#endif
|
||||
#elif defined(GB_SYSTEM_HAIKU)
|
||||
metrics = &target_haiku_amd64;
|
||||
#elif defined(GB_CPU_ARM)
|
||||
|
||||
@@ -256,6 +256,7 @@ extern "C" {
|
||||
|
||||
#if defined(GB_SYSTEM_NETBSD)
|
||||
#include <stdio.h>
|
||||
#include <lwp.h>
|
||||
#define lseek64 lseek
|
||||
#endif
|
||||
|
||||
@@ -3027,6 +3028,8 @@ gb_inline u32 gb_thread_current_id(void) {
|
||||
thread_id = find_thread(NULL);
|
||||
#elif defined(GB_SYSTEM_FREEBSD)
|
||||
thread_id = pthread_getthreadid_np();
|
||||
#elif defined(GB_SYSTEM_NETBSD)
|
||||
thread_id = (u32)_lwp_self();
|
||||
#else
|
||||
#error Unsupported architecture for gb_thread_current_id()
|
||||
#endif
|
||||
|
||||
@@ -494,6 +494,8 @@ gb_internal u32 thread_current_id(void) {
|
||||
thread_id = find_thread(NULL);
|
||||
#elif defined(GB_SYSTEM_FREEBSD)
|
||||
thread_id = pthread_getthreadid_np();
|
||||
#elif defined(GB_SYSTEM_NETBSD)
|
||||
thread_id = (u32)_lwp_self();
|
||||
#else
|
||||
#error Unsupported architecture for thread_current_id()
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@ all_bsd: download_test_assets \
|
||||
reflect_test \
|
||||
runtime_test \
|
||||
slice_test \
|
||||
strconv_test \
|
||||
strings_test \
|
||||
thread_test \
|
||||
time_test
|
||||
@@ -98,6 +99,9 @@ runtime_test:
|
||||
slice_test:
|
||||
$(ODIN) test slice $(COMMON) -out:test_core_slice
|
||||
|
||||
strconv_test:
|
||||
$(ODIN) test strconv $(COMMON) -out:test_core_strconv
|
||||
|
||||
strings_test:
|
||||
$(ODIN) test strings $(COMMON) -out:test_core_strings
|
||||
|
||||
|
||||
@@ -103,6 +103,11 @@ echo Running core:slice tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test slice %COMMON% -out:test_core_slice.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:strconv tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test strconv %COMMON% -out:test_core_strconv.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:strings tests
|
||||
echo ---
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package test_core_strconv
|
||||
|
||||
import "core:math"
|
||||
import "core:strconv"
|
||||
import "core:testing"
|
||||
|
||||
@(test)
|
||||
test_float :: proc(t: ^testing.T) {
|
||||
n: int
|
||||
f: f64
|
||||
ok: bool
|
||||
|
||||
f, ok = strconv.parse_f64("1.2", &n)
|
||||
testing.expect_value(t, f, 1.2)
|
||||
testing.expect_value(t, n, 3)
|
||||
testing.expect_value(t, ok, true)
|
||||
|
||||
f, ok = strconv.parse_f64("1.2a", &n)
|
||||
testing.expect_value(t, f, 1.2)
|
||||
testing.expect_value(t, n, 3)
|
||||
testing.expect_value(t, ok, false)
|
||||
|
||||
f, ok = strconv.parse_f64("+", &n)
|
||||
testing.expect_value(t, f, 0)
|
||||
testing.expect_value(t, n, 0)
|
||||
testing.expect_value(t, ok, false)
|
||||
|
||||
f, ok = strconv.parse_f64("-", &n)
|
||||
testing.expect_value(t, f, 0)
|
||||
testing.expect_value(t, n, 0)
|
||||
testing.expect_value(t, ok, false)
|
||||
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_nan :: proc(t: ^testing.T) {
|
||||
n: int
|
||||
f: f64
|
||||
ok: bool
|
||||
|
||||
f, ok = strconv.parse_f64("nan", &n)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.NaN)
|
||||
testing.expect_value(t, n, 3)
|
||||
testing.expect_value(t, ok, true)
|
||||
|
||||
f, ok = strconv.parse_f64("nAN", &n)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.NaN)
|
||||
testing.expect_value(t, n, 3)
|
||||
testing.expect_value(t, ok, true)
|
||||
|
||||
f, ok = strconv.parse_f64("Nani", &n)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.NaN)
|
||||
testing.expect_value(t, n, 3)
|
||||
testing.expect_value(t, ok, false)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_infinity :: proc(t: ^testing.T) {
|
||||
pos_inf := math.inf_f64(+1)
|
||||
neg_inf := math.inf_f64(-1)
|
||||
|
||||
n: int
|
||||
s := "infinity"
|
||||
|
||||
for i in 0 ..< len(s) + 1 {
|
||||
ss := s[:i]
|
||||
f, ok := strconv.parse_f64(ss, &n)
|
||||
if i >= 3 { // "inf" .. "infinity"
|
||||
expected_n := 8 if i == 8 else 3
|
||||
expected_ok := i == 3 || i == 8
|
||||
testing.expect_value(t, f, pos_inf)
|
||||
testing.expect_value(t, n, expected_n)
|
||||
testing.expect_value(t, ok, expected_ok)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
||||
} else { // invalid substring
|
||||
testing.expect_value(t, f, 0)
|
||||
testing.expect_value(t, n, 0)
|
||||
testing.expect_value(t, ok, false)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Zero)
|
||||
}
|
||||
}
|
||||
|
||||
s = "+infinity"
|
||||
for i in 0 ..< len(s) + 1 {
|
||||
ss := s[:i]
|
||||
f, ok := strconv.parse_f64(ss, &n)
|
||||
if i >= 4 { // "+inf" .. "+infinity"
|
||||
expected_n := 9 if i == 9 else 4
|
||||
expected_ok := i == 4 || i == 9
|
||||
testing.expect_value(t, f, pos_inf)
|
||||
testing.expect_value(t, n, expected_n)
|
||||
testing.expect_value(t, ok, expected_ok)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
||||
} else { // invalid substring
|
||||
testing.expect_value(t, f, 0)
|
||||
testing.expect_value(t, n, 0)
|
||||
testing.expect_value(t, ok, false)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Zero)
|
||||
}
|
||||
}
|
||||
|
||||
s = "-infinity"
|
||||
for i in 0 ..< len(s) + 1 {
|
||||
ss := s[:i]
|
||||
f, ok := strconv.parse_f64(ss, &n)
|
||||
if i >= 4 { // "-inf" .. "infinity"
|
||||
expected_n := 9 if i == 9 else 4
|
||||
expected_ok := i == 4 || i == 9
|
||||
testing.expect_value(t, f, neg_inf)
|
||||
testing.expect_value(t, n, expected_n)
|
||||
testing.expect_value(t, ok, expected_ok)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Neg_Inf)
|
||||
} else { // invalid substring
|
||||
testing.expect_value(t, f, 0)
|
||||
testing.expect_value(t, n, 0)
|
||||
testing.expect_value(t, ok, false)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Zero)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure odd casing works.
|
||||
batch := [?]string {"INFiniTY", "iNfInItY", "InFiNiTy"}
|
||||
for ss in batch {
|
||||
f, ok := strconv.parse_f64(ss, &n)
|
||||
testing.expect_value(t, f, pos_inf)
|
||||
testing.expect_value(t, n, 8)
|
||||
testing.expect_value(t, ok, true)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
||||
}
|
||||
|
||||
// Explicitly check how trailing characters are handled.
|
||||
s = "infinityyyy"
|
||||
f, ok := strconv.parse_f64(s, &n)
|
||||
testing.expect_value(t, f, pos_inf)
|
||||
testing.expect_value(t, n, 8)
|
||||
testing.expect_value(t, ok, false)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
||||
|
||||
s = "inflippity"
|
||||
f, ok = strconv.parse_f64(s, &n)
|
||||
testing.expect_value(t, f, pos_inf)
|
||||
testing.expect_value(t, n, 3)
|
||||
testing.expect_value(t, ok, false)
|
||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// Tests issue #2087 https://github.com/odin-lang/Odin/issues/2087
|
||||
package test_issues
|
||||
|
||||
import "core:math"
|
||||
import "core:strconv"
|
||||
import "core:testing"
|
||||
|
||||
@(test)
|
||||
test_parse_float :: proc(t: ^testing.T) {
|
||||
{
|
||||
f, ok := strconv.parse_f64("1.2")
|
||||
testing.expect(t, ok && f == 1.2, "expected f64(1.2), fully consumed")
|
||||
f, ok = strconv.parse_f64("1.2a")
|
||||
testing.expect(t, !ok && f == 1.2, "expected f64(1.2), partially consumed")
|
||||
f, ok = strconv.parse_f64("+")
|
||||
testing.expect(t, !ok && f == 0.0, "expected f64(0.0), with ok=false")
|
||||
f, ok = strconv.parse_f64("-")
|
||||
testing.expect(t, !ok && f == 0.0, "expected f64(0.0), with ok=false")
|
||||
|
||||
|
||||
f, ok = strconv.parse_f64("inf")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), fully consumed")
|
||||
f, ok = strconv.parse_f64("+inf")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), fully consumed")
|
||||
f, ok = strconv.parse_f64("-inf")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f64(-inf), fully consumed")
|
||||
f, ok = strconv.parse_f64("inFinity")
|
||||
testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), partially consumed")
|
||||
f, ok = strconv.parse_f64("+InFinity")
|
||||
testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), partially consumed")
|
||||
f, ok = strconv.parse_f64("-InfiniTy")
|
||||
testing.expect(t, !ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f64(-inf), partially consumed")
|
||||
f, ok = strconv.parse_f64("nan")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f64(nan), fully consumed")
|
||||
f, ok = strconv.parse_f64("nAN")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f64(nan), fully consumed")
|
||||
}
|
||||
{
|
||||
f, ok := strconv.parse_f32("1.2")
|
||||
testing.expect(t, ok && f == 1.2, "expected f32(1.2), fully consumed")
|
||||
|
||||
f, ok = strconv.parse_f32("1.2a")
|
||||
testing.expect(t, !ok && f == 1.2, "expected f32(1.2), partially consumed")
|
||||
|
||||
f, ok = strconv.parse_f32("inf")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), fully consumed")
|
||||
f, ok = strconv.parse_f32("+inf")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), fully consumed")
|
||||
f, ok = strconv.parse_f32("-inf")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f32(-inf), fully consumed")
|
||||
f, ok = strconv.parse_f32("inFinity")
|
||||
testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), partially consumed")
|
||||
f, ok = strconv.parse_f32("+InFinity")
|
||||
testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), partially consumed")
|
||||
f, ok = strconv.parse_f32("-InfiniTy")
|
||||
testing.expect(t, !ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f32(-inf), partially consumed")
|
||||
f, ok = strconv.parse_f32("nan")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f32(nan), fully consumed")
|
||||
f, ok = strconv.parse_f32("nAN")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f32(nan), fully consumed")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user