|
22 | 22 |
|
23 | 23 | # Our own |
24 | 24 | if sys.platform == 'win32': |
| 25 | + import ctypes |
| 26 | + from ctypes.wintypes import LPCWSTR, HLOCAL |
| 27 | + from ctypes import c_int, POINTER |
25 | 28 | from ._process_win32 import _find_cmd, system, getoutput, AvoidUNCPath |
| 29 | + CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW |
| 30 | + CommandLineToArgvW.arg_types = [LPCWSTR, POINTER(c_int)] |
| 31 | + CommandLineToArgvW.res_types = [POINTER(LPCWSTR)] |
| 32 | + LocalFree = ctypes.windll.kernel32.LocalFree |
| 33 | + LocalFree.res_type = HLOCAL |
| 34 | + LocalFree.arg_types = [HLOCAL] |
26 | 35 | else: |
27 | 36 | from ._process_posix import _find_cmd, system, getoutput |
28 | 37 |
|
@@ -103,29 +112,42 @@ def pycmd2argv(cmd): |
103 | 112 | else: |
104 | 113 | return [sys.executable, cmd] |
105 | 114 |
|
106 | | - |
107 | | -def arg_split(s, posix=False): |
108 | | - """Split a command line's arguments in a shell-like manner. |
109 | | -
|
110 | | - This is a modified version of the standard library's shlex.split() |
111 | | - function, but with a default of posix=False for splitting, so that quotes |
112 | | - in inputs are respected.""" |
113 | | - |
114 | | - # Unfortunately, python's shlex module is buggy with unicode input: |
115 | | - # http://bugs.python.org/issue1170 |
116 | | - # At least encoding the input when it's unicode seems to help, but there |
117 | | - # may be more problems lurking. Apparently this is fixed in python3. |
118 | | - is_unicode = False |
119 | | - if (not py3compat.PY3) and isinstance(s, unicode): |
120 | | - is_unicode = True |
121 | | - s = s.encode('utf-8') |
122 | | - lex = shlex.shlex(s, posix=posix) |
123 | | - lex.whitespace_split = True |
124 | | - tokens = list(lex) |
125 | | - if is_unicode: |
126 | | - # Convert the tokens back to unicode. |
127 | | - tokens = [x.decode('utf-8') for x in tokens] |
128 | | - return tokens |
| 115 | +if sys.platform == 'win32': |
| 116 | + def arg_split(commandline, posix=False): |
| 117 | + """Split a command line's arguments in a shell-like manner. |
| 118 | +
|
| 119 | + This is a special version for windows that use a ctypes call to CommandLineToArgvW |
| 120 | + to do the argv splitting. The posix paramter is ignored. |
| 121 | + """ |
| 122 | + argvn = c_int() |
| 123 | + result_pointer = CommandLineToArgvW(py3compat.str_to_unicode(commandline.lstrip()), ctypes.byref(argvn)) |
| 124 | + result_array_type = LPCWSTR * argvn.value |
| 125 | + result = [arg for arg in result_array_type.from_address(result_pointer)] |
| 126 | + retval = LocalFree(result_pointer) |
| 127 | + return result |
| 128 | +else: |
| 129 | + def arg_split(s, posix=False): |
| 130 | + """Split a command line's arguments in a shell-like manner. |
| 131 | +
|
| 132 | + This is a modified version of the standard library's shlex.split() |
| 133 | + function, but with a default of posix=False for splitting, so that quotes |
| 134 | + in inputs are respected.""" |
| 135 | + |
| 136 | + # Unfortunately, python's shlex module is buggy with unicode input: |
| 137 | + # http://bugs.python.org/issue1170 |
| 138 | + # At least encoding the input when it's unicode seems to help, but there |
| 139 | + # may be more problems lurking. Apparently this is fixed in python3. |
| 140 | + is_unicode = False |
| 141 | + if (not py3compat.PY3) and isinstance(s, unicode): |
| 142 | + is_unicode = True |
| 143 | + s = s.encode('utf-8') |
| 144 | + lex = shlex.shlex(s, posix=posix) |
| 145 | + lex.whitespace_split = True |
| 146 | + tokens = list(lex) |
| 147 | + if is_unicode: |
| 148 | + # Convert the tokens back to unicode. |
| 149 | + tokens = [x.decode('utf-8') for x in tokens] |
| 150 | + return tokens |
129 | 151 |
|
130 | 152 |
|
131 | 153 | def abbrev_cwd(): |
|
0 commit comments