Browse Source

Merge branch 'master' of https://github.com/odin-lang/Odin

gingerBill 1 year ago
parent
commit
75fcd50b9a
6 changed files with 63 additions and 18 deletions
  1. 19 2
      core/fmt/fmt.odin
  2. 4 0
      core/fmt/fmt_js.odin
  3. 6 2
      core/net/socket_linux.odin
  4. 2 4
      src/build_settings.cpp
  5. 4 4
      src/main.cpp
  6. 28 6
      src/string.cpp

+ 19 - 2
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..<n {
 			if !hash && index > 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
 

+ 4 - 0
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) }

+ 6 - 2
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)

+ 2 - 4
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;

+ 4 - 4
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<BuildFlag> *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<BuildFlag> *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<String> args) {
 						}
 					}
 
-					if (!bf.allow_mulitple) {
+					if (!bf.allow_multiple) {
 						set_flags[bf.kind] = ok;
 					}
 				}

+ 28 - 6
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)