diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 547d59ce0..ba749d102 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1900,7 +1900,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St // fi.hash = false; fi.indent += 1 - if hash { + if !is_soa && hash { io.write_byte(fi.writer, '\n', &fi.n) } defer { @@ -1934,6 +1934,9 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St n = uintptr((^int)(uintptr(v.data) + info.offsets[actual_field_count])^) } + if hash && n > 0 { + io.write_byte(fi.writer, '\n', &fi.n) + } for index in 0.. 0 { io.write_string(fi.writer, ", ", &fi.n) } @@ -1942,9 +1945,23 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St if !hash && field_count > 0 { io.write_string(fi.writer, ", ", &fi.n) } + if hash { + fi.indent -= 1 + fmt_write_indent(fi) + fi.indent += 1 + } io.write_string(fi.writer, base_type_name, &fi.n) io.write_byte(fi.writer, '{', &fi.n) - defer io.write_byte(fi.writer, '}', &fi.n) + if hash { io.write_byte(fi.writer, '\n', &fi.n) } + defer { + if hash { + fi.indent -= 1 + fmt_write_indent(fi) + fi.indent += 1 + } + io.write_byte(fi.writer, '}', &fi.n) + if hash { io.write_string(fi.writer, ",\n", &fi.n) } + } fi.record_level += 1 defer fi.record_level -= 1 diff --git a/core/fmt/fmt_js.odin b/core/fmt/fmt_js.odin index c70b7c1c0..a0a890a9a 100644 --- a/core/fmt/fmt_js.odin +++ b/core/fmt/fmt_js.odin @@ -37,6 +37,8 @@ print :: proc(args: ..any, sep := " ", flush := true) -> int { return wprint(w println :: proc(args: ..any, sep := " ", flush := true) -> int { return wprintln(w=stdout, args=args, sep=sep, flush=flush) } // printf formats according to the specififed format string and writes to stdout printf :: proc(fmt: string, args: ..any, flush := true) -> int { return wprintf(stdout, fmt, ..args, flush=flush) } +// printfln formats according to the specified format string and writes to stdout, followed by a newline. +printfln :: proc(fmt: string, args: ..any, flush := true) -> int { return wprintf(stdout, fmt, ..args, flush=flush, newline=true) } // eprint formats using the default print settings and writes to stderr eprint :: proc(args: ..any, sep := " ", flush := true) -> int { return wprint(w=stderr, args=args, sep=sep, flush=flush) } @@ -44,3 +46,5 @@ eprint :: proc(args: ..any, sep := " ", flush := true) -> int { return wprint( eprintln :: proc(args: ..any, sep := " ", flush := true) -> int { return wprintln(w=stderr, args=args, sep=sep, flush=flush) } // eprintf formats according to the specififed format string and writes to stderr eprintf :: proc(fmt: string, args: ..any, flush := true) -> int { return wprintf(stderr, fmt, ..args, flush=flush) } +// eprintfln formats according to the specified format string and writes to stderr, followed by a newline. +eprintfln :: proc(fmt: string, args: ..any, flush := true) -> int { return wprintf(stdout, fmt, ..args, flush=flush, newline=true) } diff --git a/core/net/socket_linux.odin b/core/net/socket_linux.odin index ba48959fb..a4d75b92b 100644 --- a/core/net/socket_linux.odin +++ b/core/net/socket_linux.odin @@ -258,8 +258,12 @@ _send_tcp :: proc(tcp_sock: TCP_Socket, buf: []byte) -> (int, Network_Error) { for total_written < len(buf) { limit := min(int(max(i32)), len(buf) - total_written) remaining := buf[total_written:][:limit] - res, errno := linux.send(linux.Fd(tcp_sock), remaining, {}) - if errno != .NONE { + res, errno := linux.send(linux.Fd(tcp_sock), remaining, {.NOSIGNAL}) + if errno == .EPIPE { + // If the peer is disconnected when we are trying to send we will get an `EPIPE` error, + // so we turn that into a clearer error + return total_written, TCP_Send_Error.Connection_Closed + } else if errno != .NONE { return total_written, TCP_Send_Error(errno) } total_written += int(res) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index b806adcd6..03a95a19b 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -840,13 +840,11 @@ gb_internal String odin_root_dir(void) { char const *found = gb_get_env("ODIN_ROOT", a); if (found) { String path = path_to_full_path(a, make_string_c(found)); - if (path[path.len-1] != '/' && path[path.len-1] != '\\') { #if defined(GB_SYSTEM_WINDOWS) - path = concatenate_strings(a, path, WIN32_SEPARATOR_STRING); + path = normalize_path(a, path, WIN32_SEPARATOR_STRING); #else - path = concatenate_strings(a, path, NIX_SEPARATOR_STRING); + path = normalize_path(a, path, NIX_SEPARATOR_STRING); #endif - } global_module_path = path; global_module_path_set = true; diff --git a/src/main.cpp b/src/main.cpp index 8a1f4852e..ee7de7f81 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -342,12 +342,12 @@ struct BuildFlag { String name; BuildFlagParamKind param_kind; u32 command_support; - bool allow_mulitple; + bool allow_multiple; }; -gb_internal void add_flag(Array *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind, u32 command_support, bool allow_mulitple=false) { - BuildFlag flag = {kind, name, param_kind, command_support, allow_mulitple}; +gb_internal void add_flag(Array *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind, u32 command_support, bool allow_multiple=false) { + BuildFlag flag = {kind, name, param_kind, command_support, allow_multiple}; array_add(build_flags, flag); } @@ -1363,7 +1363,7 @@ gb_internal bool parse_build_flags(Array args) { } } - if (!bf.allow_mulitple) { + if (!bf.allow_multiple) { set_flags[bf.kind] = ok; } } diff --git a/src/string.cpp b/src/string.cpp index 3747f4564..b92dd589e 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -237,11 +237,16 @@ gb_internal String string_split_iterator(String_Iterator *it, const char sep) { return substring(it->str, start, end); } +gb_internal gb_inline bool is_separator(u8 const &ch) { + return (ch == '/' || ch == '\\'); +} + + gb_internal gb_inline isize string_extension_position(String const &str) { isize dot_pos = -1; isize i = str.len; while (i --> 0) { - if (str[i] == '\\' || str[i] == '/') + if (is_separator(str[i])) break; if (str[i] == '.') { dot_pos = i; @@ -332,8 +337,7 @@ gb_internal String filename_from_path(String s) { if (i > 0) { isize j = 0; for (j = s.len-1; j >= 0; j--) { - if (s[j] == '/' || - s[j] == '\\') { + if (is_separator(s[j])) { break; } } @@ -346,8 +350,7 @@ gb_internal String filename_from_path(String s) { gb_internal String filename_without_directory(String s) { isize j = 0; for (j = s.len-1; j >= 0; j--) { - if (s[j] == '/' || - s[j] == '\\') { + if (is_separator(s[j])) { break; } } @@ -410,7 +413,26 @@ gb_internal String copy_string(gbAllocator a, String const &s) { return make_string(data, s.len); } - +gb_internal String normalize_path(gbAllocator a, String const &path, String const &sep) { + String s; + if (sep.len < 1) { + return path; + } + if (path.len < 1) { + s = STR_LIT(""); + } else if (is_separator(path[path.len-1])) { + s = copy_string(a, path); + } else { + s = concatenate_strings(a, path, sep); + } + isize i; + for (i = 0; i < s.len; i++) { + if (is_separator(s.text[i])) { + s.text[i] = sep.text[0]; + } + } + return s; +} #if defined(GB_SYSTEM_WINDOWS)