~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/win32utils.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-01 06:45:57 UTC
  • mfrom: (5247.2.41 more-ignored-exceptions)
  • Revision ID: pqm@pqm.ubuntu.com-20100901064557-qsxmjmp195ozbluf
(vila) Catch EPIPE when shutting down test servers. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
19
19
Only one dependency: ctypes should be installed.
20
20
"""
21
21
 
 
22
import glob
22
23
import os
23
24
import struct
24
25
import sys
25
26
 
 
27
from bzrlib import cmdline
26
28
 
27
29
# Windows version
28
30
if sys.platform == 'win32':
133
135
                'WorkingSetSize': mem_struct.WorkingSetSize,
134
136
                'QuotaPeakPagedPoolUsage': mem_struct.QuotaPeakPagedPoolUsage,
135
137
                'QuotaPagedPoolUsage': mem_struct.QuotaPagedPoolUsage,
136
 
                'QuotaPeakNonPagedPoolUsage': mem_struct.QuotaPeakNonPagedPoolUsage,
 
138
                'QuotaPeakNonPagedPoolUsage':
 
139
                    mem_struct.QuotaPeakNonPagedPoolUsage,
137
140
                'QuotaNonPagedPoolUsage': mem_struct.QuotaNonPagedPoolUsage,
138
141
                'PagefileUsage': mem_struct.PagefileUsage,
139
142
                'PeakPagefileUsage': mem_struct.PeakPagefileUsage,
150
153
                   ' or win32process')
151
154
        return
152
155
    if short:
153
 
        trace.note('WorkingSize %7dKB'
154
 
                   '\tPeakWorking %7dKB\t%s',
 
156
        # using base-2 units (see HACKING.txt).
 
157
        trace.note('WorkingSize %7dKiB'
 
158
                   '\tPeakWorking %7dKiB\t%s',
155
159
                   info['WorkingSetSize'] / 1024,
156
160
                   info['PeakWorkingSetSize'] / 1024,
157
161
                   message)
158
162
        return
159
163
    if message:
160
164
        trace.note('%s', message)
161
 
    trace.note('WorkingSize       %8d KB', info['WorkingSetSize'] / 1024)
162
 
    trace.note('PeakWorking       %8d KB', info['PeakWorkingSetSize'] / 1024)
163
 
    trace.note('PagefileUsage     %8d KB', info.get('PagefileUsage', 0) / 1024)
164
 
    trace.note('PeakPagefileUsage %8d KB', info.get('PeakPagefileUsage', 0) / 1024)
165
 
    trace.note('PrivateUsage      %8d KB', info.get('PrivateUsage', 0) / 1024)
 
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',
 
169
               info.get('PeakPagefileUsage', 0) / 1024)
 
170
    trace.note('PrivateUsage      %8d KiB', info.get('PrivateUsage', 0) / 1024)
166
171
    trace.note('PageFaultCount    %8d', info.get('PageFaultCount', 0))
167
172
 
168
173
 
178
183
        return (defaultx, defaulty)
179
184
 
180
185
    # To avoid problem with redirecting output via pipe
181
 
    # need to use stderr instead of stdout
 
186
    # we need to use stderr instead of stdout
182
187
    h = ctypes.windll.kernel32.GetStdHandle(WIN32_STDERR_HANDLE)
183
188
    csbi = ctypes.create_string_buffer(22)
184
189
    res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
185
190
 
186
191
    if res:
187
192
        (bufx, bufy, curx, cury, wattr,
188
 
        left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
 
193
        left, top, right, bottom, maxx, maxy) = struct.unpack(
 
194
            "hhhhHhhhhhh", csbi.raw)
189
195
        sizex = right - left + 1
190
196
        sizey = bottom - top + 1
191
197
        return (sizex, sizey)
388
394
 
389
395
 
390
396
def _ensure_unicode(s):
391
 
    from bzrlib import osutils
392
397
    if s and type(s) != unicode:
393
398
        from bzrlib import osutils
394
399
        s = s.decode(osutils.get_user_encoding())
409
414
 
410
415
 
411
416
def _ensure_with_dir(path):
412
 
    if not os.path.split(path)[0] or path.startswith(u'*') or path.startswith(u'?'):
 
417
    if (not os.path.split(path)[0] or path.startswith(u'*')
 
418
        or path.startswith(u'?')):
413
419
        return u'./' + path, True
414
420
    else:
415
421
        return path, False
422
428
 
423
429
 
424
430
 
 
431
def glob_one(possible_glob):
 
432
    """Same as glob.glob().
 
433
 
 
434
    work around bugs in glob.glob()
 
435
    - Python bug #1001604 ("glob doesn't return unicode with ...")
 
436
    - failing expansion for */* with non-iso-8859-* chars
 
437
    """
 
438
    corrected_glob, corrected = _ensure_with_dir(possible_glob)
 
439
    glob_files = glob.glob(corrected_glob)
 
440
 
 
441
    if not glob_files:
 
442
        # special case to let the normal code path handle
 
443
        # files that do not exist, etc.
 
444
        glob_files = [possible_glob]
 
445
    elif corrected:
 
446
        glob_files = [_undo_ensure_with_dir(elem, corrected)
 
447
                      for elem in glob_files]
 
448
    return [elem.replace(u'\\', u'/') for elem in glob_files]
 
449
 
 
450
 
425
451
def glob_expand(file_list):
426
452
    """Replacement for glob expansion by the shell.
427
453
 
435
461
    """
436
462
    if not file_list:
437
463
        return []
438
 
    import glob
439
464
    expanded_file_list = []
440
465
    for possible_glob in file_list:
441
 
        # work around bugs in glob.glob()
442
 
        # - Python bug #1001604 ("glob doesn't return unicode with ...")
443
 
        # - failing expansion for */* with non-iso-8859-* chars
444
 
        possible_glob, corrected = _ensure_with_dir(possible_glob)
445
 
        glob_files = glob.glob(possible_glob)
446
 
 
447
 
        if glob_files == []:
448
 
            # special case to let the normal code path handle
449
 
            # files that do not exists
450
 
            expanded_file_list.append(
451
 
                _undo_ensure_with_dir(possible_glob, corrected))
452
 
        else:
453
 
            glob_files = [_undo_ensure_with_dir(elem, corrected) for elem in glob_files]
454
 
            expanded_file_list += glob_files
455
 
 
456
 
    return [elem.replace(u'\\', u'/') for elem in expanded_file_list]
 
466
        expanded_file_list.extend(glob_one(possible_glob))
 
467
    return expanded_file_list
457
468
 
458
469
 
459
470
def get_app_path(appname):
511
522
            trace.mutter('Unable to set hidden attribute on %r: %s', path, e)
512
523
 
513
524
 
 
525
def _command_line_to_argv(command_line, argv, single_quotes_allowed=False):
 
526
    """Convert a Unicode command line into a list of argv arguments.
 
527
 
 
528
    It performs wildcard expansion to make wildcards act closer to how they
 
529
    work in posix shells, versus how they work by default on Windows. Quoted
 
530
    arguments are left untouched.
 
531
 
 
532
    :param command_line: The unicode string to split into an arg list.
 
533
    :param single_quotes_allowed: Whether single quotes are accepted as quoting
 
534
                                  characters like double quotes. False by
 
535
                                  default.
 
536
    :return: A list of unicode strings.
 
537
    """
 
538
    # First, spit the command line
 
539
    s = cmdline.Splitter(command_line, single_quotes_allowed=single_quotes_allowed)
 
540
    
 
541
    # Bug #587868 Now make sure that the length of s agrees with sys.argv 
 
542
    # we do this by simply counting the number of arguments in each. The counts should 
 
543
    # agree no matter what encoding sys.argv is in (AFAIK) 
 
544
    # len(arguments) < len(sys.argv) should be an impossibility since python gets 
 
545
    # args from the very same PEB as does GetCommandLineW
 
546
    arguments = list(s)
 
547
    
 
548
    # Now shorten the command line we get from GetCommandLineW to match sys.argv
 
549
    if len(arguments) < len(argv):
 
550
        raise AssertionError("Split command line can't be shorter than argv")
 
551
    arguments = arguments[len(arguments) - len(argv):]
 
552
    
 
553
    # Carry on to process globs (metachars) in the command line
 
554
    # expand globs if necessary
 
555
    # TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
 
556
    #       '**/' style globs
 
557
    args = []
 
558
    for is_quoted, arg in arguments:
 
559
        if is_quoted or not glob.has_magic(arg):
 
560
            args.append(arg)
 
561
        else:
 
562
            args.extend(glob_one(arg))
 
563
    return args
 
564
 
 
565
 
514
566
if has_ctypes and winver != 'Windows 98':
515
567
    def get_unicode_argv():
516
 
        LPCWSTR = ctypes.c_wchar_p
517
 
        INT = ctypes.c_int
518
 
        POINTER = ctypes.POINTER
519
 
        prototype = ctypes.WINFUNCTYPE(LPCWSTR)
520
 
        GetCommandLine = prototype(("GetCommandLineW",
521
 
                                    ctypes.windll.kernel32))
522
 
        prototype = ctypes.WINFUNCTYPE(POINTER(LPCWSTR), LPCWSTR, POINTER(INT))
523
 
        CommandLineToArgv = prototype(("CommandLineToArgvW",
524
 
                                       ctypes.windll.shell32))
525
 
        c = INT(0)
526
 
        pargv = CommandLineToArgv(GetCommandLine(), ctypes.byref(c))
 
568
        prototype = ctypes.WINFUNCTYPE(ctypes.c_wchar_p)
 
569
        GetCommandLineW = prototype(("GetCommandLineW",
 
570
                                     ctypes.windll.kernel32))
 
571
        command_line = GetCommandLineW()
 
572
        if command_line is None:
 
573
            raise ctypes.WinError()
527
574
        # Skip the first argument, since we only care about parameters
528
 
        argv = [pargv[i] for i in range(1, c.value)]
529
 
        if getattr(sys, 'frozen', None) is None:
530
 
            # Invoked via 'python.exe' which takes the form:
531
 
            #   python.exe [PYTHON_OPTIONS] C:\Path\bzr [BZR_OPTIONS]
532
 
            # we need to get only BZR_OPTIONS part,
533
 
            # so let's using sys.argv[1:] as reference to get the tail
534
 
            # of unicode argv
535
 
            tail_len = len(sys.argv[1:])
536
 
            ix = len(argv) - tail_len
537
 
            argv = argv[ix:]
 
575
        argv = _command_line_to_argv(command_line, sys.argv)[1:]
538
576
        return argv
539
577
else:
540
578
    get_unicode_argv = None