mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
@@ -208,6 +208,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true
|
odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true
|
||||||
|
- name: Check issues
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
|
cd tests/issues
|
||||||
|
call run.bat
|
||||||
- name: Check benchmarks
|
- name: Check benchmarks
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ OpenBSD)
|
|||||||
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
||||||
;;
|
;;
|
||||||
Haiku)
|
Haiku)
|
||||||
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags) -I/system/develop/headers/private/shared -I/system/develop/headers/private/kernel"
|
CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE $($LLVM_CONFIG --cxxflags --ldflags) -I/system/develop/headers/private/shared -I/system/develop/headers/private/kernel"
|
||||||
LDFLAGS="$LDFLAGS -liconv"
|
LDFLAGS="$LDFLAGS -liconv"
|
||||||
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -88,14 +88,15 @@ when ODIN_OS == .Haiku {
|
|||||||
_get_errno :: proc() -> ^int ---
|
_get_errno :: proc() -> ^int ---
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private="file")
|
_HAIKU_USE_POSITIVE_POSIX_ERRORS :: #config(HAIKU_USE_POSITIVE_POSIX_ERRORS, false)
|
||||||
B_GENERAL_ERROR_BASE :: min(i32)
|
_POSIX_ERROR_FACTOR :: -1 when _HAIKU_USE_POSITIVE_POSIX_ERRORS else 1
|
||||||
@(private="file")
|
|
||||||
B_POSIX_ERROR_BASE :: B_GENERAL_ERROR_BASE + 0x7000
|
|
||||||
|
|
||||||
EDOM :: B_POSIX_ERROR_BASE + 16
|
@(private="file") _GENERAL_ERROR_BASE :: min(int)
|
||||||
EILSEQ :: B_POSIX_ERROR_BASE + 38
|
@(private="file") _POSIX_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x7000
|
||||||
ERANGE :: B_POSIX_ERROR_BASE + 17
|
|
||||||
|
EDOM :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 16)
|
||||||
|
EILSEQ :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 38)
|
||||||
|
ERANGE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 17)
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .JS {
|
when ODIN_OS == .JS {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ when ODIN_OS == .Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Windows {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku || ODIN_OS == .Windows {
|
||||||
|
|
||||||
LC_ALL :: 0
|
LC_ALL :: 0
|
||||||
LC_COLLATE :: 1
|
LC_COLLATE :: 1
|
||||||
|
|||||||
@@ -42,6 +42,21 @@ when ODIN_OS == .Linux {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .Haiku {
|
||||||
|
RAND_MAX :: 0x7fffffff
|
||||||
|
|
||||||
|
// GLIBC and MUSL only
|
||||||
|
@(private="file")
|
||||||
|
@(default_calling_convention="c")
|
||||||
|
foreign libc {
|
||||||
|
__ctype_get_mb_cur_max :: proc() -> ushort ---
|
||||||
|
}
|
||||||
|
|
||||||
|
MB_CUR_MAX :: #force_inline proc() -> size_t {
|
||||||
|
return size_t(__ctype_get_mb_cur_max())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD {
|
||||||
RAND_MAX :: 0x7fffffff
|
RAND_MAX :: 0x7fffffff
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin || ODIN_OS =
|
|||||||
|
|
||||||
time_t :: distinct i64
|
time_t :: distinct i64
|
||||||
|
|
||||||
when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
|
when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Haiku {
|
||||||
clock_t :: distinct int32_t
|
clock_t :: distinct int32_t
|
||||||
} else {
|
} else {
|
||||||
clock_t :: distinct long
|
clock_t :: distinct long
|
||||||
|
|||||||
@@ -34,12 +34,18 @@ Tracking_Allocator_Bad_Free_Entry :: struct {
|
|||||||
location: runtime.Source_Code_Location,
|
location: runtime.Source_Code_Location,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Callback type for when tracking allocator runs into a bad free.
|
||||||
|
*/
|
||||||
|
Tracking_Allocator_Bad_Free_Callback :: proc(t: ^Tracking_Allocator, memory: rawptr, location: runtime.Source_Code_Location)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tracking allocator data.
|
Tracking allocator data.
|
||||||
*/
|
*/
|
||||||
Tracking_Allocator :: struct {
|
Tracking_Allocator :: struct {
|
||||||
backing: Allocator,
|
backing: Allocator,
|
||||||
allocation_map: map[rawptr]Tracking_Allocator_Entry,
|
allocation_map: map[rawptr]Tracking_Allocator_Entry,
|
||||||
|
bad_free_callback: Tracking_Allocator_Bad_Free_Callback,
|
||||||
bad_free_array: [dynamic]Tracking_Allocator_Bad_Free_Entry,
|
bad_free_array: [dynamic]Tracking_Allocator_Bad_Free_Entry,
|
||||||
mutex: sync.Mutex,
|
mutex: sync.Mutex,
|
||||||
clear_on_free_all: bool,
|
clear_on_free_all: bool,
|
||||||
@@ -61,6 +67,7 @@ allocate the tracked data.
|
|||||||
tracking_allocator_init :: proc(t: ^Tracking_Allocator, backing_allocator: Allocator, internals_allocator := context.allocator) {
|
tracking_allocator_init :: proc(t: ^Tracking_Allocator, backing_allocator: Allocator, internals_allocator := context.allocator) {
|
||||||
t.backing = backing_allocator
|
t.backing = backing_allocator
|
||||||
t.allocation_map.allocator = internals_allocator
|
t.allocation_map.allocator = internals_allocator
|
||||||
|
t.bad_free_callback = tracking_allocator_bad_free_callback_panic
|
||||||
t.bad_free_array.allocator = internals_allocator
|
t.bad_free_array.allocator = internals_allocator
|
||||||
if .Free_All in query_features(t.backing) {
|
if .Free_All in query_features(t.backing) {
|
||||||
t.clear_on_free_all = true
|
t.clear_on_free_all = true
|
||||||
@@ -109,6 +116,33 @@ tracking_allocator_reset :: proc(t: ^Tracking_Allocator) {
|
|||||||
sync.mutex_unlock(&t.mutex)
|
sync.mutex_unlock(&t.mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Default behavior for a bad free: Crash with error message that says where the
|
||||||
|
bad free happened.
|
||||||
|
|
||||||
|
Override Tracking_Allocator.bad_free_callback to have something else happen. For
|
||||||
|
example, you can use tracking_allocator_bad_free_callback_add_to_array to return
|
||||||
|
the tracking allocator to the old behavior, where the bad_free_array was used.
|
||||||
|
*/
|
||||||
|
tracking_allocator_bad_free_callback_panic :: proc(t: ^Tracking_Allocator, memory: rawptr, location: runtime.Source_Code_Location) {
|
||||||
|
runtime.print_caller_location(location)
|
||||||
|
runtime.print_string(" Tracking allocator error: Bad free of pointer ")
|
||||||
|
runtime.print_uintptr(uintptr(memory))
|
||||||
|
runtime.print_string("\n")
|
||||||
|
runtime.trap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Alternative behavior for a bad free: Store in `bad_free_array`. If you use this,
|
||||||
|
then you must make sure to check Tracking_Allocator.bad_free_array at some point.
|
||||||
|
*/
|
||||||
|
tracking_allocator_bad_free_callback_add_to_array :: proc(t: ^Tracking_Allocator, memory: rawptr, location: runtime.Source_Code_Location) {
|
||||||
|
append(&t.bad_free_array, Tracking_Allocator_Bad_Free_Entry {
|
||||||
|
memory = memory,
|
||||||
|
location = location,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tracking allocator.
|
Tracking allocator.
|
||||||
|
|
||||||
@@ -116,8 +150,10 @@ The tracking allocator is an allocator wrapper that tracks memory allocations.
|
|||||||
This allocator stores all the allocations in a map. Whenever a pointer that's
|
This allocator stores all the allocations in a map. Whenever a pointer that's
|
||||||
not inside of the map is freed, the `bad_free_array` entry is added.
|
not inside of the map is freed, the `bad_free_array` entry is added.
|
||||||
|
|
||||||
An example of how to use the `Tracking_Allocator` to track subsequent allocations
|
Here follows an example of how to use the `Tracking_Allocator` to track
|
||||||
in your program and report leaks and bad frees:
|
subsequent allocations in your program and report leaks. By default, the
|
||||||
|
tracking allocator will crash on bad frees. You can override that behavior by
|
||||||
|
overriding `track.bad_free_callback`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -137,9 +173,6 @@ Example:
|
|||||||
for _, leak in track.allocation_map {
|
for _, leak in track.allocation_map {
|
||||||
fmt.printf("%v leaked %m\n", leak.location, leak.size)
|
fmt.printf("%v leaked %m\n", leak.location, leak.size)
|
||||||
}
|
}
|
||||||
for bad_free in track.bad_free_array {
|
|
||||||
fmt.printf("%v allocation %p was freed badly\n", bad_free.location, bad_free.memory)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
@@ -191,10 +224,9 @@ tracking_allocator_proc :: proc(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mode == .Free && old_memory != nil && old_memory not_in data.allocation_map {
|
if mode == .Free && old_memory != nil && old_memory not_in data.allocation_map {
|
||||||
append(&data.bad_free_array, Tracking_Allocator_Bad_Free_Entry{
|
if data.bad_free_callback != nil {
|
||||||
memory = old_memory,
|
data.bad_free_callback(data, old_memory, loc)
|
||||||
location = loc,
|
}
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
result = data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, loc) or_return
|
result = data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, loc) or_return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,10 +432,13 @@ Range_Stmt :: struct {
|
|||||||
reverse: bool,
|
reverse: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
Inline_Range_Stmt :: struct {
|
Inline_Range_Stmt :: Unroll_Range_Stmt
|
||||||
|
|
||||||
|
Unroll_Range_Stmt :: struct {
|
||||||
using node: Stmt,
|
using node: Stmt,
|
||||||
label: ^Expr,
|
label: ^Expr,
|
||||||
inline_pos: tokenizer.Pos,
|
unroll_pos: tokenizer.Pos,
|
||||||
|
args: []^Expr,
|
||||||
for_pos: tokenizer.Pos,
|
for_pos: tokenizer.Pos,
|
||||||
val0: ^Expr,
|
val0: ^Expr,
|
||||||
val1: ^Expr,
|
val1: ^Expr,
|
||||||
|
|||||||
@@ -242,8 +242,9 @@ clone_node :: proc(node: ^Node) -> ^Node {
|
|||||||
r.vals = clone(r.vals)
|
r.vals = clone(r.vals)
|
||||||
r.expr = clone(r.expr)
|
r.expr = clone(r.expr)
|
||||||
r.body = clone(r.body)
|
r.body = clone(r.body)
|
||||||
case ^Inline_Range_Stmt:
|
case ^Unroll_Range_Stmt:
|
||||||
r.label = clone(r.label)
|
r.label = clone(r.label)
|
||||||
|
r.args = clone(r.args)
|
||||||
r.val0 = clone(r.val0)
|
r.val0 = clone(r.val0)
|
||||||
r.val1 = clone(r.val1)
|
r.val1 = clone(r.val1)
|
||||||
r.expr = clone(r.expr)
|
r.expr = clone(r.expr)
|
||||||
|
|||||||
@@ -1262,11 +1262,49 @@ parse_foreign_decl :: proc(p: ^Parser) -> ^ast.Decl {
|
|||||||
|
|
||||||
|
|
||||||
parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast.Stmt {
|
parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast.Stmt {
|
||||||
for_tok := expect_token(p, .For)
|
|
||||||
val0, val1: ^ast.Expr
|
val0, val1: ^ast.Expr
|
||||||
in_tok: tokenizer.Token
|
in_tok: tokenizer.Token
|
||||||
expr: ^ast.Expr
|
expr: ^ast.Expr
|
||||||
body: ^ast.Stmt
|
body: ^ast.Stmt
|
||||||
|
args: [dynamic]^ast.Expr
|
||||||
|
|
||||||
|
if allow_token(p, .Open_Paren) {
|
||||||
|
p.expr_level += 1
|
||||||
|
if p.curr_tok.kind == .Close_Paren {
|
||||||
|
error(p, p.curr_tok.pos, "#unroll expected at least 1 argument, got 0")
|
||||||
|
} else {
|
||||||
|
args = make([dynamic]^ast.Expr)
|
||||||
|
for p.curr_tok.kind != .Close_Paren &&
|
||||||
|
p.curr_tok.kind != .EOF {
|
||||||
|
arg := parse_value(p)
|
||||||
|
|
||||||
|
if p.curr_tok.kind == .Eq {
|
||||||
|
eq := expect_token(p, .Eq)
|
||||||
|
if arg != nil {
|
||||||
|
if _, ok := arg.derived.(^ast.Ident); !ok {
|
||||||
|
error(p, arg.pos, "expected an identifier for 'key=value'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := parse_value(p)
|
||||||
|
fv := ast.new(ast.Field_Value, arg.pos, value)
|
||||||
|
fv.field = arg
|
||||||
|
fv.sep = eq.pos
|
||||||
|
fv.value = value
|
||||||
|
|
||||||
|
arg = fv
|
||||||
|
}
|
||||||
|
|
||||||
|
append(&args, arg)
|
||||||
|
|
||||||
|
allow_token(p, .Comma) or_break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.expr_level -= 1
|
||||||
|
_ = expect_token_after(p, .Close_Paren, "#unroll")
|
||||||
|
}
|
||||||
|
|
||||||
|
for_tok := expect_token(p, .For)
|
||||||
|
|
||||||
bad_stmt := false
|
bad_stmt := false
|
||||||
|
|
||||||
@@ -1309,7 +1347,8 @@ parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast
|
|||||||
}
|
}
|
||||||
|
|
||||||
range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body)
|
range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body)
|
||||||
range_stmt.inline_pos = inline_tok.pos
|
range_stmt.unroll_pos = inline_tok.pos
|
||||||
|
range_stmt.args = args[:]
|
||||||
range_stmt.for_pos = for_tok.pos
|
range_stmt.for_pos = for_tok.pos
|
||||||
range_stmt.val0 = val0
|
range_stmt.val0 = val0
|
||||||
range_stmt.val1 = val1
|
range_stmt.val1 = val1
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build darwin, linux, netbsd, freebsd, openbsd
|
#+build darwin, linux, netbsd, freebsd, openbsd, haiku
|
||||||
package os
|
package os
|
||||||
|
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
|||||||
@@ -624,6 +624,14 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
|
|||||||
is_file :: proc {is_file_path, is_file_handle}
|
is_file :: proc {is_file_path, is_file_handle}
|
||||||
is_dir :: proc {is_dir_path, is_dir_handle}
|
is_dir :: proc {is_dir_path, is_dir_handle}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
exists :: proc(path: string) -> bool {
|
||||||
|
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||||
|
cpath := strings.clone_to_cstring(path, context.temp_allocator)
|
||||||
|
res := _unix_access(cpath, O_RDONLY)
|
||||||
|
return res == 0
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(bill): Uses startup to initialize it
|
// NOTE(bill): Uses startup to initialize it
|
||||||
|
|
||||||
stdin: Handle = 0
|
stdin: Handle = 0
|
||||||
|
|||||||
+25
-9
@@ -1,11 +1,13 @@
|
|||||||
package os
|
package os
|
||||||
|
|
||||||
foreign import libc "system:c"
|
foreign import lib "system:c"
|
||||||
|
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
import "core:c/libc"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:sys/haiku"
|
import "core:sys/haiku"
|
||||||
|
import "core:sys/posix"
|
||||||
|
|
||||||
Handle :: i32
|
Handle :: i32
|
||||||
Pid :: i32
|
Pid :: i32
|
||||||
@@ -14,7 +16,7 @@ _Platform_Error :: haiku.Errno
|
|||||||
|
|
||||||
MAX_PATH :: haiku.PATH_MAX
|
MAX_PATH :: haiku.PATH_MAX
|
||||||
|
|
||||||
ENOSYS :: _Platform_Error(i32(haiku.Errno.POSIX_ERROR_BASE) + 9)
|
ENOSYS :: _Platform_Error(haiku.Errno.ENOSYS)
|
||||||
|
|
||||||
INVALID_HANDLE :: ~Handle(0)
|
INVALID_HANDLE :: ~Handle(0)
|
||||||
|
|
||||||
@@ -117,14 +119,13 @@ S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK
|
|||||||
S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO }
|
S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO }
|
||||||
S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK }
|
S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK }
|
||||||
|
|
||||||
|
__error :: libc.errno
|
||||||
|
_unix_open :: posix.open
|
||||||
|
|
||||||
foreign libc {
|
foreign lib {
|
||||||
@(link_name="_errorp") __error :: proc() -> ^c.int ---
|
|
||||||
|
|
||||||
@(link_name="fork") _unix_fork :: proc() -> pid_t ---
|
@(link_name="fork") _unix_fork :: proc() -> pid_t ---
|
||||||
@(link_name="getthrid") _unix_getthrid :: proc() -> int ---
|
@(link_name="getthrid") _unix_getthrid :: proc() -> int ---
|
||||||
|
|
||||||
@(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, #c_vararg mode: ..u16) -> Handle ---
|
|
||||||
@(link_name="close") _unix_close :: proc(fd: Handle) -> c.int ---
|
@(link_name="close") _unix_close :: proc(fd: Handle) -> c.int ---
|
||||||
@(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t ---
|
@(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t ---
|
||||||
@(link_name="pread") _unix_pread :: proc(fd: Handle, buf: rawptr, size: c.size_t, offset: i64) -> c.ssize_t ---
|
@(link_name="pread") _unix_pread :: proc(fd: Handle, buf: rawptr, size: c.size_t, offset: i64) -> c.ssize_t ---
|
||||||
@@ -150,6 +151,7 @@ foreign libc {
|
|||||||
@(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int ---
|
@(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int ---
|
||||||
@(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) ---
|
@(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) ---
|
||||||
@(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int ---
|
@(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int ---
|
||||||
|
@(link_name="dup") _unix_dup :: proc(fd: Handle) -> Handle ---
|
||||||
|
|
||||||
@(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr ---
|
@(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr ---
|
||||||
@(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr ---
|
@(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr ---
|
||||||
@@ -157,7 +159,7 @@ foreign libc {
|
|||||||
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---
|
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---
|
||||||
|
|
||||||
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
|
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
|
||||||
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr ---
|
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: [^]byte = nil) -> cstring ---
|
||||||
|
|
||||||
@(link_name="exit") _unix_exit :: proc(status: c.int) -> ! ---
|
@(link_name="exit") _unix_exit :: proc(status: c.int) -> ! ---
|
||||||
|
|
||||||
@@ -203,7 +205,7 @@ fork :: proc() -> (Pid, Error) {
|
|||||||
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) {
|
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) {
|
||||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||||
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||||
handle := _unix_open(cstr, c.int(flags), u16(mode))
|
handle := cast(Handle)_unix_open(cstr, transmute(posix.O_Flags)i32(flags), transmute(posix.mode_t)i32(mode))
|
||||||
if handle == -1 {
|
if handle == -1 {
|
||||||
return INVALID_HANDLE, get_last_error()
|
return INVALID_HANDLE, get_last_error()
|
||||||
}
|
}
|
||||||
@@ -444,7 +446,7 @@ absolute_path_from_relative :: proc(rel: string, allocator := context.allocator)
|
|||||||
if path_ptr == nil {
|
if path_ptr == nil {
|
||||||
return "", get_last_error()
|
return "", get_last_error()
|
||||||
}
|
}
|
||||||
defer _unix_free(path_ptr)
|
defer _unix_free(rawptr(path_ptr))
|
||||||
|
|
||||||
path_cstr := cstring(path_ptr)
|
path_cstr := cstring(path_ptr)
|
||||||
return strings.clone(string(path_cstr), allocator)
|
return strings.clone(string(path_cstr), allocator)
|
||||||
@@ -488,3 +490,17 @@ exit :: proc "contextless" (code: int) -> ! {
|
|||||||
runtime._cleanup_runtime_contextless()
|
runtime._cleanup_runtime_contextless()
|
||||||
_unix_exit(i32(code))
|
_unix_exit(i32(code))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
current_thread_id :: proc "contextless" () -> int {
|
||||||
|
return int(haiku.find_thread(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private, require_results)
|
||||||
|
_dup :: proc(fd: Handle) -> (Handle, Error) {
|
||||||
|
dup := _unix_dup(fd)
|
||||||
|
if dup == -1 {
|
||||||
|
return INVALID_HANDLE, get_last_error()
|
||||||
|
}
|
||||||
|
return dup, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ File_Info :: struct {
|
|||||||
@(private, require_results)
|
@(private, require_results)
|
||||||
_make_time_from_unix_file_time :: proc(uft: Unix_File_Time) -> time.Time {
|
_make_time_from_unix_file_time :: proc(uft: Unix_File_Time) -> time.Time {
|
||||||
return time.Time{
|
return time.Time{
|
||||||
_nsec = uft.nanoseconds + uft.seconds * 1_000_000_000,
|
_nsec = i64(uft.nanoseconds) + i64(uft.seconds) * 1_000_000_000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, freebsd, openbsd, netbsd
|
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||||
package filepath
|
package filepath
|
||||||
|
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ intern_get_cstring :: proc(m: ^Intern, text: string) -> (str: cstring, err: runt
|
|||||||
entry := _intern_get_entry(m, text) or_return
|
entry := _intern_get_entry(m, text) or_return
|
||||||
return cstring(&entry.str[0]), nil
|
return cstring(&entry.str[0]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Internal function to lookup whether the text string exists in the map, returns the entry
|
Internal function to lookup whether the text string exists in the map, returns the entry
|
||||||
Sets and allocates the entry if it wasn't set yet
|
Sets and allocates the entry if it wasn't set yet
|
||||||
@@ -104,13 +105,15 @@ Returns:
|
|||||||
- err: An allocator error if one occured, `nil` otherwise
|
- err: An allocator error if one occured, `nil` otherwise
|
||||||
*/
|
*/
|
||||||
_intern_get_entry :: proc(m: ^Intern, text: string) -> (new_entry: ^Intern_Entry, err: runtime.Allocator_Error) #no_bounds_check {
|
_intern_get_entry :: proc(m: ^Intern, text: string) -> (new_entry: ^Intern_Entry, err: runtime.Allocator_Error) #no_bounds_check {
|
||||||
if prev, ok := m.entries[text]; ok {
|
|
||||||
return prev, nil
|
|
||||||
}
|
|
||||||
if m.allocator.procedure == nil {
|
if m.allocator.procedure == nil {
|
||||||
m.allocator = context.allocator
|
m.allocator = context.allocator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key_ptr, val_ptr, inserted := map_entry(&m.entries, text) or_return
|
||||||
|
if !inserted {
|
||||||
|
return val_ptr^, nil
|
||||||
|
}
|
||||||
|
|
||||||
entry_size := int(offset_of(Intern_Entry, str)) + len(text) + 1
|
entry_size := int(offset_of(Intern_Entry, str)) + len(text) + 1
|
||||||
bytes := runtime.mem_alloc(entry_size, align_of(Intern_Entry), m.allocator) or_return
|
bytes := runtime.mem_alloc(entry_size, align_of(Intern_Entry), m.allocator) or_return
|
||||||
new_entry = (^Intern_Entry)(raw_data(bytes))
|
new_entry = (^Intern_Entry)(raw_data(bytes))
|
||||||
@@ -120,6 +123,9 @@ _intern_get_entry :: proc(m: ^Intern, text: string) -> (new_entry: ^Intern_Entry
|
|||||||
new_entry.str[new_entry.len] = 0
|
new_entry.str[new_entry.len] = 0
|
||||||
|
|
||||||
key := string(new_entry.str[:new_entry.len])
|
key := string(new_entry.str[:new_entry.len])
|
||||||
m.entries[key] = new_entry
|
|
||||||
return new_entry, nil
|
key_ptr^ = key
|
||||||
|
val_ptr^ = new_entry
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-26
@@ -1,14 +1,13 @@
|
|||||||
#+private
|
#+private
|
||||||
package sync
|
package sync
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
import "core:sys/haiku"
|
import "core:sys/haiku"
|
||||||
import "core:sys/unix"
|
import "core:sys/posix"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
|
|
||||||
@(private="file")
|
@(private="file")
|
||||||
Wait_Node :: struct {
|
Wait_Node :: struct {
|
||||||
thread: unix.pthread_t,
|
thread: posix.pthread_t,
|
||||||
futex: ^Futex,
|
futex: ^Futex,
|
||||||
prev, next: ^Wait_Node,
|
prev, next: ^Wait_Node,
|
||||||
}
|
}
|
||||||
@@ -58,7 +57,7 @@ _futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> (ok: bool) {
|
|||||||
|
|
||||||
head := &waitq.list
|
head := &waitq.list
|
||||||
waiter := Wait_Node{
|
waiter := Wait_Node{
|
||||||
thread = unix.pthread_self(),
|
thread = posix.pthread_self(),
|
||||||
futex = f,
|
futex = f,
|
||||||
prev = head,
|
prev = head,
|
||||||
next = head.next,
|
next = head.next,
|
||||||
@@ -67,25 +66,24 @@ _futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> (ok: bool) {
|
|||||||
waiter.prev.next = &waiter
|
waiter.prev.next = &waiter
|
||||||
waiter.next.prev = &waiter
|
waiter.next.prev = &waiter
|
||||||
|
|
||||||
old_mask, mask: haiku.sigset_t
|
old_mask, mask: posix.sigset_t
|
||||||
haiku.sigemptyset(&mask)
|
posix.sigemptyset(&mask)
|
||||||
haiku.sigaddset(&mask, haiku.SIGCONT)
|
posix.sigaddset(&mask, .SIGCONT)
|
||||||
unix.pthread_sigmask(haiku.SIG_BLOCK, &mask, &old_mask)
|
posix.pthread_sigmask(.BLOCK, &mask, &old_mask)
|
||||||
|
|
||||||
if u32(atomic_load_explicit(f, .Acquire)) == expect {
|
if u32(atomic_load_explicit(f, .Acquire)) == expect {
|
||||||
waitq_unlock(waitq)
|
waitq_unlock(waitq)
|
||||||
defer waitq_lock(waitq)
|
defer waitq_lock(waitq)
|
||||||
|
|
||||||
sig: c.int
|
sig: posix.Signal
|
||||||
haiku.sigwait(&mask, &sig)
|
errno := posix.sigwait(&mask, &sig)
|
||||||
errno := haiku.errno()
|
ok = errno == nil
|
||||||
ok = errno == .OK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
waiter.prev.next = waiter.next
|
waiter.prev.next = waiter.next
|
||||||
waiter.next.prev = waiter.prev
|
waiter.next.prev = waiter.prev
|
||||||
|
|
||||||
_ = unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
|
_ = posix.pthread_sigmask(.SETMASK, &old_mask, nil)
|
||||||
|
|
||||||
// FIXME: Add error handling!
|
// FIXME: Add error handling!
|
||||||
return
|
return
|
||||||
@@ -101,7 +99,7 @@ _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration
|
|||||||
|
|
||||||
head := &waitq.list
|
head := &waitq.list
|
||||||
waiter := Wait_Node{
|
waiter := Wait_Node{
|
||||||
thread = unix.pthread_self(),
|
thread = posix.pthread_self(),
|
||||||
futex = f,
|
futex = f,
|
||||||
prev = head,
|
prev = head,
|
||||||
next = head.next,
|
next = head.next,
|
||||||
@@ -110,29 +108,29 @@ _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration
|
|||||||
waiter.prev.next = &waiter
|
waiter.prev.next = &waiter
|
||||||
waiter.next.prev = &waiter
|
waiter.next.prev = &waiter
|
||||||
|
|
||||||
old_mask, mask: haiku.sigset_t
|
old_mask, mask: posix.sigset_t
|
||||||
haiku.sigemptyset(&mask)
|
posix.sigemptyset(&mask)
|
||||||
haiku.sigaddset(&mask, haiku.SIGCONT)
|
posix.sigaddset(&mask, .SIGCONT)
|
||||||
unix.pthread_sigmask(haiku.SIG_BLOCK, &mask, &old_mask)
|
posix.pthread_sigmask(.BLOCK, &mask, &old_mask)
|
||||||
|
|
||||||
if u32(atomic_load_explicit(f, .Acquire)) == expect {
|
if u32(atomic_load_explicit(f, .Acquire)) == expect {
|
||||||
waitq_unlock(waitq)
|
waitq_unlock(waitq)
|
||||||
defer waitq_lock(waitq)
|
defer waitq_lock(waitq)
|
||||||
|
|
||||||
info: haiku.siginfo_t
|
info: posix.siginfo_t
|
||||||
ts := unix.timespec{
|
ts := posix.timespec{
|
||||||
tv_sec = i64(duration / 1e9),
|
tv_sec = posix.time_t(i64(duration / 1e9)),
|
||||||
tv_nsec = i64(duration % 1e9),
|
tv_nsec = i64(duration % 1e9),
|
||||||
}
|
}
|
||||||
haiku.sigtimedwait(&mask, &info, &ts)
|
haiku.sigtimedwait(&mask, &info, &ts)
|
||||||
errno := haiku.errno()
|
errno := posix.errno()
|
||||||
ok = errno == .EAGAIN || errno == .OK
|
ok = errno == .EAGAIN || errno == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
waiter.prev.next = waiter.next
|
waiter.prev.next = waiter.next
|
||||||
waiter.next.prev = waiter.prev
|
waiter.next.prev = waiter.prev
|
||||||
|
|
||||||
unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
|
posix.pthread_sigmask(.SETMASK, &old_mask, nil)
|
||||||
|
|
||||||
// FIXME: Add error handling!
|
// FIXME: Add error handling!
|
||||||
return
|
return
|
||||||
@@ -146,7 +144,7 @@ _futex_signal :: proc "contextless" (f: ^Futex) {
|
|||||||
head := &waitq.list
|
head := &waitq.list
|
||||||
for waiter := head.next; waiter != head; waiter = waiter.next {
|
for waiter := head.next; waiter != head; waiter = waiter.next {
|
||||||
if waiter.futex == f {
|
if waiter.futex == f {
|
||||||
unix.pthread_kill(waiter.thread, haiku.SIGCONT)
|
posix.pthread_kill(waiter.thread, .SIGCONT)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +158,7 @@ _futex_broadcast :: proc "contextless" (f: ^Futex) {
|
|||||||
head := &waitq.list
|
head := &waitq.list
|
||||||
for waiter := head.next; waiter != head; waiter = waiter.next {
|
for waiter := head.next; waiter != head; waiter = waiter.next {
|
||||||
if waiter.futex == f {
|
if waiter.futex == f {
|
||||||
unix.pthread_kill(waiter.thread, haiku.SIGCONT)
|
posix.pthread_kill(waiter.thread, .SIGCONT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,31 @@
|
|||||||
#+build haiku
|
#+build haiku
|
||||||
package sys_haiku
|
package sys_haiku
|
||||||
|
|
||||||
import "core:c"
|
import "core:sys/posix"
|
||||||
|
|
||||||
Errno :: enum c.int {
|
foreign import libroot "system:c"
|
||||||
// Error baselines
|
|
||||||
GENERAL_ERROR_BASE = min(c.int),
|
|
||||||
OS_ERROR_BASE = GENERAL_ERROR_BASE + 0x1000,
|
|
||||||
APP_ERROR_BASE = GENERAL_ERROR_BASE + 0x2000,
|
|
||||||
INTERFACE_ERROR_BASE = GENERAL_ERROR_BASE + 0x3000,
|
|
||||||
MEDIA_ERROR_BASE = GENERAL_ERROR_BASE + 0x4000,
|
|
||||||
TRANSLATION_ERROR_BASE = GENERAL_ERROR_BASE + 0x4800,
|
|
||||||
MIDI_ERROR_BASE = GENERAL_ERROR_BASE + 0x5000,
|
|
||||||
STORAGE_ERROR_BASE = GENERAL_ERROR_BASE + 0x6000,
|
|
||||||
POSIX_ERROR_BASE = GENERAL_ERROR_BASE + 0x7000,
|
|
||||||
MAIL_ERROR_BASE = GENERAL_ERROR_BASE + 0x8000,
|
|
||||||
PRINT_ERROR_BASE = GENERAL_ERROR_BASE + 0x9000,
|
|
||||||
DEVICE_ERROR_BASE = GENERAL_ERROR_BASE + 0xa000,
|
|
||||||
|
|
||||||
// Developer-defined errors start at (ERRORS_END+1)
|
USE_POSITIVE_POSIX_ERRORS :: posix._HAIKU_USE_POSITIVE_POSIX_ERRORS
|
||||||
ERRORS_END = GENERAL_ERROR_BASE + 0xffff,
|
POSIX_ERROR_FACTOR :: posix._POSIX_ERROR_FACTOR
|
||||||
|
|
||||||
|
// Error baselines
|
||||||
|
GENERAL_ERROR_BASE :: min(i32)
|
||||||
|
OS_ERROR_BASE :: GENERAL_ERROR_BASE + 0x1000
|
||||||
|
APP_ERROR_BASE :: GENERAL_ERROR_BASE + 0x2000
|
||||||
|
INTERFACE_ERROR_BASE :: GENERAL_ERROR_BASE + 0x3000
|
||||||
|
MEDIA_ERROR_BASE :: GENERAL_ERROR_BASE + 0x4000
|
||||||
|
TRANSLATION_ERROR_BASE :: GENERAL_ERROR_BASE + 0x4800
|
||||||
|
MIDI_ERROR_BASE :: GENERAL_ERROR_BASE + 0x5000
|
||||||
|
STORAGE_ERROR_BASE :: GENERAL_ERROR_BASE + 0x6000
|
||||||
|
POSIX_ERROR_BASE :: GENERAL_ERROR_BASE + 0x7000
|
||||||
|
MAIL_ERROR_BASE :: GENERAL_ERROR_BASE + 0x8000
|
||||||
|
PRINT_ERROR_BASE :: GENERAL_ERROR_BASE + 0x9000
|
||||||
|
DEVICE_ERROR_BASE :: GENERAL_ERROR_BASE + 0xA000
|
||||||
|
|
||||||
|
// Developer-defined errors start at (ERRORS_END+1)
|
||||||
|
ERRORS_END :: GENERAL_ERROR_BASE + 0xFFFF
|
||||||
|
|
||||||
|
Errno :: enum i32 {
|
||||||
// General Errors
|
// General Errors
|
||||||
NO_MEMORY = GENERAL_ERROR_BASE + 0,
|
NO_MEMORY = GENERAL_ERROR_BASE + 0,
|
||||||
IO_ERROR = GENERAL_ERROR_BASE + 1,
|
IO_ERROR = GENERAL_ERROR_BASE + 1,
|
||||||
@@ -107,31 +112,95 @@ Errno :: enum c.int {
|
|||||||
PARTIAL_READ = STORAGE_ERROR_BASE + 16,
|
PARTIAL_READ = STORAGE_ERROR_BASE + 16,
|
||||||
PARTIAL_WRITE = STORAGE_ERROR_BASE + 17,
|
PARTIAL_WRITE = STORAGE_ERROR_BASE + 17,
|
||||||
|
|
||||||
// Some POSIX errors
|
EIO = posix.EIO,
|
||||||
E2BIG = POSIX_ERROR_BASE + 1,
|
EACCES = posix.EACCES,
|
||||||
EFBIG = POSIX_ERROR_BASE + 4,
|
EINVAL = posix.EINVAL,
|
||||||
ENODEV = POSIX_ERROR_BASE + 7,
|
ETIMEDOUT = posix.ETIMEDOUT,
|
||||||
ERANGE = POSIX_ERROR_BASE + 17,
|
EINTR = posix.EINTR,
|
||||||
EOVERFLOW = POSIX_ERROR_BASE + 41,
|
EAGAIN = posix.EAGAIN,
|
||||||
EOPNOTSUPP = POSIX_ERROR_BASE + 43,
|
EWOULDBLOCK = posix.EWOULDBLOCK,
|
||||||
|
EBUSY = posix.EBUSY,
|
||||||
ENOSYS = POSIX_ERROR_BASE + 9,
|
EPERM = posix.EPERM,
|
||||||
EAGAIN = WOULD_BLOCK,
|
EFAULT = posix.EFAULT,
|
||||||
|
ENOEXEC = posix.ENOEXEC,
|
||||||
|
EBADF = posix.EBADF,
|
||||||
|
EEXIST = posix.EEXIST,
|
||||||
|
ENOENT = posix.ENOENT,
|
||||||
|
ENAMETOOLONG = posix.ENAMETOOLONG,
|
||||||
|
ENOTDIR = posix.ENOTDIR,
|
||||||
|
ENOTEMPTY = posix.ENOTEMPTY,
|
||||||
|
ENOSPC = posix.ENOSPC,
|
||||||
|
EROFS = posix.EROFS,
|
||||||
|
EISDIR = posix.EISDIR,
|
||||||
|
EMFILE = posix.EMFILE,
|
||||||
|
EXDEV = posix.EXDEV,
|
||||||
|
ELOOP = posix.ELOOP,
|
||||||
|
EPIPE = posix.EPIPE,
|
||||||
|
ENOMEM = posix.ENOMEM,
|
||||||
|
E2BIG = posix.E2BIG,
|
||||||
|
ECHILD = posix.ECHILD,
|
||||||
|
EDEADLK = posix.EDEADLK,
|
||||||
|
EFBIG = posix.EFBIG,
|
||||||
|
EMLINK = posix.EMLINK,
|
||||||
|
ENFILE = posix.ENFILE,
|
||||||
|
ENODEV = posix.ENODEV,
|
||||||
|
ENOLCK = posix.ENOLCK,
|
||||||
|
ENOSYS = posix.ENOSYS,
|
||||||
|
ENOTTY = posix.ENOTTY,
|
||||||
|
ENXIO = posix.ENXIO,
|
||||||
|
ESPIPE = posix.ESPIPE,
|
||||||
|
ESRCH = posix.ESRCH,
|
||||||
|
EDOM = posix.EDOM,
|
||||||
|
ERANGE = posix.ERANGE,
|
||||||
|
EPROTOTYPE = posix.EPROTOTYPE,
|
||||||
|
EPROTONOSUPPORT = posix.EPROTONOSUPPORT,
|
||||||
|
EAFNOSUPPORT = posix.EAFNOSUPPORT,
|
||||||
|
EADDRINUSE = posix.EADDRINUSE,
|
||||||
|
EADDRNOTAVAIL = posix.EADDRNOTAVAIL,
|
||||||
|
ENETDOWN = posix.ENETDOWN,
|
||||||
|
ENETUNREACH = posix.ENETUNREACH,
|
||||||
|
ENETRESET = posix.ENETRESET,
|
||||||
|
ECONNABORTED = posix.ECONNABORTED,
|
||||||
|
ECONNRESET = posix.ECONNRESET,
|
||||||
|
EISCONN = posix.EISCONN,
|
||||||
|
ENOTCONN = posix.ENOTCONN,
|
||||||
|
ECONNREFUSED = posix.ECONNREFUSED,
|
||||||
|
EHOSTUNREACH = posix.EHOSTUNREACH,
|
||||||
|
ENOPROTOOPT = posix.ENOPROTOOPT,
|
||||||
|
ENOBUFS = posix.ENOBUFS,
|
||||||
|
EINPROGRESS = posix.EINPROGRESS,
|
||||||
|
EALREADY = posix.EALREADY,
|
||||||
|
EILSEQ = posix.EILSEQ,
|
||||||
|
ENOMSG = posix.ENOMSG,
|
||||||
|
ESTALE = posix.ESTALE,
|
||||||
|
EOVERFLOW = posix.EOVERFLOW,
|
||||||
|
EMSGSIZE = posix.EMSGSIZE,
|
||||||
|
EOPNOTSUPP = posix.EOPNOTSUPP,
|
||||||
|
ENOTSOCK = posix.ENOTSOCK,
|
||||||
|
EBADMSG = posix.EBADMSG,
|
||||||
|
ECANCELED = posix.ECANCELED,
|
||||||
|
EDESTADDRREQ = posix.EDESTADDRREQ,
|
||||||
|
EDQUOT = posix.EDQUOT,
|
||||||
|
EIDRM = posix.EIDRM,
|
||||||
|
EMULTIHOP = posix.EMULTIHOP,
|
||||||
|
ENODATA = posix.ENODATA,
|
||||||
|
ENOLINK = posix.ENOLINK,
|
||||||
|
ENOSR = posix.ENOSR,
|
||||||
|
ENOSTR = posix.ENOSTR,
|
||||||
|
ENOTSUP = posix.ENOTSUP,
|
||||||
|
EPROTO = posix.EPROTO,
|
||||||
|
ETIME = posix.ETIME,
|
||||||
|
ETXTBSY = posix.ETXTBSY,
|
||||||
|
ENOTRECOVERABLE = posix.ENOTRECOVERABLE,
|
||||||
|
EOWNERDEAD = posix.EOWNERDEAD,
|
||||||
|
|
||||||
// New error codes that can be mapped to POSIX errors
|
// New error codes that can be mapped to POSIX errors
|
||||||
TOO_MANY_ARGS_NEG = E2BIG,
|
TOO_MANY_ARGS = POSIX_ERROR_FACTOR * E2BIG,
|
||||||
FILE_TOO_LARGE_NEG = EFBIG,
|
FILE_TOO_LARGE = POSIX_ERROR_FACTOR * EFBIG,
|
||||||
DEVICE_NOT_FOUND_NEG = ENODEV,
|
DEVICE_NOT_FOUND = POSIX_ERROR_FACTOR * ENODEV,
|
||||||
RESULT_NOT_REPRESENTABLE_NEG = ERANGE,
|
RESULT_NOT_REPRESENTABLE = POSIX_ERROR_FACTOR * ERANGE,
|
||||||
BUFFER_OVERFLOW_NEG = EOVERFLOW,
|
BUFFER_OVERFLOW = POSIX_ERROR_FACTOR * EOVERFLOW,
|
||||||
NOT_SUPPORTED_NEG = EOPNOTSUPP,
|
NOT_SUPPORTED = POSIX_ERROR_FACTOR * EOPNOTSUPP,
|
||||||
|
|
||||||
TOO_MANY_ARGS_POS = -E2BIG,
|
|
||||||
FILE_TOO_LARGE_POS = -EFBIG,
|
|
||||||
DEVICE_NOT_FOUND_POS = -ENODEV,
|
|
||||||
RESULT_NOT_REPRESENTABLE_POS = -ERANGE,
|
|
||||||
BUFFER_OVERFLOW_POS = -EOVERFLOW,
|
|
||||||
NOT_SUPPORTED_POS = -EOPNOTSUPP,
|
|
||||||
|
|
||||||
// Media Kit Errors
|
// Media Kit Errors
|
||||||
STREAM_NOT_FOUND = MEDIA_ERROR_BASE + 0,
|
STREAM_NOT_FOUND = MEDIA_ERROR_BASE + 0,
|
||||||
@@ -226,14 +295,8 @@ Errno :: enum c.int {
|
|||||||
ILLEGAL_DATA = TRANSLATION_ERROR_BASE + 2,
|
ILLEGAL_DATA = TRANSLATION_ERROR_BASE + 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
errno :: #force_inline proc "contextless" () -> Errno {
|
@(default_calling_convention="c")
|
||||||
return Errno(_errnop()^)
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign import libroot "system:c"
|
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
_to_positive_error :: proc(error: c.int) -> c.int ---
|
_to_positive_error :: proc(error: i32) -> i32 ---
|
||||||
_to_negative_error :: proc(error: c.int) -> c.int ---
|
_to_negative_error :: proc(error: i32) -> i32 ---
|
||||||
|
|
||||||
_errnop :: proc() -> ^c.int ---
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
#+build haiku
|
#+build haiku
|
||||||
package sys_haiku
|
package sys_haiku
|
||||||
|
|
||||||
import "core:c"
|
import "base:intrinsics"
|
||||||
|
|
||||||
directory_which :: enum c.int {
|
foreign import libroot "system:c"
|
||||||
|
|
||||||
|
directory_which :: enum i32 {
|
||||||
// Per volume directories
|
// Per volume directories
|
||||||
DESKTOP_DIRECTORY = 0,
|
DESKTOP_DIRECTORY = 0,
|
||||||
TRASH_DIRECTORY,
|
TRASH_DIRECTORY,
|
||||||
@@ -110,17 +112,18 @@ directory_which :: enum c.int {
|
|||||||
BEOS_SOUNDS_DIRECTORY,
|
BEOS_SOUNDS_DIRECTORY,
|
||||||
}
|
}
|
||||||
|
|
||||||
find_path_flags :: enum c.int {
|
find_path_flag :: enum u32 {
|
||||||
CREATE_DIRECTORY = 0x0001,
|
CREATE_DIRECTORY = intrinsics.constant_log2(0x0001),
|
||||||
CREATE_PARENT_DIRECTORY = 0x0002,
|
CREATE_PARENT_DIRECTORY = intrinsics.constant_log2(0x0002),
|
||||||
EXISTING_ONLY = 0x0004,
|
EXISTING_ONLY = intrinsics.constant_log2(0x0004),
|
||||||
|
|
||||||
// find_paths() only!
|
// find_paths() only
|
||||||
SYSTEM_ONLY = 0x0010,
|
SYSTEM_ONLY = intrinsics.constant_log2(0x0010),
|
||||||
USER_ONLY = 0x0020,
|
USER_ONLY = intrinsics.constant_log2(0x0020),
|
||||||
}
|
}
|
||||||
|
find_path_flags :: distinct bit_set[find_path_flag; u32]
|
||||||
|
|
||||||
path_base_directory :: enum c.int {
|
path_base_directory :: enum i32 {
|
||||||
INSTALLATION_LOCATION_DIRECTORY,
|
INSTALLATION_LOCATION_DIRECTORY,
|
||||||
ADD_ONS_DIRECTORY,
|
ADD_ONS_DIRECTORY,
|
||||||
APPS_DIRECTORY,
|
APPS_DIRECTORY,
|
||||||
@@ -146,7 +149,7 @@ path_base_directory :: enum c.int {
|
|||||||
TRANSLATORS_DIRECTORY,
|
TRANSLATORS_DIRECTORY,
|
||||||
VAR_DIRECTORY,
|
VAR_DIRECTORY,
|
||||||
|
|
||||||
// find_path() only!
|
// find_path() only
|
||||||
IMAGE_PATH = 1000,
|
IMAGE_PATH = 1000,
|
||||||
PACKAGE_PATH,
|
PACKAGE_PATH,
|
||||||
}
|
}
|
||||||
@@ -154,15 +157,15 @@ path_base_directory :: enum c.int {
|
|||||||
// value that can be used instead of a pointer to a symbol in the program image
|
// value that can be used instead of a pointer to a symbol in the program image
|
||||||
APP_IMAGE_SYMBOL :: rawptr(addr_t(0))
|
APP_IMAGE_SYMBOL :: rawptr(addr_t(0))
|
||||||
// pointer to a symbol in the callers image (same as B_CURRENT_IMAGE_SYMBOL)
|
// pointer to a symbol in the callers image (same as B_CURRENT_IMAGE_SYMBOL)
|
||||||
current_image_symbol :: proc() -> rawptr { return rawptr(current_image_symbol) }
|
current_image_symbol :: proc "contextless" () -> rawptr { return rawptr(current_image_symbol) }
|
||||||
|
|
||||||
foreign import libroot "system:c"
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
find_directory :: proc(which: directory_which, volume: dev_t, createIt: bool, pathString: [^]c.char, length: i32) -> status_t ---
|
find_directory :: proc(which: directory_which, volume: dev_t, createIt: bool, pathString: [^]byte, length: i32) -> status_t ---
|
||||||
find_path :: proc(codePointer: rawptr, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
|
find_path :: proc(codePointer: rawptr, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||||
find_path_etc :: proc(codePointer: rawptr, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
|
find_path_etc :: proc(codePointer: rawptr, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||||
find_path_for_path :: proc(path: cstring, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
|
find_path_for_path :: proc(path: cstring, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||||
find_path_for_path_etc :: proc(path: cstring, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
|
find_path_for_path_etc :: proc(path: cstring, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||||
find_paths :: proc(baseDirectory: path_base_directory, subPath: cstring, _paths: ^[^][^]c.char, _pathCount: ^c.size_t) -> status_t ---
|
find_paths :: proc(baseDirectory: path_base_directory, subPath: cstring, _paths: ^[^][^]byte, _pathCount: ^uint) -> status_t ---
|
||||||
find_paths_etc :: proc(architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, _paths: ^[^][^]c.char, _pathCount: ^c.size_t) -> status_t ---
|
find_paths_etc :: proc(architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, _paths: ^[^][^]byte, _pathCount: ^uint) -> status_t ---
|
||||||
}
|
}
|
||||||
|
|||||||
+141
-145
@@ -1,8 +1,8 @@
|
|||||||
#+build haiku
|
#+build haiku
|
||||||
package sys_haiku
|
package sys_haiku
|
||||||
|
|
||||||
import "core:c"
|
import "base:intrinsics"
|
||||||
import "core:sys/unix"
|
import "core:sys/posix"
|
||||||
|
|
||||||
foreign import libroot "system:c"
|
foreign import libroot "system:c"
|
||||||
|
|
||||||
@@ -18,8 +18,8 @@ OS_NAME_LENGTH :: 32
|
|||||||
|
|
||||||
area_info :: struct {
|
area_info :: struct {
|
||||||
area: area_id,
|
area: area_id,
|
||||||
name: [OS_NAME_LENGTH]c.char,
|
name: [OS_NAME_LENGTH]byte,
|
||||||
size: c.size_t,
|
size: uint,
|
||||||
lock: u32,
|
lock: u32,
|
||||||
protection: u32,
|
protection: u32,
|
||||||
team: team_id,
|
team: team_id,
|
||||||
@@ -31,11 +31,11 @@ area_info :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
area_locking :: enum u32 {
|
area_locking :: enum u32 {
|
||||||
NO_LOCK = 0,
|
NO_LOCK = 0,
|
||||||
LAZY_LOCK = 1,
|
LAZY_LOCK = 1,
|
||||||
FULL_LOCK = 2,
|
FULL_LOCK = 2,
|
||||||
CONTIGUOUS = 3,
|
CONTIGUOUS = 3,
|
||||||
LOMEM = 4, // CONTIGUOUS, < 16 MB physical address
|
LOMEM = 4, // CONTIGUOUS, < 16 MB physical address
|
||||||
_32_BIT_FULL_LOCK = 5, // FULL_LOCK, < 4 GB physical addresses
|
_32_BIT_FULL_LOCK = 5, // FULL_LOCK, < 4 GB physical addresses
|
||||||
_32_BIT_CONTIGUOUS = 6, // CONTIGUOUS, < 4 GB physical address
|
_32_BIT_CONTIGUOUS = 6, // CONTIGUOUS, < 4 GB physical address
|
||||||
}
|
}
|
||||||
@@ -52,27 +52,29 @@ address_spec :: enum u32 {
|
|||||||
RANDOMIZED_BASE_ADDRESS = 7,
|
RANDOMIZED_BASE_ADDRESS = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
area_protection_flags :: enum u32 {
|
area_protection_flag :: enum u32 {
|
||||||
READ_AREA = 1 << 0,
|
READ_AREA = 0,
|
||||||
WRITE_AREA = 1 << 1,
|
WRITE_AREA = 1,
|
||||||
EXECUTE_AREA = 1 << 2,
|
EXECUTE_AREA = 2,
|
||||||
// "stack" protection is not available on most platforms - it's used
|
// "stack" protection is not available on most platforms - it's used
|
||||||
// to only commit memory as needed, and have guard pages at the
|
// to only commit memory as needed, and have guard pages at the
|
||||||
// bottom of the stack.
|
// bottom of the stack.
|
||||||
STACK_AREA = 1 << 3,
|
STACK_AREA = 3,
|
||||||
CLONEABLE_AREA = 1 << 8,
|
CLONEABLE_AREA = 8,
|
||||||
}
|
}
|
||||||
|
area_protection_flags :: distinct bit_set[area_protection_flag; u32]
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
create_area :: proc(name: cstring, startAddress: ^rawptr, addressSpec: address_spec, size: c.size_t, lock: area_locking, protection: area_protection_flags) -> area_id ---
|
create_area :: proc(name: cstring, startAddress: ^rawptr, addressSpec: address_spec, size: uint, lock: area_locking, protection: area_protection_flags) -> area_id ---
|
||||||
clone_area :: proc(name: cstring, destAddress: ^rawptr, addressSpec: address_spec, protection: area_protection_flags, source: area_id) -> area_id ---
|
clone_area :: proc(name: cstring, destAddress: ^rawptr, addressSpec: address_spec, protection: area_protection_flags, source: area_id) -> area_id ---
|
||||||
find_area :: proc(name: cstring) -> area_id ---
|
find_area :: proc(name: cstring) -> area_id ---
|
||||||
area_for :: proc(address: rawptr) -> area_id ---
|
area_for :: proc(address: rawptr) -> area_id ---
|
||||||
delete_area :: proc(id: area_id) -> status_t ---
|
delete_area :: proc(id: area_id) -> status_t ---
|
||||||
resize_area :: proc(id: area_id, newSize: c.size_t) -> status_t ---
|
resize_area :: proc(id: area_id, newSize: uint) -> status_t ---
|
||||||
set_area_protection :: proc(id: area_id, newProtection: area_protection_flags) -> status_t ---
|
set_area_protection :: proc(id: area_id, newProtection: area_protection_flags) -> status_t ---
|
||||||
_get_area_info :: proc(id: area_id, areaInfo: ^area_info, size: c.size_t) -> status_t ---
|
_get_area_info :: proc(id: area_id, areaInfo: ^area_info, size: uint) -> status_t ---
|
||||||
_get_next_area_info :: proc(team: team_id, cookie: ^c.ssize_t, areaInfo: ^area_info, size: c.size_t) -> status_t ---
|
_get_next_area_info :: proc(team: team_id, cookie: ^int, areaInfo: ^area_info, size: uint) -> status_t ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ports
|
// Ports
|
||||||
@@ -80,33 +82,35 @@ foreign libroot {
|
|||||||
port_info :: struct {
|
port_info :: struct {
|
||||||
port: port_id,
|
port: port_id,
|
||||||
team: team_id,
|
team: team_id,
|
||||||
name: [OS_NAME_LENGTH]c.char,
|
name: [OS_NAME_LENGTH]byte,
|
||||||
capacity: i32, // queue depth
|
capacity: i32, // queue depth
|
||||||
queue_count: i32, // # msgs waiting to be read
|
queue_count: i32, // # msgs waiting to be read
|
||||||
total_count: i32, // total # msgs read so far
|
total_count: i32, // total # msgs read so far
|
||||||
}
|
}
|
||||||
|
|
||||||
port_flags :: enum u32 {
|
port_flag :: enum u32 {
|
||||||
USE_USER_MEMCPY = 0x80000000,
|
USE_USER_MEMCPY = intrinsics.constant_log2(0x80000000),
|
||||||
// read the message, but don't remove it; kernel-only; memory must be locked
|
// read the message, but don't remove it; kernel-only; memory must be locked
|
||||||
PEEK_PORT_MESSAGE = 0x100,
|
PEEK_PORT_MESSAGE = intrinsics.constant_log2(0x100),
|
||||||
}
|
}
|
||||||
|
port_flags :: distinct bit_set[port_flag; u32]
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
create_port :: proc(capacity: i32, name: cstring) -> port_id ---
|
create_port :: proc(capacity: i32, name: cstring) -> port_id ---
|
||||||
find_port :: proc(name: cstring) -> port_id ---
|
find_port :: proc(name: cstring) -> port_id ---
|
||||||
read_port :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: c.size_t) -> c.ssize_t ---
|
read_port :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: uint) -> int ---
|
||||||
read_port_etc :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: c.size_t, flags: port_flags, timeout: bigtime_t) -> c.ssize_t ---
|
read_port_etc :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: uint, flags: port_flags, timeout: bigtime_t) -> int ---
|
||||||
write_port :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: c.size_t) -> status_t ---
|
write_port :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: uint) -> status_t ---
|
||||||
write_port_etc :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: c.size_t, flags: port_flags, timeout: bigtime_t) -> status_t ---
|
write_port_etc :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: uint, flags: port_flags, timeout: bigtime_t) -> status_t ---
|
||||||
close_port :: proc(port: port_id) -> status_t ---
|
close_port :: proc(port: port_id) -> status_t ---
|
||||||
delete_port :: proc(port: port_id) -> status_t ---
|
delete_port :: proc(port: port_id) -> status_t ---
|
||||||
port_buffer_size :: proc(port: port_id) -> c.ssize_t ---
|
port_buffer_size :: proc(port: port_id) -> int ---
|
||||||
port_buffer_size_etc :: proc(port: port_id, flags: port_flags, timeout: bigtime_t) -> c.ssize_t ---
|
port_buffer_size_etc :: proc(port: port_id, flags: port_flags, timeout: bigtime_t) -> int ---
|
||||||
port_count :: proc(port: port_id) -> c.ssize_t ---
|
port_count :: proc(port: port_id) -> int ---
|
||||||
set_port_owner :: proc(port: port_id, team: team_id) -> status_t ---
|
set_port_owner :: proc(port: port_id, team: team_id) -> status_t ---
|
||||||
_get_port_info :: proc(port: port_id, portInfo: ^port_info, portInfoSize: c.size_t) -> status_t ---
|
_get_port_info :: proc(port: port_id, portInfo: ^port_info, portInfoSize: uint) -> status_t ---
|
||||||
_get_next_port_info :: proc(team: team_id, cookie: ^i32, portInfo: ^port_info, portInfoSize: c.size_t) -> status_t ---
|
_get_next_port_info :: proc(team: team_id, cookie: ^i32, portInfo: ^port_info, portInfoSize: uint) -> status_t ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// Semaphores
|
// Semaphores
|
||||||
@@ -114,22 +118,24 @@ foreign libroot {
|
|||||||
sem_info :: struct {
|
sem_info :: struct {
|
||||||
sem: sem_id,
|
sem: sem_id,
|
||||||
team: team_id,
|
team: team_id,
|
||||||
name: [OS_NAME_LENGTH]c.char,
|
name: [OS_NAME_LENGTH]byte,
|
||||||
count: i32,
|
count: i32,
|
||||||
latest_holder: thread_id,
|
latest_holder: thread_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore_flags :: enum u32 {
|
semaphore_flag :: enum u32 {
|
||||||
CAN_INTERRUPT = 0x01, // acquisition of the semaphore can be interrupted (system use only)
|
CAN_INTERRUPT = intrinsics.constant_log2(0x01), // acquisition of the semaphore can be interrupted (system use only)
|
||||||
CHECK_PERMISSION = 0x04, // ownership will be checked (system use only)
|
CHECK_PERMISSION = intrinsics.constant_log2(0x04), // ownership will be checked (system use only)
|
||||||
KILL_CAN_INTERRUPT = 0x20, // acquisition of the semaphore can be interrupted by SIGKILL[THR], even if not CAN_INTERRUPT (system use only)
|
KILL_CAN_INTERRUPT = intrinsics.constant_log2(0x20), // acquisition of the semaphore can be interrupted by SIGKILL[THR], even if not CAN_INTERRUPT (system use only)
|
||||||
|
|
||||||
// release_sem_etc() only flags
|
// release_sem_etc() only flags
|
||||||
DO_NOT_RESCHEDULE = 0x02, // thread is not rescheduled
|
DO_NOT_RESCHEDULE = intrinsics.constant_log2(0x02), // thread is not rescheduled
|
||||||
RELEASE_ALL = 0x08, // all waiting threads will be woken up, count will be zeroed
|
RELEASE_ALL = intrinsics.constant_log2(0x08), // all waiting threads will be woken up, count will be zeroed
|
||||||
RELEASE_IF_WAITING_ONLY = 0x10, // release count only if there are any threads waiting
|
RELEASE_IF_WAITING_ONLY = intrinsics.constant_log2(0x10), // release count only if there are any threads waiting
|
||||||
}
|
}
|
||||||
|
semaphore_flags :: distinct bit_set[semaphore_flag; u32]
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
create_sem :: proc(count: i32, name: cstring) -> sem_id ---
|
create_sem :: proc(count: i32, name: cstring) -> sem_id ---
|
||||||
delete_sem :: proc(id: sem_id) -> status_t ---
|
delete_sem :: proc(id: sem_id) -> status_t ---
|
||||||
@@ -141,8 +147,8 @@ foreign libroot {
|
|||||||
switch_sem_etc :: proc(semToBeReleased: sem_id, id: sem_id, count: i32, flags: semaphore_flags, timeout: bigtime_t) -> status_t ---
|
switch_sem_etc :: proc(semToBeReleased: sem_id, id: sem_id, count: i32, flags: semaphore_flags, timeout: bigtime_t) -> status_t ---
|
||||||
get_sem_count :: proc(id: sem_id, threadCount: ^i32) -> status_t ---
|
get_sem_count :: proc(id: sem_id, threadCount: ^i32) -> status_t ---
|
||||||
set_sem_owner :: proc(id: sem_id, team: team_id) -> status_t ---
|
set_sem_owner :: proc(id: sem_id, team: team_id) -> status_t ---
|
||||||
_get_sem_info :: proc(id: sem_id, info: ^sem_info, infoSize: c.size_t) -> status_t ---
|
_get_sem_info :: proc(id: sem_id, info: ^sem_info, infoSize: uint) -> status_t ---
|
||||||
_get_next_sem_info :: proc(team: team_id, cookie: ^i32, info: ^sem_info, infoSize: c.size_t) -> status_t ---
|
_get_next_sem_info :: proc(team: team_id, cookie: ^i32, info: ^sem_info, infoSize: uint) -> status_t ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teams
|
// Teams
|
||||||
@@ -155,7 +161,7 @@ team_info :: struct {
|
|||||||
debugger_nub_thread: thread_id,
|
debugger_nub_thread: thread_id,
|
||||||
debugger_nub_port: port_id,
|
debugger_nub_port: port_id,
|
||||||
argc: i32,
|
argc: i32,
|
||||||
args: [64]c.char,
|
args: [64]byte,
|
||||||
uid: uid_t,
|
uid: uid_t,
|
||||||
gid: gid_t,
|
gid: gid_t,
|
||||||
|
|
||||||
@@ -165,7 +171,7 @@ team_info :: struct {
|
|||||||
group_id: pid_t,
|
group_id: pid_t,
|
||||||
session_id: pid_t,
|
session_id: pid_t,
|
||||||
parent: team_id,
|
parent: team_id,
|
||||||
name: [OS_NAME_LENGTH]c.char,
|
name: [OS_NAME_LENGTH]byte,
|
||||||
start_time: bigtime_t,
|
start_time: bigtime_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,17 +189,18 @@ team_usage_who :: enum i32 {
|
|||||||
CHILDREN = -1,
|
CHILDREN = -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
// see also: send_signal()
|
// see also: send_signal()
|
||||||
kill_team :: proc(team: team_id) -> status_t ---
|
kill_team :: proc(team: team_id) -> status_t ---
|
||||||
_get_team_info :: proc(id: team_id, info: ^team_info, size: c.size_t) -> status_t ---
|
_get_team_info :: proc(id: team_id, info: ^team_info, size: uint) -> status_t ---
|
||||||
_get_next_team_info :: proc(cookie: ^i32, info: ^team_info, size: c.size_t) -> status_t ---
|
_get_next_team_info :: proc(cookie: ^i32, info: ^team_info, size: uint) -> status_t ---
|
||||||
_get_team_usage_info :: proc(id: team_id, who: team_usage_who, info: ^team_usage_info, size: c.size_t) -> status_t ---
|
_get_team_usage_info :: proc(id: team_id, who: team_usage_who, info: ^team_usage_info, size: uint) -> status_t ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// Threads
|
// Threads
|
||||||
|
|
||||||
thread_state :: enum c.int {
|
thread_state :: enum i32 {
|
||||||
RUNNING = 1,
|
RUNNING = 1,
|
||||||
READY,
|
READY,
|
||||||
RECEIVING,
|
RECEIVING,
|
||||||
@@ -205,7 +212,7 @@ thread_state :: enum c.int {
|
|||||||
thread_info :: struct {
|
thread_info :: struct {
|
||||||
thread: thread_id,
|
thread: thread_id,
|
||||||
team: team_id,
|
team: team_id,
|
||||||
name: [OS_NAME_LENGTH]c.char,
|
name: [OS_NAME_LENGTH]byte,
|
||||||
state: thread_state,
|
state: thread_state,
|
||||||
priority: thread_priority,
|
priority: thread_priority,
|
||||||
sem: sem_id,
|
sem: sem_id,
|
||||||
@@ -234,6 +241,7 @@ SYSTEM_TIMEBASE :: 0
|
|||||||
|
|
||||||
thread_func :: #type proc "c" (rawptr) -> status_t
|
thread_func :: #type proc "c" (rawptr) -> status_t
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
spawn_thread :: proc(thread_func, name: cstring, priority: thread_priority, data: rawptr) -> thread_id ---
|
spawn_thread :: proc(thread_func, name: cstring, priority: thread_priority, data: rawptr) -> thread_id ---
|
||||||
kill_thread :: proc(thread: thread_id) -> status_t ---
|
kill_thread :: proc(thread: thread_id) -> status_t ---
|
||||||
@@ -247,24 +255,25 @@ foreign libroot {
|
|||||||
wait_for_thread_etc :: proc(id: thread_id, flags: u32, timeout: bigtime_t, _returnCode: ^status_t) -> status_t ---
|
wait_for_thread_etc :: proc(id: thread_id, flags: u32, timeout: bigtime_t, _returnCode: ^status_t) -> status_t ---
|
||||||
on_exit_thread :: proc(callback: proc "c" (rawptr), data: rawptr) -> status_t ---
|
on_exit_thread :: proc(callback: proc "c" (rawptr), data: rawptr) -> status_t ---
|
||||||
find_thread :: proc(name: cstring) -> thread_id ---
|
find_thread :: proc(name: cstring) -> thread_id ---
|
||||||
send_data :: proc(thread: thread_id, code: i32, buffer: rawptr, bufferSize: c.size_t) -> status_t ---
|
send_data :: proc(thread: thread_id, code: i32, buffer: rawptr, bufferSize: uint) -> status_t ---
|
||||||
receive_data :: proc(sender: ^thread_id, buffer: rawptr, bufferSize: c.size_t) -> i32 ---
|
receive_data :: proc(sender: ^thread_id, buffer: rawptr, bufferSize: uint) -> i32 ---
|
||||||
has_data :: proc(thread: thread_id) -> bool ---
|
has_data :: proc(thread: thread_id) -> bool ---
|
||||||
snooze :: proc(amount: bigtime_t) -> status_t ---
|
snooze :: proc(amount: bigtime_t) -> status_t ---
|
||||||
// FIXME: Find and define those flags.
|
// FIXME: Find and define those flags.
|
||||||
snooze_etc :: proc(amount: bigtime_t, timeBase: c.int, flags: u32) -> status_t ---
|
snooze_etc :: proc(amount: bigtime_t, timeBase: i32, flags: u32) -> status_t ---
|
||||||
snooze_until :: proc(time: bigtime_t, timeBase: c.int) -> status_t ---
|
snooze_until :: proc(time: bigtime_t, timeBase: i32) -> status_t ---
|
||||||
_get_thread_info :: proc(id: thread_id, info: ^thread_info, size: c.size_t) -> status_t ---
|
_get_thread_info :: proc(id: thread_id, info: ^thread_info, size: uint) -> status_t ---
|
||||||
_get_next_thread_info :: proc(team: team_id, cookie: ^i32, info: ^thread_info, size: c.size_t) -> status_t ---
|
_get_next_thread_info :: proc(team: team_id, cookie: ^i32, info: ^thread_info, size: uint) -> status_t ---
|
||||||
// bridge to the pthread API
|
// bridge to the pthread API
|
||||||
get_pthread_thread_id :: proc(thread: pthread_t) -> thread_id ---
|
get_pthread_thread_id :: proc(thread: pthread_t) -> thread_id ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time
|
// Time
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
real_time_clock :: proc() -> c.ulong ---
|
real_time_clock :: proc() -> uint ---
|
||||||
set_real_time_clock :: proc(secsSinceJan1st1970: c.ulong) ---
|
set_real_time_clock :: proc(secsSinceJan1st1970: uint) ---
|
||||||
real_time_clock_usecs :: proc() -> bigtime_t ---
|
real_time_clock_usecs :: proc() -> bigtime_t ---
|
||||||
// time since booting in microseconds
|
// time since booting in microseconds
|
||||||
system_time :: proc() -> bigtime_t ---
|
system_time :: proc() -> bigtime_t ---
|
||||||
@@ -280,12 +289,14 @@ alarm_mode :: enum u32 {
|
|||||||
PERIODIC_ALARM, // "when" specifies the period
|
PERIODIC_ALARM, // "when" specifies the period
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
set_alarm :: proc(_when: bigtime_t, mode: alarm_mode) -> bigtime_t ---
|
set_alarm :: proc(_when: bigtime_t, mode: alarm_mode) -> bigtime_t ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debugger
|
// Debugger
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
debugger :: proc(message: cstring) ---
|
debugger :: proc(message: cstring) ---
|
||||||
/*
|
/*
|
||||||
@@ -296,7 +307,7 @@ foreign libroot {
|
|||||||
|
|
||||||
to re-enable the default debugger pass a zero.
|
to re-enable the default debugger pass a zero.
|
||||||
*/
|
*/
|
||||||
disable_debugger :: proc(state: c.int) -> c.int ---
|
disable_debugger :: proc(state: i32) -> i32 ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// System information
|
// System information
|
||||||
@@ -338,15 +349,15 @@ system_info :: struct {
|
|||||||
max_teams: u32,
|
max_teams: u32,
|
||||||
used_teams: u32,
|
used_teams: u32,
|
||||||
|
|
||||||
kernel_name: [FILE_NAME_LENGTH]c.char,
|
kernel_name: [FILE_NAME_LENGTH]byte,
|
||||||
kernel_build_date: [OS_NAME_LENGTH]c.char,
|
kernel_build_date: [OS_NAME_LENGTH]byte,
|
||||||
kernel_build_time: [OS_NAME_LENGTH]c.char,
|
kernel_build_time: [OS_NAME_LENGTH]byte,
|
||||||
|
|
||||||
kernel_version: i64,
|
kernel_version: i64,
|
||||||
abi: u32, // the system API
|
abi: u32, // the system API
|
||||||
}
|
}
|
||||||
|
|
||||||
topology_level_type :: enum c.int {
|
topology_level_type :: enum i32 {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
ROOT,
|
ROOT,
|
||||||
SMT,
|
SMT,
|
||||||
@@ -354,7 +365,7 @@ topology_level_type :: enum c.int {
|
|||||||
PACKAGE,
|
PACKAGE,
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_platform :: enum c.int {
|
cpu_platform :: enum i32 {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
x86,
|
x86,
|
||||||
x86_64,
|
x86_64,
|
||||||
@@ -370,7 +381,7 @@ cpu_platform :: enum c.int {
|
|||||||
RISC_V,
|
RISC_V,
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_vendor :: enum c.int {
|
cpu_vendor :: enum i32 {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
AMD,
|
AMD,
|
||||||
CYRIX,
|
CYRIX,
|
||||||
@@ -408,95 +419,80 @@ cpu_topology_node_info :: struct {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Add cpuid_info when bit fields are ready.
|
when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
|
||||||
|
cpuid_info :: struct #raw_union {
|
||||||
|
eax_0: struct {
|
||||||
|
max_eax: u32,
|
||||||
|
vendor_id: [12]byte,
|
||||||
|
},
|
||||||
|
|
||||||
|
eax_1: struct {
|
||||||
|
using _: bit_field u32 {
|
||||||
|
stepping: u32 | 4,
|
||||||
|
model: u32 | 4,
|
||||||
|
family: u32 | 4,
|
||||||
|
type: u32 | 2,
|
||||||
|
reserved_0: u32 | 2,
|
||||||
|
extended_model: u32 | 4,
|
||||||
|
extended_family: u32 | 8,
|
||||||
|
reserved_1: u32 | 4,
|
||||||
|
},
|
||||||
|
|
||||||
|
using _: bit_field u32 {
|
||||||
|
brand_index: u32 | 8,
|
||||||
|
clflush: u32 | 8,
|
||||||
|
logical_cpus: u32 | 8,
|
||||||
|
apic_id: u32 | 8,
|
||||||
|
},
|
||||||
|
|
||||||
|
features: u32,
|
||||||
|
extended_features: u32,
|
||||||
|
},
|
||||||
|
|
||||||
|
eax_2: struct {
|
||||||
|
call_num: u8,
|
||||||
|
cache_descriptors: [15]u8,
|
||||||
|
},
|
||||||
|
|
||||||
|
eax_3: struct {
|
||||||
|
reserved: [2]u32,
|
||||||
|
serial_number_high: u32,
|
||||||
|
serial_number_low: u32,
|
||||||
|
},
|
||||||
|
|
||||||
|
as_chars: [16]byte,
|
||||||
|
|
||||||
|
regs: struct {
|
||||||
|
eax: u32,
|
||||||
|
ebx: u32,
|
||||||
|
edx: u32,
|
||||||
|
ecx: u32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
get_system_info :: proc(info: ^system_info) -> status_t ---
|
get_system_info :: proc(info: ^system_info) -> status_t ---
|
||||||
_get_cpu_info_etc :: proc(firstCPU: u32, cpuCount: u32, info: ^cpu_info, size: c.size_t) -> status_t ---
|
_get_cpu_info_etc :: proc(firstCPU: u32, cpuCount: u32, info: ^cpu_info, size: uint) -> status_t ---
|
||||||
get_cpu_topology_info :: proc(topologyInfos: [^]cpu_topology_node_info, topologyInfoCount: ^u32) -> status_t ---
|
get_cpu_topology_info :: proc(topologyInfos: [^]cpu_topology_node_info, topologyInfoCount: ^u32) -> status_t ---
|
||||||
|
|
||||||
is_computer_on :: proc() -> i32 ---
|
when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
|
||||||
is_computer_on_fire :: proc() -> f64 ---
|
get_cpuid :: proc(info: ^cpuid_info, eaxRegister: u32, cpuNum: u32) -> status_t ---
|
||||||
|
}
|
||||||
|
|
||||||
|
is_computer_on :: proc() -> i32 ---
|
||||||
|
is_computer_on_fire :: proc() -> f64 ---
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal.h
|
// POSIX signals
|
||||||
|
|
||||||
SIG_BLOCK :: 1
|
|
||||||
SIG_UNBLOCK :: 2
|
|
||||||
SIG_SETMASK :: 3
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The list of all defined signals:
|
|
||||||
*
|
|
||||||
* The numbering of signals for Haiku attempts to maintain
|
|
||||||
* some consistency with UN*X conventions so that things
|
|
||||||
* like "kill -9" do what you expect.
|
|
||||||
*/
|
|
||||||
|
|
||||||
SIGHUP :: 1 // hangup -- tty is gone!
|
|
||||||
SIGINT :: 2 // interrupt
|
|
||||||
SIGQUIT :: 3 // `quit' special character typed in tty
|
|
||||||
SIGILL :: 4 // illegal instruction
|
|
||||||
SIGCHLD :: 5 // child process exited
|
|
||||||
SIGABRT :: 6 // abort() called, dont' catch
|
|
||||||
SIGPIPE :: 7 // write to a pipe w/no readers
|
|
||||||
SIGFPE :: 8 // floating point exception
|
|
||||||
SIGKILL :: 9 // kill a team (not catchable)
|
|
||||||
SIGSTOP :: 10 // suspend a thread (not catchable)
|
|
||||||
SIGSEGV :: 11 // segmentation violation (read: invalid pointer)
|
|
||||||
SIGCONT :: 12 // continue execution if suspended
|
|
||||||
SIGTSTP :: 13 // `stop' special character typed in tty
|
|
||||||
SIGALRM :: 14 // an alarm has gone off (see alarm())
|
|
||||||
SIGTERM :: 15 // termination requested
|
|
||||||
SIGTTIN :: 16 // read of tty from bg process
|
|
||||||
SIGTTOU :: 17 // write to tty from bg process
|
|
||||||
SIGUSR1 :: 18 // app defined signal 1
|
|
||||||
SIGUSR2 :: 19 // app defined signal 2
|
|
||||||
SIGWINCH :: 20 // tty window size changed
|
|
||||||
SIGKILLTHR :: 21 // be specific: kill just the thread, not team
|
|
||||||
SIGTRAP :: 22 // Trace/breakpoint trap
|
|
||||||
SIGPOLL :: 23 // Pollable event
|
|
||||||
SIGPROF :: 24 // Profiling timer expired
|
|
||||||
SIGSYS :: 25 // Bad system call
|
|
||||||
SIGURG :: 26 // High bandwidth data is available at socket
|
|
||||||
SIGVTALRM :: 27 // Virtual timer expired
|
|
||||||
SIGXCPU :: 28 // CPU time limit exceeded
|
|
||||||
SIGXFSZ :: 29 // File size limit exceeded
|
|
||||||
SIGBUS :: 30 // access to undefined portion of a memory object
|
|
||||||
|
|
||||||
sigval :: struct #raw_union {
|
|
||||||
sival_int: c.int,
|
|
||||||
sival_ptr: rawptr,
|
|
||||||
}
|
|
||||||
|
|
||||||
siginfo_t :: struct {
|
|
||||||
si_signo: c.int, // signal number
|
|
||||||
si_code: c.int, // signal code
|
|
||||||
si_errno: c.int, // if non zero, an error number associated with this signal
|
|
||||||
|
|
||||||
si_pid: pid_t, // sending process ID
|
|
||||||
si_uid: uid_t, // real user ID of sending process
|
|
||||||
si_addr: rawptr, // address of faulting instruction
|
|
||||||
si_status: c.int, // exit value or signal
|
|
||||||
si_band: c.long, // band event for SIGPOLL
|
|
||||||
si_value: sigval, // signal value
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
foreign libroot {
|
foreign libroot {
|
||||||
// signal set (sigset_t) manipulation
|
/*
|
||||||
sigemptyset :: proc(set: ^sigset_t) -> c.int ---
|
Wait for queued signals.
|
||||||
sigfillset :: proc(set: ^sigset_t) -> c.int ---
|
|
||||||
sigaddset :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
|
|
||||||
sigdelset :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
|
|
||||||
sigismember :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
|
|
||||||
// querying and waiting for signals
|
|
||||||
sigpending :: proc(set: ^sigset_t) -> c.int ---
|
|
||||||
sigsuspend :: proc(mask: ^sigset_t) -> c.int ---
|
|
||||||
sigpause :: proc(_signal: c.int) -> c.int ---
|
|
||||||
sigwait :: proc(set: ^sigset_t, _signal: ^c.int) -> c.int ---
|
|
||||||
sigwaitinfo :: proc(set: ^sigset_t, info: ^siginfo_t) -> c.int ---
|
|
||||||
sigtimedwait :: proc(set: ^sigset_t, info: ^siginfo_t, timeout: ^unix.timespec) -> c.int ---
|
|
||||||
|
|
||||||
send_signal :: proc(threadID: thread_id, signal: c.uint) -> c.int ---
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigtimedwait.html ]]
|
||||||
set_signal_stack :: proc(base: rawptr, size: c.size_t) ---
|
*/
|
||||||
|
sigtimedwait :: proc(set: ^posix.sigset_t, info: ^posix.siginfo_t, timeout: ^posix.timespec) -> posix.result ---
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#+build haiku
|
#+build haiku
|
||||||
package sys_haiku
|
package sys_haiku
|
||||||
|
|
||||||
import "core:c"
|
status_t :: Errno
|
||||||
|
|
||||||
status_t :: i32
|
|
||||||
bigtime_t :: i64
|
bigtime_t :: i64
|
||||||
nanotime_t :: i64
|
nanotime_t :: i64
|
||||||
type_code :: u32
|
type_code :: u32
|
||||||
@@ -37,16 +35,20 @@ mode_t :: u32
|
|||||||
umode_t :: u32
|
umode_t :: u32
|
||||||
nlink_t :: i32
|
nlink_t :: i32
|
||||||
|
|
||||||
caddr_t :: ^c.char
|
caddr_t :: [^]byte
|
||||||
|
|
||||||
addr_t :: phys_addr_t
|
addr_t :: phys_addr_t
|
||||||
key_t :: i32
|
key_t :: i32
|
||||||
|
|
||||||
clockid_t :: i32
|
clockid_t :: i32
|
||||||
|
|
||||||
time_t :: i64 when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 else i32
|
time_t :: int
|
||||||
|
timespec :: struct {
|
||||||
|
tv_sec: time_t,
|
||||||
|
tv_nsec: int,
|
||||||
|
}
|
||||||
|
|
||||||
sig_atomic_t :: c.int
|
sig_atomic_t :: i32
|
||||||
sigset_t :: u64
|
sigset_t :: u64
|
||||||
|
|
||||||
image_id :: i32
|
image_id :: i32
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#+build darwin, linux, freebsd, openbsd, netbsd
|
#+build darwin, linux, freebsd, openbsd, netbsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
foreign import lib "system:System.framework"
|
foreign import lib "system:System.framework"
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
foreign import lib "system:network"
|
||||||
} else {
|
} else {
|
||||||
foreign import lib "system:c"
|
foreign import lib "system:c"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build darwin, linux, freebsd, openbsd, netbsd
|
#+build darwin, linux, freebsd, openbsd, netbsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -219,12 +219,23 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
dirent :: struct {
|
dirent :: struct {
|
||||||
d_ino: u64, /* [PSX] file number of entry */
|
d_ino: u64, /* [PSX] file number of entry */
|
||||||
d_off: i64, /* directory offset of the next entry */
|
d_off: i64, /* directory offset of the next entry */
|
||||||
d_reclen: u16, /* length of this record */
|
d_reclen: u16, /* length of this record */
|
||||||
d_type: D_Type, /* file type */
|
d_type: D_Type, /* file type */
|
||||||
d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */
|
d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
dirent :: struct {
|
||||||
|
d_dev: dev_t, /* device */
|
||||||
|
d_pdev: dev_t, /* parent device (only for queries) */
|
||||||
|
d_ino: ino_t, /* inode number */
|
||||||
|
d_pino: ino_t, /* parent inode (only for queries) */
|
||||||
|
d_reclen: c.ushort, /* length of this record, not the name */
|
||||||
|
d_name: [0]c.char `fmt:"s,0"`, /* name of the entry (null byte terminated) */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build windows, darwin, linux, freebsd, openbsd, netbsd
|
#+build windows, darwin, linux, freebsd, openbsd, netbsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -536,5 +536,92 @@ when ODIN_OS == .Darwin {
|
|||||||
ETXTBSY :: 139
|
ETXTBSY :: 139
|
||||||
EWOULDBLOCK :: 140
|
EWOULDBLOCK :: 140
|
||||||
EXDEV :: 18
|
EXDEV :: 18
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
_HAIKU_USE_POSITIVE_POSIX_ERRORS :: libc._HAIKU_USE_POSITIVE_POSIX_ERRORS
|
||||||
|
_POSIX_ERROR_FACTOR :: libc._POSIX_ERROR_FACTOR
|
||||||
|
|
||||||
|
_GENERAL_ERROR_BASE :: min(c.int)
|
||||||
|
_OS_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x1000
|
||||||
|
_STORAGE_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x6000
|
||||||
|
_POSIX_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x7000
|
||||||
|
|
||||||
|
EIO :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 1) // B_IO_ERROR
|
||||||
|
EACCES :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 2) // B_PERMISSION_DENIED
|
||||||
|
EINVAL :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 5) // B_BAD_VALUE
|
||||||
|
ETIMEDOUT :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 9) // B_TIMED_OUT
|
||||||
|
EINTR :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 10) // B_INTERRUPTED
|
||||||
|
EAGAIN :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 11) // B_WOULD_BLOCK /* SysV compatibility */
|
||||||
|
EWOULDBLOCK :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 11) // B_WOULD_BLOCK /* BSD compatibility */
|
||||||
|
EBUSY :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 14) // B_BUSY
|
||||||
|
EPERM :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 15) // B_NOT_ALLOWED
|
||||||
|
EFAULT :: _POSIX_ERROR_FACTOR * (_OS_ERROR_BASE + 0x301) // B_BAD_ADDRESS
|
||||||
|
ENOEXEC :: _POSIX_ERROR_FACTOR * (_OS_ERROR_BASE + 0x302) // B_NOT_AN_EXECUTABLE
|
||||||
|
EBADF :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 0) // B_FILE_ERROR
|
||||||
|
EEXIST :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 2) // B_FILE_EXISTS
|
||||||
|
ENOENT :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 3) // B_ENTRY_NOT_FOUND
|
||||||
|
ENAMETOOLONG :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 4) // B_NAME_TOO_LONG
|
||||||
|
ENOTDIR :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 5) // B_NOT_A_DIRECTORY
|
||||||
|
ENOTEMPTY :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 6) // B_DIRECTORY_NOT_EMPTY
|
||||||
|
ENOSPC :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 7) // B_DEVICE_FULL
|
||||||
|
EROFS :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 8) // B_READ_ONLY_DEVICE
|
||||||
|
EISDIR :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 9) // B_IS_A_DIRECTORY
|
||||||
|
EMFILE :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 10) // B_NO_MORE_FDS
|
||||||
|
EXDEV :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 11) // B_CROSS_DEVICE_LINK
|
||||||
|
ELOOP :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 12) // B_LINK_LIMIT
|
||||||
|
EPIPE :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 13) // B_BUSTED_PIPE
|
||||||
|
ENOMEM :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 0) when _HAIKU_USE_POSITIVE_POSIX_ERRORS else (_GENERAL_ERROR_BASE + 0) // B_NO_MEMORY
|
||||||
|
E2BIG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 1)
|
||||||
|
ECHILD :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 2)
|
||||||
|
EDEADLK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 3)
|
||||||
|
EFBIG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 4)
|
||||||
|
EMLINK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 5)
|
||||||
|
ENFILE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 6)
|
||||||
|
ENODEV :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 7)
|
||||||
|
ENOLCK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 8)
|
||||||
|
ENOSYS :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 9)
|
||||||
|
ENOTTY :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 10)
|
||||||
|
ENXIO :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 11)
|
||||||
|
ESPIPE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 12)
|
||||||
|
ESRCH :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 13)
|
||||||
|
EPROTOTYPE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 18)
|
||||||
|
EPROTONOSUPPORT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 19)
|
||||||
|
EAFNOSUPPORT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 21)
|
||||||
|
EADDRINUSE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 22)
|
||||||
|
EADDRNOTAVAIL :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 23)
|
||||||
|
ENETDOWN :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 24)
|
||||||
|
ENETUNREACH :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 25)
|
||||||
|
ENETRESET :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 26)
|
||||||
|
ECONNABORTED :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 27)
|
||||||
|
ECONNRESET :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 28)
|
||||||
|
EISCONN :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 29)
|
||||||
|
ENOTCONN :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 30)
|
||||||
|
ECONNREFUSED :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 32)
|
||||||
|
EHOSTUNREACH :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 33)
|
||||||
|
ENOPROTOOPT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 34)
|
||||||
|
ENOBUFS :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 35)
|
||||||
|
EINPROGRESS :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 36)
|
||||||
|
EALREADY :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 37)
|
||||||
|
ENOMSG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 39)
|
||||||
|
ESTALE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 40)
|
||||||
|
EOVERFLOW :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 41)
|
||||||
|
EMSGSIZE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 42)
|
||||||
|
EOPNOTSUPP :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 43)
|
||||||
|
ENOTSOCK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 44)
|
||||||
|
EBADMSG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 46)
|
||||||
|
ECANCELED :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 47)
|
||||||
|
EDESTADDRREQ :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 48)
|
||||||
|
EDQUOT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 49)
|
||||||
|
EIDRM :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 50)
|
||||||
|
EMULTIHOP :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 51)
|
||||||
|
ENODATA :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 52)
|
||||||
|
ENOLINK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 53)
|
||||||
|
ENOSR :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 54)
|
||||||
|
ENOSTR :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 55)
|
||||||
|
ENOTSUP :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 56)
|
||||||
|
EPROTO :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 57)
|
||||||
|
ETIME :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 58)
|
||||||
|
ETXTBSY :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 59)
|
||||||
|
ENOTRECOVERABLE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 61)
|
||||||
|
EOWNERDEAD :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 62)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, openbsd, freebsd, netbsd
|
#+build linux, darwin, openbsd, freebsd, netbsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -343,6 +343,7 @@ when ODIN_OS == .Darwin {
|
|||||||
l_type: Lock_Type, /* [PSX] type of lock */
|
l_type: Lock_Type, /* [PSX] type of lock */
|
||||||
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
|
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else when ODIN_OS == .OpenBSD {
|
} else when ODIN_OS == .OpenBSD {
|
||||||
|
|
||||||
off_t :: distinct c.int64_t
|
off_t :: distinct c.int64_t
|
||||||
@@ -408,6 +409,72 @@ when ODIN_OS == .Darwin {
|
|||||||
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
|
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
off_t :: distinct c.int64_t
|
||||||
|
pid_t :: distinct c.int32_t
|
||||||
|
|
||||||
|
/* commands that can be passed to fcntl() */
|
||||||
|
F_DUPFD :: 0x0001 /* duplicate fd */
|
||||||
|
F_GETFD :: 0x0002 /* get fd flags */
|
||||||
|
F_SETFD :: 0x0004 /* set fd flags */
|
||||||
|
F_GETFL :: 0x0008 /* get file status flags and access mode */
|
||||||
|
F_SETFL :: 0x0010 /* set file status flags */
|
||||||
|
F_GETLK :: 0x0020 /* get locking information */
|
||||||
|
F_SETLK :: 0x0080 /* set locking information */
|
||||||
|
F_SETLKW :: 0x0100 /* as above, but waits if blocked */
|
||||||
|
F_DUPFD_CLOEXEC :: 0x0200 /* duplicate fd with close on exec set */
|
||||||
|
F_GETOWN :: -1 // NOTE: Not supported.
|
||||||
|
F_SETOWN :: -1 // NOTE: Not supported.
|
||||||
|
|
||||||
|
/* advisory locking types */
|
||||||
|
F_RDLCK :: 0x0040 /* read or shared lock */
|
||||||
|
F_UNLCK :: 0x0200 /* unlock */
|
||||||
|
F_WRLCK :: 0x0400 /* write or exclusive lock */
|
||||||
|
|
||||||
|
/* file descriptor flags for fcntl() */
|
||||||
|
FD_CLOEXEC :: 1
|
||||||
|
|
||||||
|
O_CLOEXEC :: 0x00000040
|
||||||
|
O_CREAT :: 0x0200
|
||||||
|
O_DIRECTORY :: 0x00200000
|
||||||
|
O_EXCL :: 0x0100
|
||||||
|
O_NOCTTY :: 0x1000
|
||||||
|
O_NOFOLLOW :: 0x00080000
|
||||||
|
O_TRUNC :: 0x0400
|
||||||
|
|
||||||
|
_O_TTY_INIT :: 0
|
||||||
|
O_TTY_INIT :: O_Flags{} // NOTE: not defined in the headers
|
||||||
|
|
||||||
|
O_APPEND :: 0x0800
|
||||||
|
O_DSYNC :: 0x040000
|
||||||
|
O_NONBLOCK :: 0x0080
|
||||||
|
O_SYNC :: 0x010000
|
||||||
|
O_RSYNC :: 0x020000
|
||||||
|
|
||||||
|
O_EXEC :: 0x04000000 // NOTE: not defined in the headers
|
||||||
|
O_RDONLY :: 0
|
||||||
|
O_RDWR :: 0x0002
|
||||||
|
O_WRONLY :: 0x0001
|
||||||
|
|
||||||
|
_O_SEARCH :: 0
|
||||||
|
O_SEARCH :: O_Flags{} // NOTE: not defined in the headers
|
||||||
|
|
||||||
|
AT_FDCWD: FD: -100
|
||||||
|
|
||||||
|
AT_EACCESS :: 0x08
|
||||||
|
AT_SYMLINK_NOFOLLOW :: 0x01
|
||||||
|
AT_SYMLINK_FOLLOW :: 0x02
|
||||||
|
AT_REMOVEDIR :: 0x04
|
||||||
|
|
||||||
|
flock :: struct {
|
||||||
|
l_type: Lock_Type, /* [PSX] type of lock */
|
||||||
|
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
|
||||||
|
l_start: off_t, /* [PSX] relative offset in bytes */
|
||||||
|
l_len: off_t, /* [PSX] size; if 0 then until EOF */
|
||||||
|
l_pid: pid_t, /* [PSX] process ID of the process holding the lock */
|
||||||
|
}
|
||||||
|
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
off_t :: distinct c.int64_t
|
off_t :: distinct c.int64_t
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build darwin, linux, openbsd, freebsd, netbsd
|
#+build darwin, linux, openbsd, freebsd, netbsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -46,7 +46,7 @@ FNM_Flag_Bits :: enum c.int {
|
|||||||
}
|
}
|
||||||
FNM_Flags :: bit_set[FNM_Flag_Bits; c.int]
|
FNM_Flags :: bit_set[FNM_Flag_Bits; c.int]
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
FNM_NOMATCH :: 1
|
FNM_NOMATCH :: 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -109,7 +109,7 @@ when ODIN_OS == .Darwin {
|
|||||||
GLOB_NOMATCH :: -3
|
GLOB_NOMATCH :: -3
|
||||||
GLOB_NOSPACE :: -1
|
GLOB_NOSPACE :: -1
|
||||||
|
|
||||||
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
|
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
glob_t :: struct {
|
glob_t :: struct {
|
||||||
gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
|
gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
|
||||||
@@ -134,7 +134,7 @@ when ODIN_OS == .Darwin {
|
|||||||
GLOB_ERR :: 0x0004
|
GLOB_ERR :: 0x0004
|
||||||
GLOB_MARK :: 0x0008
|
GLOB_MARK :: 0x0008
|
||||||
GLOB_NOCHECK :: 0x0010
|
GLOB_NOCHECK :: 0x0010
|
||||||
GLOB_NOESCAPE :: 0x2000 when ODIN_OS == .FreeBSD else 0x0100
|
GLOB_NOESCAPE :: 0x2000 when ODIN_OS == .FreeBSD || ODIN_OS == .Haiku else 0x0100
|
||||||
GLOB_NOSORT :: 0x0020
|
GLOB_NOSORT :: 0x0020
|
||||||
|
|
||||||
GLOB_ABORTED :: -2
|
GLOB_ABORTED :: -2
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -115,7 +115,7 @@ foreign lib {
|
|||||||
getgrnam_r :: proc(name: cstring, grp: ^group, buffer: [^]byte, bufsize: c.size_t, result: ^^group) -> Errno ---
|
getgrnam_r :: proc(name: cstring, grp: ^group, buffer: [^]byte, bufsize: c.size_t, result: ^^group) -> Errno ---
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku || ODIN_OS == .Linux {
|
||||||
|
|
||||||
gid_t :: distinct c.uint32_t
|
gid_t :: distinct c.uint32_t
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -143,7 +143,7 @@ nl_item :: enum nl_item_t {
|
|||||||
CRNCYSTR = CRNCYSTR,
|
CRNCYSTR = CRNCYSTR,
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
// NOTE: declared with `_t` so we can enumerate the real `nl_info`.
|
// NOTE: declared with `_t` so we can enumerate the real `nl_info`.
|
||||||
nl_item_t :: distinct c.int
|
nl_item_t :: distinct c.int
|
||||||
@@ -210,7 +210,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
|
|||||||
YESEXPR :: 52
|
YESEXPR :: 52
|
||||||
NOEXPR :: 53
|
NOEXPR :: 53
|
||||||
|
|
||||||
CRNCYSTR :: 56
|
CRNCYSTR :: 54 when ODIN_OS == .Haiku else 56
|
||||||
|
|
||||||
} else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
} else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build windows, linux, darwin, netbsd, openbsd, freebsd
|
#+build windows, linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c/libc"
|
import "core:c/libc"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -319,7 +319,7 @@ Info_Errno :: enum c.int {
|
|||||||
OVERFLOW = EAI_OVERFLOW,
|
OVERFLOW = EAI_OVERFLOW,
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
hostent :: struct {
|
hostent :: struct {
|
||||||
h_name: cstring, /* [PSX] official name of host */
|
h_name: cstring, /* [PSX] official name of host */
|
||||||
@@ -431,6 +431,23 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
NI_NUMERICSCOPE :: 0x100
|
NI_NUMERICSCOPE :: 0x100
|
||||||
NI_DGRAM :: 16
|
NI_DGRAM :: 16
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
AI_PASSIVE :: 0x001
|
||||||
|
AI_CANONNAME :: 0x002
|
||||||
|
AI_NUMERICHOST :: 0x004
|
||||||
|
AI_NUMERICSERV :: 0x008
|
||||||
|
AI_V4MAPPED :: 0x800
|
||||||
|
AI_ALL :: 0x100
|
||||||
|
AI_ADDRCONFIG :: 0x400
|
||||||
|
|
||||||
|
NI_NOFQDN :: 0x01
|
||||||
|
NI_NUMERICHOST :: 0x02
|
||||||
|
NI_NAMEREQD :: 0x04
|
||||||
|
NI_NUMERICSERV :: 0x08
|
||||||
|
NI_DGRAM :: 0x10
|
||||||
|
NI_NUMERICSCOPE :: 0x40
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .OpenBSD {
|
when ODIN_OS == .OpenBSD {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -31,20 +31,31 @@ Protocol :: enum c.int {
|
|||||||
UDP = IPPROTO_UDP,
|
UDP = IPPROTO_UDP,
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
in_addr :: struct {
|
in_addr :: struct {
|
||||||
s_addr: in_addr_t, /* [PSX] big endian address */
|
s_addr: in_addr_t, /* [PSX] big endian address */
|
||||||
}
|
}
|
||||||
|
|
||||||
in6_addr :: struct {
|
when ODIN_OS == .Haiku {
|
||||||
using _: struct #raw_union {
|
in6_addr :: struct #packed {
|
||||||
s6_addr: [16]c.uint8_t, /* [PSX] big endian address */
|
using _: struct #raw_union {
|
||||||
__u6_addr16: [8]c.uint16_t,
|
s6_addr: [16]c.uint8_t, /* [PSX] big endian address */
|
||||||
__u6_addr32: [4]c.uint32_t,
|
__u6_addr16: [8]c.uint16_t,
|
||||||
},
|
__u6_addr32: [4]c.uint32_t,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
in6_addr :: struct {
|
||||||
|
using _: struct #raw_union {
|
||||||
|
s6_addr: [16]c.uint8_t, /* [PSX] big endian address */
|
||||||
|
__u6_addr16: [8]c.uint16_t,
|
||||||
|
__u6_addr32: [4]c.uint32_t,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
when ODIN_OS == .Linux {
|
when ODIN_OS == .Linux {
|
||||||
|
|
||||||
sockaddr_in :: struct {
|
sockaddr_in :: struct {
|
||||||
@@ -77,12 +88,20 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
when ODIN_OS == .Haiku {
|
||||||
|
@(private)
|
||||||
|
_SIN_ZEROSIZE :: 24
|
||||||
|
} else {
|
||||||
|
@(private)
|
||||||
|
_SIN_ZEROSIZE :: 8
|
||||||
|
}
|
||||||
|
|
||||||
sockaddr_in :: struct {
|
sockaddr_in :: struct {
|
||||||
sin_len: c.uint8_t,
|
sin_len: c.uint8_t,
|
||||||
sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */
|
sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */
|
||||||
sin_port: in_port_t, /* [PSX] port number */
|
sin_port: in_port_t, /* [PSX] port number */
|
||||||
sin_addr: in_addr, /* [PSX] IP address */
|
sin_addr: in_addr, /* [PSX] IP address */
|
||||||
sin_zero: [8]c.char,
|
sin_zero: [_SIN_ZEROSIZE]c.char,
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_in6 :: struct {
|
sockaddr_in6 :: struct {
|
||||||
@@ -99,13 +118,23 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
ipv6mr_interface: c.uint, /* [PSX] interface index */
|
ipv6mr_interface: c.uint, /* [PSX] interface index */
|
||||||
}
|
}
|
||||||
|
|
||||||
IPV6_JOIN_GROUP :: 12
|
when ODIN_OS == .Haiku {
|
||||||
IPV6_LEAVE_GROUP :: 13
|
IPV6_JOIN_GROUP :: 28
|
||||||
IPV6_MULTICAST_HOPS :: 10
|
IPV6_LEAVE_GROUP :: 29
|
||||||
IPV6_MULTICAST_IF :: 9
|
IPV6_MULTICAST_HOPS :: 25
|
||||||
IPV6_MULTICAST_LOOP :: 11
|
IPV6_MULTICAST_IF :: 24
|
||||||
IPV6_UNICAST_HOPS :: 4
|
IPV6_MULTICAST_LOOP :: 26
|
||||||
IPV6_V6ONLY :: 27
|
IPV6_UNICAST_HOPS :: 27
|
||||||
|
IPV6_V6ONLY :: 30
|
||||||
|
} else {
|
||||||
|
IPV6_JOIN_GROUP :: 12
|
||||||
|
IPV6_LEAVE_GROUP :: 13
|
||||||
|
IPV6_MULTICAST_HOPS :: 10
|
||||||
|
IPV6_MULTICAST_IF :: 9
|
||||||
|
IPV6_MULTICAST_LOOP :: 11
|
||||||
|
IPV6_UNICAST_HOPS :: 4
|
||||||
|
IPV6_V6ONLY :: 27
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-13
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
@@ -25,7 +25,11 @@ foreign lib {
|
|||||||
poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: c.int) -> c.int ---
|
poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: c.int) -> c.int ---
|
||||||
}
|
}
|
||||||
|
|
||||||
nfds_t :: c.uint
|
when ODIN_OS == .Haiku {
|
||||||
|
nfds_t :: c.ulong
|
||||||
|
} else {
|
||||||
|
nfds_t :: c.uint
|
||||||
|
}
|
||||||
|
|
||||||
Poll_Event_Bits :: enum c.short {
|
Poll_Event_Bits :: enum c.short {
|
||||||
// Data other than high-priority data may be read without blocking.
|
// Data other than high-priority data may be read without blocking.
|
||||||
@@ -53,7 +57,7 @@ Poll_Event_Bits :: enum c.short {
|
|||||||
}
|
}
|
||||||
Poll_Event :: bit_set[Poll_Event_Bits; c.short]
|
Poll_Event :: bit_set[Poll_Event_Bits; c.short]
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
pollfd :: struct {
|
pollfd :: struct {
|
||||||
fd: FD, /* [PSX] the following descriptor being polled */
|
fd: FD, /* [PSX] the following descriptor being polled */
|
||||||
@@ -61,17 +65,36 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
revents: Poll_Event, /* [PSX] the output event flags */
|
revents: Poll_Event, /* [PSX] the output event flags */
|
||||||
}
|
}
|
||||||
|
|
||||||
POLLIN :: 0x0001
|
when ODIN_OS == .Haiku {
|
||||||
POLLRDNORM :: 0x0040
|
|
||||||
POLLRDBAND :: 0x0080
|
POLLIN :: 0x0001 /* any readable data available */
|
||||||
POLLPRI :: 0x0002
|
POLLOUT :: 0x0002 /* file descriptor is writeable */
|
||||||
POLLOUT :: 0x0004
|
POLLRDNORM :: POLLIN
|
||||||
POLLWRNORM :: POLLOUT
|
POLLWRNORM :: POLLOUT
|
||||||
POLLWRBAND :: 0x0100
|
POLLRDBAND :: 0x0008 /* priority readable data */
|
||||||
|
POLLWRBAND :: 0x0010 /* priority data can be written */
|
||||||
|
POLLPRI :: 0x0020 /* high priority readable data */
|
||||||
|
|
||||||
|
POLLERR :: 0x0004 /* errors pending */
|
||||||
|
POLLHUP :: 0x0080 /* disconnected */
|
||||||
|
POLLNVAL :: 0x1000 /* invalid file descriptor */
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
POLLIN :: 0x0001
|
||||||
|
POLLRDNORM :: 0x0040
|
||||||
|
POLLRDBAND :: 0x0080
|
||||||
|
POLLPRI :: 0x0002
|
||||||
|
POLLOUT :: 0x0004
|
||||||
|
POLLWRNORM :: POLLOUT
|
||||||
|
POLLWRBAND :: 0x0100
|
||||||
|
|
||||||
|
POLLERR :: 0x0008
|
||||||
|
POLLHUP :: 0x0010
|
||||||
|
POLLNVAL :: 0x0020
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
POLLERR :: 0x0008
|
|
||||||
POLLHUP :: 0x0010
|
|
||||||
POLLNVAL :: 0x0020
|
|
||||||
|
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -554,6 +554,56 @@ when ODIN_OS == .Darwin {
|
|||||||
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
|
||||||
|
PTHREAD_CANCEL_DEFERRED :: 0
|
||||||
|
|
||||||
|
PTHREAD_CANCEL_DISABLE :: 1
|
||||||
|
PTHREAD_CANCEL_ENABLE :: 0
|
||||||
|
|
||||||
|
PTHREAD_CANCELED :: rawptr(uintptr(1))
|
||||||
|
|
||||||
|
PTHREAD_CREATE_DETACHED :: 0x1
|
||||||
|
PTHREAD_CREATE_JOINABLE :: 0
|
||||||
|
|
||||||
|
PTHREAD_EXPLICIT_SCHED :: 0
|
||||||
|
PTHREAD_INHERIT_SCHED :: 0x4
|
||||||
|
|
||||||
|
PTHREAD_PRIO_INHERIT :: 1
|
||||||
|
PTHREAD_PRIO_NONE :: 0
|
||||||
|
PTHREAD_PRIO_PROTECT :: 2
|
||||||
|
|
||||||
|
PTHREAD_PROCESS_SHARED :: 1
|
||||||
|
PTHREAD_PROCESS_PRIVATE :: 0
|
||||||
|
|
||||||
|
PTHREAD_SCOPE_PROCESS :: 0
|
||||||
|
PTHREAD_SCOPE_SYSTEM :: 0x2
|
||||||
|
|
||||||
|
pthread_t :: distinct rawptr
|
||||||
|
pthread_attr_t :: distinct rawptr
|
||||||
|
pthread_key_t :: distinct c.int
|
||||||
|
|
||||||
|
pthread_mutex_t :: struct {
|
||||||
|
flags: u32,
|
||||||
|
lock: i32,
|
||||||
|
unused: i32,
|
||||||
|
owner: i32,
|
||||||
|
owner_count: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cond_t :: struct {
|
||||||
|
flags: u32,
|
||||||
|
unused: i32,
|
||||||
|
mutex: ^pthread_mutex_t,
|
||||||
|
waiter_count: i32,
|
||||||
|
lock: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
sched_param :: struct {
|
||||||
|
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
||||||
|
}
|
||||||
|
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
PTHREAD_CANCEL_DEFERRED :: 0
|
PTHREAD_CANCEL_DEFERRED :: 0
|
||||||
|
|||||||
+13
-1
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -176,4 +176,16 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
|||||||
pw_shell: cstring, /* Shell program. */
|
pw_shell: cstring, /* Shell program. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
passwd :: struct {
|
||||||
|
pw_name: cstring, /* [PSX] user name */
|
||||||
|
pw_passwd: cstring, /* encrypted password */
|
||||||
|
pw_uid: uid_t, /* [PSX] user uid */
|
||||||
|
pw_gid: gid_t, /* [PSX] user gid */
|
||||||
|
pw_dir: cstring, /* Home directory. */
|
||||||
|
pw_shell: cstring, /* Shell program. */
|
||||||
|
pw_gecos: cstring, /* Real name. */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -101,4 +101,11 @@ when ODIN_OS == .Darwin {
|
|||||||
SCHED_FIFO :: 1
|
SCHED_FIFO :: 1
|
||||||
SCHED_RR :: 2
|
SCHED_RR :: 2
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
SCHED_FIFO :: 1
|
||||||
|
SCHED_RR :: 2
|
||||||
|
// SCHED_SPORADIC :: 3 NOTE: not a thing on freebsd, netbsd and probably others, leaving it out
|
||||||
|
SCHED_OTHER :: 4
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+148
-1
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
@@ -1180,4 +1180,151 @@ when ODIN_OS == .Darwin {
|
|||||||
SI_TIMER :: -2
|
SI_TIMER :: -2
|
||||||
SI_MESGQ :: -3
|
SI_MESGQ :: -3
|
||||||
SI_ASYNCIO :: -4
|
SI_ASYNCIO :: -4
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
// Request that signal be held
|
||||||
|
SIG_HOLD :: rawptr(uintptr(3))
|
||||||
|
|
||||||
|
uid_t :: distinct c.uint32_t
|
||||||
|
sigset_t :: distinct u64
|
||||||
|
|
||||||
|
SIGHUP :: 1 // hangup -- tty is gone!
|
||||||
|
//SIGINT :: 2 // interrupt
|
||||||
|
SIGQUIT :: 3 // `quit' special character typed in tty
|
||||||
|
//SIGILL :: 4 // illegal instruction
|
||||||
|
SIGCHLD :: 5 // child process exited
|
||||||
|
//SIGABRT :: 6 // abort() called, dont' catch
|
||||||
|
SIGPIPE :: 7 // write to a pipe w/no readers
|
||||||
|
//SIGFPE :: 8 // floating point exception
|
||||||
|
SIGKILL :: 9 // kill a team (not catchable)
|
||||||
|
SIGSTOP :: 10 // suspend a thread (not catchable)
|
||||||
|
//SIGSEGV :: 11 // segmentation violation (read: invalid pointer)
|
||||||
|
SIGCONT :: 12 // continue execution if suspended
|
||||||
|
SIGTSTP :: 13 // `stop' special character typed in tty
|
||||||
|
SIGALRM :: 14 // an alarm has gone off (see alarm())
|
||||||
|
//SIGTERM :: 15 // termination requested
|
||||||
|
SIGTTIN :: 16 // read of tty from bg process
|
||||||
|
SIGTTOU :: 17 // write to tty from bg process
|
||||||
|
SIGUSR1 :: 18 // app defined signal 1
|
||||||
|
SIGUSR2 :: 19 // app defined signal 2
|
||||||
|
SIGWINCH :: 20 // tty window size changed
|
||||||
|
SIGKILLTHR :: 21 // be specific: kill just the thread, not team
|
||||||
|
SIGTRAP :: 22 // Trace/breakpoint trap
|
||||||
|
SIGPOLL :: 23 // Pollable event
|
||||||
|
SIGPROF :: 24 // Profiling timer expired
|
||||||
|
SIGSYS :: 25 // Bad system call
|
||||||
|
SIGURG :: 26 // High bandwidth data is available at socket
|
||||||
|
SIGVTALRM :: 27 // Virtual timer expired
|
||||||
|
SIGXCPU :: 28 // CPU time limit exceeded
|
||||||
|
SIGXFSZ :: 29 // File size limit exceeded
|
||||||
|
SIGBUS :: 30 // access to undefined portion of a memory object
|
||||||
|
|
||||||
|
// NOTE: this is actually defined as `sigaction`, but due to the function with the same name
|
||||||
|
// `_t` has been added.
|
||||||
|
|
||||||
|
sigaction_t :: struct {
|
||||||
|
using _: struct #raw_union {
|
||||||
|
sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */
|
||||||
|
sa_sigaction: proc "c" (Signal, ^siginfo_t, rawptr), /* [PSX] signal-catching function */
|
||||||
|
},
|
||||||
|
sa_mask: sigset_t, /* [PSX] set of signals to be blocked during execution of the signal handling function */
|
||||||
|
sa_flags: SA_Flags, /* [PSX] special flags */
|
||||||
|
sa_userdata: rawptr, /* will be passed to the signal handler, BeOS extension */
|
||||||
|
}
|
||||||
|
|
||||||
|
SIG_BLOCK :: 1
|
||||||
|
SIG_UNBLOCK :: 2
|
||||||
|
SIG_SETMASK :: 3
|
||||||
|
|
||||||
|
SA_NOCLDSTOP :: 0x01
|
||||||
|
SA_NOCLDWAIT :: 0x02
|
||||||
|
SA_RESETHAND :: 0x04
|
||||||
|
SA_NODEFER :: 0x08
|
||||||
|
SA_RESTART :: 0x10
|
||||||
|
SA_ONSTACK :: 0x20
|
||||||
|
SA_SIGINFO :: 0x40
|
||||||
|
|
||||||
|
SS_ONSTACK :: 1
|
||||||
|
SS_DISABLE :: 2
|
||||||
|
|
||||||
|
MINSIGSTKSZ :: 8192
|
||||||
|
SIGSTKSZ :: 16384
|
||||||
|
|
||||||
|
stack_t :: struct {
|
||||||
|
ss_sp: rawptr, /* [PSX] stack base or pointer */
|
||||||
|
ss_size: c.size_t, /* [PSX] stack size */
|
||||||
|
ss_flags: SS_Flags, /* [PSX] flags */
|
||||||
|
}
|
||||||
|
|
||||||
|
siginfo_t :: struct {
|
||||||
|
si_signo: Signal, /* [PSX] signal number */
|
||||||
|
si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */
|
||||||
|
ill: ILL_Code,
|
||||||
|
fpe: FPE_Code,
|
||||||
|
segv: SEGV_Code,
|
||||||
|
bus: BUS_Code,
|
||||||
|
trap: TRAP_Code,
|
||||||
|
chld: CLD_Code,
|
||||||
|
poll: POLL_Code,
|
||||||
|
any: Any_Code,
|
||||||
|
},
|
||||||
|
si_errno: Errno, /* [PSX] errno value associated with this signal */
|
||||||
|
si_pid: pid_t, /* sending process ID */
|
||||||
|
si_uid: uid_t, /* real user ID of sending process */
|
||||||
|
si_addr: rawptr, /* address of faulting instruction */
|
||||||
|
si_status: c.int, /* exit value or signal */
|
||||||
|
si_band: c.long, /* band event for SIGPOLL */
|
||||||
|
si_value: sigval, /* signal value */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* any signal */
|
||||||
|
SI_USER :: 0 /* signal sent by user */
|
||||||
|
SI_QUEUE :: 1 /* signal sent by sigqueue() */
|
||||||
|
SI_TIMER :: 2 /* signal sent on timer_settime() timeout */
|
||||||
|
SI_ASYNCIO :: 3 /* signal sent on asynchronous I/O completion */
|
||||||
|
SI_MESGQ :: 4 /* signal sent on arrival of message on empty message queue */
|
||||||
|
/* SIGILL */
|
||||||
|
ILL_ILLOPC :: 10 /* illegal opcode */
|
||||||
|
ILL_ILLOPN :: 11 /* illegal operand */
|
||||||
|
ILL_ILLADR :: 12 /* illegal addressing mode */
|
||||||
|
ILL_ILLTRP :: 13 /* illegal trap */
|
||||||
|
ILL_PRVOPC :: 14 /* privileged opcode */
|
||||||
|
ILL_PRVREG :: 15 /* privileged register */
|
||||||
|
ILL_COPROC :: 16 /* coprocessor error */
|
||||||
|
ILL_BADSTK :: 17 /* internal stack error */
|
||||||
|
/* SIGFPE */
|
||||||
|
FPE_INTDIV :: 20 /* integer division by zero */
|
||||||
|
FPE_INTOVF :: 21 /* integer overflow */
|
||||||
|
FPE_FLTDIV :: 22 /* floating-point division by zero */
|
||||||
|
FPE_FLTOVF :: 23 /* floating-point overflow */
|
||||||
|
FPE_FLTUND :: 24 /* floating-point underflow */
|
||||||
|
FPE_FLTRES :: 25 /* floating-point inexact result */
|
||||||
|
FPE_FLTINV :: 26 /* invalid floating-point operation */
|
||||||
|
FPE_FLTSUB :: 27 /* subscript out of range */
|
||||||
|
/* SIGSEGV */
|
||||||
|
SEGV_MAPERR :: 30 /* address not mapped to object */
|
||||||
|
SEGV_ACCERR :: 31 /* invalid permissions for mapped object */
|
||||||
|
/* SIGBUS */
|
||||||
|
BUS_ADRALN :: 40 /* invalid address alignment */
|
||||||
|
BUS_ADRERR :: 41 /* nonexistent physical address */
|
||||||
|
BUS_OBJERR :: 42 /* object-specific hardware error */
|
||||||
|
/* SIGTRAP */
|
||||||
|
TRAP_BRKPT :: 50 /* process breakpoint */
|
||||||
|
TRAP_TRACE :: 51 /* process trace trap. */
|
||||||
|
/* SIGCHLD */
|
||||||
|
CLD_EXITED :: 60 /* child exited */
|
||||||
|
CLD_KILLED :: 61 /* child terminated abnormally without core dump */
|
||||||
|
CLD_DUMPED :: 62 /* child terminated abnormally with core dump */
|
||||||
|
CLD_TRAPPED :: 63 /* traced child trapped */
|
||||||
|
CLD_STOPPED :: 64 /* child stopped */
|
||||||
|
CLD_CONTINUED :: 65 /* stopped child continued */
|
||||||
|
/* SIGPOLL */
|
||||||
|
POLL_IN :: 70 /* input available */
|
||||||
|
POLL_OUT :: 71 /* output available */
|
||||||
|
POLL_MSG :: 72 /* input message available */
|
||||||
|
POLL_ERR :: 73 /* I/O error */
|
||||||
|
POLL_PRI :: 74 /* high priority input available */
|
||||||
|
POLL_HUP :: 75 /* device disconnected */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, windows, linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, windows, linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
when ODIN_OS == .Windows {
|
when ODIN_OS == .Windows {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -111,4 +111,27 @@ when ODIN_OS == .Darwin {
|
|||||||
IPC_SET :: 1
|
IPC_SET :: 1
|
||||||
IPC_STAT :: 2
|
IPC_STAT :: 2
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
key_t :: distinct c.int32_t
|
||||||
|
|
||||||
|
ipc_perm :: struct {
|
||||||
|
key: key_t,
|
||||||
|
uid: uid_t, /* [PSX] owner's user ID */
|
||||||
|
gid: gid_t, /* [PSX] owner's group ID */
|
||||||
|
cuid: uid_t, /* [PSX] creator's user ID */
|
||||||
|
cgid: gid_t, /* [PSX] creator's group ID */
|
||||||
|
mode: mode_t, /* [PSX] read/write perms */
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC_CREAT :: 0o01000
|
||||||
|
IPC_EXCL :: 0o02000
|
||||||
|
IPC_NOWAIT :: 0o04000
|
||||||
|
|
||||||
|
IPC_PRIVATE :: key_t(0)
|
||||||
|
|
||||||
|
IPC_RMID :: 0
|
||||||
|
IPC_SET :: 1
|
||||||
|
IPC_STAT :: 2
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -171,4 +171,22 @@ when ODIN_OS == .Darwin {
|
|||||||
__unused: [2]c.ulong,
|
__unused: [2]c.ulong,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
msgqnum_t :: distinct c.uint32_t
|
||||||
|
msglen_t :: distinct c.uint32_t
|
||||||
|
|
||||||
|
MSG_NOERROR :: 0o10000
|
||||||
|
|
||||||
|
msqid_ds :: struct {
|
||||||
|
msg_perm: ipc_perm, /* [PSX] operation permission structure */
|
||||||
|
msg_qnum: msgqnum_t, /* [PSX] number of messages currently on queue */
|
||||||
|
msg_qbytes: msglen_t, /* [PSX] maximum number of bytes allowed on queue */
|
||||||
|
msg_lspid: pid_t, /* [PSX] process ID of last msgsnd() */
|
||||||
|
msg_lrpid: pid_t, /* [PSX] process ID of last msgrcv() */
|
||||||
|
msg_stime: time_t, /* [PSX] time of last msgsnd() */
|
||||||
|
msg_rtime: time_t, /* [PSX] time of last msgrcv() */
|
||||||
|
msg_ctime: time_t, /* [PSX] time of last change */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -96,15 +96,26 @@ when ODIN_OS == .NetBSD {
|
|||||||
@(private) LGETRUSAGE :: "getrusage"
|
@(private) LGETRUSAGE :: "getrusage"
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
PRIO_PROCESS :: 0
|
PRIO_PROCESS :: 0
|
||||||
PRIO_PGRP :: 1
|
PRIO_PGRP :: 1
|
||||||
PRIO_USER :: 2
|
PRIO_USER :: 2
|
||||||
|
|
||||||
rlim_t :: distinct c.uint64_t
|
when ODIN_OS == .Haiku {
|
||||||
|
rlim_t :: distinct c.ulong
|
||||||
|
} else {
|
||||||
|
rlim_t :: distinct c.uint64_t
|
||||||
|
}
|
||||||
|
|
||||||
RLIM_INFINITY :: ~rlim_t(0) when ODIN_OS == .Linux else (rlim_t(1) << 63) - 1
|
when ODIN_OS == .Haiku {
|
||||||
|
RLIM_INFINITY :: rlim_t(0xFFFFFFFF)
|
||||||
|
} else when ODIN_OS == .Linux {
|
||||||
|
RLIM_INFINITY :: ~rlim_t(0)
|
||||||
|
} else {
|
||||||
|
RLIM_INFINITY :: (rlim_t(1) << 63) - 1
|
||||||
|
}
|
||||||
|
|
||||||
RLIM_SAVED_MAX :: RLIM_INFINITY
|
RLIM_SAVED_MAX :: RLIM_INFINITY
|
||||||
RLIM_SAVED_CUR :: RLIM_INFINITY
|
RLIM_SAVED_CUR :: RLIM_INFINITY
|
||||||
|
|
||||||
@@ -140,19 +151,29 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
ru_nivcsw: c.long, /* involuntary " */
|
ru_nivcsw: c.long, /* involuntary " */
|
||||||
}
|
}
|
||||||
|
|
||||||
RLIMIT_CORE :: 4
|
when ODIN_OS == .Haiku {
|
||||||
RLIMIT_CPU :: 0
|
RLIMIT_CORE :: 0
|
||||||
RLIMIT_DATA :: 2
|
RLIMIT_CPU :: 1
|
||||||
RLIMIT_FSIZE :: 1
|
RLIMIT_DATA :: 2
|
||||||
RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8
|
RLIMIT_FSIZE :: 3
|
||||||
RLIMIT_STACK :: 3
|
RLIMIT_NOFILE :: 4
|
||||||
|
RLIMIT_STACK :: 5
|
||||||
when ODIN_OS == .Linux {
|
RLIMIT_AS :: 6
|
||||||
RLIMIT_AS :: 9
|
|
||||||
} else when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
|
|
||||||
RLIMIT_AS :: 5
|
|
||||||
} else {
|
} else {
|
||||||
RLIMIT_AS :: 10
|
RLIMIT_CORE :: 4
|
||||||
|
RLIMIT_CPU :: 0
|
||||||
|
RLIMIT_DATA :: 2
|
||||||
|
RLIMIT_FSIZE :: 1
|
||||||
|
RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8
|
||||||
|
RLIMIT_STACK :: 3
|
||||||
|
|
||||||
|
when ODIN_OS == .Linux {
|
||||||
|
RLIMIT_AS :: 9
|
||||||
|
} else when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
|
||||||
|
RLIMIT_AS :: 5
|
||||||
|
} else {
|
||||||
|
RLIMIT_AS :: 10
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
@@ -56,9 +56,9 @@ when ODIN_OS == .NetBSD {
|
|||||||
LSELECT :: "select"
|
LSELECT :: "select"
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
suseconds_t :: distinct (c.int32_t when ODIN_OS == .Darwin || ODIN_OS == .NetBSD else c.long)
|
suseconds_t :: distinct (c.int32_t when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .Haiku else c.long)
|
||||||
|
|
||||||
timeval :: struct {
|
timeval :: struct {
|
||||||
tv_sec: time_t, /* [PSX] seconds */
|
tv_sec: time_t, /* [PSX] seconds */
|
||||||
@@ -75,8 +75,14 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
@(private)
|
@(private)
|
||||||
ALIGN :: align_of(c.long) when ODIN_OS == .FreeBSD || ODIN_OS == .Linux else align_of(c.int32_t)
|
ALIGN :: align_of(c.long) when ODIN_OS == .FreeBSD || ODIN_OS == .Linux else align_of(c.int32_t)
|
||||||
|
|
||||||
fd_set :: struct #align(ALIGN) {
|
when ODIN_OS == .Haiku {
|
||||||
fds_bits: [(FD_SETSIZE / __NFDBITS) when (FD_SETSIZE % __NFDBITS) == 0 else (FD_SETSIZE / __NFDBITS) + 1]c.int32_t,
|
fd_set :: struct #align(ALIGN) {
|
||||||
|
fds_bits: [(FD_SETSIZE + (__NFDBITS - 1)) / __NFDBITS]c.int32_t,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fd_set :: struct #align(ALIGN) {
|
||||||
|
fds_bits: [(FD_SETSIZE / __NFDBITS) when (FD_SETSIZE % __NFDBITS) == 0 else (FD_SETSIZE / __NFDBITS) + 1]c.int32_t,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -154,4 +154,30 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
sem_flg: c.short, /* [PSX] operation flags */
|
sem_flg: c.short, /* [PSX] operation flags */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
SEM_UNDO :: 10 // undo the operation on exit
|
||||||
|
|
||||||
|
// Commands for `semctl'.
|
||||||
|
GETPID :: 3
|
||||||
|
GETVAL :: 4
|
||||||
|
GETALL :: 5
|
||||||
|
GETNCNT :: 6
|
||||||
|
GETZCNT :: 7
|
||||||
|
SETVAL :: 8
|
||||||
|
SETALL :: 9
|
||||||
|
|
||||||
|
semid_ds :: struct {
|
||||||
|
sem_perm: ipc_perm, // [PSX] operation permission structure
|
||||||
|
sem_nsems: c.ushort, // [PSX] number of semaphores in set
|
||||||
|
sem_otime: time_t, // [PSX] last semop()
|
||||||
|
sem_ctime: time_t, // [PSX] last time changed by semctl()
|
||||||
|
}
|
||||||
|
|
||||||
|
sembuf :: struct {
|
||||||
|
sem_num: c.ushort, /* [PSX] semaphore number */
|
||||||
|
sem_op: c.short, /* [PSX] semaphore operation */
|
||||||
|
sem_flg: c.short, /* [PSX] operation flags */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -328,24 +328,32 @@ when ODIN_OS == .NetBSD {
|
|||||||
@(private) LSOCKET :: "socket"
|
@(private) LSOCKET :: "socket"
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
socklen_t :: distinct c.uint
|
socklen_t :: distinct c.uint
|
||||||
|
|
||||||
|
when ODIN_OS == .Haiku {
|
||||||
|
@(private)
|
||||||
|
_SA_DATASIZE :: 30
|
||||||
|
} else {
|
||||||
|
@(private)
|
||||||
|
_SA_DATASIZE :: 14
|
||||||
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Linux {
|
when ODIN_OS == .Linux {
|
||||||
_sa_family_t :: distinct c.ushort
|
_sa_family_t :: distinct c.ushort
|
||||||
|
|
||||||
sockaddr :: struct {
|
sockaddr :: struct {
|
||||||
sa_family: sa_family_t, /* [PSX] address family */
|
sa_family: sa_family_t, /* [PSX] address family */
|
||||||
sa_data: [14]c.char, /* [PSX] socket address */
|
sa_data: [_SA_DATASIZE]c.char, /* [PSX] socket address */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_sa_family_t :: distinct c.uint8_t
|
_sa_family_t :: distinct c.uint8_t
|
||||||
|
|
||||||
sockaddr :: struct {
|
sockaddr :: struct {
|
||||||
sa_len: c.uint8_t, /* total length */
|
sa_len: c.uint8_t, /* total length */
|
||||||
sa_family: sa_family_t, /* [PSX] address family */
|
sa_family: sa_family_t, /* [PSX] address family */
|
||||||
sa_data: [14]c.char, /* [PSX] socket address */
|
sa_data: [_SA_DATASIZE]c.char, /* [PSX] socket address */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,6 +363,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
_SS_PAD1SIZE :: 6
|
_SS_PAD1SIZE :: 6
|
||||||
@(private)
|
@(private)
|
||||||
_SS_PAD2SIZE :: 240
|
_SS_PAD2SIZE :: 240
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
@(private)
|
||||||
|
_SS_PAD1SIZE :: 6
|
||||||
|
@(private)
|
||||||
|
_SS_PAD2SIZE :: 112
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
@(private)
|
@(private)
|
||||||
_SS_SIZE :: 128
|
_SS_SIZE :: 128
|
||||||
@@ -486,6 +499,26 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
|
|
||||||
SO_RCVTIMEO :: 66
|
SO_RCVTIMEO :: 66
|
||||||
SO_SNDTIMEO :: 67
|
SO_SNDTIMEO :: 67
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
SOL_SOCKET :: -1
|
||||||
|
|
||||||
|
SO_ACCEPTCONN :: 0x00000001
|
||||||
|
SO_BROADCAST :: 0x00000002
|
||||||
|
SO_DEBUG :: 0x00000004
|
||||||
|
SO_DONTROUTE :: 0x00000008
|
||||||
|
SO_ERROR :: 0x40000007
|
||||||
|
SO_KEEPALIVE :: 0x00000010
|
||||||
|
SO_OOBINLINE :: 0x00000020
|
||||||
|
SO_RCVBUF :: 0x40000004
|
||||||
|
SO_RCVLOWAT :: 0x40000005
|
||||||
|
SO_REUSEADDR :: 0x00000040
|
||||||
|
SO_SNDBUF :: 0x40000001
|
||||||
|
SO_SNDLOWAT :: 0x40000002
|
||||||
|
SO_TYPE :: 0x40000008
|
||||||
|
|
||||||
|
SO_LINGER :: 0x00000200
|
||||||
|
SO_RCVTIMEO :: 0x40000006
|
||||||
|
SO_SNDTIMEO :: 0x40000003
|
||||||
} else {
|
} else {
|
||||||
SOL_SOCKET :: 0xffff
|
SOL_SOCKET :: 0xffff
|
||||||
|
|
||||||
@@ -523,7 +556,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The maximum backlog queue length for listen().
|
// The maximum backlog queue length for listen().
|
||||||
SOMAXCONN :: 128
|
when ODIN_OS == .Haiku {
|
||||||
|
SOMAXCONN :: 32
|
||||||
|
} else {
|
||||||
|
SOMAXCONN :: 128
|
||||||
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Linux {
|
when ODIN_OS == .Linux {
|
||||||
MSG_CTRUNC :: 0x008
|
MSG_CTRUNC :: 0x008
|
||||||
@@ -549,11 +586,18 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
MSG_NOSIGNAL :: 0x00020000
|
MSG_NOSIGNAL :: 0x00020000
|
||||||
} else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
} else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
||||||
MSG_NOSIGNAL :: 0x0400
|
MSG_NOSIGNAL :: 0x0400
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
MSG_NOSIGNAL :: 0x800
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AF_INET :: 2
|
when ODIN_OS == .Haiku {
|
||||||
AF_UNIX :: 1
|
AF_INET :: 1
|
||||||
|
AF_UNIX :: 9
|
||||||
|
} else {
|
||||||
|
AF_INET :: 2
|
||||||
|
AF_UNIX :: 1
|
||||||
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
AF_INET6 :: 30
|
AF_INET6 :: 30
|
||||||
@@ -563,6 +607,8 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
AF_INET6 :: 24
|
AF_INET6 :: 24
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
AF_INET6 :: 10
|
AF_INET6 :: 10
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
AF_INET6 :: 5
|
||||||
}
|
}
|
||||||
|
|
||||||
SHUT_RD :: 0
|
SHUT_RD :: 0
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -428,6 +428,36 @@ when ODIN_OS == .Darwin {
|
|||||||
UTIME_NOW :: -2
|
UTIME_NOW :: -2
|
||||||
UTIME_OMIT :: -1
|
UTIME_OMIT :: -1
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
dev_t :: distinct c.int32_t
|
||||||
|
nlink_t :: distinct c.int32_t
|
||||||
|
_mode_t :: distinct c.uint32_t
|
||||||
|
blkcnt_t :: distinct c.int64_t
|
||||||
|
blksize_t :: distinct c.int32_t
|
||||||
|
ino_t :: distinct c.int64_t
|
||||||
|
|
||||||
|
stat_t :: struct {
|
||||||
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
|
st_crtim: timespec, /* [PSX] time of last status change */
|
||||||
|
st_type: c.uint32_t,
|
||||||
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
|
}
|
||||||
|
|
||||||
|
UTIME_NOW :: 1000000000
|
||||||
|
UTIME_OMIT :: 1000000001
|
||||||
|
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
dev_t :: distinct u64
|
dev_t :: distinct u64
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -78,4 +78,15 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
ITIMER_VIRTUAL :: 1
|
ITIMER_VIRTUAL :: 1
|
||||||
ITIMER_PROF :: 2
|
ITIMER_PROF :: 2
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
itimerval :: struct {
|
||||||
|
it_interval: timeval, /* [PSX] timer interval */
|
||||||
|
it_value: timeval, /* [PSX] current value */
|
||||||
|
}
|
||||||
|
|
||||||
|
ITIMER_REAL :: 1
|
||||||
|
ITIMER_VIRTUAL :: 2
|
||||||
|
ITIMER_PROF :: 3
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
@@ -25,7 +25,7 @@ when ODIN_OS == .NetBSD {
|
|||||||
@(private) LTIMES :: "times"
|
@(private) LTIMES :: "times"
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
tms :: struct {
|
tms :: struct {
|
||||||
tms_utime: clock_t, /* [PSX] user CPU time */
|
tms_utime: clock_t, /* [PSX] user CPU time */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -31,7 +31,7 @@ foreign libc {
|
|||||||
writev :: proc(fildes: FD, iov: [^]iovec, iovcnt: c.int) -> c.ssize_t ---
|
writev :: proc(fildes: FD, iov: [^]iovec, iovcnt: c.int) -> c.ssize_t ---
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
iovec :: struct {
|
iovec :: struct {
|
||||||
iov_base: rawptr, /* [PSX] base address of I/O memory region */
|
iov_base: rawptr, /* [PSX] base address of I/O memory region */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -20,4 +20,12 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
sun_path: [108]c.char, /* [PSX] socket pathname */
|
sun_path: [108]c.char, /* [PSX] socket pathname */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
sockaddr_un :: struct {
|
||||||
|
sun_len: c.uint8_t,
|
||||||
|
sun_family: sa_family_t, /* [PSX] address family */
|
||||||
|
sun_path: [126]c.char, /* [PSX] socket pathname */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -38,10 +38,10 @@ foreign lib {
|
|||||||
uname :: proc(uname: ^utsname) -> c.int ---
|
uname :: proc(uname: ^utsname) -> c.int ---
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
_SYS_NAMELEN :: 256
|
_SYS_NAMELEN :: 32 when ODIN_OS == .Haiku else 256
|
||||||
|
|
||||||
utsname :: struct {
|
utsname :: struct {
|
||||||
sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */
|
sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -442,4 +442,56 @@ when ODIN_OS == .Darwin {
|
|||||||
_WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
_WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
return x == 0xffff
|
return x == 0xffff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
id_t :: distinct c.int32_t
|
||||||
|
|
||||||
|
WCONTINUED :: 0x04
|
||||||
|
WNOHANG :: 0x01
|
||||||
|
WUNTRACED :: 0x02
|
||||||
|
|
||||||
|
WEXITED :: 0x08
|
||||||
|
WNOWAIT :: 0x20
|
||||||
|
WSTOPPED :: 0x10
|
||||||
|
|
||||||
|
_P_ALL :: 0
|
||||||
|
_P_PID :: 1
|
||||||
|
_P_PGID :: 2
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFEXITED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return (x & ~(c.int)(0xff)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WEXITSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
|
||||||
|
return x & 0xff
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFSIGNALED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return ((x >> 8) & 0xff) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WTERMSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
|
||||||
|
return Signal((x >> 8) & 0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFSTOPPED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return ((x >> 16) & 0xff) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WSTOPSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
|
||||||
|
return Signal((x >> 16) & 0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return (x & 0x20000) != 0
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+172
-12
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -138,17 +138,30 @@ CLocal_Flag_Bits :: enum tcflag_t {
|
|||||||
}
|
}
|
||||||
CLocal_Flags :: bit_set[CLocal_Flag_Bits; tcflag_t]
|
CLocal_Flags :: bit_set[CLocal_Flag_Bits; tcflag_t]
|
||||||
|
|
||||||
CControl_Flag_Bits :: enum tcflag_t {
|
when ODIN_OS == .Haiku {
|
||||||
// CS5 = log2(CS5), /* 5 bits (pseudo) (default) */
|
CControl_Flag_Bits :: enum tcflag_t {
|
||||||
CS6 = log2(CS6), /* 6 bits */
|
// CS7 = log2(CS7), /* 7 bits (default) */
|
||||||
CS7 = log2(CS7), /* 7 bits */
|
CS8 = log2(CS8), /* 8 bits */
|
||||||
CS8 = log2(CS8), /* 8 bits */
|
CSTOPB = log2(CSTOPB), /* send 2 stop bits */
|
||||||
CSTOPB = log2(CSTOPB), /* send 2 stop bits */
|
CREAD = log2(CREAD), /* enable receiver */
|
||||||
CREAD = log2(CREAD), /* enable receiver */
|
PARENB = log2(PARENB), /* parity enable */
|
||||||
PARENB = log2(PARENB), /* parity enable */
|
PARODD = log2(PARODD), /* odd parity, else even */
|
||||||
PARODD = log2(PARODD), /* odd parity, else even */
|
HUPCL = log2(HUPCL), /* hang up on last close */
|
||||||
HUPCL = log2(HUPCL), /* hang up on last close */
|
CLOCAL = log2(CLOCAL), /* ignore modem status lines */
|
||||||
CLOCAL = log2(CLOCAL), /* ignore modem status lines */
|
}
|
||||||
|
} else {
|
||||||
|
CControl_Flag_Bits :: enum tcflag_t {
|
||||||
|
// CS5 = log2(CS5), /* 5 bits (pseudo) (default) */
|
||||||
|
CS6 = log2(CS6), /* 6 bits */
|
||||||
|
CS7 = log2(CS7), /* 7 bits */
|
||||||
|
CS8 = log2(CS8), /* 8 bits */
|
||||||
|
CSTOPB = log2(CSTOPB), /* send 2 stop bits */
|
||||||
|
CREAD = log2(CREAD), /* enable receiver */
|
||||||
|
PARENB = log2(PARENB), /* parity enable */
|
||||||
|
PARODD = log2(PARODD), /* odd parity, else even */
|
||||||
|
HUPCL = log2(HUPCL), /* hang up on last close */
|
||||||
|
CLOCAL = log2(CLOCAL), /* ignore modem status lines */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CControl_Flags :: bit_set[CControl_Flag_Bits; tcflag_t]
|
CControl_Flags :: bit_set[CControl_Flag_Bits; tcflag_t]
|
||||||
|
|
||||||
@@ -597,4 +610,151 @@ when ODIN_OS == .Darwin {
|
|||||||
TCOOFF :: 0
|
TCOOFF :: 0
|
||||||
TCOON :: 1
|
TCOON :: 1
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
cc_t :: distinct c.uchar
|
||||||
|
_speed_t :: distinct c.uint32_t
|
||||||
|
tcflag_t :: distinct c.uint16_t
|
||||||
|
|
||||||
|
// Same as speed_t, but 16-bit.
|
||||||
|
CSpeed :: enum tcflag_t {
|
||||||
|
B0 = B0,
|
||||||
|
B50 = B50,
|
||||||
|
B75 = B75,
|
||||||
|
B110 = B110,
|
||||||
|
B134 = B134,
|
||||||
|
B150 = B150,
|
||||||
|
B200 = B200,
|
||||||
|
B300 = B300,
|
||||||
|
B600 = B600,
|
||||||
|
B1200 = B1200,
|
||||||
|
B1800 = B1800,
|
||||||
|
B2400 = B2400,
|
||||||
|
B4800 = B4800,
|
||||||
|
B9600 = B9600,
|
||||||
|
B19200 = B19200,
|
||||||
|
B38400 = B38400,
|
||||||
|
}
|
||||||
|
|
||||||
|
termios :: struct {
|
||||||
|
c_iflag: CInput_Flags, /* [XBD] input flags */
|
||||||
|
c_ispeed: CSpeed, /* input speed */
|
||||||
|
c_oflag: COutput_Flags, /* [XBD] output flags */
|
||||||
|
c_ospeed: CSpeed, /* output speed */
|
||||||
|
c_cflag: CControl_Flags, /* [XBD] control flags */
|
||||||
|
c_ispeed_high: tcflag_t, /* high word of input baudrate */
|
||||||
|
c_lflag: CLocal_Flags, /* [XBD] local flag */
|
||||||
|
c_ospeed_high: tcflag_t, /* high word of output baudrate */
|
||||||
|
c_line: c.char,
|
||||||
|
_padding: c.uchar,
|
||||||
|
_padding2: c.uchar,
|
||||||
|
c_cc: [NCCS]cc_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
NCCS :: 11
|
||||||
|
|
||||||
|
VINTR :: 0
|
||||||
|
VQUIT :: 1
|
||||||
|
VERASE :: 2
|
||||||
|
VKILL :: 3
|
||||||
|
VEOF :: 4
|
||||||
|
VEOL :: 5
|
||||||
|
VMIN :: 4
|
||||||
|
VTIME :: 5
|
||||||
|
VEOL2 :: 6
|
||||||
|
VSWTCH :: 7
|
||||||
|
VSTART :: 8
|
||||||
|
VSTOP :: 9
|
||||||
|
VSUSP :: 10
|
||||||
|
|
||||||
|
IGNBRK :: 0x01 /* ignore break condition */
|
||||||
|
BRKINT :: 0x02 /* break sends interrupt */
|
||||||
|
IGNPAR :: 0x04 /* ignore characters with parity errors */
|
||||||
|
PARMRK :: 0x08 /* mark parity errors */
|
||||||
|
INPCK :: 0x10 /* enable input parity checking */
|
||||||
|
ISTRIP :: 0x20 /* strip high bit from characters */
|
||||||
|
INLCR :: 0x40 /* maps newline to CR on input */
|
||||||
|
IGNCR :: 0x80 /* ignore carriage returns */
|
||||||
|
ICRNL :: 0x100 /* map CR to newline on input */
|
||||||
|
IXON :: 0x400 /* enable input SW flow control */
|
||||||
|
IXANY :: 0x800 /* any character will restart input */
|
||||||
|
IXOFF :: 0x1000 /* enable output SW flow control */
|
||||||
|
|
||||||
|
OPOST :: 0x01 /* enable postprocessing of output */
|
||||||
|
ONLCR :: 0x04 /* map NL to CR-NL on output */
|
||||||
|
OCRNL :: 0x08 /* map CR to NL on output */
|
||||||
|
ONOCR :: 0x10 /* no CR output when at column 0 */
|
||||||
|
ONLRET :: 0x20 /* newline performs CR function */
|
||||||
|
OFILL :: 0x40 /* use fill characters for delays */
|
||||||
|
OFDEL :: 0x80 /* Fills are DEL, otherwise NUL */
|
||||||
|
_NLDLY :: 0x100 /* Newline delays: */
|
||||||
|
NL0 :: 0x000
|
||||||
|
NL1 :: 0x100
|
||||||
|
_CRDLY :: 0x600 /* Carriage return delays: */
|
||||||
|
CR0 :: 0x000
|
||||||
|
CR1 :: 0x200
|
||||||
|
CR2 :: 0x400
|
||||||
|
CR3 :: 0x600
|
||||||
|
_TABDLY :: 0x1800 /* Tab delays: */
|
||||||
|
TAB0 :: 0x0000
|
||||||
|
TAB1 :: 0x0800
|
||||||
|
TAB3 :: 0x1800
|
||||||
|
_BSDLY :: 0x2000 /* Backspace delays: */
|
||||||
|
BS0 :: 0x0000
|
||||||
|
BS1 :: 0x2000
|
||||||
|
_VTDLY :: 0x4000 /* Vertical tab delays: */
|
||||||
|
VT0 :: 0x0000
|
||||||
|
VT1 :: 0x4000
|
||||||
|
_FFDLY :: 0x8000 /* Form feed delays: */
|
||||||
|
FF0 :: 0x0000
|
||||||
|
FF1 :: 0x8000
|
||||||
|
|
||||||
|
B0 :: 0x00 /* hang up */
|
||||||
|
B50 :: 0x01 /* 50 baud */
|
||||||
|
B75 :: 0x02
|
||||||
|
B110 :: 0x03
|
||||||
|
B134 :: 0x04
|
||||||
|
B150 :: 0x05
|
||||||
|
B200 :: 0x06
|
||||||
|
B300 :: 0x07
|
||||||
|
B600 :: 0x08
|
||||||
|
B1200 :: 0x09
|
||||||
|
B1800 :: 0x0A
|
||||||
|
B2400 :: 0x0B
|
||||||
|
B4800 :: 0x0C
|
||||||
|
B9600 :: 0x0D
|
||||||
|
B19200 :: 0x0E
|
||||||
|
B38400 :: 0x0F
|
||||||
|
|
||||||
|
_CSIZE :: 0x20 /* character size */
|
||||||
|
//CS5 :: 0x00 /* only 7 and 8 bits supported */
|
||||||
|
//CS6 :: 0x00 /* Note, it was not very wise to set all of these */
|
||||||
|
//CS7 :: 0x00 /* to zero, but there is not much we can do about it*/
|
||||||
|
CS8 :: 0x20
|
||||||
|
CSTOPB :: 0x40 /* send 2 stop bits, not 1 */
|
||||||
|
CREAD :: 0x80 /* enable receiver */
|
||||||
|
PARENB :: 0x100 /* parity enable */
|
||||||
|
PARODD :: 0x200 /* odd parity, else even */
|
||||||
|
HUPCL :: 0x400 /* hangs up on last close */
|
||||||
|
CLOCAL :: 0x800 /* indicates local line */
|
||||||
|
|
||||||
|
ISIG :: 0x01 /* enable signals */
|
||||||
|
ICANON :: 0x02 /* Canonical input */
|
||||||
|
ECHO :: 0x08 /* Enable echo */
|
||||||
|
ECHOE :: 0x10 /* Echo erase as bs-sp-bs */
|
||||||
|
ECHOK :: 0x20 /* Echo nl after kill */
|
||||||
|
ECHONL :: 0x40 /* Echo nl */
|
||||||
|
NOFLSH :: 0x80 /* Disable flush after int or quit */
|
||||||
|
TOSTOP :: 0x100 /* stop bg processes that write to tty */
|
||||||
|
IEXTEN :: 0x200 /* implementation defined extensions */
|
||||||
|
|
||||||
|
TCIFLUSH :: 1
|
||||||
|
TCOFLUSH :: 2
|
||||||
|
TCIOFLUSH :: 3
|
||||||
|
|
||||||
|
TCIOFF :: 0x04
|
||||||
|
TCION :: 0x08
|
||||||
|
TCOOFF :: 0x01
|
||||||
|
TCOON :: 0x02
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -230,6 +230,17 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on OpenBSD.
|
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on OpenBSD.
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
clockid_t :: distinct c.int32_t
|
||||||
|
|
||||||
|
CLOCK_MONOTONIC :: 0
|
||||||
|
CLOCK_PROCESS_CPUTIME_ID :: -2
|
||||||
|
CLOCK_REALTIME :: -1
|
||||||
|
CLOCK_THREAD_CPUTIME_ID :: -3
|
||||||
|
|
||||||
|
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on Haiku.
|
||||||
|
|
||||||
} else when ODIN_OS == .Linux {
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
clockid_t :: distinct c.int
|
clockid_t :: distinct c.int
|
||||||
|
|||||||
+172
-2
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -1852,7 +1852,7 @@ when ODIN_OS == .Darwin {
|
|||||||
_PC_ALLOC_SIZE_MIN :: 19
|
_PC_ALLOC_SIZE_MIN :: 19
|
||||||
_PC_SYMLINK_MAX :: 20
|
_PC_SYMLINK_MAX :: 20
|
||||||
_PC_2_SYMLINK :: 21
|
_PC_2_SYMLINK :: 21
|
||||||
|
|
||||||
_SC_ARG_MAX :: 1
|
_SC_ARG_MAX :: 1
|
||||||
_SC_CHILD_MAX :: 2
|
_SC_CHILD_MAX :: 2
|
||||||
_SC_CLK_TCK :: 3
|
_SC_CLK_TCK :: 3
|
||||||
@@ -1992,4 +1992,174 @@ when ODIN_OS == .Darwin {
|
|||||||
// NOTE: Not implemented.
|
// NOTE: Not implemented.
|
||||||
_POSIX_VDISABLE :: 0
|
_POSIX_VDISABLE :: 0
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Haiku {
|
||||||
|
|
||||||
|
_F_OK :: 0
|
||||||
|
X_OK :: 1
|
||||||
|
W_OK :: 2
|
||||||
|
R_OK :: 4
|
||||||
|
|
||||||
|
F_LOCK :: 1
|
||||||
|
F_TEST :: 3
|
||||||
|
F_TLOCK :: 2
|
||||||
|
F_ULOCK :: 0
|
||||||
|
|
||||||
|
_CS_PATH :: 1
|
||||||
|
_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_ILP32_OFF32_LIBS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_LP64_OFF64_CFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_LP64_OFF64_LIBS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 0 // Undefined.
|
||||||
|
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 0 // Undefined.
|
||||||
|
|
||||||
|
_SC_ASYNCHRONOUS_IO :: 0 // Undefined.
|
||||||
|
_SC_RAW_SOCKETS :: 0 // Undefined.
|
||||||
|
_SC_SS_REPL_MAX :: 0 // Undefined.
|
||||||
|
_SC_TRACE_EVENT_NAME_MAX :: 0 // Undefined.
|
||||||
|
_SC_TRACE_NAME_MAX :: 0 // Undefined.
|
||||||
|
_SC_TRACE_SYS_MAX :: 0 // Undefined.
|
||||||
|
_SC_TRACE_USER_EVENT_MAX :: 0 // Undefined.
|
||||||
|
|
||||||
|
_PC_CHOWN_RESTRICTED :: 1
|
||||||
|
_PC_MAX_CANON :: 2
|
||||||
|
_PC_MAX_INPUT :: 3
|
||||||
|
_PC_NAME_MAX :: 4
|
||||||
|
_PC_NO_TRUNC :: 5
|
||||||
|
_PC_PATH_MAX :: 6
|
||||||
|
_PC_PIPE_BUF :: 7
|
||||||
|
_PC_VDISABLE :: 8
|
||||||
|
_PC_LINK_MAX :: 25
|
||||||
|
_PC_SYNC_IO :: 26
|
||||||
|
_PC_ASYNC_IO :: 27
|
||||||
|
_PC_PRIO_IO :: 28
|
||||||
|
_PC_FILESIZEBITS :: 30
|
||||||
|
_PC_REC_INCR_XFER_SIZE :: 31
|
||||||
|
_PC_REC_MAX_XFER_SIZE :: 32
|
||||||
|
_PC_REC_MIN_XFER_SIZE :: 33
|
||||||
|
_PC_REC_XFER_ALIGN :: 34
|
||||||
|
_PC_ALLOC_SIZE_MIN :: 35
|
||||||
|
_PC_SYMLINK_MAX :: 36
|
||||||
|
_PC_2_SYMLINK :: 37
|
||||||
|
|
||||||
|
_SC_ARG_MAX :: 15
|
||||||
|
_SC_CHILD_MAX :: 16
|
||||||
|
_SC_CLK_TCK :: 17
|
||||||
|
_SC_JOB_CONTROL :: 18
|
||||||
|
_SC_NGROUPS_MAX :: 19
|
||||||
|
_SC_OPEN_MAX :: 20
|
||||||
|
_SC_SAVED_IDS :: 21
|
||||||
|
_SC_STREAM_MAX :: 22
|
||||||
|
_SC_TZNAME_MAX :: 23
|
||||||
|
_SC_VERSION :: 24
|
||||||
|
_SC_GETGR_R_SIZE_MAX :: 25
|
||||||
|
_SC_GETPW_R_SIZE_MAX :: 26
|
||||||
|
_SC_PAGE_SIZE :: 27
|
||||||
|
_SC_PAGESIZE :: _SC_PAGE_SIZE
|
||||||
|
_SC_SEM_NSEMS_MAX :: 28
|
||||||
|
_SC_SEM_VALUE_MAX :: 29
|
||||||
|
_SC_SEMAPHORES :: 30
|
||||||
|
_SC_THREADS :: 31
|
||||||
|
_SC_IOV_MAX :: 32
|
||||||
|
_SC_NPROCESSORS_CONF :: 34
|
||||||
|
_SC_NPROCESSORS_ONLN :: 35
|
||||||
|
_SC_ATEXIT_MAX :: 37
|
||||||
|
_SC_MAPPED_FILES :: 45
|
||||||
|
_SC_THREAD_PROCESS_SHARED :: 46
|
||||||
|
_SC_THREAD_STACK_MIN :: 47
|
||||||
|
_SC_THREAD_ATTR_STACKADDR :: 48
|
||||||
|
_SC_THREAD_ATTR_STACKSIZE :: 49
|
||||||
|
_SC_THREAD_PRIORITY_SCHEDULING :: 50
|
||||||
|
_SC_REALTIME_SIGNALS :: 51
|
||||||
|
_SC_MEMORY_PROTECTION :: 52
|
||||||
|
_SC_SIGQUEUE_MAX :: 53
|
||||||
|
_SC_RTSIG_MAX :: 54
|
||||||
|
_SC_MONOTONIC_CLOCK :: 55
|
||||||
|
_SC_DELAYTIMER_MAX :: 56
|
||||||
|
_SC_TIMER_MAX :: 57
|
||||||
|
_SC_TIMERS :: 58
|
||||||
|
_SC_CPUTIME :: 59
|
||||||
|
_SC_THREAD_CPUTIME :: 60
|
||||||
|
_SC_HOST_NAME_MAX :: 61
|
||||||
|
_SC_REGEXP :: 62
|
||||||
|
_SC_SYMLOOP_MAX :: 63
|
||||||
|
_SC_SHELL :: 64
|
||||||
|
_SC_TTY_NAME_MAX :: 65
|
||||||
|
_SC_ADVISORY_INFO :: 66
|
||||||
|
_SC_BARRIERS :: 67
|
||||||
|
_SC_CLOCK_SELECTION :: 68
|
||||||
|
_SC_FSYNC :: 69
|
||||||
|
_SC_IPV6 :: 70
|
||||||
|
_SC_MEMLOCK :: 71
|
||||||
|
_SC_MEMLOCK_RANGE :: 72
|
||||||
|
_SC_MESSAGE_PASSING :: 73
|
||||||
|
_SC_PRIORITIZED_IO :: 74
|
||||||
|
_SC_PRIORITY_SCHEDULING :: 75
|
||||||
|
_SC_READER_WRITER_LOCKS :: 76
|
||||||
|
_SC_SHARED_MEMORY_OBJECTS :: 77
|
||||||
|
_SC_SPAWN :: 78
|
||||||
|
_SC_SPIN_LOCKS :: 79
|
||||||
|
_SC_SPORADIC_SERVER :: 80
|
||||||
|
_SC_SYNCHRONIZED_IO :: 81
|
||||||
|
_SC_THREAD_PRIO_INHERIT :: 82
|
||||||
|
_SC_THREAD_PRIO_PROTECT :: 83
|
||||||
|
_SC_THREAD_SAFE_FUNCTIONS :: 86
|
||||||
|
_SC_THREAD_SPORADIC_SERVER :: 87
|
||||||
|
_SC_TIMEOUTS :: 88
|
||||||
|
_SC_TRACE :: 89
|
||||||
|
_SC_TRACE_EVENT_FILTER :: 90
|
||||||
|
_SC_TRACE_INHERIT :: 91
|
||||||
|
_SC_TRACE_LOG :: 92
|
||||||
|
_SC_TYPED_MEMORY_OBJECTS :: 93
|
||||||
|
_SC_V6_ILP32_OFF32 :: 94
|
||||||
|
_SC_V6_ILP32_OFFBIG :: 95
|
||||||
|
_SC_V6_LP64_OFF64 :: 96
|
||||||
|
_SC_V6_LPBIG_OFFBIG :: 97
|
||||||
|
_SC_2_C_BIND :: 102
|
||||||
|
_SC_2_C_DEV :: 103
|
||||||
|
_SC_2_CHAR_TERM :: 104
|
||||||
|
_SC_2_FORT_DEV :: 105
|
||||||
|
_SC_2_FORT_RUN :: 106
|
||||||
|
_SC_2_LOCALEDEF :: 107
|
||||||
|
_SC_2_PBS :: 108
|
||||||
|
_SC_2_PBS_ACCOUNTING :: 109
|
||||||
|
_SC_2_PBS_CHECKPOINT :: 110
|
||||||
|
_SC_2_PBS_LOCATE :: 111
|
||||||
|
_SC_2_PBS_MESSAGE :: 112
|
||||||
|
_SC_2_PBS_TRACK :: 113
|
||||||
|
_SC_2_SW_DEV :: 114
|
||||||
|
_SC_2_UPE :: 115
|
||||||
|
_SC_2_VERSION :: 116
|
||||||
|
_SC_XOPEN_CRYPT :: 117
|
||||||
|
_SC_XOPEN_ENH_I18N :: 118
|
||||||
|
_SC_XOPEN_REALTIME :: 119
|
||||||
|
_SC_XOPEN_REALTIME_THREADS :: 120
|
||||||
|
_SC_XOPEN_SHM :: 121
|
||||||
|
_SC_XOPEN_STREAMS :: 122
|
||||||
|
_SC_XOPEN_UNIX :: 123
|
||||||
|
_SC_XOPEN_VERSION :: 125
|
||||||
|
_SC_AIO_LISTIO_MAX :: 126
|
||||||
|
_SC_AIO_MAX :: 127
|
||||||
|
_SC_AIO_PRIO_DELTA_MAX :: 128
|
||||||
|
_SC_BC_BASE_MAX :: 129
|
||||||
|
_SC_BC_DIM_MAX :: 130
|
||||||
|
_SC_BC_SCALE_MAX :: 131
|
||||||
|
_SC_BC_STRING_MAX :: 132
|
||||||
|
_SC_COLL_WEIGHTS_MAX :: 133
|
||||||
|
_SC_EXPR_NEST_MAX :: 134
|
||||||
|
_SC_LINE_MAX :: 135
|
||||||
|
_SC_LOGIN_NAME_MAX :: 136
|
||||||
|
_SC_MQ_OPEN_MAX :: 137
|
||||||
|
_SC_MQ_PRIO_MAX :: 138
|
||||||
|
_SC_THREAD_DESTRUCTOR_ITERATIONS :: 139
|
||||||
|
_SC_THREAD_KEYS_MAX :: 140
|
||||||
|
_SC_THREAD_THREADS_MAX :: 141
|
||||||
|
_SC_RE_DUP_MAX :: 142
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
@@ -25,7 +25,7 @@ when ODIN_OS == .NetBSD {
|
|||||||
@(private) LUTIME :: "utime"
|
@(private) LUTIME :: "utime"
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
|
||||||
|
|
||||||
utimbuf :: struct {
|
utimbuf :: struct {
|
||||||
actime: time_t, /* [PSX] access time (seconds since epoch) */
|
actime: time_t, /* [PSX] access time (seconds since epoch) */
|
||||||
|
|||||||
@@ -110,7 +110,10 @@ class WasmMemoryInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadCstring(ptr) {
|
loadCstring(ptr) {
|
||||||
const start = this.loadPtr(ptr);
|
return this.loadCstringDirect(this.loadPtr(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCstringDirect(start) {
|
||||||
if (start == 0) {
|
if (start == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ foreign import "system:Comctl32.lib"
|
|||||||
@(default_calling_convention="system")
|
@(default_calling_convention="system")
|
||||||
foreign Comctl32 {
|
foreign Comctl32 {
|
||||||
LoadIconWithScaleDown :: proc(hinst: HINSTANCE, pszName: PCWSTR, cx: c_int, cy: c_int, phico: ^HICON) -> HRESULT ---
|
LoadIconWithScaleDown :: proc(hinst: HINSTANCE, pszName: PCWSTR, cx: c_int, cy: c_int, phico: ^HICON) -> HRESULT ---
|
||||||
|
SetWindowSubclass :: proc(hwnd: HWND, pfnSubclass: SUBCLASSPROC, uIdSubclass: UINT_PTR, dwRefData: DWORD_PTR) ---
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ MINIDUMP_DIRECTORY :: struct {
|
|||||||
Location: MINIDUMP_LOCATION_DESCRIPTOR,
|
Location: MINIDUMP_LOCATION_DESCRIPTOR,
|
||||||
}
|
}
|
||||||
|
|
||||||
MINIDUMP_EXCEPTION_INFORMATION :: struct {
|
MINIDUMP_EXCEPTION_INFORMATION :: struct #max_field_align(4) {
|
||||||
ThreadId: DWORD,
|
ThreadId: DWORD,
|
||||||
ExceptionPointers: ^EXCEPTION_POINTERS,
|
ExceptionPointers: ^EXCEPTION_POINTERS,
|
||||||
ClientPointers: BOOL,
|
ClientPointers: BOOL,
|
||||||
|
|||||||
@@ -796,6 +796,8 @@ TIMERPROC :: #type proc "system" (HWND, UINT, UINT_PTR, DWORD)
|
|||||||
|
|
||||||
WNDPROC :: #type proc "system" (HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
WNDPROC :: #type proc "system" (HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||||
|
|
||||||
|
SUBCLASSPROC :: #type proc "system" (HWND, UINT, WPARAM, LPARAM, UINT_PTR, DWORD_PTR) -> LRESULT
|
||||||
|
|
||||||
HOOKPROC :: #type proc "system" (code: c_int, wParam: WPARAM, lParam: LPARAM) -> LRESULT
|
HOOKPROC :: #type proc "system" (code: c_int, wParam: WPARAM, lParam: LPARAM) -> LRESULT
|
||||||
|
|
||||||
WINEVENTPROC :: #type proc "system" (
|
WINEVENTPROC :: #type proc "system" (
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
package sys_windows
|
package sys_windows
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
import "core:c"
|
||||||
foreign import user32 "system:User32.lib"
|
foreign import user32 "system:User32.lib"
|
||||||
|
|
||||||
@(default_calling_convention="system")
|
@(default_calling_convention="system")
|
||||||
@@ -32,6 +33,8 @@ foreign user32 {
|
|||||||
RegisterClassExW :: proc(^WNDCLASSEXW) -> ATOM ---
|
RegisterClassExW :: proc(^WNDCLASSEXW) -> ATOM ---
|
||||||
UnregisterClassW :: proc(lpClassName: LPCWSTR, hInstance: HINSTANCE) -> BOOL ---
|
UnregisterClassW :: proc(lpClassName: LPCWSTR, hInstance: HINSTANCE) -> BOOL ---
|
||||||
|
|
||||||
|
RegisterHotKey :: proc(hnwd: HWND, id: c.int, fsModifiers: UINT, vk: UINT) -> BOOL ---
|
||||||
|
|
||||||
CreateWindowExW :: proc(
|
CreateWindowExW :: proc(
|
||||||
dwExStyle: DWORD,
|
dwExStyle: DWORD,
|
||||||
lpClassName: LPCWSTR,
|
lpClassName: LPCWSTR,
|
||||||
@@ -553,7 +556,7 @@ MOUSE_ATTRIBUTES_CHANGED :: 0x04
|
|||||||
MOUSE_MOVE_NOCOALESCE :: 0x08
|
MOUSE_MOVE_NOCOALESCE :: 0x08
|
||||||
|
|
||||||
RI_MOUSE_BUTTON_1_DOWN :: 0x0001
|
RI_MOUSE_BUTTON_1_DOWN :: 0x0001
|
||||||
RI_MOUSE_LEFT_BUTTON_DOWNS :: RI_MOUSE_BUTTON_1_DOWN
|
RI_MOUSE_LEFT_BUTTON_DOWN :: RI_MOUSE_BUTTON_1_DOWN
|
||||||
RI_MOUSE_BUTTON_1_UP :: 0x0002
|
RI_MOUSE_BUTTON_1_UP :: 0x0002
|
||||||
RI_MOUSE_LEFT_BUTTON_UP :: RI_MOUSE_BUTTON_1_UP
|
RI_MOUSE_LEFT_BUTTON_UP :: RI_MOUSE_BUTTON_1_UP
|
||||||
RI_MOUSE_BUTTON_2_DOWN :: 0x0004
|
RI_MOUSE_BUTTON_2_DOWN :: 0x0004
|
||||||
|
|||||||
@@ -391,6 +391,7 @@ runner :: proc(internal_tests: []Internal_Test) -> bool {
|
|||||||
fmt.assertf(alloc_error == nil, "Error allocating memory for task allocator #%i: %v", i, alloc_error)
|
fmt.assertf(alloc_error == nil, "Error allocating memory for task allocator #%i: %v", i, alloc_error)
|
||||||
when TRACKING_MEMORY {
|
when TRACKING_MEMORY {
|
||||||
mem.tracking_allocator_init(&task_memory_trackers[i], mem.rollback_stack_allocator(&task_allocators[i]))
|
mem.tracking_allocator_init(&task_memory_trackers[i], mem.rollback_stack_allocator(&task_allocators[i]))
|
||||||
|
task_memory_trackers[i].bad_free_callback = mem.tracking_allocator_bad_free_callback_add_to_array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||||
#+private
|
#+private
|
||||||
package testing
|
package testing
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#+build !wasi
|
#+build !wasi
|
||||||
#+build !windows
|
#+build !windows
|
||||||
#+build !orca
|
#+build !orca
|
||||||
|
#+build !haiku
|
||||||
package time
|
package time
|
||||||
|
|
||||||
_IS_SUPPORTED :: false
|
_IS_SUPPORTED :: false
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#+private
|
#+private
|
||||||
#+build darwin, freebsd, openbsd, netbsd
|
#+build darwin, freebsd, openbsd, netbsd, haiku
|
||||||
package time
|
package time
|
||||||
|
|
||||||
import "core:sys/posix"
|
import "core:sys/posix"
|
||||||
|
|||||||
+59
-6
@@ -894,15 +894,49 @@ gb_internal void error_var_decl_identifier(Ast *name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
gb_internal void check_unroll_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
||||||
ast_node(irs, UnrollRangeStmt, node);
|
ast_node(irs, UnrollRangeStmt, node);
|
||||||
check_open_scope(ctx, node);
|
check_open_scope(ctx, node);
|
||||||
|
defer (check_close_scope(ctx));
|
||||||
|
|
||||||
Type *val0 = nullptr;
|
Type *val0 = nullptr;
|
||||||
Type *val1 = nullptr;
|
Type *val1 = nullptr;
|
||||||
Entity *entities[2] = {};
|
Entity *entities[2] = {};
|
||||||
isize entity_count = 0;
|
isize entity_count = 0;
|
||||||
|
|
||||||
|
i64 unroll_count = -1;
|
||||||
|
|
||||||
|
if (irs->args.count > 0) {
|
||||||
|
if (irs->args.count > 1) {
|
||||||
|
error(irs->args[1], "#unroll only supports a single argument for the unroll per loop amount");
|
||||||
|
}
|
||||||
|
Ast *arg = irs->args[0];
|
||||||
|
if (arg->kind == Ast_FieldValue) {
|
||||||
|
error(arg, "#unroll does not yet support named arguments");
|
||||||
|
arg = arg->FieldValue.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand x = {};
|
||||||
|
check_expr(ctx, &x, arg);
|
||||||
|
if (x.mode != Addressing_Constant || !is_type_integer(x.type)) {
|
||||||
|
gbString s = expr_to_string(x.expr);
|
||||||
|
error(x.expr, "Expected a constant integer for #unroll, got '%s'", s);
|
||||||
|
gb_string_free(s);
|
||||||
|
} else {
|
||||||
|
ExactValue value = exact_value_to_integer(x.value);
|
||||||
|
i64 v = exact_value_to_i64(value);
|
||||||
|
if (v < 1) {
|
||||||
|
error(x.expr, "Expected a constant integer >= 1 for #unroll, got %lld", cast(long long)v);
|
||||||
|
} else {
|
||||||
|
unroll_count = v;
|
||||||
|
if (v > 1024) {
|
||||||
|
error(x.expr, "Too large of a value for #unroll, got %lld, expected <= 1024", cast(long long)v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ast *expr = unparen_expr(irs->expr);
|
Ast *expr = unparen_expr(irs->expr);
|
||||||
|
|
||||||
ExactValue inline_for_depth = exact_value_i64(0);
|
ExactValue inline_for_depth = exact_value_i64(0);
|
||||||
@@ -946,18 +980,39 @@ gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod
|
|||||||
val0 = t_rune;
|
val0 = t_rune;
|
||||||
val1 = t_int;
|
val1 = t_int;
|
||||||
inline_for_depth = exact_value_i64(operand.value.value_string.len);
|
inline_for_depth = exact_value_i64(operand.value.value_string.len);
|
||||||
|
if (unroll_count > 0) {
|
||||||
|
error(node, "#unroll(%lld) does not support strings", cast(long long)unroll_count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Type_Array:
|
case Type_Array:
|
||||||
val0 = t->Array.elem;
|
val0 = t->Array.elem;
|
||||||
val1 = t_int;
|
val1 = t_int;
|
||||||
inline_for_depth = exact_value_i64(t->Array.count);
|
inline_for_depth = unroll_count > 0 ? exact_value_i64(unroll_count) : exact_value_i64(t->Array.count);
|
||||||
break;
|
break;
|
||||||
case Type_EnumeratedArray:
|
case Type_EnumeratedArray:
|
||||||
val0 = t->EnumeratedArray.elem;
|
val0 = t->EnumeratedArray.elem;
|
||||||
val1 = t->EnumeratedArray.index;
|
val1 = t->EnumeratedArray.index;
|
||||||
|
if (unroll_count > 0) {
|
||||||
|
error(node, "#unroll(%lld) does not support enumerated arrays", cast(long long)unroll_count);
|
||||||
|
}
|
||||||
inline_for_depth = exact_value_i64(t->EnumeratedArray.count);
|
inline_for_depth = exact_value_i64(t->EnumeratedArray.count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Type_Slice:
|
||||||
|
if (unroll_count > 0) {
|
||||||
|
val0 = t->Slice.elem;
|
||||||
|
val1 = t_int;
|
||||||
|
inline_for_depth = exact_value_i64(unroll_count);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_DynamicArray:
|
||||||
|
if (unroll_count > 0) {
|
||||||
|
val0 = t->DynamicArray.elem;
|
||||||
|
val1 = t_int;
|
||||||
|
inline_for_depth = exact_value_i64(unroll_count);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,7 +1022,7 @@ gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod
|
|||||||
error(operand.expr, "Cannot iterate over '%s' of type '%s' in an '#unroll for' statement", s, t);
|
error(operand.expr, "Cannot iterate over '%s' of type '%s' in an '#unroll for' statement", s, t);
|
||||||
gb_string_free(t);
|
gb_string_free(t);
|
||||||
gb_string_free(s);
|
gb_string_free(s);
|
||||||
} else if (operand.mode != Addressing_Constant) {
|
} else if (operand.mode != Addressing_Constant && unroll_count <= 0) {
|
||||||
error(operand.expr, "An '#unroll for' expression must be known at compile time");
|
error(operand.expr, "An '#unroll for' expression must be known at compile time");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1050,8 +1105,6 @@ gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod
|
|||||||
|
|
||||||
check_stmt(ctx, irs->body, mod_flags);
|
check_stmt(ctx, irs->body, mod_flags);
|
||||||
|
|
||||||
|
|
||||||
check_close_scope(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
||||||
@@ -2679,7 +2732,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(irs, UnrollRangeStmt, node);
|
case_ast_node(irs, UnrollRangeStmt, node);
|
||||||
check_inline_range_stmt(ctx, node, mod_flags);
|
check_unroll_range_stmt(ctx, node, mod_flags);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(ss, SwitchStmt, node);
|
case_ast_node(ss, SwitchStmt, node);
|
||||||
|
|||||||
@@ -408,13 +408,18 @@ gb_internal LLVMMetadataRef lb_debug_union(lbModule *m, Type *type, String name,
|
|||||||
lb_set_llvm_metadata(m, type, temp_forward_decl);
|
lb_set_llvm_metadata(m, type, temp_forward_decl);
|
||||||
|
|
||||||
isize index_offset = 1;
|
isize index_offset = 1;
|
||||||
|
isize variant_offset = 1;
|
||||||
if (is_type_union_maybe_pointer(bt)) {
|
if (is_type_union_maybe_pointer(bt)) {
|
||||||
index_offset = 0;
|
index_offset = 0;
|
||||||
|
variant_offset = 0;
|
||||||
|
} else if (bt->Union.kind == UnionType_no_nil) {
|
||||||
|
variant_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Union.scope);
|
LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Union.scope);
|
||||||
unsigned element_count = cast(unsigned)bt->Union.variants.count;
|
unsigned element_count = cast(unsigned)bt->Union.variants.count;
|
||||||
if (index_offset > 0) {
|
if (index_offset > 0) {
|
||||||
|
GB_ASSERT(index_offset == 1);
|
||||||
element_count += 1;
|
element_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,13 +442,11 @@ gb_internal LLVMMetadataRef lb_debug_union(lbModule *m, Type *type, String name,
|
|||||||
for_array(j, bt->Union.variants) {
|
for_array(j, bt->Union.variants) {
|
||||||
Type *variant = bt->Union.variants[j];
|
Type *variant = bt->Union.variants[j];
|
||||||
|
|
||||||
unsigned field_index = cast(unsigned)(index_offset+j);
|
char name[32] = {};
|
||||||
|
gb_snprintf(name, gb_size_of(name), "v%td", variant_offset+j);
|
||||||
char name[16] = {};
|
|
||||||
gb_snprintf(name, gb_size_of(name), "v%u", field_index);
|
|
||||||
isize name_len = gb_strlen(name);
|
isize name_len = gb_strlen(name);
|
||||||
|
|
||||||
elements[field_index] = LLVMDIBuilderCreateMemberType(
|
elements[index_offset+j] = LLVMDIBuilderCreateMemberType(
|
||||||
m->debug_builder, member_scope,
|
m->debug_builder, member_scope,
|
||||||
name, name_len,
|
name, name_len,
|
||||||
file, line,
|
file, line,
|
||||||
|
|||||||
+184
-55
@@ -256,7 +256,7 @@ gb_internal void lb_build_when_stmt(lbProcedure *p, AstWhenStmt *ws) {
|
|||||||
|
|
||||||
gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr,
|
gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr,
|
||||||
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_,
|
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_,
|
||||||
bool is_reverse) {
|
bool is_reverse, i64 unroll_count=0) {
|
||||||
lbModule *m = p->module;
|
lbModule *m = p->module;
|
||||||
|
|
||||||
lbValue count = {};
|
lbValue count = {};
|
||||||
@@ -1230,7 +1230,6 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *
|
|||||||
TypeAndValue tav = type_and_value_of_expr(expr);
|
TypeAndValue tav = type_and_value_of_expr(expr);
|
||||||
|
|
||||||
if (is_ast_range(expr)) {
|
if (is_ast_range(expr)) {
|
||||||
|
|
||||||
lbAddr val0_addr = {};
|
lbAddr val0_addr = {};
|
||||||
lbAddr val1_addr = {};
|
lbAddr val1_addr = {};
|
||||||
if (val0_type) val0_addr = lb_build_addr(p, val0);
|
if (val0_type) val0_addr = lb_build_addr(p, val0);
|
||||||
@@ -1268,7 +1267,6 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else if (tav.mode == Addressing_Type) {
|
} else if (tav.mode == Addressing_Type) {
|
||||||
GB_ASSERT(is_type_enum(type_deref(tav.type)));
|
GB_ASSERT(is_type_enum(type_deref(tav.type)));
|
||||||
Type *et = type_deref(tav.type);
|
Type *et = type_deref(tav.type);
|
||||||
@@ -1293,72 +1291,203 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *
|
|||||||
if (val0_type) val0_addr = lb_build_addr(p, val0);
|
if (val0_type) val0_addr = lb_build_addr(p, val0);
|
||||||
if (val1_type) val1_addr = lb_build_addr(p, val1);
|
if (val1_type) val1_addr = lb_build_addr(p, val1);
|
||||||
|
|
||||||
GB_ASSERT(expr->tav.mode == Addressing_Constant);
|
ExactValue unroll_count_ev = {};
|
||||||
|
if (rs->args.count != 0) {
|
||||||
Type *t = base_type(expr->tav.type);
|
unroll_count_ev = rs->args[0]->tav.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (t->kind) {
|
if (unroll_count_ev.kind == ExactValue_Invalid) {
|
||||||
case Type_Basic:
|
GB_ASSERT(expr->tav.mode == Addressing_Constant);
|
||||||
GB_ASSERT(is_type_string(t));
|
|
||||||
{
|
|
||||||
ExactValue value = expr->tav.value;
|
|
||||||
GB_ASSERT(value.kind == ExactValue_String);
|
|
||||||
String str = value.value_string;
|
|
||||||
Rune codepoint = 0;
|
|
||||||
isize offset = 0;
|
|
||||||
do {
|
|
||||||
isize width = utf8_decode(str.text+offset, str.len-offset, &codepoint);
|
|
||||||
if (val0_type) lb_addr_store(p, val0_addr, lb_const_value(m, val0_type, exact_value_i64(codepoint)));
|
|
||||||
if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, exact_value_i64(offset)));
|
|
||||||
lb_build_stmt(p, rs->body);
|
|
||||||
|
|
||||||
offset += width;
|
Type *t = base_type(expr->tav.type);
|
||||||
} while (offset < str.len);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Type_Array:
|
|
||||||
if (t->Array.count > 0) {
|
|
||||||
lbValue val = lb_build_expr(p, expr);
|
|
||||||
lbValue val_addr = lb_address_from_load_or_generate_local(p, val);
|
|
||||||
|
|
||||||
for (i64 i = 0; i < t->Array.count; i++) {
|
switch (t->kind) {
|
||||||
if (val0_type) {
|
case Type_Basic:
|
||||||
// NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32
|
GB_ASSERT(is_type_string(t));
|
||||||
lbValue elem = lb_emit_array_epi(p, val_addr, cast(i32)i);
|
{
|
||||||
lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
|
ExactValue value = expr->tav.value;
|
||||||
|
GB_ASSERT(value.kind == ExactValue_String);
|
||||||
|
String str = value.value_string;
|
||||||
|
Rune codepoint = 0;
|
||||||
|
isize offset = 0;
|
||||||
|
do {
|
||||||
|
isize width = utf8_decode(str.text+offset, str.len-offset, &codepoint);
|
||||||
|
if (val0_type) lb_addr_store(p, val0_addr, lb_const_value(m, val0_type, exact_value_i64(codepoint)));
|
||||||
|
if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, exact_value_i64(offset)));
|
||||||
|
lb_build_stmt(p, rs->body);
|
||||||
|
|
||||||
|
offset += width;
|
||||||
|
} while (offset < str.len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_Array:
|
||||||
|
if (t->Array.count > 0) {
|
||||||
|
lbValue val = lb_build_expr(p, expr);
|
||||||
|
lbValue val_addr = lb_address_from_load_or_generate_local(p, val);
|
||||||
|
|
||||||
|
for (i64 i = 0; i < t->Array.count; i++) {
|
||||||
|
if (val0_type) {
|
||||||
|
// NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32
|
||||||
|
lbValue elem = lb_emit_array_epi(p, val_addr, cast(i32)i);
|
||||||
|
lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
|
||||||
|
}
|
||||||
|
if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, exact_value_i64(i)));
|
||||||
|
|
||||||
|
lb_build_stmt(p, rs->body);
|
||||||
}
|
}
|
||||||
if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, exact_value_i64(i)));
|
|
||||||
|
|
||||||
lb_build_stmt(p, rs->body);
|
}
|
||||||
|
break;
|
||||||
|
case Type_EnumeratedArray:
|
||||||
|
if (t->EnumeratedArray.count > 0) {
|
||||||
|
lbValue val = lb_build_expr(p, expr);
|
||||||
|
lbValue val_addr = lb_address_from_load_or_generate_local(p, val);
|
||||||
|
|
||||||
|
for (i64 i = 0; i < t->EnumeratedArray.count; i++) {
|
||||||
|
if (val0_type) {
|
||||||
|
// NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32
|
||||||
|
lbValue elem = lb_emit_array_epi(p, val_addr, cast(i32)i);
|
||||||
|
lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
|
||||||
|
}
|
||||||
|
if (val1_type) {
|
||||||
|
ExactValue idx = exact_value_add(exact_value_i64(i), *t->EnumeratedArray.min_value);
|
||||||
|
lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
lb_build_stmt(p, rs->body);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GB_PANIC("Invalid '#unroll for' type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// //
|
||||||
|
// #unroll(N) logic //
|
||||||
|
// //
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
i64 unroll_count = exact_value_to_i64(unroll_count_ev);
|
||||||
|
gb_unused(unroll_count);
|
||||||
|
|
||||||
|
Type *t = base_type(expr->tav.type);
|
||||||
|
|
||||||
|
lbValue data_ptr = {};
|
||||||
|
lbValue count_ptr = {};
|
||||||
|
|
||||||
|
switch (t->kind) {
|
||||||
|
case Type_Slice:
|
||||||
|
case Type_DynamicArray: {
|
||||||
|
lbValue slice = lb_build_expr(p, expr);
|
||||||
|
if (is_type_pointer(slice.type)) {
|
||||||
|
count_ptr = lb_emit_struct_ep(p, slice, 1);
|
||||||
|
slice = lb_emit_load(p, slice);
|
||||||
|
} else {
|
||||||
|
count_ptr = lb_add_local_generated(p, t_int, false).addr;
|
||||||
|
lb_emit_store(p, count_ptr, lb_slice_len(p, slice));
|
||||||
|
}
|
||||||
|
data_ptr = lb_emit_struct_ev(p, slice, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Type_Array: {
|
||||||
|
lbValue array = lb_build_expr(p, expr);
|
||||||
|
count_ptr = lb_add_local_generated(p, t_int, false).addr;
|
||||||
|
lb_emit_store(p, count_ptr, lb_const_int(p->module, t_int, t->Array.count));
|
||||||
|
|
||||||
|
if (!is_type_pointer(array.type)) {
|
||||||
|
array = lb_address_from_load_or_generate_local(p, array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GB_ASSERT(is_type_pointer(array.type));
|
||||||
|
data_ptr = lb_emit_conv(p, array, alloc_type_pointer(t->Array.elem));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case Type_EnumeratedArray:
|
|
||||||
if (t->EnumeratedArray.count > 0) {
|
|
||||||
lbValue val = lb_build_expr(p, expr);
|
|
||||||
lbValue val_addr = lb_address_from_load_or_generate_local(p, val);
|
|
||||||
|
|
||||||
for (i64 i = 0; i < t->EnumeratedArray.count; i++) {
|
default:
|
||||||
if (val0_type) {
|
GB_PANIC("Invalid '#unroll for' type");
|
||||||
// NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32
|
break;
|
||||||
lbValue elem = lb_emit_array_epi(p, val_addr, cast(i32)i);
|
}
|
||||||
lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
|
|
||||||
}
|
data_ptr.type = alloc_type_multi_pointer_to_pointer(data_ptr.type);
|
||||||
if (val1_type) {
|
|
||||||
ExactValue idx = exact_value_add(exact_value_i64(i), *t->EnumeratedArray.min_value);
|
lbBlock *loop_top = lb_create_block(p, "for.unroll.loop.top");
|
||||||
lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, idx));
|
|
||||||
}
|
lbBlock *body_top = lb_create_block(p, "for.unroll.body.top");
|
||||||
|
lbBlock *body_bot = lb_create_block(p, "for.unroll.body.bot");
|
||||||
|
|
||||||
|
lbBlock *done = lb_create_block(p, "for.unroll.done");
|
||||||
|
|
||||||
|
lbBlock *loop_bot = unroll_count > 1 ? lb_create_block(p, "for.unroll.loop.bot") : done;
|
||||||
|
|
||||||
|
/*
|
||||||
|
i := 0
|
||||||
|
for ; i+N <= len(array); i += N {
|
||||||
|
body
|
||||||
|
}
|
||||||
|
for ; i < len(array); i += 1 {
|
||||||
|
body
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Entity *val_entity = val0 ? entity_of_node(val0) : nullptr;
|
||||||
|
Entity *idx_entity = val1 ? entity_of_node(val1) : nullptr;
|
||||||
|
|
||||||
|
lbAddr val_addr = lb_add_local(p, type_deref(data_ptr.type, true), val_entity);
|
||||||
|
lbAddr idx_addr = lb_add_local(p, t_int, idx_entity);
|
||||||
|
lb_addr_store(p, idx_addr, lb_const_nil(p->module, t_int));
|
||||||
|
|
||||||
|
lb_emit_jump(p, loop_top);
|
||||||
|
lb_start_block(p, loop_top);
|
||||||
|
|
||||||
|
lbValue idx_add_n = lb_addr_load(p, idx_addr);
|
||||||
|
idx_add_n = lb_emit_arith(p, Token_Add, idx_add_n, lb_const_int(p->module, t_int, unroll_count), t_int);
|
||||||
|
|
||||||
|
lbValue cond_top = lb_emit_comp(p, Token_LtEq, idx_add_n, lb_emit_load(p, count_ptr));
|
||||||
|
lb_emit_if(p, cond_top, body_top, loop_bot);
|
||||||
|
|
||||||
|
lb_start_block(p, body_top);
|
||||||
|
for (i64 top = 0; top < unroll_count; top++) {
|
||||||
|
lbValue idx = lb_addr_load(p, idx_addr);
|
||||||
|
lbValue val = lb_emit_load(p, lb_emit_ptr_offset(p, data_ptr, idx));
|
||||||
|
lb_addr_store(p, val_addr, val);
|
||||||
|
|
||||||
|
lb_build_stmt(p, rs->body);
|
||||||
|
|
||||||
|
lb_emit_increment(p, lb_addr_get_ptr(p, idx_addr));
|
||||||
|
}
|
||||||
|
lb_emit_jump(p, loop_top);
|
||||||
|
|
||||||
|
if (unroll_count > 1) {
|
||||||
|
lb_start_block(p, loop_bot);
|
||||||
|
|
||||||
|
lbValue cond_bot = lb_emit_comp(p, Token_Lt, lb_addr_load(p, idx_addr), lb_emit_load(p, count_ptr));
|
||||||
|
lb_emit_if(p, cond_bot, body_bot, done);
|
||||||
|
|
||||||
|
lb_start_block(p, body_bot);
|
||||||
|
{
|
||||||
|
lbValue idx = lb_addr_load(p, idx_addr);
|
||||||
|
lbValue val = lb_emit_load(p, lb_emit_ptr_offset(p, data_ptr, idx));
|
||||||
|
lb_addr_store(p, val_addr, val);
|
||||||
|
|
||||||
lb_build_stmt(p, rs->body);
|
lb_build_stmt(p, rs->body);
|
||||||
}
|
|
||||||
|
|
||||||
|
lb_emit_increment(p, lb_addr_get_ptr(p, idx_addr));
|
||||||
|
}
|
||||||
|
lb_emit_jump(p, loop_bot);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
lb_close_scope(p, lbDeferExit_Default, nullptr, rs->body);
|
||||||
GB_PANIC("Invalid '#unroll for' type");
|
lb_emit_jump(p, done);
|
||||||
break;
|
lb_start_block(p, done);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+47
-11
@@ -348,10 +348,11 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) {
|
|||||||
n->RangeStmt.body = clone_ast(n->RangeStmt.body, f);
|
n->RangeStmt.body = clone_ast(n->RangeStmt.body, f);
|
||||||
break;
|
break;
|
||||||
case Ast_UnrollRangeStmt:
|
case Ast_UnrollRangeStmt:
|
||||||
n->UnrollRangeStmt.val0 = clone_ast(n->UnrollRangeStmt.val0, f);
|
n->UnrollRangeStmt.args = clone_ast_array(n->UnrollRangeStmt.args, f);
|
||||||
n->UnrollRangeStmt.val1 = clone_ast(n->UnrollRangeStmt.val1, f);
|
n->UnrollRangeStmt.val0 = clone_ast(n->UnrollRangeStmt.val0, f);
|
||||||
n->UnrollRangeStmt.expr = clone_ast(n->UnrollRangeStmt.expr, f);
|
n->UnrollRangeStmt.val1 = clone_ast(n->UnrollRangeStmt.val1, f);
|
||||||
n->UnrollRangeStmt.body = clone_ast(n->UnrollRangeStmt.body, f);
|
n->UnrollRangeStmt.expr = clone_ast(n->UnrollRangeStmt.expr, f);
|
||||||
|
n->UnrollRangeStmt.body = clone_ast(n->UnrollRangeStmt.body, f);
|
||||||
break;
|
break;
|
||||||
case Ast_CaseClause:
|
case Ast_CaseClause:
|
||||||
n->CaseClause.list = clone_ast_array(n->CaseClause.list, f);
|
n->CaseClause.list = clone_ast_array(n->CaseClause.list, f);
|
||||||
@@ -1037,15 +1038,16 @@ gb_internal Ast *ast_range_stmt(AstFile *f, Token token, Slice<Ast *> vals, Toke
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal Ast *ast_unroll_range_stmt(AstFile *f, Token unroll_token, Token for_token, Ast *val0, Ast *val1, Token in_token, Ast *expr, Ast *body) {
|
gb_internal Ast *ast_unroll_range_stmt(AstFile *f, Token unroll_token, Slice<Ast *> args, Token for_token, Ast *val0, Ast *val1, Token in_token, Ast *expr, Ast *body) {
|
||||||
Ast *result = alloc_ast_node(f, Ast_UnrollRangeStmt);
|
Ast *result = alloc_ast_node(f, Ast_UnrollRangeStmt);
|
||||||
result->UnrollRangeStmt.unroll_token = unroll_token;
|
result->UnrollRangeStmt.unroll_token = unroll_token;
|
||||||
|
result->UnrollRangeStmt.args = args;
|
||||||
result->UnrollRangeStmt.for_token = for_token;
|
result->UnrollRangeStmt.for_token = for_token;
|
||||||
result->UnrollRangeStmt.val0 = val0;
|
result->UnrollRangeStmt.val0 = val0;
|
||||||
result->UnrollRangeStmt.val1 = val1;
|
result->UnrollRangeStmt.val1 = val1;
|
||||||
result->UnrollRangeStmt.in_token = in_token;
|
result->UnrollRangeStmt.in_token = in_token;
|
||||||
result->UnrollRangeStmt.expr = expr;
|
result->UnrollRangeStmt.expr = expr;
|
||||||
result->UnrollRangeStmt.body = body;
|
result->UnrollRangeStmt.body = body;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5137,6 +5139,40 @@ gb_internal Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, T
|
|||||||
|
|
||||||
|
|
||||||
gb_internal Ast *parse_unrolled_for_loop(AstFile *f, Token unroll_token) {
|
gb_internal Ast *parse_unrolled_for_loop(AstFile *f, Token unroll_token) {
|
||||||
|
Array<Ast *> args = {};
|
||||||
|
|
||||||
|
if (allow_token(f, Token_OpenParen)) {
|
||||||
|
f->expr_level++;
|
||||||
|
if (f->curr_token.kind == Token_CloseParen) {
|
||||||
|
syntax_error(f->curr_token, "#unroll expected at least 1 argument, got 0");
|
||||||
|
} else {
|
||||||
|
args = array_make<Ast *>(ast_allocator(f));
|
||||||
|
while (f->curr_token.kind != Token_CloseParen &&
|
||||||
|
f->curr_token.kind != Token_EOF) {
|
||||||
|
Ast *arg = nullptr;
|
||||||
|
arg = parse_value(f);
|
||||||
|
|
||||||
|
if (f->curr_token.kind == Token_Eq) {
|
||||||
|
Token eq = expect_token(f, Token_Eq);
|
||||||
|
if (arg != nullptr && arg->kind != Ast_Ident) {
|
||||||
|
syntax_error(arg, "Expected an identifier for 'key=value'");
|
||||||
|
}
|
||||||
|
Ast *value = parse_value(f);
|
||||||
|
arg = ast_field_value(f, arg, value, eq);
|
||||||
|
}
|
||||||
|
|
||||||
|
array_add(&args, arg);
|
||||||
|
|
||||||
|
if (!allow_field_separator(f)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f->expr_level--;
|
||||||
|
Token close = expect_closing(f, Token_CloseParen, str_lit("#unroll"));
|
||||||
|
gb_unused(close);
|
||||||
|
}
|
||||||
|
|
||||||
Token for_token = expect_token(f, Token_for);
|
Token for_token = expect_token(f, Token_for);
|
||||||
Ast *val0 = nullptr;
|
Ast *val0 = nullptr;
|
||||||
Ast *val1 = nullptr;
|
Ast *val1 = nullptr;
|
||||||
@@ -5180,7 +5216,7 @@ gb_internal Ast *parse_unrolled_for_loop(AstFile *f, Token unroll_token) {
|
|||||||
if (bad_stmt) {
|
if (bad_stmt) {
|
||||||
return ast_bad_stmt(f, unroll_token, f->curr_token);
|
return ast_bad_stmt(f, unroll_token, f->curr_token);
|
||||||
}
|
}
|
||||||
return ast_unroll_range_stmt(f, unroll_token, for_token, val0, val1, in_token, expr, body);
|
return ast_unroll_range_stmt(f, unroll_token, slice_from_array(args), for_token, val0, val1, in_token, expr, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal Ast *parse_stmt(AstFile *f) {
|
gb_internal Ast *parse_stmt(AstFile *f) {
|
||||||
|
|||||||
@@ -563,6 +563,7 @@ AST_KIND(_ComplexStmtBegin, "", bool) \
|
|||||||
AST_KIND(UnrollRangeStmt, "#unroll range statement", struct { \
|
AST_KIND(UnrollRangeStmt, "#unroll range statement", struct { \
|
||||||
Scope *scope; \
|
Scope *scope; \
|
||||||
Token unroll_token; \
|
Token unroll_token; \
|
||||||
|
Slice<Ast *> args; \
|
||||||
Token for_token; \
|
Token for_token; \
|
||||||
Ast *val0; \
|
Ast *val0; \
|
||||||
Ast *val1; \
|
Ast *val1; \
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import "core:log"
|
|||||||
test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
||||||
track: mem.Tracking_Allocator
|
track: mem.Tracking_Allocator
|
||||||
mem.tracking_allocator_init(&track, context.allocator)
|
mem.tracking_allocator_init(&track, context.allocator)
|
||||||
|
track.bad_free_callback = mem.tracking_allocator_bad_free_callback_add_to_array
|
||||||
defer mem.tracking_allocator_destroy(&track)
|
defer mem.tracking_allocator_destroy(&track)
|
||||||
context.allocator = mem.tracking_allocator(&track)
|
context.allocator = mem.tracking_allocator(&track)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, freebsd, openbsd, netbsd
|
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||||
package tests_core_posix
|
package tests_core_posix
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
@@ -65,8 +65,17 @@ test_dirent :: proc(t: ^testing.T) {
|
|||||||
for entry in entries {
|
for entry in entries {
|
||||||
defer posix.free(entry)
|
defer posix.free(entry)
|
||||||
|
|
||||||
if entry.d_type != .REG {
|
when ODIN_OS == .Haiku {
|
||||||
continue
|
stat: posix.stat_t
|
||||||
|
posix.stat(cstring(raw_data(entry.d_name[:])), &stat)
|
||||||
|
|
||||||
|
if !posix.S_ISREG(stat.st_mode) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if entry.d_type != .REG {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name := string(cstring(raw_data(entry.d_name[:])))
|
name := string(cstring(raw_data(entry.d_name[:])))
|
||||||
@@ -86,8 +95,17 @@ test_dirent :: proc(t: ^testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.d_type != .REG {
|
when ODIN_OS == .Haiku {
|
||||||
continue
|
stat: posix.stat_t
|
||||||
|
posix.stat(cstring(raw_data(entry.d_name[:])), &stat)
|
||||||
|
|
||||||
|
if !posix.S_ISREG(stat.st_mode) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if entry.d_type != .REG {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name := string(cstring(raw_data(entry.d_name[:])))
|
name := string(cstring(raw_data(entry.d_name[:])))
|
||||||
@@ -140,15 +158,15 @@ test_langinfo :: proc(t: ^testing.T) {
|
|||||||
@(test)
|
@(test)
|
||||||
test_libgen :: proc(t: ^testing.T) {
|
test_libgen :: proc(t: ^testing.T) {
|
||||||
tests := [][3]cstring{
|
tests := [][3]cstring{
|
||||||
{ "usr", ".", "usr" },
|
{ "usr", ".", "usr" },
|
||||||
{ "usr/", ".", "usr" },
|
{ "usr/", ".", "usr" },
|
||||||
{ "", ".", "." },
|
{ "", ".", "." },
|
||||||
{ "/", "/", "/" },
|
{ "/", "/", "/" },
|
||||||
{ "///", "/", "/" },
|
{ "///", "/", "/" },
|
||||||
{ "/usr/", "/", "usr" },
|
{ "/usr/", "/", "usr" },
|
||||||
{ "/usr/lib", "/usr", "lib" },
|
{ "/usr/lib", "/usr", "lib" },
|
||||||
{ "//usr//lib//", "//usr", "lib" },
|
{ "//usr//lib//", "//usr" + ("/" when ODIN_OS == .Haiku else ""), "lib" },
|
||||||
{ "/home//dwc//test", "/home//dwc", "test" },
|
{ "/home//dwc//test", "/home//dwc" + ("/" when ODIN_OS == .Haiku else ""), "test" },
|
||||||
}
|
}
|
||||||
|
|
||||||
for test in tests {
|
for test in tests {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build linux, darwin, freebsd, openbsd, netbsd
|
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||||
package tests_core_posix
|
package tests_core_posix
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
|
|||||||
@@ -10,7 +10,11 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/msg.h>
|
#include <sys/msg.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
@@ -25,7 +29,11 @@
|
|||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -67,7 +75,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("passwd %zu %zu\n", sizeof(struct passwd), _Alignof(struct passwd));
|
printf("passwd %zu %zu\n", sizeof(struct passwd), _Alignof(struct passwd));
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
printf("shmid_ds %zu %zu\n", sizeof(struct shmid_ds), _Alignof(struct shmid_ds));
|
printf("shmid_ds %zu %zu\n", sizeof(struct shmid_ds), _Alignof(struct shmid_ds));
|
||||||
|
#endif
|
||||||
|
|
||||||
printf("ipc_perm %zu %zu\n", sizeof(struct ipc_perm), _Alignof(struct ipc_perm));
|
printf("ipc_perm %zu %zu\n", sizeof(struct ipc_perm), _Alignof(struct ipc_perm));
|
||||||
printf("msqid_ds %zu %zu\n", sizeof(struct msqid_ds), _Alignof(struct msqid_ds));
|
printf("msqid_ds %zu %zu\n", sizeof(struct msqid_ds), _Alignof(struct msqid_ds));
|
||||||
|
|
||||||
@@ -95,7 +106,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("utimbuf %zu %zu\n", sizeof(struct utimbuf), _Alignof(struct utimbuf));
|
printf("utimbuf %zu %zu\n", sizeof(struct utimbuf), _Alignof(struct utimbuf));
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
printf("wordexp_t %zu %zu\n", sizeof(wordexp_t), _Alignof(wordexp_t));
|
printf("wordexp_t %zu %zu\n", sizeof(wordexp_t), _Alignof(wordexp_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
printf("time_t %zu %zu\n", sizeof(time_t), _Alignof(time_t));
|
printf("time_t %zu %zu\n", sizeof(time_t), _Alignof(time_t));
|
||||||
printf("timespec %zu %zu\n", sizeof(struct timespec), _Alignof(struct timespec));
|
printf("timespec %zu %zu\n", sizeof(struct timespec), _Alignof(struct timespec));
|
||||||
|
|||||||
@@ -42,7 +42,10 @@ main :: proc() {
|
|||||||
fmt.println("pollfd", size_of(posix.pollfd), align_of(posix.pollfd))
|
fmt.println("pollfd", size_of(posix.pollfd), align_of(posix.pollfd))
|
||||||
fmt.println("passwd", size_of(posix.passwd), align_of(posix.passwd))
|
fmt.println("passwd", size_of(posix.passwd), align_of(posix.passwd))
|
||||||
|
|
||||||
fmt.println("shmid_ds", size_of(posix.shmid_ds), align_of(posix.shmid_ds))
|
when ODIN_OS != .Haiku {
|
||||||
|
fmt.println("shmid_ds", size_of(posix.shmid_ds), align_of(posix.shmid_ds))
|
||||||
|
}
|
||||||
|
|
||||||
fmt.println("ipc_perm", size_of(posix.ipc_perm), align_of(posix.ipc_perm))
|
fmt.println("ipc_perm", size_of(posix.ipc_perm), align_of(posix.ipc_perm))
|
||||||
fmt.println("msqid_ds", size_of(posix.msqid_ds), align_of(posix.msqid_ds))
|
fmt.println("msqid_ds", size_of(posix.msqid_ds), align_of(posix.msqid_ds))
|
||||||
|
|
||||||
@@ -70,8 +73,10 @@ main :: proc() {
|
|||||||
|
|
||||||
fmt.println("utimbuf", size_of(posix.utimbuf), align_of(posix.utimbuf))
|
fmt.println("utimbuf", size_of(posix.utimbuf), align_of(posix.utimbuf))
|
||||||
|
|
||||||
fmt.println("wordexp_t", size_of(posix.wordexp_t), align_of(posix.wordexp_t))
|
when ODIN_OS != .Haiku {
|
||||||
|
fmt.println("wordexp_t", size_of(posix.wordexp_t), align_of(posix.wordexp_t))
|
||||||
|
}
|
||||||
|
|
||||||
fmt.println("time_t", size_of(posix.time_t), align_of(posix.time_t))
|
fmt.println("time_t", size_of(posix.time_t), align_of(posix.time_t))
|
||||||
fmt.println("timespec", size_of(posix.timespec), align_of(posix.timespec))
|
fmt.println("timespec", size_of(posix.timespec), align_of(posix.timespec))
|
||||||
fmt.println("clock_t", size_of(posix.clock_t), align_of(posix.clock_t))
|
fmt.println("clock_t", size_of(posix.clock_t), align_of(posix.clock_t))
|
||||||
|
|||||||
Vendored
+11
-1
@@ -1571,7 +1571,7 @@ VIEW_INSTANCING_DESC :: struct {
|
|||||||
Flags: VIEW_INSTANCING_FLAGS,
|
Flags: VIEW_INSTANCING_FLAGS,
|
||||||
}
|
}
|
||||||
|
|
||||||
SHADER_COMPONENT_MAPPING :: enum i32 {
|
SHADER_COMPONENT_MAPPING :: enum u32 {
|
||||||
FROM_MEMORY_COMPONENT_0 = 0,
|
FROM_MEMORY_COMPONENT_0 = 0,
|
||||||
FROM_MEMORY_COMPONENT_1 = 1,
|
FROM_MEMORY_COMPONENT_1 = 1,
|
||||||
FROM_MEMORY_COMPONENT_2 = 2,
|
FROM_MEMORY_COMPONENT_2 = 2,
|
||||||
@@ -1579,6 +1579,16 @@ SHADER_COMPONENT_MAPPING :: enum i32 {
|
|||||||
FORCE_VALUE_0 = 4,
|
FORCE_VALUE_0 = 4,
|
||||||
FORCE_VALUE_1 = 5,
|
FORCE_VALUE_1 = 5,
|
||||||
}
|
}
|
||||||
|
ENCODE_SHADER_4_COMPONENT_MAPPING :: #force_inline proc "contextless" (Src0, Src1, Src2, Src3: u32) -> u32 {
|
||||||
|
return (Src0 & SHADER_COMPONENT_MAPPING_MASK) |
|
||||||
|
((Src1 & SHADER_COMPONENT_MAPPING_MASK) << SHADER_COMPONENT_MAPPING_SHIFT) |
|
||||||
|
((Src2 & SHADER_COMPONENT_MAPPING_MASK) << (SHADER_COMPONENT_MAPPING_SHIFT * 2)) |
|
||||||
|
((Src3 & SHADER_COMPONENT_MAPPING_MASK) << (SHADER_COMPONENT_MAPPING_SHIFT * 3)) |
|
||||||
|
SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES
|
||||||
|
}
|
||||||
|
DECODE_SHADER_4_COMPONENT_MAPPING :: #force_inline proc "contextless" (ComponentToExtract, Mapping: u32) -> u32 {
|
||||||
|
return Mapping >> (SHADER_COMPONENT_MAPPING_SHIFT * ComponentToExtract) & SHADER_COMPONENT_MAPPING_MASK
|
||||||
|
}
|
||||||
|
|
||||||
BUFFER_SRV_FLAGS :: distinct bit_set[BUFFER_SRV_FLAG; u32]
|
BUFFER_SRV_FLAGS :: distinct bit_set[BUFFER_SRV_FLAG; u32]
|
||||||
BUFFER_SRV_FLAG :: enum u32 {
|
BUFFER_SRV_FLAG :: enum u32 {
|
||||||
|
|||||||
+6
@@ -498,6 +498,12 @@ WHQL_DRAW_VERTEX_COUNT_2_TO_EXP :: 25
|
|||||||
|
|
||||||
SHADER_COMPONENT_MAPPING_MASK :: 0x7
|
SHADER_COMPONENT_MAPPING_MASK :: 0x7
|
||||||
SHADER_COMPONENT_MAPPING_SHIFT :: 3
|
SHADER_COMPONENT_MAPPING_SHIFT :: 3
|
||||||
|
SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES :: 1 << (SHADER_COMPONENT_MAPPING_SHIFT * 4)
|
||||||
|
DEFAULT_SHADER_4_COMPONENT_MAPPING :: (0 & SHADER_COMPONENT_MAPPING_MASK) |
|
||||||
|
((1 & SHADER_COMPONENT_MAPPING_MASK) << SHADER_COMPONENT_MAPPING_SHIFT) |
|
||||||
|
((2 & SHADER_COMPONENT_MAPPING_MASK) << (SHADER_COMPONENT_MAPPING_SHIFT * 2)) |
|
||||||
|
((3 & SHADER_COMPONENT_MAPPING_MASK) << (SHADER_COMPONENT_MAPPING_SHIFT * 3)) |
|
||||||
|
SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES
|
||||||
|
|
||||||
FILTER_REDUCTION_TYPE_MASK :: 0x3
|
FILTER_REDUCTION_TYPE_MASK :: 0x3
|
||||||
FILTER_REDUCTION_TYPE_SHIFT :: 7
|
FILTER_REDUCTION_TYPE_SHIFT :: 7
|
||||||
|
|||||||
Vendored
+2
-6
@@ -18,12 +18,8 @@ when LIB != "" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
foreign import stbi {
|
||||||
foreign import stbi "../lib/stb_image_wasm.o"
|
LIB when LIB != "" else "system:stb_image",
|
||||||
} else when LIB != "" {
|
|
||||||
foreign import stbi { LIB }
|
|
||||||
} else {
|
|
||||||
foreign import stbi "system:stb_image"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NO_STDIO :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32
|
NO_STDIO :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32
|
||||||
|
|||||||
+2
-6
@@ -18,12 +18,8 @@ when RESIZE_LIB != "" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
foreign import lib {
|
||||||
foreign import lib "../lib/stb_image_resize_wasm.o"
|
RESIZE_LIB when RESIZE_LIB != "" else "system:stb_image_resize",
|
||||||
} else when RESIZE_LIB != "" {
|
|
||||||
foreign import lib { RESIZE_LIB }
|
|
||||||
} else {
|
|
||||||
foreign import lib "system:stb_image_resize"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+2
-6
@@ -18,12 +18,8 @@ when WRITE_LIB != "" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
foreign import stbiw {
|
||||||
foreign import stbiw "../lib/stb_image_write_wasm.o"
|
WRITE_LIB when WRITE_LIB != "" else "system:stb_image_write",
|
||||||
} else when WRITE_LIB != "" {
|
|
||||||
foreign import stbiw { WRITE_LIB }
|
|
||||||
} else {
|
|
||||||
foreign import stbiw "system:stb_image_write"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_func :: proc "c" (ctx: rawptr, data: rawptr, size: c.int)
|
write_func :: proc "c" (ctx: rawptr, data: rawptr, size: c.int)
|
||||||
|
|||||||
Vendored
+12
-12
@@ -1181,7 +1181,7 @@ class WebGPUInterface {
|
|||||||
*/
|
*/
|
||||||
wgpuBufferSetLabel: (bufferIdx, labelPtr) => {
|
wgpuBufferSetLabel: (bufferIdx, labelPtr) => {
|
||||||
const buffer = this.buffers.get(bufferIdx);
|
const buffer = this.buffers.get(bufferIdx);
|
||||||
buffer.buffer.label = this.mem.loadCstring(labelPtr);
|
buffer.buffer.label = this.mem.loadCstringDirect(labelPtr);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1370,7 +1370,7 @@ class WebGPUInterface {
|
|||||||
*/
|
*/
|
||||||
wgpuCommandEncoderInsertDebugMarker: (commandEncoderIdx, markerLabelPtr) => {
|
wgpuCommandEncoderInsertDebugMarker: (commandEncoderIdx, markerLabelPtr) => {
|
||||||
const commandEncoder = this.commandEncoders.get(commandEncoderIdx);
|
const commandEncoder = this.commandEncoders.get(commandEncoderIdx);
|
||||||
commandEncoder.insertDebugMarker(this.mem.loadCstring(markerLabelPtr));
|
commandEncoder.insertDebugMarker(this.mem.loadCstringDirect(markerLabelPtr));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1387,7 +1387,7 @@ class WebGPUInterface {
|
|||||||
*/
|
*/
|
||||||
wgpuCommandEncoderPushDebugGroup: (commandEncoderIdx, groupLabelPtr) => {
|
wgpuCommandEncoderPushDebugGroup: (commandEncoderIdx, groupLabelPtr) => {
|
||||||
const commandEncoder = this.commandEncoders.get(commandEncoderIdx);
|
const commandEncoder = this.commandEncoders.get(commandEncoderIdx);
|
||||||
commandEncoder.pushDebugGroup(this.mem.loadCstring(groupLabelPtr));
|
commandEncoder.pushDebugGroup(this.mem.loadCstringDirect(groupLabelPtr));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1459,7 +1459,7 @@ class WebGPUInterface {
|
|||||||
*/
|
*/
|
||||||
wgpuComputePassEncoderInsertDebugMarker: (computePassEncoderIdx, markerLabelPtr) => {
|
wgpuComputePassEncoderInsertDebugMarker: (computePassEncoderIdx, markerLabelPtr) => {
|
||||||
const computePassEncoder = this.computePassEncoders.get(computePassEncoderIdx);
|
const computePassEncoder = this.computePassEncoders.get(computePassEncoderIdx);
|
||||||
computePassEncoder.insertDebugMarker(this.mem.loadCstring(markerLabelPtr));
|
computePassEncoder.insertDebugMarker(this.mem.loadCstringDirect(markerLabelPtr));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1476,7 +1476,7 @@ class WebGPUInterface {
|
|||||||
*/
|
*/
|
||||||
wgpuComputePassEncoderPushDebugGroup: (computePassEncoderIdx, groupLabelPtr) => {
|
wgpuComputePassEncoderPushDebugGroup: (computePassEncoderIdx, groupLabelPtr) => {
|
||||||
const computePassEncoder = this.computePassEncoders.get(computePassEncoderIdx);
|
const computePassEncoder = this.computePassEncoders.get(computePassEncoderIdx);
|
||||||
computePassEncoder.pushDebugGroup(this.mem.loadCstring(groupLabelPtr));
|
computePassEncoder.pushDebugGroup(this.mem.loadCstringDirect(groupLabelPtr));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2216,7 +2216,7 @@ class WebGPUInterface {
|
|||||||
wgpuRenderBundleEncoderInsertDebugMarker: (renderBundleEncoderIdx, markerLabelPtr) => {
|
wgpuRenderBundleEncoderInsertDebugMarker: (renderBundleEncoderIdx, markerLabelPtr) => {
|
||||||
const renderBundleEncoder = this.renderBundleEncoders.get(renderBundleEncoderIdx);
|
const renderBundleEncoder = this.renderBundleEncoders.get(renderBundleEncoderIdx);
|
||||||
this.assert(markerLabelPtr != 0);
|
this.assert(markerLabelPtr != 0);
|
||||||
const markerLabel = this.mem.loadCstring(markerLabelPtr);
|
const markerLabel = this.mem.loadCstringDirect(markerLabelPtr);
|
||||||
renderBundleEncoder.insertDebugMarker(markerLabel);
|
renderBundleEncoder.insertDebugMarker(markerLabel);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2235,7 +2235,7 @@ class WebGPUInterface {
|
|||||||
wgpuRenderBundleEncoderPushDebugGroup: (renderBundleEncoderIdx, groupLabelPtr) => {
|
wgpuRenderBundleEncoderPushDebugGroup: (renderBundleEncoderIdx, groupLabelPtr) => {
|
||||||
const renderBundleEncoder = this.renderBundleEncoders.get(renderBundleEncoderIdx);
|
const renderBundleEncoder = this.renderBundleEncoders.get(renderBundleEncoderIdx);
|
||||||
this.assert(groupLabelPtr!= 0);
|
this.assert(groupLabelPtr!= 0);
|
||||||
const groupLabel = this.mem.loadCstring(groupLabelPtr);
|
const groupLabel = this.mem.loadCstringDirect(groupLabelPtr);
|
||||||
renderBundleEncoder.pushDebugGroup(groupLabel);
|
renderBundleEncoder.pushDebugGroup(groupLabel);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2407,7 +2407,7 @@ class WebGPUInterface {
|
|||||||
*/
|
*/
|
||||||
wgpuRenderPassEncoderInsertDebugMarker: (renderPassEncoderIdx, markerLabelPtr) => {
|
wgpuRenderPassEncoderInsertDebugMarker: (renderPassEncoderIdx, markerLabelPtr) => {
|
||||||
const renderPassEncoder = this.renderPassEncoders.get(renderPassEncoderIdx);
|
const renderPassEncoder = this.renderPassEncoders.get(renderPassEncoderIdx);
|
||||||
const markerLabel = this.mem.loadCstring(markerLabelPtr);
|
const markerLabel = this.mem.loadCstringDirect(markerLabelPtr);
|
||||||
renderPassEncoder.insertDebugMarker(markerLabel);
|
renderPassEncoder.insertDebugMarker(markerLabel);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2425,7 +2425,7 @@ class WebGPUInterface {
|
|||||||
*/
|
*/
|
||||||
wgpuRenderPassEncoderPushDebugGroup: (renderPassEncoderIdx, groupLabelPtr) => {
|
wgpuRenderPassEncoderPushDebugGroup: (renderPassEncoderIdx, groupLabelPtr) => {
|
||||||
const renderPassEncoder = this.renderPassEncoders.get(renderPassEncoderIdx);
|
const renderPassEncoder = this.renderPassEncoders.get(renderPassEncoderIdx);
|
||||||
const groupLabel = this.mem.loadCstring(groupLabelPtr);
|
const groupLabel = this.mem.loadCstringDirect(groupLabelPtr);
|
||||||
renderPassEncoder.pushDebugGroup(groupLabel);
|
renderPassEncoder.pushDebugGroup(groupLabel);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2881,11 +2881,11 @@ class WebGPUObjectManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} idx
|
* @param {?number} idx
|
||||||
* @returns {T}
|
* @returns {T}
|
||||||
*/
|
*/
|
||||||
get(idx) {
|
get(idx) {
|
||||||
return this.objects[idx-1].object;
|
return this.objects[idx-1]?.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {number} idx */
|
/** @param {number} idx */
|
||||||
@@ -2908,7 +2908,7 @@ class WebGPUObjectManager {
|
|||||||
if (withLabelSetter) {
|
if (withLabelSetter) {
|
||||||
inter[`wgpu${this.name}SetLabel`] = (idx, labelPtr) => {
|
inter[`wgpu${this.name}SetLabel`] = (idx, labelPtr) => {
|
||||||
const obj = this.get(idx);
|
const obj = this.get(idx);
|
||||||
obj.label = this.mem.loadCstring(labelPtr);
|
obj.label = this.mem.loadCstringDirect(labelPtr);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return inter;
|
return inter;
|
||||||
|
|||||||
Reference in New Issue
Block a user