parseWindowsCommand parses windows command lines and returns the command and the arguments as an array. It should be able to parse commonly used command lines. Only basic syntax is supported: - spaces in double quotes are not token delimiters - double quotes are escaped by either backspace or anothe
(cmd string)
| 78 | // of the shlex package because this function treats backslash |
| 79 | // characters properly. |
| 80 | func parseWindowsCommand(cmd string) []string { |
| 81 | const backslash = '\\' |
| 82 | const quote = '"' |
| 83 | |
| 84 | var parts []string |
| 85 | var part string |
| 86 | var inQuotes bool |
| 87 | var lastRune rune |
| 88 | |
| 89 | for i, ch := range cmd { |
| 90 | if i != 0 { |
| 91 | lastRune = rune(cmd[i-1]) |
| 92 | } |
| 93 | |
| 94 | if ch == backslash { |
| 95 | // put it in the part - for now we don't know if it's an |
| 96 | // escaping char or path separator |
| 97 | part += string(ch) |
| 98 | continue |
| 99 | } |
| 100 | |
| 101 | if ch == quote { |
| 102 | if lastRune == backslash { |
| 103 | // remove the backslash from the part and add the escaped quote instead |
| 104 | part = part[:len(part)-1] |
| 105 | part += string(ch) |
| 106 | continue |
| 107 | } |
| 108 | |
| 109 | if lastRune == quote { |
| 110 | // revert the last change of the inQuotes state |
| 111 | // it was an escaping quote |
| 112 | inQuotes = !inQuotes |
| 113 | part += string(ch) |
| 114 | continue |
| 115 | } |
| 116 | |
| 117 | // normal escaping quotes |
| 118 | inQuotes = !inQuotes |
| 119 | continue |
| 120 | } |
| 121 | |
| 122 | if unicode.IsSpace(ch) && !inQuotes && part != "" { |
| 123 | parts = append(parts, part) |
| 124 | part = "" |
| 125 | continue |
| 126 | } |
| 127 | |
| 128 | part += string(ch) |
| 129 | } |
| 130 | |
| 131 | if part != "" { |
| 132 | parts = append(parts, part) |
| 133 | } |
| 134 | |
| 135 | return parts |
| 136 | } |
no outgoing calls