# HG changeset patch # User Matt Mackall # Date 1247776813 18000 # Node ID 47ce7a3a1fb0364a15ab7217831e0cb847cf178e # Parent 6adc899c98d00cf6f70d2261e0ce8b7a64d21c5f# Parent 996c1cd8f53068ce88e77414a5d3dc7ead419c3c Merge with stable diff -r 6adc899c98d0 -r 47ce7a3a1fb0 hgext/win32mbcs.py --- a/hgext/win32mbcs.py Thu Jul 16 14:49:52 2009 -0500 +++ b/hgext/win32mbcs.py Thu Jul 16 15:40:13 2009 -0500 @@ -49,6 +49,9 @@ return tuple(map(decode, arg)) elif isinstance(arg, list): return map(decode, arg) + elif isinstance(arg, dict): + for k, v in arg.items(): + arg[k] = decode(v) return arg def encode(arg): @@ -58,29 +61,50 @@ return tuple(map(encode, arg)) elif isinstance(arg, list): return map(encode, arg) + elif isinstance(arg, dict): + for k, v in arg.items(): + arg[k] = encode(v) return arg -def wrapper(func, args): +def appendsep(s): + # ensure the path ends with os.sep, appending it if necessary. + try: + us = decode(s) + except UnicodeError: + us = s + if us and us[-1] not in ':/\\': + s += os.sep + return s + +def wrapper(func, args, kwds): # check argument is unicode, then call original for arg in args: if isinstance(arg, unicode): - return func(*args) + return func(*args, **kwds) try: # convert arguments to unicode, call func, then convert back - return encode(func(*decode(args))) + return encode(func(*decode(args), **decode(kwds))) except UnicodeError: - # If not encoded with encoding.encoding, report it then - # continue with calling original function. - raise util.Abort(_("[win32mbcs] filename conversion fail with" + raise util.Abort(_("[win32mbcs] filename conversion failed with" " %s encoding\n") % (encoding.encoding)) -def wrapname(name): +def wrapperforlistdir(func, args, kwds): + # Ensure 'path' argument ends with os.sep to avoids + # misinterpreting last 0x5c of MBCS 2nd byte as path separator. + if args: + args = list(args) + args[0] = appendsep(args[0]) + if kwds.has_key('path'): + kwds['path'] = appendsep(kwds['path']) + return func(*args, **kwds) + +def wrapname(name, wrapper): module, name = name.rsplit('.', 1) module = sys.modules[module] func = getattr(module, name) - def f(*args): - return wrapper(func, args) + def f(*args, **kwds): + return wrapper(func, args, kwds) try: f.__name__ = func.__name__ # fail with python23 except Exception: @@ -110,7 +134,8 @@ # fake is only for relevant environment. if encoding.encoding.lower() in problematic_encodings.split(): for f in funcs.split(): - wrapname(f) + wrapname(f, wrapper) + wrapname("mercurial.osutil.listdir", wrapperforlistdir) ui.debug(_("[win32mbcs] activated with encoding: %s\n") % encoding.encoding) diff -r 6adc899c98d0 -r 47ce7a3a1fb0 mercurial/store.py --- a/mercurial/store.py Thu Jul 16 14:49:52 2009 -0500 +++ b/mercurial/store.py Thu Jul 16 15:40:13 2009 -0500 @@ -284,16 +284,17 @@ self.pathjoiner = pathjoiner self.path = self.pathjoiner(path, 'store') self.createmode = _calcmode(self.path) - self._op = opener(self.path) - self._op.createmode = self.createmode - self.fncache = fncache(self._op) + op = opener(self.path) + op.createmode = self.createmode + fnc = fncache(op) + self.fncache = fnc def fncacheopener(path, mode='r', *args, **kw): if (mode not in ('r', 'rb') and path.startswith('data/') - and path not in self.fncache): - self.fncache.add(path) - return self._op(hybridencode(path), mode, *args, **kw) + and path not in fnc): + fnc.add(path) + return op(hybridencode(path), mode, *args, **kw) self.opener = fncacheopener def join(self, f):