149
150
proc = win32process.GetCurrentProcess()
150
151
info = win32process.GetProcessMemoryInfo(proc)
152
trace.note('Cannot debug memory on win32 without ctypes'
153
trace.note(gettext('Cannot debug memory on win32 without ctypes'
156
157
# using base-2 units (see HACKING.txt).
157
trace.note('WorkingSize %7dKiB'
158
'\tPeakWorking %7dKiB\t%s',
158
trace.note(gettext('WorkingSize {0:>7}KiB'
159
'\tPeakWorking {1:>7}KiB\t{2}').format(
159
160
info['WorkingSetSize'] / 1024,
160
161
info['PeakWorkingSetSize'] / 1024,
164
165
trace.note('%s', message)
165
trace.note('WorkingSize %8d KiB', info['WorkingSetSize'] / 1024)
166
trace.note('PeakWorking %8d KiB', info['PeakWorkingSetSize'] / 1024)
167
trace.note('PagefileUsage %8d KiB', info.get('PagefileUsage', 0) / 1024)
168
trace.note('PeakPagefileUsage %8d KiB',
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'),
169
170
info.get('PeakPagefileUsage', 0) / 1024)
170
trace.note('PrivateUsage %8d KiB', info.get('PrivateUsage', 0) / 1024)
171
trace.note('PageFaultCount %8d', info.get('PageFaultCount', 0))
171
trace.note(gettext('PrivateUsage %8d KiB'), info.get('PrivateUsage', 0) / 1024)
172
trace.note(gettext('PageFaultCount %8d'), info.get('PageFaultCount', 0))
174
175
def get_console_size(defaultx=80, defaulty=25):
522
523
trace.mutter('Unable to set hidden attribute on %r: %s', path, e)
526
class UnicodeShlex(object):
527
"""This is a very simplified version of shlex.shlex.
529
The main change is that it supports non-ascii input streams. The internal
530
structure is quite simplified relative to shlex.shlex, since we aren't
531
trying to handle multiple input streams, etc. In fact, we don't use a
532
file-like api either.
535
def __init__(self, uni_string):
536
self._input = uni_string
537
self._input_iter = iter(self._input)
538
self._whitespace_match = re.compile(u'\s').match
539
self._word_match = re.compile(u'\S').match
540
self._quote_chars = u'"'
541
# self._quote_match = re.compile(u'[\'"]').match
542
self._escape_match = lambda x: None # Never matches
545
# ' ' - after whitespace, starting a new token
546
# 'a' - after text, currently working on a token
547
# '"' - after ", currently in a "-delimited quoted section
548
# "\" - after '\', checking the next char
550
self._token = [] # Current token being parsed
552
def _get_token(self):
553
# Were there quote chars as part of this token?
556
for nextchar in self._input_iter:
557
if self._state == ' ':
558
if self._whitespace_match(nextchar):
559
# if self._token: return token
561
elif nextchar in self._quote_chars:
562
self._state = nextchar # quoted state
563
elif self._word_match(nextchar):
564
self._token.append(nextchar)
567
raise AssertionError('wtttf?')
568
elif self._state in self._quote_chars:
570
if nextchar == self._state: # End of quote
571
self._state = 'a' # posix allows 'foo'bar to translate to
573
elif self._state == '"' and nextchar == self._escape:
574
quoted_state = self._state
575
self._state = nextchar
577
self._token.append(nextchar)
578
elif self._state == self._escape:
580
self._token.append('\\')
581
elif nextchar == '"':
582
self._token.append(nextchar)
584
self._token.append('\\' + nextchar)
585
self._state = quoted_state
586
elif self._state == 'a':
587
if self._whitespace_match(nextchar):
589
break # emit this token
591
continue # no token to emit
592
elif nextchar in self._quote_chars:
593
# Start a new quoted section
594
self._state = nextchar
596
elif (self._word_match(nextchar)
597
or nextchar in self._quote_chars
598
# or whitespace_split?
600
self._token.append(nextchar)
602
raise AssertionError('state == "a", char: %r'
605
raise AssertionError('unknown state: %r' % (self._state,))
606
result = ''.join(self._token)
608
if not quoted and result == '':
610
return quoted, result
616
quoted, token = self._get_token()
622
def _command_line_to_argv(command_line):
623
"""Convert a Unicode command line into a set of argv arguments.
625
This does wildcard expansion, etc. It is intended to make wildcards act
626
closer to how they work in posix shells, versus how they work by default on
629
s = UnicodeShlex(command_line)
630
# Now that we've split the content, expand globs
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
631
556
# TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
632
557
# '**/' style globs
634
for is_quoted, arg in s:
559
for is_quoted, arg in arguments:
635
560
if is_quoted or not glob.has_magic(arg):
642
567
if has_ctypes and winver != 'Windows 98':
643
568
def get_unicode_argv():
644
LPCWSTR = ctypes.c_wchar_p
646
POINTER = ctypes.POINTER
647
prototype = ctypes.WINFUNCTYPE(LPCWSTR)
648
GetCommandLine = prototype(("GetCommandLineW",
649
ctypes.windll.kernel32))
650
prototype = ctypes.WINFUNCTYPE(POINTER(LPCWSTR), LPCWSTR, POINTER(INT))
651
command_line = GetCommandLine()
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()
652
575
# Skip the first argument, since we only care about parameters
653
argv = _command_line_to_argv(command_line)[1:]
654
if getattr(sys, 'frozen', None) is None:
655
# Invoked via 'python.exe' which takes the form:
656
# python.exe [PYTHON_OPTIONS] C:\Path\bzr [BZR_OPTIONS]
657
# we need to get only BZR_OPTIONS part,
658
# We already removed 'python.exe' so we remove everything up to and
659
# including the first non-option ('-') argument.
660
for idx in xrange(len(argv)):
661
if argv[idx][:1] != '-':
576
argv = _command_line_to_argv(command_line, sys.argv)[1:]
666
579
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