Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ae9bb8e

Browse files
author
J�rgen Stenarson
committed
Special version of arg_split for win32
1 parent 52fc956 commit ae9bb8e

2 files changed

Lines changed: 59 additions & 24 deletions

File tree

IPython/utils/process.py

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,16 @@
2222

2323
# Our own
2424
if sys.platform == 'win32':
25+
import ctypes
26+
from ctypes.wintypes import LPCWSTR, HLOCAL
27+
from ctypes import c_int, POINTER
2528
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]
2635
else:
2736
from ._process_posix import _find_cmd, system, getoutput
2837

@@ -103,29 +112,42 @@ def pycmd2argv(cmd):
103112
else:
104113
return [sys.executable, cmd]
105114

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
129151

130152

131153
def abbrev_cwd():

IPython/utils/tests/test_process.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,25 @@ def test_find_cmd_fail():
6262
nt.assert_raises(FindCmdError,find_cmd,'asdfasdf')
6363

6464

65+
@dec.skip_win32
6566
def test_arg_split():
6667
"""Ensure that argument lines are correctly split like in a shell."""
6768
tests = [['hi', ['hi']],
6869
[u'hi', [u'hi']],
6970
['hello there', ['hello', 'there']],
70-
[u'h\N{LATIN SMALL LETTER A WITH CARON}llo', [u'h\N{LATIN SMALL LETTER A WITH CARON}llo']],
71+
# [u'h\N{LATIN SMALL LETTER A WITH CARON}llo', [u'h\N{LATIN SMALL LETTER A WITH CARON}llo']],
72+
['something "with quotes"', ['something', '"with quotes"']],
73+
]
74+
for argstr, argv in tests:
75+
nt.assert_equal(arg_split(argstr), argv)
76+
77+
@dec.skip_win32
78+
def test_arg_split_win32():
79+
"""Ensure that argument lines are correctly split like in a shell."""
80+
tests = [['hi', ['hi']],
81+
[u'hi', [u'hi']],
82+
['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']],
7184
['something "with quotes"', ['something', '"with quotes"']],
7285
]
7386
for argstr, argv in tests:

0 commit comments

Comments
 (0)