sh_windows.odin (1883B)
1 #+build windows 2 package sh 3 4 import "core:os" 5 import "core:slice" 6 import "core:strings" 7 8 shell_argv :: proc(cmd: string, shell: Shell, allocator := context.allocator) -> []string { 9 switch shell { 10 case .Pwsh: 11 exe := "pwsh" 12 if _, found := which("pwsh", allocator); !found { 13 exe = "powershell" 14 } 15 return slice.clone([]string{exe, "-NoProfile", "-Command", cmd}, allocator) 16 case .Sh: 17 return slice.clone([]string{"sh", "-c", cmd}, allocator) 18 case .Default, .Cmd: 19 comspec, found := os.lookup_env("COMSPEC", allocator) 20 if !found || comspec == "" { 21 comspec = "cmd.exe" 22 } 23 return slice.clone([]string{comspec, "/C", cmd}, allocator) 24 } 25 return slice.clone([]string{"cmd.exe", "/C", cmd}, allocator) 26 } 27 28 executable_extensions :: proc(allocator := context.temp_allocator) -> []string { 29 pathext, found := os.lookup_env("PATHEXT", allocator) 30 if !found || pathext == "" { 31 pathext = ".COM;.EXE;.BAT;.CMD" 32 } 33 exts := make([dynamic]string, allocator) 34 append(&exts, "") 35 for ext in strings.split_iterator(&pathext, ";") { 36 if ext != "" { 37 append(&exts, ext) 38 } 39 } 40 return exts[:] 41 } 42 43 // quote makes s safe as one argument for cmd.exe and the C runtime parser. 44 quote :: proc(s: string, allocator := context.allocator) -> string { 45 if s != "" && strings.index_any(s, " \t\n\"&|<>^%()") < 0 { 46 return strings.clone(s, allocator) 47 } 48 b := strings.builder_make(allocator) 49 strings.write_byte(&b, '"') 50 backslashes := 0 51 for c in s { 52 switch c { 53 case '\\': 54 backslashes += 1 55 continue 56 case '"': 57 for _ in 0 ..< backslashes * 2 + 1 { 58 strings.write_byte(&b, '\\') 59 } 60 strings.write_byte(&b, '"') 61 case: 62 for _ in 0 ..< backslashes { 63 strings.write_byte(&b, '\\') 64 } 65 strings.write_rune(&b, c) 66 } 67 backslashes = 0 68 } 69 for _ in 0 ..< backslashes * 2 { 70 strings.write_byte(&b, '\\') 71 } 72 strings.write_byte(&b, '"') 73 return strings.to_string(b) 74 }