1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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)
}
}
|