jm

Odin for scripts: small packages and a runner, on core: only
Log | Files | Refs | README

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 }