##// END OF EJS Templates
Moved arg_split to _process_win32.py and _process_posix.py.
Jörgen Stenarson -
Show More
@@ -18,6 +18,7 b' from __future__ import print_function'
18 # Stdlib
18 # Stdlib
19 import subprocess as sp
19 import subprocess as sp
20 import sys
20 import sys
21 import shlex
21
22
22 from IPython.external import pexpect
23 from IPython.external import pexpect
23
24
@@ -192,3 +193,29 b' class ProcessHandler(object):'
192 # programs think they are talking to a tty and produce highly formatted output
193 # programs think they are talking to a tty and produce highly formatted output
193 # (ls is a good example) that makes them hard.
194 # (ls is a good example) that makes them hard.
194 system = ProcessHandler().system
195 system = ProcessHandler().system
196
197 def arg_split(s, posix=False):
198 """Split a command line's arguments in a shell-like manner.
199
200 This is a modified version of the standard library's shlex.split()
201 function, but with a default of posix=False for splitting, so that quotes
202 in inputs are respected."""
203
204 # Unfortunately, python's shlex module is buggy with unicode input:
205 # http://bugs.python.org/issue1170
206 # At least encoding the input when it's unicode seems to help, but there
207 # may be more problems lurking. Apparently this is fixed in python3.
208 is_unicode = False
209 if (not py3compat.PY3) and isinstance(s, unicode):
210 is_unicode = True
211 s = s.encode('utf-8')
212 lex = shlex.shlex(s, posix=posix)
213 lex.whitespace_split = True
214 tokens = list(lex)
215 if is_unicode:
216 # Convert the tokens back to unicode.
217 tokens = [x.decode('utf-8') for x in tokens]
218 return tokens
219
220
221
@@ -18,11 +18,15 b' from __future__ import print_function'
18 # stdlib
18 # stdlib
19 import os
19 import os
20 import sys
20 import sys
21 import ctypes
21
22
23 from ctypes import c_int, POINTER
24 from ctypes.wintypes import LPCWSTR, HLOCAL
22 from subprocess import STDOUT
25 from subprocess import STDOUT
23
26
24 # our own imports
27 # our own imports
25 from ._process_common import read_no_interrupt, process_handler
28 from ._process_common import read_no_interrupt, process_handler
29 from . import py3compat
26 from . import text
30 from . import text
27
31
28 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
@@ -146,3 +150,27 b' def getoutput(cmd):'
146 if out is None:
150 if out is None:
147 out = ''
151 out = ''
148 return out
152 return out
153
154
155 CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
156 CommandLineToArgvW.arg_types = [LPCWSTR, POINTER(c_int)]
157 CommandLineToArgvW.res_types = [POINTER(LPCWSTR)]
158 LocalFree = ctypes.windll.kernel32.LocalFree
159 LocalFree.res_type = HLOCAL
160 LocalFree.arg_types = [HLOCAL]
161
162 def arg_split(commandline, posix=False):
163 """Split a command line's arguments in a shell-like manner.
164
165 This is a special version for windows that use a ctypes call to CommandLineToArgvW
166 to do the argv splitting. The posix paramter is ignored.
167 """
168 #CommandLineToArgvW returns path to executable if called with empty string.
169 if commandline.strip() == "":
170 return []
171 argvn = c_int()
172 result_pointer = CommandLineToArgvW(py3compat.cast_unicode(commandline.lstrip()), ctypes.byref(argvn))
173 result_array_type = LPCWSTR * argvn.value
174 result = [arg for arg in result_array_type.from_address(result_pointer)]
175 retval = LocalFree(result_pointer)
176 return result
@@ -22,18 +22,10 b' import shlex'
22
22
23 # Our own
23 # Our own
24 if sys.platform == 'win32':
24 if sys.platform == 'win32':
25 import ctypes
25 from ._process_win32 import _find_cmd, system, getoutput, AvoidUNCPath, arg_split
26 from ctypes.wintypes import LPCWSTR, HLOCAL
27 from ctypes import c_int, POINTER
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]
35 else:
26 else:
36 from ._process_posix import _find_cmd, system, getoutput
27 from ._process_posix import _find_cmd, system, getoutput, arg_split
28
37
29
38 from ._process_common import getoutputerror
30 from ._process_common import getoutputerror
39 from IPython.utils import py3compat
31 from IPython.utils import py3compat
@@ -112,44 +104,6 b' def pycmd2argv(cmd):'
112 else:
104 else:
113 return [sys.executable, cmd]
105 return [sys.executable, cmd]
114
106
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
151
152
153 def abbrev_cwd():
107 def abbrev_cwd():
154 """ Return abbreviated version of cwd, e.g. d:mydir """
108 """ Return abbreviated version of cwd, e.g. d:mydir """
155 cwd = os.getcwdu().replace('\\','/')
109 cwd = os.getcwdu().replace('\\','/')
@@ -68,7 +68,10 b' def test_arg_split():'
68 tests = [['hi', ['hi']],
68 tests = [['hi', ['hi']],
69 [u'hi', [u'hi']],
69 [u'hi', [u'hi']],
70 ['hello there', ['hello', 'there']],
70 ['hello there', ['hello', 'there']],
71 # [u'h\N{LATIN SMALL LETTER A WITH CARON}llo', [u'h\N{LATIN SMALL LETTER A WITH CARON}llo']],
71 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
72 # Do not use \N because the tests crash with syntax error in
73 # some cases, for example windows python2.6.
74 [u'h\u01cello', [u'h\u01cello']],
72 ['something "with quotes"', ['something', '"with quotes"']],
75 ['something "with quotes"', ['something', '"with quotes"']],
73 ]
76 ]
74 for argstr, argv in tests:
77 for argstr, argv in tests:
@@ -80,7 +83,7 b' def test_arg_split_win32():'
80 tests = [['hi', ['hi']],
83 tests = [['hi', ['hi']],
81 [u'hi', [u'hi']],
84 [u'hi', [u'hi']],
82 ['hello there', ['hello', 'there']],
85 ['hello there', ['hello', 'there']],
83 # [u'h\N{LATIN SMALL LETTER A WITH CARON}llo', [u'h\N{LATIN SMALL LETTER A WITH CARON}llo']],
86 [u'h\u01cello', [u'h\u01cello']],
84 ['something "with quotes"', ['something', 'with quotes']],
87 ['something "with quotes"', ['something', 'with quotes']],
85 ]
88 ]
86 for argstr, argv in tests:
89 for argstr, argv in tests:
General Comments 0
You need to be logged in to leave comments. Login now