diff --git a/core/os/os2/process_windows.odin b/core/os/os2/process_windows.odin index edb321509..f2b889c72 100644 --- a/core/os/os2/process_windows.odin +++ b/core/os/os2/process_windows.odin @@ -638,6 +638,19 @@ _parse_command_line :: proc(cmd_line_w: [^]u16, allocator: runtime.Allocator) -> return } +@(private) +QUOTED_CHARS :: "()[]{}^=;!'+,`~\" " + +@(private) +_char_needs_escape :: proc(ch: u8) -> bool { + for r in transmute([]byte) string(QUOTED_CHARS) { + if ch == r { + return true + } + } + return false +} + _build_command_line :: proc(command: []string, allocator: runtime.Allocator) -> string { _write_byte_n_times :: #force_inline proc(builder: ^strings.Builder, b: byte, n: int) { for _ in 0 ..< n { @@ -650,26 +663,35 @@ _build_command_line :: proc(command: []string, allocator: runtime.Allocator) -> strings.write_byte(&builder, ' ') } j := 0 - strings.write_byte(&builder, '"') - for j < len(arg) { - backslashes := 0 - for j < len(arg) && arg[j] == '\\' { - backslashes += 1 + arg_needs_quoting := false + // Note(flysand): From documentation of `cmd.exe`, run "cmd /?" + if strings.contains_any(arg, QUOTED_CHARS) { + arg_needs_quoting = true + } + if !arg_needs_quoting { + strings.write_string(&builder, arg) + } else { + strings.write_byte(&builder, '"') + for j < len(arg) { + backslashes := 0 + for j < len(arg) && arg[j] == '\\' { + backslashes += 1 + j += 1 + } + if j == len(arg) { + _write_byte_n_times(&builder, '\\', 2*backslashes) + break + } else if arg[j] == '"' { + _write_byte_n_times(&builder, '\\', 2*backslashes+1) + strings.write_byte(&builder, arg[j]) + } else { + _write_byte_n_times(&builder, '\\', backslashes) + strings.write_byte(&builder, arg[j]) + } j += 1 } - if j == len(arg) { - _write_byte_n_times(&builder, '\\', 2*backslashes) - break - } else if arg[j] == '"' { - _write_byte_n_times(&builder, '\\', 2*backslashes+1) - strings.write_byte(&builder, '"') - } else { - _write_byte_n_times(&builder, '\\', backslashes) - strings.write_byte(&builder, arg[j]) - } - j += 1 + strings.write_byte(&builder, '"') } - strings.write_byte(&builder, '"') } return strings.to_string(builder) }