diff --git a/core/c/frontend/preprocessor/preprocess.odin b/core/c/frontend/preprocessor/preprocess.odin index 21ff2b4eb..62b4183bc 100644 --- a/core/c/frontend/preprocessor/preprocess.odin +++ b/core/c/frontend/preprocessor/preprocess.odin @@ -8,6 +8,7 @@ import "core:path/filepath" import "core:unicode/utf8" import "core:unicode/utf16" import "core:os" +import "core:io" @(private) Tokenizer :: tokenizer.Tokenizer @@ -518,9 +519,8 @@ join_adjacent_string_literals :: proc(cpp: ^Preprocessor, initial_tok: ^Token) { quote_string :: proc(s: string) -> []byte { - b := &strings.Builder{} - strings.init_builder(b, 0, len(s)+2) - strings.write_quoted_string(b, s, '"') + b := strings.make_builder(0, len(s)+2) + io.write_quoted_string(strings.to_writer(&b), s, '"') return b.buf[:] } diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index f0e6147bf..7ac2198c0 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -77,11 +77,13 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int { } fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) -> int { w := io.to_writer(os.stream_from_handle(fd)) - return wprint_type(w, info) + n, _ := wprint_type(w, info) + return n } fprint_typeid :: proc(fd: os.Handle, id: typeid) -> int { w := io.to_writer(os.stream_from_handle(fd)) - return wprint_typeid(w, id) + n, _ := wprint_typeid(w, id) + return n } // print* procedures return the number of bytes written @@ -526,15 +528,15 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { return int(size1 - size0) } -wprint_type :: proc(w: io.Writer, info: ^runtime.Type_Info) -> int { - n := reflect.write_type(w, info) +wprint_type :: proc(w: io.Writer, info: ^runtime.Type_Info) -> (int, io.Error) { + n, err := reflect.write_type(w, info) io.flush(auto_cast w) - return n + return n, err } -wprint_typeid :: proc(w: io.Writer, id: typeid) -> int { - n := reflect.write_type(w, type_info_of(id)) +wprint_typeid :: proc(w: io.Writer, id: typeid) -> (int, io.Error) { + n, err := reflect.write_type(w, type_info_of(id)) io.flush(auto_cast w) - return n + return n, err } @@ -971,7 +973,7 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) { } case 'q': // quoted string - strings.write_quoted_string(fi.writer, s, '"') + io.write_quoted_string(fi.writer, s, '"') case 'x', 'X': space := fi.space diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 5be8a8be0..d40c80aeb 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -305,7 +305,7 @@ foreign libc { @(link_name="chdir") _unix_chdir :: proc(buf: cstring) -> c.int --- @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- - @(link_name="exit") _unix_exit :: proc(status: int) -> ! --- + @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- } foreign dl { @@ -571,7 +571,7 @@ set_current_directory :: proc(path: string) -> (err: Errno) { } exit :: proc "contextless" (code: int) -> ! { - _unix_exit(code) + _unix_exit(i32(code)) } current_thread_id :: proc "contextless" () -> int { diff --git a/core/reflect/types.odin b/core/reflect/types.odin index 56e9db021..a43d9deb1 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -346,237 +346,247 @@ write_type :: proc{ } write_type_builder :: proc(buf: ^strings.Builder, ti: ^Type_Info) -> int { - return write_type_writer(strings.to_writer(buf), ti) + n, _ := write_type_writer(strings.to_writer(buf), ti) + return n } -write_type_writer :: proc(w: io.Writer, ti: ^Type_Info) -> (n: int) { - using strings +write_type_writer :: proc(w: io.Writer, ti: ^Type_Info) -> (n: int, err: io.Error) { if ti == nil { - return write_string(w, "nil") + return io.write_string(w, "nil") } - _n1 :: proc(err: io.Error) -> int { return 1 if err == nil else 0 } - _n2 :: proc(n: int, _: io.Error) -> int { return n } + _n1 :: proc(err: io.Error, n: ^int) -> io.Error { + n^ += 1 if err == nil else 0 + return err + } + _n2 :: io.n_wrapper _n :: proc{_n1, _n2} switch info in ti.variant { case Type_Info_Named: - return write_string(w, info.name) + return io.write_string(w, info.name) case Type_Info_Integer: switch ti.id { - case int: return write_string(w, "int") - case uint: return write_string(w, "uint") - case uintptr: return write_string(w, "uintptr") + case int: return io.write_string(w, "int") + case uint: return io.write_string(w, "uint") + case uintptr: return io.write_string(w, "uintptr") case: - n += _n(io.write_byte(w, 'i' if info.signed else 'u')) - n += _n(io.write_i64(w, i64(8*ti.size), 10)) + _n(io.write_byte(w, 'i' if info.signed else 'u'), &n) or_return + _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return switch info.endianness { case .Platform: // Okay - case .Little: n += write_string(w, "le") - case .Big: n += write_string(w, "be") + case .Little: _n(io.write_string(w, "le"), &n) or_return + case .Big: _n(io.write_string(w, "be"), &n) or_return } } case Type_Info_Rune: - n += _n(io.write_string(w, "rune")) + _n(io.write_string(w, "rune"), &n) or_return case Type_Info_Float: - n += _n(io.write_byte(w, 'f')) - n += _n(io.write_i64(w, i64(8*ti.size), 10)) + _n(io.write_byte(w, 'f'), &n) or_return + _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return switch info.endianness { case .Platform: // Okay - case .Little: n += write_string(w, "le") - case .Big: n += write_string(w, "be") + case .Little: _n(io.write_string(w, "le"), &n) or_return + case .Big: _n(io.write_string(w, "be"), &n) or_return } case Type_Info_Complex: - n += _n(io.write_string(w, "complex")) - n += _n(io.write_i64(w, i64(8*ti.size), 10)) + _n(io.write_string(w, "complex"), &n) or_return + _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return case Type_Info_Quaternion: - n += _n(io.write_string(w, "quaternion")) - n += _n(io.write_i64(w, i64(8*ti.size), 10)) + _n(io.write_string(w, "quaternion"), &n) or_return + _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return case Type_Info_String: if info.is_cstring { - n += write_string(w, "cstring") + _n(io.write_string(w, "cstring"), &n) or_return } else { - n += write_string(w, "string") + _n(io.write_string(w, "string"), &n) or_return } case Type_Info_Boolean: switch ti.id { - case bool: n += write_string(w, "bool") + case bool: _n(io.write_string(w, "bool"), &n) or_return case: - n += _n(io.write_byte(w, 'b')) - n += _n(io.write_i64(w, i64(8*ti.size), 10)) + _n(io.write_byte(w, 'b'), &n) or_return + _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return } case Type_Info_Any: - n += write_string(w, "any") + _n(io.write_string(w, "any"), &n) or_return case Type_Info_Type_Id: - n += write_string(w, "typeid") + _n(io.write_string(w, "typeid"), &n) or_return case Type_Info_Pointer: if info.elem == nil { - write_string(w, "rawptr") + return io.write_string(w, "rawptr") } else { - write_string(w, "^") - write_type(w, info.elem) + _n(io.write_string(w, "^"), &n) or_return + return write_type(w, info.elem) } case Type_Info_Multi_Pointer: - write_string(w, "[^]") - write_type(w, info.elem) + _n(io.write_string(w, "[^]"), &n) or_return + return write_type(w, info.elem) case Type_Info_Procedure: - n += write_string(w, "proc") + _n(io.write_string(w, "proc"), &n) or_return if info.params == nil { - n += write_string(w, "()") + _n(io.write_string(w, "()"), &n) or_return } else { t := info.params.variant.(Type_Info_Tuple) - n += write_string(w, "(") + _n(io.write_string(w, "("), &n) or_return for t, i in t.types { if i > 0 { - n += write_string(w, ", ") + _n(io.write_string(w, ", "), &n) or_return } - n += write_type(w, t) + _n(write_type(w, t), &n) or_return } - n += write_string(w, ")") + _n(io.write_string(w, ")"), &n) or_return } if info.results != nil { - n += write_string(w, " -> ") - n += write_type(w, info.results) + _n(io.write_string(w, " -> "), &n) or_return + _n(write_type(w, info.results), &n) or_return } case Type_Info_Tuple: count := len(info.names) - if count != 1 { n += write_string(w, "(") } + if count != 1 { + _n(io.write_string(w, "("), &n) or_return + } for name, i in info.names { - if i > 0 { n += write_string(w, ", ") } + if i > 0 { _n(io.write_string(w, ", "), &n) or_return } t := info.types[i] if len(name) > 0 { - n += write_string(w, name) - n += write_string(w, ": ") + _n(io.write_string(w, name), &n) or_return + _n(io.write_string(w, ": "), &n) or_return } - n += write_type(w, t) + _n(write_type(w, t), &n) or_return + } + if count != 1 { + _n(io.write_string(w, ")"), &n) or_return } - if count != 1 { n += write_string(w, ")") } case Type_Info_Array: - n += _n(io.write_string(w, "[")) - n += _n(io.write_i64(w, i64(info.count), 10)) - n += _n(io.write_string(w, "]")) - n += write_type(w, info.elem) + _n(io.write_string(w, "["), &n) or_return + _n(io.write_i64(w, i64(info.count), 10), &n) or_return + _n(io.write_string(w, "]"), &n) or_return + _n(write_type(w, info.elem), &n) or_return case Type_Info_Enumerated_Array: - n += write_string(w, "[") - n += write_type(w, info.index) - n += write_string(w, "]") - n += write_type(w, info.elem) + _n(io.write_string(w, "["), &n) or_return + _n(write_type(w, info.index), &n) or_return + _n(io.write_string(w, "]"), &n) or_return + _n(write_type(w, info.elem), &n) or_return case Type_Info_Dynamic_Array: - n += _n(io.write_string(w, "[dynamic]")) - n += write_type(w, info.elem) + _n(io.write_string(w, "[dynamic]"), &n) or_return + _n(write_type(w, info.elem), &n) or_return case Type_Info_Slice: - n += _n(io.write_string(w, "[]")) - n += write_type(w, info.elem) + _n(io.write_string(w, "[]"), &n) or_return + _n(write_type(w, info.elem), &n) or_return case Type_Info_Map: - n += _n(io.write_string(w, "map[")) - n += write_type(w, info.key) - n += _n(io.write_byte(w, ']')) - n += write_type(w, info.value) + _n(io.write_string(w, "map["), &n) or_return + _n(write_type(w, info.key), &n) or_return + _n(io.write_byte(w, ']'), &n) or_return + _n(write_type(w, info.value), &n) or_return case Type_Info_Struct: switch info.soa_kind { case .None: // Ignore case .Fixed: - n += _n(io.write_string(w, "#soa[")) - n += _n(io.write_i64(w, i64(info.soa_len))) - n += _n(io.write_byte(w, ']')) - n += write_type(w, info.soa_base_type) + _n(io.write_string(w, "#soa["), &n) or_return + _n(io.write_i64(w, i64(info.soa_len)), &n) or_return + _n(io.write_byte(w, ']'), &n) or_return + _n(write_type(w, info.soa_base_type), &n) or_return return case .Slice: - n += _n(io.write_string(w, "#soa[]")) - n += write_type(w, info.soa_base_type) + _n(io.write_string(w, "#soa[]"), &n) or_return + _n(write_type(w, info.soa_base_type), &n) or_return return case .Dynamic: - n += _n(io.write_string(w, "#soa[dynamic]")) - n += write_type(w, info.soa_base_type) + _n(io.write_string(w, "#soa[dynamic]"), &n) or_return + _n(write_type(w, info.soa_base_type), &n) or_return return } - n += write_string(w, "struct ") - if info.is_packed { n += write_string(w, "#packed ") } - if info.is_raw_union { n += write_string(w, "#raw_union ") } + _n(io.write_string(w, "struct "), &n) or_return + if info.is_packed { _n(io.write_string(w, "#packed "), &n) or_return } + if info.is_raw_union { _n(io.write_string(w, "#raw_union "), &n) or_return } if info.custom_align { - n += _n(io.write_string(w, "#align ")) - n += _n(io.write_i64(w, i64(ti.align), 10)) - n += _n(io.write_byte(w, ' ')) + _n(io.write_string(w, "#align "), &n) or_return + _n(io.write_i64(w, i64(ti.align), 10), &n) or_return + _n(io.write_byte(w, ' '), &n) or_return } - n += _n(io.write_byte(w, '{')) + _n(io.write_byte(w, '{'), &n) or_return for name, i in info.names { - if i > 0 { n += write_string(w, ", ") } - n += _n(io.write_string(w, name)) - n += _n(io.write_string(w, ": ")) - n += write_type(w, info.types[i]) + if i > 0 { _n(io.write_string(w, ", "), &n) or_return } + _n(io.write_string(w, name), &n) or_return + _n(io.write_string(w, ": "), &n) or_return + _n(write_type(w, info.types[i]), &n) or_return } - n += _n(io.write_byte(w, '}')) + _n(io.write_byte(w, '}'), &n) or_return case Type_Info_Union: - n += write_string(w, "union ") + _n(io.write_string(w, "union "), &n) or_return + if info.maybe { + _n(io.write_string(w, "#maybe "), &n) or_return + } if info.custom_align { - n += write_string(w, "#align ") - n += _n(io.write_i64(w, i64(ti.align), 10)) - n += _n(io.write_byte(w, ' ')) + _n(io.write_string(w, "#align "), &n) or_return + _n(io.write_i64(w, i64(ti.align), 10), &n) or_return + _n(io.write_byte(w, ' '), &n) or_return } - n += _n(io.write_byte(w, '{')) + _n(io.write_byte(w, '{'), &n) or_return for variant, i in info.variants { - if i > 0 { n += write_string(w, ", ") } - n += write_type(w, variant) + if i > 0 { _n(io.write_string(w, ", "), &n) or_return } + _n(write_type(w, variant), &n) or_return } - n += _n(io.write_byte(w, '}')) + _n(io.write_byte(w, '}'), &n) or_return case Type_Info_Enum: - n += write_string(w, "enum ") - n += write_type(w, info.base) - n += write_string(w, " {") + _n(io.write_string(w, "enum "), &n) or_return + _n(write_type(w, info.base), &n) or_return + _n(io.write_string(w, " {"), &n) or_return for name, i in info.names { - if i > 0 { n += write_string(w, ", ") } - n += write_string(w, name) + if i > 0 { _n(io.write_string(w, ", "), &n) or_return } + _n(io.write_string(w, name), &n) or_return } - n += _n(io.write_byte(w, '}')) + _n(io.write_byte(w, '}'), &n) or_return case Type_Info_Bit_Set: - n += write_string(w, "bit_set[") + _n(io.write_string(w, "bit_set["), &n) or_return switch { case is_enum(info.elem): - n += write_type(w, info.elem) + _n(write_type(w, info.elem), &n) or_return case is_rune(info.elem): - n += write_encoded_rune(w, rune(info.lower)) - n += write_string(w, "..") - n += write_encoded_rune(w, rune(info.upper)) + _n(io.write_encoded_rune(w, rune(info.lower)), &n) or_return + _n(io.write_string(w, ".."), &n) or_return + _n(io.write_encoded_rune(w, rune(info.upper)), &n) or_return case: - n += _n(io.write_i64(w, info.lower, 10)) - n += write_string(w, "..") - n += _n(io.write_i64(w, info.upper, 10)) + _n(io.write_i64(w, info.lower, 10), &n) or_return + _n(io.write_string(w, ".."), &n) or_return + _n(io.write_i64(w, info.upper, 10), &n) or_return } if info.underlying != nil { - n += write_string(w, "; ") - n += write_type(w, info.underlying) + _n(io.write_string(w, "; "), &n) or_return + _n(write_type(w, info.underlying), &n) or_return } - n += _n(io.write_byte(w, ']')) + _n(io.write_byte(w, ']'), &n) or_return case Type_Info_Simd_Vector: - n += write_string(w, "#simd[") - n += _n(io.write_i64(w, i64(info.count))) - n += _n(io.write_byte(w, ']')) - n += write_type(w, info.elem) + _n(io.write_string(w, "#simd["), &n) or_return + _n(io.write_i64(w, i64(info.count)), &n) or_return + _n(io.write_byte(w, ']'), &n) or_return + _n(write_type(w, info.elem), &n) or_return case Type_Info_Relative_Pointer: - n += write_string(w, "#relative(") - n += write_type(w, info.base_integer) - n += write_string(w, ") ") - n += write_type(w, info.pointer) + _n(io.write_string(w, "#relative("), &n) or_return + _n(write_type(w, info.base_integer), &n) or_return + _n(io.write_string(w, ") "), &n) or_return + _n(write_type(w, info.pointer), &n) or_return case Type_Info_Relative_Slice: - n += write_string(w, "#relative(") - n += write_type(w, info.base_integer) - n += write_string(w, ") ") - n += write_type(w, info.slice) + _n(io.write_string(w, "#relative("), &n) or_return + _n(write_type(w, info.base_integer), &n) or_return + _n(io.write_string(w, ") "), &n) or_return + _n(write_type(w, info.slice), &n) or_return } return diff --git a/core/strings/builder.odin b/core/strings/builder.odin index b4b1e43b2..dbf886b3e 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -166,7 +166,8 @@ write_quoted_rune :: proc(w: io.Writer, r: rune) -> (n: int) { n += _write_byte(w, DIGITS_LOWER[buf[0]>>4]) n += _write_byte(w, DIGITS_LOWER[buf[0]&0xf]) } else { - n += write_escaped_rune(w, r, quote) + i, _ := io.write_escaped_rune(w, r, quote) + n += i } n += _write_byte(w, quote) return @@ -216,11 +217,13 @@ write_quoted_string :: proc{ write_quoted_string_writer, } +@(deprecated="prefer io.write_quoted_string") write_quoted_string_builder :: proc(b: ^Builder, str: string, quote: byte = '"') -> (n: int) { n, _ = io.write_quoted_string(to_writer(b), str, quote) return } +@(deprecated="prefer io.write_quoted_string") write_quoted_string_writer :: proc(w: io.Writer, str: string, quote: byte = '"') -> (n: int) { n, _ = io.write_quoted_string(w, str, quote) return @@ -231,11 +234,13 @@ write_encoded_rune :: proc{ write_encoded_rune_writer, } +@(deprecated="prefer io.write_encoded_rune") write_encoded_rune_builder :: proc(b: ^Builder, r: rune, write_quote := true) -> (n: int) { n, _ = io.write_encoded_rune(to_writer(b), r, write_quote) return } +@(deprecated="prefer io.write_encoded_rune") write_encoded_rune_writer :: proc(w: io.Writer, r: rune, write_quote := true) -> (n: int) { n, _ = io.write_encoded_rune(w, r, write_quote) return @@ -247,11 +252,13 @@ write_escaped_rune :: proc{ write_escaped_rune_writer, } +@(deprecated="prefer io.write_escaped_rune") write_escaped_rune_builder :: proc(b: ^Builder, r: rune, quote: byte, html_safe := false) -> (n: int) { n, _ = io.write_escaped_rune(to_writer(b), r, quote, html_safe) return } +@(deprecated="prefer io.write_escaped_rune") write_escaped_rune_writer :: proc(w: io.Writer, r: rune, quote: byte, html_safe := false) -> (n: int) { n, _ = io.write_escaped_rune(w, r, quote, html_safe) return