Merge remote-tracking branch 'offical/master'

This commit is contained in:
ed
2024-06-11 19:23:35 -04:00
30 changed files with 466 additions and 189 deletions
+2 -2
View File
@@ -11,7 +11,7 @@ HAS_RAND_BYTES :: true
_rand_bytes :: proc(dst: []byte) {
err := Sec.RandomCopyBytes(count=len(dst), bytes=raw_data(dst))
if err != .Success {
msg := CF.StringCopyToOdinString(Sec.CopyErrorMessageString(err))
panic(fmt.tprintf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", err, msg))
msg := CF.StringCopyToOdinString(Sec.CopyErrorMessageString(err))
fmt.panicf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", err, msg)
}
}
+1 -1
View File
@@ -32,7 +32,7 @@ _rand_bytes :: proc (dst: []byte) {
// All other failures are things that should NEVER happen
// unless the kernel interface changes (ie: the Linux
// developers break userland).
panic(fmt.tprintf("crypto: getrandom failed: %v", errno))
fmt.panicf("crypto: getrandom failed: %v", errno)
}
l -= n_read
dst = dst[n_read:]
+10 -10
View File
@@ -11,16 +11,16 @@ _rand_bytes :: proc(dst: []byte) {
ret := (os.Errno)(win32.BCryptGenRandom(nil, raw_data(dst), u32(len(dst)), win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG))
if ret != os.ERROR_NONE {
switch ret {
case os.ERROR_INVALID_HANDLE:
// The handle to the first parameter is invalid.
// This should not happen here, since we explicitly pass nil to it
panic("crypto: BCryptGenRandom Invalid handle for hAlgorithm")
case os.ERROR_INVALID_PARAMETER:
// One of the parameters was invalid
panic("crypto: BCryptGenRandom Invalid parameter")
case:
// Unknown error
panic(fmt.tprintf("crypto: BCryptGenRandom failed: %d\n", ret))
case os.ERROR_INVALID_HANDLE:
// The handle to the first parameter is invalid.
// This should not happen here, since we explicitly pass nil to it
panic("crypto: BCryptGenRandom Invalid handle for hAlgorithm")
case os.ERROR_INVALID_PARAMETER:
// One of the parameters was invalid
panic("crypto: BCryptGenRandom Invalid parameter")
case:
// Unknown error
fmt.panicf("crypto: BCryptGenRandom failed: %d\n", ret)
}
}
}
+3 -3
View File
@@ -527,7 +527,7 @@ angle_from_quaternion :: proc{
@(require_results)
axis_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> Vector3f16 {
t1 := 1 - q.w*q.w
if t1 < 0 {
if t1 <= 0 {
return {0, 0, 1}
}
t2 := 1.0 / math.sqrt(t1)
@@ -536,7 +536,7 @@ axis_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> Vector3f16
@(require_results)
axis_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> Vector3f32 {
t1 := 1 - q.w*q.w
if t1 < 0 {
if t1 <= 0 {
return {0, 0, 1}
}
t2 := 1.0 / math.sqrt(t1)
@@ -545,7 +545,7 @@ axis_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> Vector3f32
@(require_results)
axis_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> Vector3f64 {
t1 := 1 - q.w*q.w
if t1 < 0 {
if t1 <= 0 {
return {0, 0, 1}
}
t2 := 1.0 / math.sqrt(t1)
+36 -1
View File
@@ -1455,7 +1455,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
case "unroll":
return parse_unrolled_for_loop(p, tag)
case "reverse":
stmt := parse_for_stmt(p)
stmt := parse_stmt(p)
if range, is_range := stmt.derived.(^ast.Range_Stmt); is_range {
if range.reverse {
@@ -3515,6 +3515,25 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
case op.kind == .Colon:
expect_token_after(p, .Colon, "identifier list")
if .Label in flags && len(lhs) == 1 {
is_partial := false
is_reverse := false
partial_token: tokenizer.Token
if p.curr_tok.kind == .Hash {
name := peek_token(p)
if name.kind == .Ident && name.text == "partial" &&
peek_token(p, 1).kind == .Switch {
partial_token = expect_token(p, .Hash)
expect_token(p, .Ident)
is_partial = true
} else if name.kind == .Ident && name.text == "reverse" &&
peek_token(p, 1).kind == .For {
partial_token = expect_token(p, .Hash)
expect_token(p, .Ident)
is_reverse = true
}
}
#partial switch p.curr_tok.kind {
case .Open_Brace, .If, .For, .Switch:
label := lhs[0]
@@ -3529,6 +3548,22 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
case ^ast.Type_Switch_Stmt: n.label = label
case ^ast.Range_Stmt: n.label = label
}
if is_partial {
#partial switch n in stmt.derived_stmt {
case ^ast.Switch_Stmt: n.partial = true
case ^ast.Type_Switch_Stmt: n.partial = true
case:
error(p, partial_token.pos, "incorrect use of directive, use '%s: #partial switch'", partial_token.text)
}
}
if is_reverse {
#partial switch n in stmt.derived_stmt {
case ^ast.Range_Stmt: n.reverse = true
case:
error(p, partial_token.pos, "incorrect use of directive, use '%s: #reverse for'", partial_token.text)
}
}
}
return stmt
+49 -12
View File
@@ -112,15 +112,15 @@ EOWNERDEAD: Errno : 96
O_RDONLY :: 0x00000
O_WRONLY :: 0x00001
O_RDWR :: 0x00002
O_CREATE :: 0x00040
O_EXCL :: 0x00080
O_NOCTTY :: 0x00100
O_TRUNC :: 0x00200
O_NONBLOCK :: 0x00800
O_APPEND :: 0x00400
O_SYNC :: 0x01000
O_ASYNC :: 0x02000
O_CLOEXEC :: 0x80000
O_NONBLOCK :: 0x00004
O_APPEND :: 0x00008
O_ASYNC :: 0x00040
O_SYNC :: 0x00080
O_CREATE :: 0x00200
O_TRUNC :: 0x00400
O_EXCL :: 0x00800
O_NOCTTY :: 0x08000
O_CLOEXEC :: 0100000
SEEK_DATA :: 3
@@ -140,6 +140,8 @@ RTLD_NOLOAD :: 0x02000
MAX_PATH :: 1024
KINFO_FILE_SIZE :: 1392
args := _alloc_command_line_arguments()
Unix_File_Time :: struct {
@@ -191,6 +193,21 @@ OS_Stat :: struct {
lspare: [10]u64,
}
KInfo_File :: struct {
structsize: c.int,
type: c.int,
fd: c.int,
ref_count: c.int,
flags: c.int,
pad0: c.int,
offset: i64,
// NOTE(Feoramund): This field represents a complicated union that I am
// avoiding implementing for now. I only need the path data below.
_union: [336]byte,
path: [MAX_PATH]c.char,
}
// since FreeBSD v12
Dirent :: struct {
@@ -254,6 +271,8 @@ X_OK :: 1 // Test for execute permission
W_OK :: 2 // Test for write permission
R_OK :: 4 // Test for read permission
F_KINFO :: 22
foreign libc {
@(link_name="__error") __errno_location :: proc() -> ^c.int ---
@@ -274,6 +293,7 @@ foreign libc {
@(link_name="unlink") _unix_unlink :: proc(path: cstring) -> c.int ---
@(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int ---
@(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int ---
@(link_name="fcntl") _unix_fcntl :: proc(fd: Handle, cmd: c.int, arg: uintptr) -> c.int ---
@(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir ---
@(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int ---
@@ -365,7 +385,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
}
file_size :: proc(fd: Handle) -> (i64, Errno) {
s, err := fstat(fd)
s, err := _fstat(fd)
if err != ERROR_NONE {
return -1, err
}
@@ -591,9 +611,26 @@ _readlink :: proc(path: string) -> (string, Errno) {
return "", Errno{}
}
// XXX FreeBSD
absolute_path_from_handle :: proc(fd: Handle) -> (string, Errno) {
return "", Errno(ENOSYS)
// NOTE(Feoramund): The situation isn't ideal, but this was the best way I
// could find to implement this. There are a couple outstanding bug reports
// regarding the desire to retrieve an absolute path from a handle, but to
// my knowledge, there hasn't been any work done on it.
//
// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198570
//
// This may be unreliable, according to a comment from 2023.
kinfo: KInfo_File
kinfo.structsize = KINFO_FILE_SIZE
res := _unix_fcntl(fd, F_KINFO, cast(uintptr)&kinfo)
if res == -1 {
return "", Errno(get_last_error())
}
path := strings.clone_from_cstring_bounded(cast(cstring)&kinfo.path[0], len(kinfo.path))
return path, ERROR_NONE
}
absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
+1 -1
View File
@@ -56,7 +56,7 @@ foreign libc {
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
}
when ODIN_OS == .Darwin {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
@(private)
foreign libc {
@(link_name="__error") __error :: proc() -> ^i32 ---
+8 -1
View File
@@ -6,6 +6,7 @@ import "base:intrinsics"
import "core:c/libc"
import "core:encoding/ansi"
import "core:sync"
import "core:os"
@require import "core:sys/unix"
@(private="file") stop_runner_flag: libc.sig_atomic_t
@@ -20,7 +21,13 @@ local_test_index: libc.sig_atomic_t
@(private="file")
stop_runner_callback :: proc "c" (sig: libc.int) {
intrinsics.atomic_store(&stop_runner_flag, 1)
prev := intrinsics.atomic_add(&stop_runner_flag, 1)
// If the flag was already set (if this is the second signal sent for example),
// consider this a forced (not graceful) exit.
if prev > 0 {
os.exit(int(sig))
}
}
@(private="file")
+2 -2
View File
@@ -127,13 +127,13 @@ days_remaining :: proc "contextless" (date: Date) -> (days_remaining: i64, err:
return delta.days, .None
}
last_day_of_month :: proc "contextless" (#any_int year: i64, #any_int month: i8) -> (day: i64, err: Error) {
last_day_of_month :: proc "contextless" (#any_int year: i64, #any_int month: i8) -> (day: i8, err: Error) {
// Not using formula 2.27 from the book. This is far simpler and gives the same answer.
validate(Date{year, month, 1}) or_return
month_days := MONTH_DAYS
day = i64(month_days[month])
day = month_days[month]
if month == 2 && is_leap_year(year) {
day += 1
}