mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-07 21:43:15 +00:00
Merge pull request #5876 from laytan/new_os-vendor/libc
new_os: vendor/libc
This commit is contained in:
66
vendor/libc/stdio.odin
vendored
66
vendor/libc/stdio.odin
vendored
@@ -4,93 +4,60 @@ package odin_libc
|
||||
import "base:runtime"
|
||||
|
||||
import "core:c"
|
||||
import "core:io"
|
||||
import "core:os"
|
||||
import "core:strconv"
|
||||
|
||||
import stb "vendor:stb/sprintf"
|
||||
|
||||
FILE :: uintptr
|
||||
FILE :: rawptr
|
||||
|
||||
EOF :: -1
|
||||
|
||||
@(require, linkage="strong", link_name="fopen")
|
||||
fopen :: proc "c" (path: cstring, mode: cstring) -> FILE {
|
||||
context = g_ctx
|
||||
unimplemented("vendor/libc: fopen")
|
||||
return _fopen(path, mode)
|
||||
}
|
||||
|
||||
@(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
|
||||
return _fseek(file, offset, whence)
|
||||
}
|
||||
|
||||
@(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)
|
||||
return _ftell(file)
|
||||
}
|
||||
|
||||
@(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
|
||||
return _fclose(file)
|
||||
}
|
||||
|
||||
@(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))
|
||||
return _fread(buffer, size, count, file)
|
||||
}
|
||||
|
||||
@(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))
|
||||
return _fwrite(buffer, size, count, file)
|
||||
}
|
||||
|
||||
@(require, linkage="strong", link_name="putchar")
|
||||
putchar :: proc "c" (char: c.int) -> c.int {
|
||||
context = g_ctx
|
||||
|
||||
n, err := os.write_byte(os.stdout, byte(char))
|
||||
if n == 0 || err != nil {
|
||||
return EOF
|
||||
}
|
||||
return char
|
||||
return _putchar(char)
|
||||
}
|
||||
|
||||
@(require, linkage="strong", link_name="getchar")
|
||||
getchar :: proc "c" () -> c.int {
|
||||
when #defined(os.stdin) {
|
||||
ret: [1]byte
|
||||
n, err := os.read(os.stdin, ret[:])
|
||||
if n == 0 || err != nil {
|
||||
return EOF
|
||||
}
|
||||
return c.int(ret[0])
|
||||
} else {
|
||||
return EOF
|
||||
}
|
||||
context = g_ctx
|
||||
return _getchar()
|
||||
}
|
||||
|
||||
@(require, linkage="strong", link_name="vsnprintf")
|
||||
@@ -109,8 +76,6 @@ vsprintf :: proc "c" (buf: [^]byte, fmt: cstring, args: ^c.va_list) -> i32 {
|
||||
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
|
||||
@@ -133,12 +98,15 @@ vfprintf :: proc "c" (file: FILE, fmt: cstring, args: ^c.va_list) -> i32 {
|
||||
delete(buf)
|
||||
}
|
||||
|
||||
_, err := io.write_full(os.stream_from_handle(handle), buf)
|
||||
if err != nil {
|
||||
return -1
|
||||
written: i32
|
||||
for len(buf) > 0 {
|
||||
n := _fwrite(raw_data(buf), size_of(byte), len(buf), file)
|
||||
if n == 0 { break }
|
||||
buf = buf[n:]
|
||||
written += i32(n)
|
||||
}
|
||||
|
||||
return i32(len(buf))
|
||||
return written
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
60
vendor/libc/stdio_js.odin
vendored
Normal file
60
vendor/libc/stdio_js.odin
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
#+private
|
||||
package odin_libc
|
||||
|
||||
import "core:c"
|
||||
|
||||
foreign import "odin_env"
|
||||
|
||||
_fopen :: proc(path, mode: cstring) -> FILE {
|
||||
unimplemented("vendor/libc: fopen in JS")
|
||||
}
|
||||
|
||||
_fseek :: proc(file: FILE, offset: c.long, whence: i32) -> i32 {
|
||||
unimplemented("vendor/libc: fseek in JS")
|
||||
}
|
||||
|
||||
_ftell :: proc(file: FILE) -> c.long {
|
||||
unimplemented("vendor/libc: ftell in JS")
|
||||
}
|
||||
|
||||
_fclose :: proc(file: FILE) -> i32 {
|
||||
unimplemented("vendor/libc: fclose in JS")
|
||||
}
|
||||
|
||||
_fread :: proc(buffer: [^]byte, size: uint, count: uint, file: FILE) -> uint {
|
||||
unimplemented("vendor/libc: fread in JS")
|
||||
}
|
||||
|
||||
_fwrite :: proc(buffer: [^]byte, size: uint, count: uint, file: FILE) -> uint {
|
||||
fd, ok := __fd(file)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
|
||||
__write(fd, buffer[:size*count])
|
||||
return count
|
||||
}
|
||||
|
||||
_putchar :: proc(char: c.int) -> c.int {
|
||||
__write(1, {byte(char)})
|
||||
return char
|
||||
}
|
||||
|
||||
_getchar :: proc() -> c.int {
|
||||
return EOF
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
foreign odin_env {
|
||||
@(link_name="write")
|
||||
__write :: proc "contextless" (fd: u32, p: []byte) ---
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
__fd :: proc(file: FILE) -> (u32, bool) {
|
||||
switch (uint(uintptr(file))) {
|
||||
case 2: return 1, true // stdout
|
||||
case 3: return 2, true // stderr
|
||||
case: return 0, false
|
||||
}
|
||||
}
|
||||
104
vendor/libc/stdio_os.odin
vendored
Normal file
104
vendor/libc/stdio_os.odin
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
#+build !freestanding
|
||||
#+build !js
|
||||
package odin_libc
|
||||
|
||||
import "core:io"
|
||||
import "core:c"
|
||||
import os "core:os/os2"
|
||||
|
||||
_fopen :: proc(path, _mode: cstring) -> FILE {
|
||||
flags: os.File_Flags
|
||||
|
||||
mode := string(_mode)
|
||||
if len(mode) > 1 {
|
||||
switch mode[0] {
|
||||
case 'r':
|
||||
flags += {.Read}
|
||||
case 'w':
|
||||
flags += {.Write, .Create, .Trunc}
|
||||
case 'a':
|
||||
flags += {.Write, .Create, .Append}
|
||||
case:
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(mode) > 1 && mode[1] == '+' {
|
||||
flags += {.Write, .Read}
|
||||
} else if len(mode) > 2 && mode[1] == 'b' && mode[2] == '+' {
|
||||
flags += {.Write, .Read}
|
||||
}
|
||||
}
|
||||
|
||||
file, err := os.open(string(path), flags, os.Permissions_Read_Write_All)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return FILE(file)
|
||||
}
|
||||
|
||||
_fseek :: proc(_file: FILE, offset: c.long, whence: i32) -> i32 {
|
||||
file := __file(_file)
|
||||
if _, err := os.seek(file, i64(offset), io.Seek_From(whence)); err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_ftell :: proc(_file: FILE) -> c.long {
|
||||
file := __file(_file)
|
||||
pos, err := os.seek(file, 0, .Current)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
return c.long(pos)
|
||||
}
|
||||
|
||||
_fclose :: proc(_file: FILE) -> i32 {
|
||||
file := __file(_file)
|
||||
if err := os.close(file); err != nil {
|
||||
return EOF
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_fread :: proc(buffer: [^]byte, size: uint, count: uint, _file: FILE) -> uint {
|
||||
file := __file(_file)
|
||||
n, _ := os.read(file, buffer[:size*count])
|
||||
return uint(max(0, n)) / size
|
||||
}
|
||||
|
||||
_fwrite :: proc(buffer: [^]byte, size: uint, count: uint, _file: FILE) -> uint {
|
||||
file := __file(_file)
|
||||
n, _ := os.write(file, buffer[:size*count])
|
||||
return uint(max(0, n)) / size
|
||||
}
|
||||
|
||||
_putchar :: proc(char: c.int) -> c.int {
|
||||
n, err := os.write_byte(os.stdout, byte(char))
|
||||
if n == 0 || err != nil {
|
||||
return EOF
|
||||
}
|
||||
return char
|
||||
}
|
||||
|
||||
_getchar :: proc() -> c.int {
|
||||
ret: [1]byte
|
||||
n, err := os.read(os.stdin, ret[:])
|
||||
if n == 0 || err != nil {
|
||||
return EOF
|
||||
}
|
||||
return c.int(ret[0])
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
__file :: proc(file: FILE) -> ^os.File {
|
||||
switch (uint(uintptr(file))) {
|
||||
case 2: return os.stdout
|
||||
case 3: return os.stderr
|
||||
case: return (^os.File)(file)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user