hgext/win32mbcs.py
changeset 9154 47ce7a3a1fb0
parent 9102 bbc78cb1bf15
parent 9132 b47d7b440c5c
child 9216 9b2649b6ce5c
--- 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)