mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-05 04:27:51 +00:00
Merge branch 'master' into bill/sdl3
This commit is contained in:
@@ -210,10 +210,24 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
case size == 0:
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
case (uintptr(old_data) & uintptr(alignment-1) == 0) && size < old_size:
|
||||
// shrink data in-place
|
||||
data = old_data[:size]
|
||||
return
|
||||
case uintptr(old_data) & uintptr(alignment-1) == 0:
|
||||
if size < old_size {
|
||||
// shrink data in-place
|
||||
data = old_data[:size]
|
||||
return
|
||||
}
|
||||
|
||||
if block := arena.curr_block; block != nil {
|
||||
start := uint(uintptr(old_memory)) - uint(uintptr(block.base))
|
||||
old_end := start + old_size
|
||||
new_end := start + size
|
||||
if start < old_end && old_end == block.used && new_end <= block.capacity {
|
||||
// grow data in-place, adjusting next allocation
|
||||
block.used = uint(new_end)
|
||||
data = block.base[start:new_end]
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new_memory := arena_alloc(arena, size, alignment, location) or_return
|
||||
|
||||
@@ -9,7 +9,7 @@ set -eu
|
||||
CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"dev-$(date +"%Y-%m")\""
|
||||
CXXFLAGS="$CXXFLAGS -std=c++14"
|
||||
DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value"
|
||||
LDFLAGS="$LDFLAGS -pthread -lm -lstdc++"
|
||||
LDFLAGS="$LDFLAGS -pthread -lm"
|
||||
OS_ARCH="$(uname -m)"
|
||||
OS_NAME="$(uname -s)"
|
||||
|
||||
@@ -95,15 +95,15 @@ Darwin)
|
||||
;;
|
||||
FreeBSD)
|
||||
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
|
||||
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
||||
LDFLAGS="$LDFLAGS -lstdc++ $($LLVM_CONFIG --libs core native --system-libs)"
|
||||
;;
|
||||
NetBSD)
|
||||
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
|
||||
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
||||
LDFLAGS="$LDFLAGS -lstdc++ $($LLVM_CONFIG --libs core native --system-libs)"
|
||||
;;
|
||||
Linux)
|
||||
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
|
||||
LDFLAGS="$LDFLAGS -ldl $($LLVM_CONFIG --libs core native --system-libs --libfiles)"
|
||||
LDFLAGS="$LDFLAGS -lstdc++ -ldl $($LLVM_CONFIG --libs core native --system-libs --libfiles)"
|
||||
# Copy libLLVM*.so into current directory for linking
|
||||
# NOTE: This is needed by the Linux release pipeline!
|
||||
# cp $(readlink -f $($LLVM_CONFIG --libfiles)) ./
|
||||
@@ -111,12 +111,12 @@ Linux)
|
||||
;;
|
||||
OpenBSD)
|
||||
CXXFLAGS="$CXXFLAGS -I/usr/local/include $($LLVM_CONFIG --cxxflags --ldflags)"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib -liconv"
|
||||
LDFLAGS="$LDFLAGS -lstdc++ -L/usr/local/lib -liconv"
|
||||
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
||||
;;
|
||||
Haiku)
|
||||
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 -lstdc++ -liconv"
|
||||
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -114,3 +114,5 @@ CHAR_BIT :: 8
|
||||
va_list :: struct #align(16) {
|
||||
_: [4096]u8,
|
||||
}
|
||||
|
||||
FILE :: struct {}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package libc
|
||||
|
||||
import "core:c"
|
||||
import "core:io"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@@ -15,7 +16,7 @@ when ODIN_OS == .Windows {
|
||||
|
||||
// 7.21 Input/output
|
||||
|
||||
FILE :: struct {}
|
||||
FILE :: c.FILE
|
||||
|
||||
Whence :: enum int {
|
||||
SET = SEEK_SET,
|
||||
|
||||
@@ -1379,9 +1379,9 @@ _pad :: proc(fi: ^Info, s: string) {
|
||||
if fi.minus { // right pad
|
||||
io.write_string(fi.writer, s, &fi.n)
|
||||
fmt_write_padding(fi, width)
|
||||
} else if !fi.space && s != "" && s[0] == '-' {
|
||||
} else if !fi.space && s != "" && (s[0] == '-' || s[0] == '+') {
|
||||
// left pad accounting for zero pad of negative number
|
||||
io.write_byte(fi.writer, '-', &fi.n)
|
||||
io.write_byte(fi.writer, s[0], &fi.n)
|
||||
fmt_write_padding(fi, width)
|
||||
io.write_string(fi.writer, s[1:], &fi.n)
|
||||
} else { // left pad
|
||||
|
||||
@@ -1207,8 +1207,8 @@ matrix2_inverse_f16 :: proc "contextless" (m: Matrix2f16) -> (c: Matrix2f16) #no
|
||||
d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
|
||||
id := 1.0/d
|
||||
c[0, 0] = +m[1, 1] * id
|
||||
c[0, 1] = -m[1, 0] * id
|
||||
c[1, 0] = -m[0, 1] * id
|
||||
c[0, 1] = -m[0, 1] * id
|
||||
c[1, 0] = -m[1, 0] * id
|
||||
c[1, 1] = +m[0, 0] * id
|
||||
return c
|
||||
}
|
||||
@@ -1217,8 +1217,8 @@ matrix2_inverse_f32 :: proc "contextless" (m: Matrix2f32) -> (c: Matrix2f32) #no
|
||||
d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
|
||||
id := 1.0/d
|
||||
c[0, 0] = +m[1, 1] * id
|
||||
c[0, 1] = -m[1, 0] * id
|
||||
c[1, 0] = -m[0, 1] * id
|
||||
c[0, 1] = -m[0, 1] * id
|
||||
c[1, 0] = -m[1, 0] * id
|
||||
c[1, 1] = +m[0, 0] * id
|
||||
return c
|
||||
}
|
||||
@@ -1227,8 +1227,8 @@ matrix2_inverse_f64 :: proc "contextless" (m: Matrix2f64) -> (c: Matrix2f64) #no
|
||||
d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
|
||||
id := 1.0/d
|
||||
c[0, 0] = +m[1, 1] * id
|
||||
c[0, 1] = -m[1, 0] * id
|
||||
c[1, 0] = -m[0, 1] * id
|
||||
c[0, 1] = -m[0, 1] * id
|
||||
c[1, 0] = -m[1, 0] * id
|
||||
c[1, 1] = +m[0, 0] * id
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -328,10 +328,24 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
case size == 0:
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
case (uintptr(old_data) & uintptr(alignment-1) == 0) && size < old_size:
|
||||
// shrink data in-place
|
||||
data = old_data[:size]
|
||||
return
|
||||
case uintptr(old_data) & uintptr(alignment-1) == 0:
|
||||
if size < old_size {
|
||||
// shrink data in-place
|
||||
data = old_data[:size]
|
||||
return
|
||||
}
|
||||
|
||||
if block := arena.curr_block; block != nil {
|
||||
start := uint(uintptr(old_memory)) - uint(uintptr(block.base))
|
||||
old_end := start + old_size
|
||||
new_end := start + size
|
||||
if start < old_end && old_end == block.used && new_end <= block.reserved {
|
||||
// grow data in-place, adjusting next allocation
|
||||
_ = alloc_from_memory_block(block, new_end - old_end, 1, default_commit_size=arena.default_commit_size) or_return
|
||||
data = block.base[start:new_end]
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new_memory := arena_alloc(arena, size, alignment, location) or_return
|
||||
|
||||
@@ -95,6 +95,7 @@ Resolve_Error :: enum u32 {
|
||||
}
|
||||
|
||||
DNS_Error :: enum u32 {
|
||||
None = 0,
|
||||
Invalid_Hostname_Error = 1,
|
||||
Invalid_Hosts_Config_Error,
|
||||
Invalid_Resolv_Config_Error,
|
||||
@@ -147,6 +148,9 @@ IP6_Loopback :: IP6_Address{0, 0, 0, 0, 0, 0, 0, 1}
|
||||
IP4_Any := IP4_Address{}
|
||||
IP6_Any := IP6_Address{}
|
||||
|
||||
IP4_mDNS_Broadcast := Endpoint{address=IP4_Address{224, 0, 0, 251}, port=5353}
|
||||
IP6_mDNS_Broadcast := Endpoint{address=IP6_Address{65282, 0, 0, 0, 0, 0, 0, 251}, port = 5353}
|
||||
|
||||
Endpoint :: struct {
|
||||
address: Address,
|
||||
port: int,
|
||||
|
||||
@@ -132,7 +132,14 @@ resolve_ip4 :: proc(hostname_and_maybe_port: string) -> (ep4: Endpoint, err: Net
|
||||
return
|
||||
}
|
||||
case Host:
|
||||
recs, _ := get_dns_records_from_os(t.hostname, .IP4, context.temp_allocator)
|
||||
recs: []DNS_Record
|
||||
|
||||
if ODIN_OS != .Windows && strings.has_suffix(t.hostname, ".local") {
|
||||
recs, _ = get_dns_records_from_nameservers(t.hostname, .IP4, {IP4_mDNS_Broadcast}, nil, context.temp_allocator)
|
||||
} else {
|
||||
recs, _ = get_dns_records_from_os(t.hostname, .IP4, context.temp_allocator)
|
||||
}
|
||||
|
||||
if len(recs) == 0 {
|
||||
err = .Unable_To_Resolve
|
||||
return
|
||||
@@ -159,7 +166,14 @@ resolve_ip6 :: proc(hostname_and_maybe_port: string) -> (ep6: Endpoint, err: Net
|
||||
return t, nil
|
||||
}
|
||||
case Host:
|
||||
recs, _ := get_dns_records_from_os(t.hostname, .IP6, context.temp_allocator)
|
||||
recs: []DNS_Record
|
||||
|
||||
if ODIN_OS != .Windows && strings.has_suffix(t.hostname, ".local") {
|
||||
recs, _ = get_dns_records_from_nameservers(t.hostname, .IP6, {IP6_mDNS_Broadcast}, nil, context.temp_allocator)
|
||||
} else {
|
||||
recs, _ = get_dns_records_from_os(t.hostname, .IP6, context.temp_allocator)
|
||||
}
|
||||
|
||||
if len(recs) == 0 {
|
||||
err = .Unable_To_Resolve
|
||||
return
|
||||
@@ -255,12 +269,6 @@ get_dns_records_from_nameservers :: proc(hostname: string, type: DNS_Record_Type
|
||||
return nil, .Connection_Error
|
||||
}
|
||||
|
||||
// recv_sz, _, recv_err := recv_udp(conn, dns_response_buf[:])
|
||||
// if recv_err == UDP_Recv_Error.Timeout {
|
||||
// continue
|
||||
// } else if recv_err != nil {
|
||||
// continue
|
||||
// }
|
||||
recv_sz, _ := recv_udp(conn, dns_response_buf[:]) or_continue
|
||||
if recv_sz == 0 {
|
||||
continue
|
||||
|
||||
@@ -29,9 +29,14 @@ import win "core:sys/windows"
|
||||
_get_dns_records_os :: proc(hostname: string, type: DNS_Record_Type, allocator := context.allocator) -> (records: []DNS_Record, err: DNS_Error) {
|
||||
context.allocator = allocator
|
||||
|
||||
options := win.DNS_QUERY_OPTIONS{}
|
||||
if strings.has_suffix(hostname, ".local") {
|
||||
options = {.MULTICAST_ONLY, .MULTICAST_WAIT} // 0x00020500
|
||||
}
|
||||
|
||||
host_cstr := strings.clone_to_cstring(hostname, context.temp_allocator)
|
||||
rec: ^win.DNS_RECORD
|
||||
res := win.DnsQuery_UTF8(host_cstr, u16(type), 0, nil, &rec, nil)
|
||||
res := win.DnsQuery_UTF8(host_cstr, u16(type), options, nil, &rec, nil)
|
||||
|
||||
switch u32(res) {
|
||||
case 0:
|
||||
|
||||
@@ -35,6 +35,7 @@ Socket_Option :: enum c.int {
|
||||
Send_Buffer_Size = c.int(linux.Socket_Option.SNDBUF),
|
||||
Receive_Timeout = c.int(linux.Socket_Option.RCVTIMEO),
|
||||
Send_Timeout = c.int(linux.Socket_Option.SNDTIMEO),
|
||||
Broadcast = c.int(linux.Socket_Option.BROADCAST),
|
||||
}
|
||||
|
||||
// Wrappers and unwrappers for system-native types
|
||||
@@ -337,7 +338,8 @@ _set_option :: proc(sock: Any_Socket, option: Socket_Option, value: any, loc :=
|
||||
.Reuse_Address,
|
||||
.Keep_Alive,
|
||||
.Out_Of_Bounds_Data_Inline,
|
||||
.TCP_Nodelay:
|
||||
.TCP_Nodelay,
|
||||
.Broadcast:
|
||||
// TODO: verify whether these are options or not on Linux
|
||||
// .Broadcast, <-- yes
|
||||
// .Conditional_Accept,
|
||||
|
||||
@@ -10,8 +10,12 @@ _error_string :: proc(errno: i32) -> string {
|
||||
return string(posix.strerror(posix.Errno(errno)))
|
||||
}
|
||||
|
||||
_get_platform_error :: proc() -> Error {
|
||||
#partial switch errno := posix.errno(); errno {
|
||||
_get_platform_error_from_errno :: proc() -> Error {
|
||||
return _get_platform_error_existing(posix.errno())
|
||||
}
|
||||
|
||||
_get_platform_error_existing :: proc(errno: posix.Errno) -> Error {
|
||||
#partial switch errno {
|
||||
case .EPERM:
|
||||
return .Permission_Denied
|
||||
case .EEXIST:
|
||||
@@ -32,3 +36,8 @@ _get_platform_error :: proc() -> Error {
|
||||
return Platform_Error(errno)
|
||||
}
|
||||
}
|
||||
|
||||
_get_platform_error :: proc{
|
||||
_get_platform_error_existing,
|
||||
_get_platform_error_from_errno,
|
||||
}
|
||||
|
||||
@@ -7,6 +7,13 @@ import "core:time"
|
||||
import "core:sync"
|
||||
import "core:sys/linux"
|
||||
|
||||
// Most implementations will EINVAL at some point when doing big writes.
|
||||
// In practice a read/write call would probably never read/write these big buffers all at once,
|
||||
// which is why the number of bytes is returned and why there are procs that will call this in a
|
||||
// loop for you.
|
||||
// We set a max of 1GB to keep alignment and to be safe.
|
||||
MAX_RW :: 1 << 30
|
||||
|
||||
File_Impl :: struct {
|
||||
file: File,
|
||||
name: string,
|
||||
@@ -179,10 +186,11 @@ _seek :: proc(f: ^File_Impl, offset: i64, whence: io.Seek_From) -> (ret: i64, er
|
||||
}
|
||||
|
||||
_read :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) {
|
||||
if len(p) == 0 {
|
||||
if len(p) <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
n, errno := linux.read(f.fd, p[:])
|
||||
|
||||
n, errno := linux.read(f.fd, p[:min(len(p), MAX_RW)])
|
||||
if errno != .NONE {
|
||||
return -1, _get_platform_error(errno)
|
||||
}
|
||||
@@ -190,13 +198,13 @@ _read :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) {
|
||||
}
|
||||
|
||||
_read_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) {
|
||||
if len(p) == 0 {
|
||||
if len(p) <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if offset < 0 {
|
||||
return 0, .Invalid_Offset
|
||||
}
|
||||
n, errno := linux.pread(f.fd, p[:], offset)
|
||||
n, errno := linux.pread(f.fd, p[:min(len(p), MAX_RW)], offset)
|
||||
if errno != .NONE {
|
||||
return -1, _get_platform_error(errno)
|
||||
}
|
||||
@@ -206,29 +214,42 @@ _read_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) {
|
||||
return i64(n), nil
|
||||
}
|
||||
|
||||
_write :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) {
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
_write :: proc(f: ^File_Impl, p: []byte) -> (nt: i64, err: Error) {
|
||||
p := p
|
||||
for len(p) > 0 {
|
||||
n, errno := linux.write(f.fd, p[:min(len(p), MAX_RW)])
|
||||
if errno != .NONE {
|
||||
err = _get_platform_error(errno)
|
||||
return
|
||||
}
|
||||
|
||||
p = p[n:]
|
||||
nt += i64(n)
|
||||
}
|
||||
n, errno := linux.write(f.fd, p[:])
|
||||
if errno != .NONE {
|
||||
return -1, _get_platform_error(errno)
|
||||
}
|
||||
return i64(n), nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
_write_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) {
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
_write_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (nt: i64, err: Error) {
|
||||
if offset < 0 {
|
||||
return 0, .Invalid_Offset
|
||||
}
|
||||
n, errno := linux.pwrite(f.fd, p[:], offset)
|
||||
if errno != .NONE {
|
||||
return -1, _get_platform_error(errno)
|
||||
|
||||
p := p
|
||||
offset := offset
|
||||
for len(p) > 0 {
|
||||
n, errno := linux.pwrite(f.fd, p[:min(len(p), MAX_RW)], offset)
|
||||
if errno != .NONE {
|
||||
err = _get_platform_error(errno)
|
||||
return
|
||||
}
|
||||
|
||||
p = p[n:]
|
||||
nt += i64(n)
|
||||
offset += i64(n)
|
||||
}
|
||||
return i64(n), nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
_file_size :: proc(f: ^File_Impl) -> (n: i64, err: Error) {
|
||||
|
||||
@@ -2,6 +2,8 @@ package os2
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:path/filepath"
|
||||
|
||||
Path_Separator :: _Path_Separator // OS-Specific
|
||||
Path_Separator_String :: _Path_Separator_String // OS-Specific
|
||||
Path_List_Separator :: _Path_List_Separator // OS-Specific
|
||||
@@ -39,3 +41,13 @@ setwd :: set_working_directory
|
||||
set_working_directory :: proc(dir: string) -> (err: Error) {
|
||||
return _set_working_directory(dir)
|
||||
}
|
||||
|
||||
get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
return _get_executable_path(allocator)
|
||||
}
|
||||
|
||||
get_executable_directory :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
path = _get_executable_path(allocator) or_return
|
||||
path, _ = filepath.split(path)
|
||||
return
|
||||
}
|
||||
|
||||
17
core/os/os2/path_darwin.odin
Normal file
17
core/os/os2/path_darwin.odin
Normal file
@@ -0,0 +1,17 @@
|
||||
package os2
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:sys/darwin"
|
||||
import "core:sys/posix"
|
||||
|
||||
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
buffer: [darwin.PIDPATHINFO_MAXSIZE]byte = ---
|
||||
ret := darwin.proc_pidpath(posix.getpid(), raw_data(buffer[:]), len(buffer))
|
||||
if ret > 0 {
|
||||
return clone_string(string(buffer[:ret]), allocator)
|
||||
}
|
||||
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
29
core/os/os2/path_freebsd.odin
Normal file
29
core/os/os2/path_freebsd.odin
Normal file
@@ -0,0 +1,29 @@
|
||||
package os2
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:sys/freebsd"
|
||||
import "core:sys/posix"
|
||||
|
||||
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
req := []freebsd.MIB_Identifier{.CTL_KERN, .KERN_PROC, .KERN_PROC_PATHNAME, freebsd.MIB_Identifier(-1)}
|
||||
|
||||
size: uint
|
||||
if ret := freebsd.sysctl(req, nil, &size, nil, 0); ret != .NONE {
|
||||
err = _get_platform_error(posix.Errno(ret))
|
||||
return
|
||||
}
|
||||
assert(size > 0)
|
||||
|
||||
buf := make([]byte, size, allocator) or_return
|
||||
defer if err != nil { delete(buf, allocator) }
|
||||
|
||||
assert(uint(len(buf)) == size)
|
||||
|
||||
if ret := freebsd.sysctl(req, raw_data(buf), &size, nil, 0); ret != .NONE {
|
||||
err = _get_platform_error(posix.Errno(ret))
|
||||
return
|
||||
}
|
||||
|
||||
return string(buf[:size]), nil
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
#+private
|
||||
package os2
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:strings"
|
||||
import "core:strconv"
|
||||
import "base:runtime"
|
||||
import "core:sys/linux"
|
||||
|
||||
_Path_Separator :: '/'
|
||||
@@ -171,6 +172,25 @@ _set_working_directory :: proc(dir: string) -> Error {
|
||||
return _get_platform_error(linux.chdir(dir_cstr))
|
||||
}
|
||||
|
||||
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
|
||||
buf := make([dynamic]byte, 1024, temp_allocator()) or_return
|
||||
for {
|
||||
n, errno := linux.readlink("/proc/self/exe", buf[:])
|
||||
if errno != .NONE {
|
||||
err = _get_platform_error(errno)
|
||||
return
|
||||
}
|
||||
|
||||
if n < len(buf) {
|
||||
return clone_string(string(buf[:n]), allocator)
|
||||
}
|
||||
|
||||
resize(&buf, len(buf)*2) or_return
|
||||
}
|
||||
}
|
||||
|
||||
_get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fullpath: string, err: Error) {
|
||||
PROC_FD_PATH :: "/proc/self/fd/"
|
||||
|
||||
|
||||
24
core/os/os2/path_netbsd.odin
Normal file
24
core/os/os2/path_netbsd.odin
Normal file
@@ -0,0 +1,24 @@
|
||||
package os2
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
|
||||
buf := make([dynamic]byte, 1024, temp_allocator()) or_return
|
||||
for {
|
||||
n := posix.readlink("/proc/curproc/exe", raw_data(buf), len(buf))
|
||||
if n < 0 {
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
|
||||
if n < len(buf) {
|
||||
return clone_string(string(buf[:n]), allocator)
|
||||
}
|
||||
|
||||
resize(&buf, len(buf)*2) or_return
|
||||
}
|
||||
}
|
||||
57
core/os/os2/path_openbsd.odin
Normal file
57
core/os/os2/path_openbsd.odin
Normal file
@@ -0,0 +1,57 @@
|
||||
package os2
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:strings"
|
||||
import "core:sys/posix"
|
||||
|
||||
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
// OpenBSD does not have an API for this, we do our best below.
|
||||
|
||||
if len(runtime.args__) <= 0 {
|
||||
err = .Invalid_Path
|
||||
return
|
||||
}
|
||||
|
||||
real :: proc(path: cstring, allocator: runtime.Allocator) -> (out: string, err: Error) {
|
||||
real := posix.realpath(path)
|
||||
if real == nil {
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
defer posix.free(real)
|
||||
return clone_string(string(real), allocator)
|
||||
}
|
||||
|
||||
arg := runtime.args__[0]
|
||||
sarg := string(arg)
|
||||
|
||||
if len(sarg) == 0 {
|
||||
err = .Invalid_Path
|
||||
return
|
||||
}
|
||||
|
||||
if sarg[0] == '.' || sarg[0] == '/' {
|
||||
return real(arg, allocator)
|
||||
}
|
||||
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
|
||||
buf := strings.builder_make(temp_allocator())
|
||||
|
||||
paths := get_env("PATH", temp_allocator())
|
||||
for dir in strings.split_iterator(&paths, ":") {
|
||||
strings.builder_reset(&buf)
|
||||
strings.write_string(&buf, dir)
|
||||
strings.write_string(&buf, "/")
|
||||
strings.write_string(&buf, sarg)
|
||||
|
||||
cpath := strings.to_cstring(&buf)
|
||||
if posix.access(cpath, {.X_OK}) == .OK {
|
||||
return real(cpath, allocator)
|
||||
}
|
||||
}
|
||||
|
||||
err = .Invalid_Path
|
||||
return
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package os2
|
||||
import "base:runtime"
|
||||
|
||||
import "core:path/filepath"
|
||||
import "core:sync"
|
||||
import "core:sys/wasm/wasi"
|
||||
|
||||
_Path_Separator :: '/'
|
||||
@@ -74,11 +75,39 @@ _remove_all :: proc(path: string) -> (err: Error) {
|
||||
return remove(path)
|
||||
}
|
||||
|
||||
g_wd: string
|
||||
g_wd_mutex: sync.Mutex
|
||||
|
||||
_get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
|
||||
return ".", .Unsupported
|
||||
sync.guard(&g_wd_mutex)
|
||||
|
||||
return clone_string(g_wd if g_wd != "" else "/", allocator)
|
||||
}
|
||||
|
||||
_set_working_directory :: proc(dir: string) -> (err: Error) {
|
||||
err = .Unsupported
|
||||
sync.guard(&g_wd_mutex)
|
||||
|
||||
if dir == g_wd {
|
||||
return
|
||||
}
|
||||
|
||||
if g_wd != "" {
|
||||
delete(g_wd, file_allocator())
|
||||
}
|
||||
|
||||
g_wd = clone_string(dir, file_allocator()) or_return
|
||||
return
|
||||
}
|
||||
|
||||
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
if len(args) <= 0 {
|
||||
return clone_string("/", allocator)
|
||||
}
|
||||
|
||||
arg := args[0]
|
||||
if len(arg) > 0 && (arg[0] == '.' || arg[0] == '/') {
|
||||
return clone_string(arg, allocator)
|
||||
}
|
||||
|
||||
return concatenate({"/", arg}, allocator)
|
||||
}
|
||||
|
||||
@@ -136,6 +136,26 @@ _set_working_directory :: proc(dir: string) -> (err: Error) {
|
||||
return
|
||||
}
|
||||
|
||||
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
|
||||
buf := make([dynamic]u16, 512, temp_allocator()) or_return
|
||||
for {
|
||||
ret := win32.GetModuleFileNameW(nil, raw_data(buf), win32.DWORD(len(buf)))
|
||||
if ret == 0 {
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
|
||||
if ret == win32.DWORD(len(buf)) && win32.GetLastError() == win32.ERROR_INSUFFICIENT_BUFFER {
|
||||
resize(&buf, len(buf)*2) or_return
|
||||
continue
|
||||
}
|
||||
|
||||
return win32_utf16_to_utf8(buf[:ret], allocator)
|
||||
}
|
||||
}
|
||||
|
||||
can_use_long_paths: bool
|
||||
|
||||
@(init)
|
||||
|
||||
@@ -1287,7 +1287,7 @@ sendto :: proc(sd: Socket, data: []u8, flags: int, addr: ^SOCKADDR, addrlen: soc
|
||||
}
|
||||
|
||||
send :: proc(sd: Socket, data: []byte, flags: int) -> (u32, Error) {
|
||||
result := _unix_send(c.int(sd), raw_data(data), len(data), 0)
|
||||
result := _unix_send(c.int(sd), raw_data(data), len(data), i32(flags))
|
||||
if result < 0 {
|
||||
return 0, get_last_error()
|
||||
}
|
||||
|
||||
@@ -1155,7 +1155,7 @@ sendto :: proc(sd: Socket, data: []u8, flags: int, addr: ^SOCKADDR, addrlen: soc
|
||||
}
|
||||
|
||||
send :: proc(sd: Socket, data: []byte, flags: int) -> (u32, Error) {
|
||||
result := unix.sys_sendto(int(sd), raw_data(data), len(data), 0, nil, 0)
|
||||
result := unix.sys_sendto(int(sd), raw_data(data), len(data), flags, nil, 0)
|
||||
if result < 0 {
|
||||
return 0, _get_errno(int(result))
|
||||
}
|
||||
|
||||
@@ -7,3 +7,13 @@ SavePanel :: struct{ using _: Panel }
|
||||
SavePanel_runModal :: proc "c" (self: ^SavePanel) -> ModalResponse {
|
||||
return msgSend(ModalResponse, self, "runModal")
|
||||
}
|
||||
|
||||
@(objc_type=SavePanel, objc_name="savePanel", objc_is_class_method=true)
|
||||
SavePanel_savePanel :: proc "c" () -> ^SavePanel {
|
||||
return msgSend(^SavePanel, SavePanel, "savePanel")
|
||||
}
|
||||
|
||||
@(objc_type=SavePanel, objc_name="URL")
|
||||
SavePanel_URL :: proc "c" (self: ^SavePanel) -> ^Array {
|
||||
return msgSend(^Array, self, "URL")
|
||||
}
|
||||
@@ -5,6 +5,6 @@ foreign import "system:Dnsapi.lib"
|
||||
|
||||
@(default_calling_convention="system")
|
||||
foreign Dnsapi {
|
||||
DnsQuery_UTF8 :: proc(name: cstring, type: u16, options: DWORD, extra: PVOID, results: ^^DNS_RECORD, reserved: PVOID) -> DNS_STATUS ---
|
||||
DnsQuery_UTF8 :: proc(name: cstring, type: u16, options: DNS_QUERY_OPTIONS, extra: PVOID, results: ^^DNS_RECORD, reserved: PVOID) -> DNS_STATUS ---
|
||||
DnsRecordListFree :: proc(list: ^DNS_RECORD, options: DWORD) ---
|
||||
}
|
||||
|
||||
@@ -4576,6 +4576,31 @@ DNS_SRV_DATAA :: struct {
|
||||
_: WORD, // padding
|
||||
}
|
||||
|
||||
// See https://learn.microsoft.com/en-us/windows/win32/dns/dns-constants
|
||||
DNS_QUERY_OPTION :: enum DWORD {
|
||||
ACCEPT_TRUNCATED_RESPONSE = 0,
|
||||
DNS_QUERY_USE_TCP_ONLY = 1,
|
||||
NO_RECURSION = 2,
|
||||
BYPASS_CACHE = 3,
|
||||
NO_WIRE_QUERY = 4,
|
||||
NO_LOCAL_NAME = 5,
|
||||
NO_HOSTS_FILE = 6,
|
||||
NO_NETBT = 7,
|
||||
WIRE_ONLY = 8,
|
||||
RETURN_MESSAGE = 9,
|
||||
MULTICAST_ONLY = 10,
|
||||
NO_MULTICAST = 11,
|
||||
TREAT_AS_FQDN = 12,
|
||||
ADDRCONFIG = 13,
|
||||
DUAL_ADDR = 14,
|
||||
MULTICAST_WAIT = 17,
|
||||
MULTICAST_VERIFY = 18,
|
||||
DONT_RESET_TTL_VALUES = 20,
|
||||
DISABLE_IDN_ENCODING = 21,
|
||||
APPEND_MULTILABEL = 23,
|
||||
}
|
||||
DNS_QUERY_OPTIONS :: bit_set[DNS_QUERY_OPTION; DWORD]
|
||||
|
||||
SOCKADDR :: struct {
|
||||
sa_family: ADDRESS_FAMILY,
|
||||
sa_data: [14]CHAR,
|
||||
|
||||
@@ -251,7 +251,10 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success
|
||||
exp *= 10;
|
||||
exp += v;
|
||||
}
|
||||
big_int_exp_u64(dst, &b, exp, success);
|
||||
BigInt tmp = {};
|
||||
mp_init(&tmp);
|
||||
big_int_exp_u64(&tmp, &b, exp, success);
|
||||
big_int_mul_eq(dst, &tmp);
|
||||
}
|
||||
|
||||
if (is_negative) {
|
||||
|
||||
@@ -5040,6 +5040,12 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) {
|
||||
ac->extra_linker_flags = ev.value_string;
|
||||
}
|
||||
return true;
|
||||
} else if (name == "ignore_duplicates") {
|
||||
if (value != nullptr) {
|
||||
error(elem, "Expected no parameter for '%.*s'", LIT(name));
|
||||
}
|
||||
ac->ignore_duplicates = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -5190,6 +5196,9 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
|
||||
if (ac.foreign_import_priority_index != 0) {
|
||||
e->LibraryName.priority_index = ac.foreign_import_priority_index;
|
||||
}
|
||||
if (ac.ignore_duplicates) {
|
||||
e->LibraryName.ignore_duplicates = true;
|
||||
}
|
||||
String extra_linker_flags = string_trim_whitespace(ac.extra_linker_flags);
|
||||
if (extra_linker_flags.len != 0) {
|
||||
e->LibraryName.extra_linker_flags = extra_linker_flags;
|
||||
|
||||
@@ -140,6 +140,7 @@ struct AttributeContext {
|
||||
bool instrumentation_enter : 1;
|
||||
bool instrumentation_exit : 1;
|
||||
bool rodata : 1;
|
||||
bool ignore_duplicates : 1;
|
||||
u32 optimization_mode; // ProcedureOptimizationMode
|
||||
i64 foreign_import_priority_index;
|
||||
String extra_linker_flags;
|
||||
|
||||
@@ -274,6 +274,7 @@ struct Entity {
|
||||
Slice<String> paths;
|
||||
String name;
|
||||
i64 priority_index;
|
||||
bool ignore_duplicates;
|
||||
String extra_linker_flags;
|
||||
} LibraryName;
|
||||
i32 Nil;
|
||||
|
||||
@@ -449,6 +449,26 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
if (extra_linker_flags.len != 0) {
|
||||
lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags));
|
||||
}
|
||||
|
||||
if (build_context.metrics.os == TargetOs_darwin) {
|
||||
// Print frameworks first
|
||||
for (String lib : e->LibraryName.paths) {
|
||||
lib = string_trim_whitespace(lib);
|
||||
if (lib.len == 0) {
|
||||
continue;
|
||||
}
|
||||
if (string_ends_with(lib, str_lit(".framework"))) {
|
||||
if (string_set_update(&min_libs_set, lib)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String lib_name = lib;
|
||||
lib_name = remove_extension_from_path(lib_name);
|
||||
lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String lib : e->LibraryName.paths) {
|
||||
lib = string_trim_whitespace(lib);
|
||||
if (lib.len == 0) {
|
||||
@@ -541,7 +561,9 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
short_circuit = true;
|
||||
} else if (string_ends_with(lib, str_lit(".dylib"))) {
|
||||
short_circuit = true;
|
||||
} else if (string_ends_with(lib, str_lit(".so"))) {
|
||||
} else if (string_ends_with(lib, str_lit(".so"))) {
|
||||
short_circuit = true;
|
||||
} else if (e->LibraryName.ignore_duplicates) {
|
||||
short_circuit = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1147,14 +1147,14 @@ gb_internal void lb_finalize_objc_names(lbProcedure *p) {
|
||||
String name = entry.key;
|
||||
args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
|
||||
lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args);
|
||||
lb_addr_store(p, entry.value, ptr);
|
||||
lb_addr_store(p, entry.value.local_module_addr, ptr);
|
||||
}
|
||||
|
||||
for (auto const &entry : m->objc_selectors) {
|
||||
String name = entry.key;
|
||||
args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
|
||||
lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args);
|
||||
lb_addr_store(p, entry.value, ptr);
|
||||
lb_addr_store(p, entry.value.local_module_addr, ptr);
|
||||
}
|
||||
|
||||
lb_end_procedure_body(p);
|
||||
|
||||
@@ -143,6 +143,11 @@ struct lbPadType {
|
||||
LLVMTypeRef type;
|
||||
};
|
||||
|
||||
struct lbObjcRef {
|
||||
Entity * entity;
|
||||
lbAddr local_module_addr;
|
||||
};
|
||||
|
||||
struct lbModule {
|
||||
LLVMModuleRef mod;
|
||||
LLVMContextRef ctx;
|
||||
@@ -196,8 +201,8 @@ struct lbModule {
|
||||
RecursiveMutex debug_values_mutex;
|
||||
PtrMap<void *, LLVMMetadataRef> debug_values;
|
||||
|
||||
StringMap<lbAddr> objc_classes;
|
||||
StringMap<lbAddr> objc_selectors;
|
||||
StringMap<lbObjcRef> objc_classes;
|
||||
StringMap<lbObjcRef> objc_selectors;
|
||||
|
||||
PtrMap<Type *, lbAddr> map_cell_info_map; // address of runtime.Map_Info
|
||||
PtrMap<Type *, lbAddr> map_info_map; // address of runtime.Map_Cell_Info
|
||||
|
||||
@@ -4294,6 +4294,17 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
|
||||
gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
|
||||
ast_node(se, SliceExpr, expr);
|
||||
|
||||
lbAddr addr = lb_build_addr(p, se->expr);
|
||||
lbValue base = lb_addr_load(p, addr);
|
||||
Type *type = base_type(base.type);
|
||||
|
||||
if (is_type_pointer(type)) {
|
||||
type = base_type(type_deref(type));
|
||||
addr = lb_addr(base);
|
||||
base = lb_addr_load(p, addr);
|
||||
}
|
||||
|
||||
|
||||
lbValue low = lb_const_int(p->module, t_int, 0);
|
||||
lbValue high = {};
|
||||
|
||||
@@ -4306,16 +4317,6 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
|
||||
|
||||
bool no_indices = se->low == nullptr && se->high == nullptr;
|
||||
|
||||
lbAddr addr = lb_build_addr(p, se->expr);
|
||||
lbValue base = lb_addr_load(p, addr);
|
||||
Type *type = base_type(base.type);
|
||||
|
||||
if (is_type_pointer(type)) {
|
||||
type = base_type(type_deref(type));
|
||||
addr = lb_addr(base);
|
||||
base = lb_addr_load(p, addr);
|
||||
}
|
||||
|
||||
switch (type->kind) {
|
||||
case Type_Slice: {
|
||||
Type *slice_type = type;
|
||||
|
||||
@@ -2093,23 +2093,34 @@ gb_internal void lb_set_wasm_export_attributes(LLVMValueRef value, String export
|
||||
|
||||
|
||||
gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &name) {
|
||||
lbAddr *found = string_map_get(&p->module->objc_selectors, name);
|
||||
lbObjcRef *found = string_map_get(&p->module->objc_selectors, name);
|
||||
if (found) {
|
||||
return *found;
|
||||
} else {
|
||||
lbModule *default_module = &p->module->gen->default_module;
|
||||
Entity *e = nullptr;
|
||||
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e);
|
||||
|
||||
lbValue ptr = lb_find_value_from_entity(p->module, e);
|
||||
lbAddr local_addr = lb_addr(ptr);
|
||||
|
||||
string_map_set(&default_module->objc_selectors, name, default_addr);
|
||||
if (default_module != p->module) {
|
||||
string_map_set(&p->module->objc_selectors, name, local_addr);
|
||||
}
|
||||
return local_addr;
|
||||
return found->local_module_addr;
|
||||
}
|
||||
|
||||
lbModule *default_module = &p->module->gen->default_module;
|
||||
Entity *entity = {};
|
||||
|
||||
if (default_module != p->module) {
|
||||
found = string_map_get(&default_module->objc_selectors, name);
|
||||
if (found) {
|
||||
entity = found->entity;
|
||||
}
|
||||
}
|
||||
|
||||
if (!entity) {
|
||||
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &entity);
|
||||
string_map_set(&default_module->objc_selectors, name, lbObjcRef{entity, default_addr});
|
||||
}
|
||||
|
||||
lbValue ptr = lb_find_value_from_entity(p->module, entity);
|
||||
lbAddr local_addr = lb_addr(ptr);
|
||||
|
||||
if (default_module != p->module) {
|
||||
string_map_set(&p->module->objc_selectors, name, lbObjcRef{entity, local_addr});
|
||||
}
|
||||
|
||||
return local_addr;
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) {
|
||||
@@ -2139,23 +2150,34 @@ gb_internal lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr)
|
||||
}
|
||||
|
||||
gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name) {
|
||||
lbAddr *found = string_map_get(&p->module->objc_classes, name);
|
||||
lbObjcRef *found = string_map_get(&p->module->objc_classes, name);
|
||||
if (found) {
|
||||
return *found;
|
||||
} else {
|
||||
lbModule *default_module = &p->module->gen->default_module;
|
||||
Entity *e = nullptr;
|
||||
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e);
|
||||
|
||||
lbValue ptr = lb_find_value_from_entity(p->module, e);
|
||||
lbAddr local_addr = lb_addr(ptr);
|
||||
|
||||
string_map_set(&default_module->objc_classes, name, default_addr);
|
||||
if (default_module != p->module) {
|
||||
string_map_set(&p->module->objc_classes, name, local_addr);
|
||||
}
|
||||
return local_addr;
|
||||
return found->local_module_addr;
|
||||
}
|
||||
|
||||
lbModule *default_module = &p->module->gen->default_module;
|
||||
Entity *entity = {};
|
||||
|
||||
if (default_module != p->module) {
|
||||
found = string_map_get(&default_module->objc_classes, name);
|
||||
if (found) {
|
||||
entity = found->entity;
|
||||
}
|
||||
}
|
||||
|
||||
if (!entity) {
|
||||
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &entity);
|
||||
string_map_set(&default_module->objc_classes, name, lbObjcRef{entity, default_addr});
|
||||
}
|
||||
|
||||
lbValue ptr = lb_find_value_from_entity(p->module, entity);
|
||||
lbAddr local_addr = lb_addr(ptr);
|
||||
|
||||
if (default_module != p->module) {
|
||||
string_map_set(&p->module->objc_classes, name, lbObjcRef{entity, local_addr});
|
||||
}
|
||||
|
||||
return local_addr;
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) {
|
||||
@@ -2196,23 +2218,7 @@ gb_internal lbValue lb_handle_objc_id(lbProcedure *p, Ast *expr) {
|
||||
GB_ASSERT(e->kind == Entity_TypeName);
|
||||
String name = e->TypeName.objc_class_name;
|
||||
|
||||
lbAddr *found = string_map_get(&p->module->objc_classes, name);
|
||||
if (found) {
|
||||
return lb_addr_load(p, *found);
|
||||
} else {
|
||||
lbModule *default_module = &p->module->gen->default_module;
|
||||
Entity *e = nullptr;
|
||||
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &e);
|
||||
|
||||
lbValue ptr = lb_find_value_from_entity(p->module, e);
|
||||
lbAddr local_addr = lb_addr(ptr);
|
||||
|
||||
string_map_set(&default_module->objc_classes, name, default_addr);
|
||||
if (default_module != p->module) {
|
||||
string_map_set(&p->module->objc_classes, name, local_addr);
|
||||
}
|
||||
return lb_addr_load(p, local_addr);
|
||||
}
|
||||
return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name));
|
||||
}
|
||||
|
||||
return lb_build_expr(p, expr);
|
||||
|
||||
22
tests/core/os/os2/path.odin
Normal file
22
tests/core/os/os2/path.odin
Normal file
@@ -0,0 +1,22 @@
|
||||
package tests_core_os_os2
|
||||
|
||||
import os "core:os/os2"
|
||||
import "core:log"
|
||||
import "core:path/filepath"
|
||||
import "core:testing"
|
||||
import "core:strings"
|
||||
|
||||
@(test)
|
||||
test_executable :: proc(t: ^testing.T) {
|
||||
path, err := os.get_executable_path(context.allocator)
|
||||
defer delete(path)
|
||||
|
||||
log.infof("executable path: %q", path)
|
||||
|
||||
// NOTE: some sanity checks that should always be the case, at least in the CI.
|
||||
|
||||
testing.expect_value(t, err, nil)
|
||||
testing.expect(t, len(path) > 0)
|
||||
testing.expect(t, filepath.is_abs(path))
|
||||
testing.expectf(t, strings.contains(path, filepath.base(os.args[0])), "expected the executable path to contain the base of os.args[0] which is %q", filepath.base(os.args[0]))
|
||||
}
|
||||
3
vendor/commonmark/cmark.odin
vendored
3
vendor/commonmark/cmark.odin
vendored
@@ -7,7 +7,6 @@
|
||||
package vendor_commonmark
|
||||
|
||||
import "core:c"
|
||||
import "core:c/libc"
|
||||
import "base:runtime"
|
||||
|
||||
COMMONMARK_SHARED :: #config(COMMONMARK_SHARED, false)
|
||||
@@ -450,7 +449,7 @@ foreign lib {
|
||||
// Called `parse_from_libc_file` so as not to confuse with Odin's file handling.
|
||||
|
||||
@(link_name = "parse_from_file")
|
||||
parse_from_libc_file :: proc(file: ^libc.FILE, options: Options) -> (root: ^Node) ---
|
||||
parse_from_libc_file :: proc(file: ^c.FILE, options: Options) -> (root: ^Node) ---
|
||||
}
|
||||
|
||||
parser_feed_from_string :: proc "c" (parser: ^Parser, s: string) {
|
||||
|
||||
8
vendor/miniaudio/engine.odin
vendored
8
vendor/miniaudio/engine.odin
vendored
@@ -150,9 +150,9 @@ sound_inlined :: struct {
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
@(deprecated="Will be removed in 0.12. Use sound_config_init2() instead.")
|
||||
@(deprecated="Will be removed in 0.12. Use sound_config_init_2() instead.")
|
||||
sound_config_init :: proc() -> sound_config ---
|
||||
sound_config_init2 :: proc(pEngine: ^engine) -> sound_config --- /* Will be renamed to sound_config_init() in version 0.12. */
|
||||
sound_config_init_2 :: proc(pEngine: ^engine) -> sound_config --- /* Will be renamed to sound_config_init() in version 0.12. */
|
||||
|
||||
sound_init_from_file :: proc(pEngine: ^engine, pFilePath: cstring, flags: sound_flags, pGroup: ^sound_group, pDoneFence: ^fence, pSound: ^sound) -> result ---
|
||||
sound_init_from_file_w :: proc(pEngine: ^engine, pFilePath: [^]c.wchar_t, flags: sound_flags, pGroup: ^sound_group, pDoneFence: ^fence, pSound: ^sound) -> result ---
|
||||
@@ -241,9 +241,9 @@ sound_group :: distinct sound
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
@(deprecated="Will be removed in 0.12. Use sound_config_init2() instead.")
|
||||
@(deprecated="Will be removed in 0.12. Use sound_config_init_2() instead.")
|
||||
sound_group_config_init :: proc() -> sound_group_config ---
|
||||
sound_group_config_init2 :: proc(pEngine: ^engine) -> sound_group_config ---
|
||||
sound_group_config_init_2 :: proc(pEngine: ^engine) -> sound_group_config ---
|
||||
|
||||
sound_group_init :: proc(pEngine: ^engine, flags: sound_flags, pParentGroup, pGroup: ^sound_group) -> result ---
|
||||
sound_group_init_ex :: proc(pEngine: ^engine, pConfig: ^sound_group_config, pGroup: ^sound_group) -> result ---
|
||||
|
||||
2
vendor/raylib/raylib.odin
vendored
2
vendor/raylib/raylib.odin
vendored
@@ -1205,7 +1205,7 @@ foreign lib {
|
||||
|
||||
CameraMoveForward :: proc(camera: ^Camera, distance: f32, moveInWorldPlane: bool) --- // move the camera in its forward direction
|
||||
CameraMoveUp :: proc(camera: ^Camera, distance: f32) --- // move camera in its up direction
|
||||
CameraMoveRight :: proc(camera: ^Camera, distance: f32, delta: f32) --- // move camera in it's current right direction
|
||||
CameraMoveRight :: proc(camera: ^Camera, distance: f32, moveInWorldPlane: bool) --- // move camera in it's current right direction
|
||||
CameraMoveToTarget :: proc(camera: ^Camera, delta: f32) --- // moves the camera position closer/farther to/from the camera target
|
||||
CameraYaw :: proc(camera: ^Camera, angle: f32, rotateAroundTarget: bool) --- // rotates the camera around its up vector (left and right)
|
||||
CameraPitch :: proc(camera: ^Camera, angle: f32, lockView: bool, rotateAroundTarget: bool, rotateUp: bool) --- // rotates the camera around its right vector (up and down)
|
||||
|
||||
2
vendor/sdl2/sdl2.odin
vendored
2
vendor/sdl2/sdl2.odin
vendored
@@ -26,8 +26,10 @@ import "core:c"
|
||||
import "base:intrinsics"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_audio.odin
vendored
2
vendor/sdl2/sdl_audio.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_blendmode.odin
vendored
2
vendor/sdl2/sdl_blendmode.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_cpuinfo.odin
vendored
2
vendor/sdl2/sdl_cpuinfo.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_events.odin
vendored
2
vendor/sdl2/sdl_events.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_gamecontroller.odin
vendored
2
vendor/sdl2/sdl_gamecontroller.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_gesture_haptic.odin
vendored
2
vendor/sdl2/sdl_gesture_haptic.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_hints.odin
vendored
2
vendor/sdl2/sdl_hints.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_joystick.odin
vendored
2
vendor/sdl2/sdl_joystick.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_keyboard.odin
vendored
2
vendor/sdl2/sdl_keyboard.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_log.odin
vendored
2
vendor/sdl2/sdl_log.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_messagebox.odin
vendored
2
vendor/sdl2/sdl_messagebox.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_metal.odin
vendored
2
vendor/sdl2/sdl_metal.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_mouse.odin
vendored
2
vendor/sdl2/sdl_mouse.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_mutex.odin
vendored
2
vendor/sdl2/sdl_mutex.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_pixels.odin
vendored
2
vendor/sdl2/sdl_pixels.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_rect.odin
vendored
2
vendor/sdl2/sdl_rect.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_render.odin
vendored
2
vendor/sdl2/sdl_render.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_rwops.odin
vendored
2
vendor/sdl2/sdl_rwops.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_stdinc.odin
vendored
2
vendor/sdl2/sdl_stdinc.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_surface.odin
vendored
2
vendor/sdl2/sdl_surface.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_system.odin
vendored
2
vendor/sdl2/sdl_system.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_syswm.odin
vendored
2
vendor/sdl2/sdl_syswm.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_thread.odin
vendored
2
vendor/sdl2/sdl_thread.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_timer.odin
vendored
2
vendor/sdl2/sdl_timer.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_touch.odin
vendored
2
vendor/sdl2/sdl_touch.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_video.odin
vendored
2
vendor/sdl2/sdl_video.odin
vendored
@@ -3,8 +3,10 @@ package sdl2
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/sdl2/sdl_vulkan.odin
vendored
2
vendor/sdl2/sdl_vulkan.odin
vendored
@@ -4,8 +4,10 @@ import "core:c"
|
||||
import vk "vendor:vulkan"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "SDL2.lib"
|
||||
} else {
|
||||
@(ignore_duplicates)
|
||||
foreign import lib "system:SDL2"
|
||||
}
|
||||
|
||||
|
||||
2
vendor/stb/image/stb_image.odin
vendored
2
vendor/stb/image/stb_image.odin
vendored
@@ -1,6 +1,6 @@
|
||||
package stb_image
|
||||
|
||||
import c "core:c/libc"
|
||||
import "core:c"
|
||||
|
||||
@(private)
|
||||
LIB :: (
|
||||
|
||||
Reference in New Issue
Block a user