mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-09 06:23:14 +00:00
108 lines
2.4 KiB
Odin
108 lines
2.4 KiB
Odin
#+build !freestanding
|
|
package odin_libc
|
|
|
|
import "core:c"
|
|
import "core:io"
|
|
import "core:os"
|
|
|
|
import stb "vendor:stb/sprintf"
|
|
|
|
FILE :: uintptr
|
|
|
|
@(require, linkage="strong", link_name="fopen")
|
|
fopen :: proc "c" (path: cstring, mode: cstring) -> FILE {
|
|
context = g_ctx
|
|
unimplemented("odin_libc.fopen")
|
|
}
|
|
|
|
@(require, linkage="strong", link_name="fseek")
|
|
fseek :: proc "c" (file: FILE, offset: c.long, whence: i32) -> i32 {
|
|
context = g_ctx
|
|
handle := os.Handle(file-1)
|
|
_, err := os.seek(handle, i64(offset), int(whence))
|
|
if err != nil {
|
|
return -1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
@(require, linkage="strong", link_name="ftell")
|
|
ftell :: proc "c" (file: FILE) -> c.long {
|
|
context = g_ctx
|
|
handle := os.Handle(file-1)
|
|
off, err := os.seek(handle, 0, os.SEEK_CUR)
|
|
if err != nil {
|
|
return -1
|
|
}
|
|
return c.long(off)
|
|
}
|
|
|
|
@(require, linkage="strong", link_name="fclose")
|
|
fclose :: proc "c" (file: FILE) -> i32 {
|
|
context = g_ctx
|
|
handle := os.Handle(file-1)
|
|
if os.close(handle) != nil {
|
|
return -1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
@(require, linkage="strong", link_name="fread")
|
|
fread :: proc "c" (buffer: [^]byte, size: uint, count: uint, file: FILE) -> uint {
|
|
context = g_ctx
|
|
handle := os.Handle(file-1)
|
|
n, _ := os.read(handle, buffer[:min(size, count)])
|
|
return uint(max(0, n))
|
|
}
|
|
|
|
@(require, linkage="strong", link_name="fwrite")
|
|
fwrite :: proc "c" (buffer: [^]byte, size: uint, count: uint, file: FILE) -> uint {
|
|
context = g_ctx
|
|
handle := os.Handle(file-1)
|
|
n, _ := os.write(handle, buffer[:min(size, count)])
|
|
return uint(max(0, n))
|
|
}
|
|
|
|
@(require, linkage="strong", link_name="vsnprintf")
|
|
vsnprintf :: proc "c" (buf: [^]byte, count: uint, fmt: cstring, args: ^c.va_list) -> i32 {
|
|
i32_count := i32(count)
|
|
assert_contextless(i32_count >= 0)
|
|
return stb.vsnprintf(buf, i32_count, fmt, args)
|
|
}
|
|
|
|
@(require, linkage="strong", link_name="vfprintf")
|
|
vfprintf :: proc "c" (file: FILE, fmt: cstring, args: ^c.va_list) -> i32 {
|
|
context = g_ctx
|
|
|
|
handle := os.Handle(file-1)
|
|
|
|
MAX_STACK :: 4096
|
|
|
|
buf: []byte
|
|
stack_buf: [MAX_STACK]byte = ---
|
|
{
|
|
n := stb.vsnprintf(&stack_buf[0], MAX_STACK, fmt, args)
|
|
if n <= 0 {
|
|
return n
|
|
}
|
|
|
|
if n >= MAX_STACK {
|
|
buf = make([]byte, n)
|
|
n2 := stb.vsnprintf(raw_data(buf), i32(len(buf)), fmt, args)
|
|
assert(n == n2)
|
|
} else {
|
|
buf = stack_buf[:n]
|
|
}
|
|
}
|
|
defer if len(buf) > MAX_STACK {
|
|
delete(buf)
|
|
}
|
|
|
|
_, err := io.write_full(os.stream_from_handle(handle), buf)
|
|
if err != nil {
|
|
return -1
|
|
}
|
|
|
|
return i32(len(buf))
|
|
}
|