Browse Source

wasm: add the `fprint` procedures to `fmt`

This makes the `log` package work on wasm
Laytan Laats 1 year ago
parent
commit
cc5faecced
2 changed files with 53 additions and 7 deletions
  1. 51 0
      core/fmt/fmt_js.odin
  2. 2 7
      core/os/os_js.odin

+ 51 - 0
core/fmt/fmt_js.odin

@@ -1,7 +1,9 @@
 //+build js
 package fmt
 
+import "core:bufio"
 import "core:io"
+import "core:os"
 
 foreign import "odin_env"
 
@@ -31,6 +33,55 @@ stderr := io.Writer{
 	data      = rawptr(uintptr(2)),
 }
 
+@(private="file")
+fd_to_writer :: proc(fd: os.Handle, loc := #caller_location) -> io.Writer {
+	switch fd {
+	case 1: return stdout
+	case 2: return stderr
+	case:   panic("`fmt.fprint` variant called with invalid file descriptor for JS, only 1 (stdout) and 2 (stderr) are supported", loc)
+	}
+}
+
+// fprint formats using the default print settings and writes to fd
+fprint :: proc(fd: os.Handle, args: ..any, sep := " ", flush := true, loc := #caller_location) -> int {
+	buf: [1024]byte
+	b: bufio.Writer
+	defer bufio.writer_flush(&b)
+
+	bufio.writer_init_with_buf(&b, fd_to_writer(fd, loc), buf[:])
+	w := bufio.writer_to_writer(&b)
+	return wprint(w, ..args, sep=sep, flush=flush)
+}
+
+// fprintln formats using the default print settings and writes to fd
+fprintln :: proc(fd: os.Handle, args: ..any, sep := " ", flush := true, loc := #caller_location) -> int {
+	buf: [1024]byte
+	b: bufio.Writer
+	defer bufio.writer_flush(&b)
+
+	bufio.writer_init_with_buf(&b, fd_to_writer(fd, loc), buf[:])
+
+	w := bufio.writer_to_writer(&b)
+	return wprintln(w, ..args, sep=sep, flush=flush)
+}
+
+// fprintf formats according to the specified format string and writes to fd
+fprintf :: proc(fd: os.Handle, fmt: string, args: ..any, flush := true, newline := false, loc := #caller_location) -> int {
+	buf: [1024]byte
+	b: bufio.Writer
+	defer bufio.writer_flush(&b)
+
+	bufio.writer_init_with_buf(&b, fd_to_writer(fd, loc), buf[:])
+
+	w := bufio.writer_to_writer(&b)
+	return wprintf(w, fmt, ..args, flush=flush, newline=newline)
+}
+
+// fprintfln formats according to the specified format string and writes to fd, followed by a newline.
+fprintfln :: proc(fd: os.Handle, fmt: string, args: ..any, flush := true, loc := #caller_location) -> int {
+	return fprintf(fd, fmt, ..args, flush=flush, newline=true, loc=loc)
+}
+
 // print formats using the default print settings and writes to stdout
 print   :: proc(args: ..any, sep := " ", flush := true) -> int { return wprint(w=stdout, args=args, sep=sep, flush=flush) }
 // println formats using the default print settings and writes to stdout

+ 2 - 7
core/os/os_js.odin

@@ -64,13 +64,8 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Errno)
 	unimplemented("core:os procedure not supported on JS target")
 }
 
-
-
-// NOTE(bill): Uses startup to initialize it
-//stdin  := get_std_handle(uint(win32.STD_INPUT_HANDLE))
-//stdout := get_std_handle(uint(win32.STD_OUTPUT_HANDLE))
-//stderr := get_std_handle(uint(win32.STD_ERROR_HANDLE))
-
+stdout: Handle = 1
+stderr: Handle = 2
 
 get_std_handle :: proc "contextless" (h: uint) -> Handle {
 	context = runtime.default_context()