129
130
ctypes.byref(mem_struct),
130
131
ctypes.sizeof(mem_struct))
132
trace.note(gettext('Failed to GetProcessMemoryInfo()'))
133
trace.note('Failed to GetProcessMemoryInfo()')
134
135
info = {'PageFaultCount': mem_struct.PageFaultCount,
135
136
'PeakWorkingSetSize': mem_struct.PeakWorkingSetSize,
136
137
'WorkingSetSize': mem_struct.WorkingSetSize,
137
138
'QuotaPeakPagedPoolUsage': mem_struct.QuotaPeakPagedPoolUsage,
138
139
'QuotaPagedPoolUsage': mem_struct.QuotaPagedPoolUsage,
139
'QuotaPeakNonPagedPoolUsage':
140
mem_struct.QuotaPeakNonPagedPoolUsage,
140
'QuotaPeakNonPagedPoolUsage': mem_struct.QuotaPeakNonPagedPoolUsage,
141
141
'QuotaNonPagedPoolUsage': mem_struct.QuotaNonPagedPoolUsage,
142
142
'PagefileUsage': mem_struct.PagefileUsage,
143
143
'PeakPagefileUsage': mem_struct.PeakPagefileUsage,
150
150
proc = win32process.GetCurrentProcess()
151
151
info = win32process.GetProcessMemoryInfo(proc)
153
trace.note(gettext('Cannot debug memory on win32 without ctypes'
153
trace.note('Cannot debug memory on win32 without ctypes'
157
# using base-2 units (see HACKING.txt).
158
trace.note(gettext('WorkingSize {0:>7}KiB'
159
'\tPeakWorking {1:>7}KiB\t{2}').format(
157
trace.note('WorkingSize %7dKB'
158
'\tPeakWorking %7dKB\t%s',
160
159
info['WorkingSetSize'] / 1024,
161
160
info['PeakWorkingSetSize'] / 1024,
165
164
trace.note('%s', message)
166
trace.note(gettext('WorkingSize %8d KiB'), info['WorkingSetSize'] / 1024)
167
trace.note(gettext('PeakWorking %8d KiB'), info['PeakWorkingSetSize'] / 1024)
168
trace.note(gettext('PagefileUsage %8d KiB'), info.get('PagefileUsage', 0) / 1024)
169
trace.note(gettext('PeakPagefileUsage %8d KiB'),
170
info.get('PeakPagefileUsage', 0) / 1024)
171
trace.note(gettext('PrivateUsage %8d KiB'), info.get('PrivateUsage', 0) / 1024)
172
trace.note(gettext('PageFaultCount %8d'), info.get('PageFaultCount', 0))
165
trace.note('WorkingSize %8d KB', info['WorkingSetSize'] / 1024)
166
trace.note('PeakWorking %8d KB', info['PeakWorkingSetSize'] / 1024)
167
trace.note('PagefileUsage %8d KB', info.get('PagefileUsage', 0) / 1024)
168
trace.note('PeakPagefileUsage %8d KB', info.get('PeakPagefileUsage', 0) / 1024)
169
trace.note('PrivateUsage %8d KB', info.get('PrivateUsage', 0) / 1024)
170
trace.note('PageFaultCount %8d', info.get('PageFaultCount', 0))
175
173
def get_console_size(defaultx=80, defaulty=25):
523
520
trace.mutter('Unable to set hidden attribute on %r: %s', path, e)
526
def _command_line_to_argv(command_line, argv, single_quotes_allowed=False):
527
"""Convert a Unicode command line into a list of argv arguments.
529
It performs wildcard expansion to make wildcards act closer to how they
530
work in posix shells, versus how they work by default on Windows. Quoted
531
arguments are left untouched.
533
:param command_line: The unicode string to split into an arg list.
534
:param single_quotes_allowed: Whether single quotes are accepted as quoting
535
characters like double quotes. False by
537
:return: A list of unicode strings.
539
# First, spit the command line
540
s = cmdline.Splitter(command_line, single_quotes_allowed=single_quotes_allowed)
542
# Bug #587868 Now make sure that the length of s agrees with sys.argv
543
# we do this by simply counting the number of arguments in each. The counts should
544
# agree no matter what encoding sys.argv is in (AFAIK)
545
# len(arguments) < len(sys.argv) should be an impossibility since python gets
546
# args from the very same PEB as does GetCommandLineW
549
# Now shorten the command line we get from GetCommandLineW to match sys.argv
550
if len(arguments) < len(argv):
551
raise AssertionError("Split command line can't be shorter than argv")
552
arguments = arguments[len(arguments) - len(argv):]
554
# Carry on to process globs (metachars) in the command line
555
# expand globs if necessary
524
class UnicodeShlex(object):
525
"""This is a very simplified version of shlex.shlex.
527
The main change is that it supports non-ascii input streams. The internal
528
structure is quite simplified relative to shlex.shlex, since we aren't
529
trying to handle multiple input streams, etc. In fact, we don't use a
530
file-like api either.
533
def __init__(self, uni_string):
534
self._input = uni_string
535
self._input_iter = iter(self._input)
536
self._whitespace_match = re.compile(u'\s').match
537
self._word_match = re.compile(u'\S').match
538
self._quote_chars = u'"'
539
# self._quote_match = re.compile(u'[\'"]').match
540
self._escape_match = lambda x: None # Never matches
543
# ' ' - after whitespace, starting a new token
544
# 'a' - after text, currently working on a token
545
# '"' - after ", currently in a "-delimited quoted section
546
# "\" - after '\', checking the next char
548
self._token = [] # Current token being parsed
550
def _get_token(self):
551
# Were there quote chars as part of this token?
554
for nextchar in self._input_iter:
555
if self._state == ' ':
556
if self._whitespace_match(nextchar):
557
# if self._token: return token
559
elif nextchar in self._quote_chars:
560
self._state = nextchar # quoted state
561
elif self._word_match(nextchar):
562
self._token.append(nextchar)
565
raise AssertionError('wtttf?')
566
elif self._state in self._quote_chars:
568
if nextchar == self._state: # End of quote
569
self._state = 'a' # posix allows 'foo'bar to translate to
571
elif self._state == '"' and nextchar == self._escape:
572
quoted_state = self._state
573
self._state = nextchar
575
self._token.append(nextchar)
576
elif self._state == self._escape:
578
self._token.append('\\')
579
elif nextchar == '"':
580
self._token.append(nextchar)
582
self._token.append('\\' + nextchar)
583
self._state = quoted_state
584
elif self._state == 'a':
585
if self._whitespace_match(nextchar):
587
break # emit this token
589
continue # no token to emit
590
elif nextchar in self._quote_chars:
591
# Start a new quoted section
592
self._state = nextchar
594
elif (self._word_match(nextchar)
595
or nextchar in self._quote_chars
596
# or whitespace_split?
598
self._token.append(nextchar)
600
raise AssertionError('state == "a", char: %r'
603
raise AssertionError('unknown state: %r' % (self._state,))
604
result = ''.join(self._token)
606
if not quoted and result == '':
608
return quoted, result
614
quoted, token = self._get_token()
620
def _command_line_to_argv(command_line):
621
"""Convert a Unicode command line into a set of argv arguments.
623
This does wildcard expansion, etc. It is intended to make wildcards act
624
closer to how they work in posix shells, versus how they work by default on
627
s = UnicodeShlex(command_line)
628
# Now that we've split the content, expand globs
556
629
# TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
557
630
# '**/' style globs
559
for is_quoted, arg in arguments:
632
for is_quoted, arg in s:
560
633
if is_quoted or not glob.has_magic(arg):
567
640
if has_ctypes and winver != 'Windows 98':
568
641
def get_unicode_argv():
569
prototype = ctypes.WINFUNCTYPE(ctypes.c_wchar_p)
570
GetCommandLineW = prototype(("GetCommandLineW",
571
ctypes.windll.kernel32))
572
command_line = GetCommandLineW()
573
if command_line is None:
574
raise ctypes.WinError()
642
LPCWSTR = ctypes.c_wchar_p
644
POINTER = ctypes.POINTER
645
prototype = ctypes.WINFUNCTYPE(LPCWSTR)
646
GetCommandLine = prototype(("GetCommandLineW",
647
ctypes.windll.kernel32))
648
prototype = ctypes.WINFUNCTYPE(POINTER(LPCWSTR), LPCWSTR, POINTER(INT))
649
command_line = GetCommandLine()
575
650
# Skip the first argument, since we only care about parameters
576
argv = _command_line_to_argv(command_line, sys.argv)[1:]
651
argv = _command_line_to_argv(GetCommandLine())[1:]
652
if getattr(sys, 'frozen', None) is None:
653
# Invoked via 'python.exe' which takes the form:
654
# python.exe [PYTHON_OPTIONS] C:\Path\bzr [BZR_OPTIONS]
655
# we need to get only BZR_OPTIONS part,
656
# We already removed 'python.exe' so we remove everything up to and
657
# including the first non-option ('-') argument.
658
for idx in xrange(len(argv)):
659
if argv[idx][:1] != '-':
579
664
get_unicode_argv = None
583
def _pywin32_is_local_pid_dead(pid):
584
"""True if pid doesn't correspond to live process on this machine"""
586
handle = win32api.OpenProcess(1, False, pid) # PROCESS_TERMINATE
587
except pywintypes.error, e:
588
if e[0] == 5: # ERROR_ACCESS_DENIED
589
# Probably something alive we're not allowed to kill
591
elif e[0] == 87: # ERROR_INVALID_PARAMETER
596
is_local_pid_dead = _pywin32_is_local_pid_dead
597
elif has_ctypes and sys.platform == 'win32':
598
from ctypes.wintypes import BOOL, DWORD, HANDLE
599
_kernel32 = ctypes.windll.kernel32
600
_CloseHandle = ctypes.WINFUNCTYPE(BOOL, HANDLE)(
601
("CloseHandle", _kernel32))
602
_OpenProcess = ctypes.WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)(
603
("OpenProcess", _kernel32))
604
def _ctypes_is_local_pid_dead(pid):
605
"""True if pid doesn't correspond to live process on this machine"""
606
handle = _OpenProcess(1, False, pid) # PROCESS_TERMINATE
608
errorcode = ctypes.GetLastError()
609
if errorcode == 5: # ERROR_ACCESS_DENIED
610
# Probably something alive we're not allowed to kill
612
elif errorcode == 87: # ERROR_INVALID_PARAMETER
614
raise ctypes.WinError(errorcode)
617
is_local_pid_dead = _ctypes_is_local_pid_dead