11#+build js
22package fmt
33
4- import " core:bufio"
5- import " core:io"
6- import os " core:os/os2"
4+ import " core:strings"
75
86foreign import " odin_env"
97
@@ -12,90 +10,77 @@ foreign odin_env {
1210 write :: proc " contextless" (fd: u32 , p: []byte ) ---
1311}
1412
15- @ (private=" file" )
16- write_stream_proc :: proc (stream_data: rawptr , mode: io.Stream_Mode, p: []byte , offset: i64 , whence: io.Seek_From) -> (n: i64 , err: io.Error) {
17- if mode == .Write {
18- fd := u32 (uintptr (stream_data))
19- write (fd, p)
20- return i64 (len (p)), nil
21- }
22- return 0 , .Empty
23- }
13+ stdout :: u32 (1 )
14+ stderr :: u32 (2 )
2415
2516@ (private=" file" )
26- stdout := io.Writer{
27- procedure = write_stream_proc,
28- data = rawptr (uintptr (1 )),
29- }
17+ BUF_SIZE :: 1024
18+
3019@ (private=" file" )
31- stderr := io.Writer{
32- procedure = write_stream_proc,
33- data = rawptr (uintptr (2 )),
34- }
20+ // TODO: Find a way to grow this if necessary
21+ buf: [BUF_SIZE]byte
3522
3623@ (private=" file" )
37- fd_to_writer :: proc (f: ^os.File, loc := #caller_location ) -> io.Writer {
38- switch {
39- case f == os.stdout: return stdout
40- case f == os.stderr: return stderr
41- case : panic (" `fmt.fprint` variant called with invalid file descriptor for JS, only 1 (stdout) and 2 (stderr) are supported" , loc)
24+ get_fd :: proc (f: any , loc := #caller_location ) -> (fd: u32 ) {
25+ if _fd, _ok := f.(u32 ); _ok {
26+ fd = _fd
4227 }
28+ if fd != 1 && fd != 2 {
29+ panic (" `fmt.fprint` variant called with invalid file descriptor for JS, only 1 (stdout) and 2 (stderr) are supported" , loc)
30+ }
31+ return fd
4332}
4433
4534// fprint formats using the default print settings and writes to fd
46- fprint :: proc (f: ^os.File, args: ..any , sep := " " , flush := true , loc := #caller_location ) -> int {
47- buf: [1024 ]byte
48- b: bufio.Writer
49- defer bufio.writer_flush (&b)
50-
51- bufio.writer_init_with_buf (&b, fd_to_writer (f, loc), buf[:])
52- w := bufio.writer_to_writer (&b)
53- return wprint (w, ..args, sep=sep, flush=flush)
35+ // flush is ignored
36+ fprint :: proc (f: any , args: ..any , sep := " " , flush := true , loc := #caller_location ) -> (n: int ) {
37+ fd := get_fd (f)
38+ s := bprint (buf[:], ..args, sep=sep)
39+ n = len (s)
40+ write (fd, transmute ([]byte )s)
41+ return n
5442}
5543
56- // fprintln formats using the default print settings and writes to fd
57- fprintln :: proc (f: ^os.File, args: ..any , sep := " " , flush := true , loc := #caller_location ) -> int {
58- buf: [1024 ]byte
59- b: bufio.Writer
60- defer bufio.writer_flush (&b)
61-
62- bufio.writer_init_with_buf (&b, fd_to_writer (f, loc), buf[:])
63-
64- w := bufio.writer_to_writer (&b)
65- return wprintln (w, ..args, sep=sep, flush=flush)
44+ // fprintln formats using the default print settings and writes to fd, followed by a newline
45+ // flush is ignored
46+ fprintln :: proc (f: any , args: ..any , sep := " " , flush := true , loc := #caller_location ) -> (n: int ) {
47+ fd := get_fd (f)
48+ s := bprintln (buf[:], ..args, sep=sep)
49+ n = len (s)
50+ write (fd, transmute ([]byte )s)
51+ return n
6652}
6753
6854// fprintf formats according to the specified format string and writes to fd
69- fprintf :: proc (f: ^os.File, fmt: string , args: ..any , flush := true , newline := false , loc := #caller_location ) -> int {
70- buf: [1024 ]byte
71- b: bufio.Writer
72- defer bufio.writer_flush (&b)
73-
74- bufio.writer_init_with_buf (&b, fd_to_writer (f, loc), buf[:])
75-
76- w := bufio.writer_to_writer (&b)
77- return wprintf (w, fmt, ..args, flush=flush, newline=newline)
55+ // flush is ignored
56+ fprintf :: proc (f: any , fmt: string , args: ..any , flush := true , newline := false , loc := #caller_location ) -> (n: int ) {
57+ fd := get_fd (f)
58+ s := bprintf (buf[:], fmt, ..args, newline=newline)
59+ n = len (s)
60+ write (fd, transmute ([]byte )s)
61+ return n
7862}
7963
8064// fprintfln formats according to the specified format string and writes to fd, followed by a newline.
81- fprintfln :: proc (f: ^os.File, fmt: string , args: ..any , flush := true , loc := #caller_location ) -> int {
65+ // flush is ignored
66+ fprintfln :: proc (f: any , fmt: string , args: ..any , flush := true , loc := #caller_location ) -> int {
8267 return fprintf (f, fmt, ..args, flush=flush, newline=true , loc=loc)
8368}
8469
8570// print formats using the default print settings and writes to stdout
86- print :: proc (args: ..any , sep := " " , flush := true ) -> int { return wprint (w= stdout, args= args, sep=sep, flush=flush) }
71+ print :: proc (args: ..any , sep := " " , flush := true ) -> int { return fprint ( stdout, .. args, sep=sep, flush=flush) }
8772// println formats using the default print settings and writes to stdout
88- println :: proc (args: ..any , sep := " " , flush := true ) -> int { return wprintln (w= stdout, args= args, sep=sep, flush=flush) }
73+ println :: proc (args: ..any , sep := " " , flush := true ) -> int { return fprintln ( stdout, .. args, sep=sep, flush=flush) }
8974// printf formats according to the specififed format string and writes to stdout
90- printf :: proc (fmt: string , args: ..any , flush := true ) -> int { return wprintf (stdout, fmt, ..args, flush=flush) }
75+ printf :: proc (fmt: string , args: ..any , flush := true ) -> int { return fprintf (stdout, fmt, ..args, flush=flush) }
9176// printfln formats according to the specified format string and writes to stdout, followed by a newline.
92- printfln :: proc (fmt: string , args: ..any , flush := true ) -> int { return wprintf (stdout, fmt, ..args, flush=flush, newline=true ) }
77+ printfln :: proc (fmt: string , args: ..any , flush := true ) -> int { return fprintf (stdout, fmt, ..args, flush=flush, newline=true ) }
9378
9479// eprint formats using the default print settings and writes to stderr
95- eprint :: proc (args: ..any , sep := " " , flush := true ) -> int { return wprint (w= stderr, args= args, sep=sep, flush=flush) }
80+ eprint :: proc (args: ..any , sep := " " , flush := true ) -> int { return fprint ( stderr, .. args, sep=sep, flush=flush) }
9681// eprintln formats using the default print settings and writes to stderr
97- eprintln :: proc (args: ..any , sep := " " , flush := true ) -> int { return wprintln (w= stderr, args= args, sep=sep, flush=flush) }
82+ eprintln :: proc (args: ..any , sep := " " , flush := true ) -> int { return fprintln ( stderr, .. args, sep=sep, flush=flush) }
9883// eprintf formats according to the specififed format string and writes to stderr
99- eprintf :: proc (fmt: string , args: ..any , flush := true ) -> int { return wprintf (stderr, fmt, ..args, flush=flush) }
84+ eprintf :: proc (fmt: string , args: ..any , flush := true ) -> int { return fprintf (stderr, fmt, ..args, flush=flush) }
10085// eprintfln formats according to the specified format string and writes to stderr, followed by a newline.
101- eprintfln :: proc (fmt: string , args: ..any , flush := true ) -> int { return wprintf (stdout , fmt, ..args, flush=flush, newline=true ) }
86+ eprintfln :: proc (fmt: string , args: ..any , flush := true ) -> int { return fprintf (stderr , fmt, ..args, flush=flush, newline=true ) }
0 commit comments