Files
Odin/vendor/libc/stdio.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))
}