[PATCH] windows: switch the console encoding into an encoding actually used (issue2926)
Adrian Buehlmann
adrian at cadifra.com
Thu Jul 28 22:53:50 UTC 2011
On 2011-07-28 22:52, Andrei Polushin wrote:
> # HG changeset patch
> # User Andrei Polushin <polushin at gmail.com>
> # Date 1311886282 -25200
> # Branch stable
> # Node ID 61ace80f43d6144bef600d7ebe05f75f80fd0fe3
> # Parent 56848e2bb0c5a43b580dd2ca7ce1e781d4e75b2b
> windows: switch the console encoding into an encoding actually used (issue2926)
>
> The encoding of the console is switched temporarily, for the time the Mercurial
> is running, and restored to the previous value on exit.
> This solution is backward compatible, it changes almost nothing, i.e. neither
> stdout/pipe encoding, nor internal string handling are affected anyway.
>
> One problem still remains: `hg log | more' doesn't produce readable output on
> OEM console, I've found no way to change the console encoding when redirected.
>
> One problem possibly introduced: killing hg process may not restore previous
> console encoding. I'm unable to reproduce the problem, however.
>
> diff -r 56848e2bb0c5 -r 61ace80f43d6 mercurial/osutil.c
> --- a/mercurial/osutil.c Fri Jul 22 20:31:15 2011 -0300
> +++ b/mercurial/osutil.c Fri Jul 29 03:51:22 2011 +0700
> @@ -402,6 +402,36 @@
> }
>
> #ifdef _WIN32
> +static UINT inputcp;
> +static UINT outputcp;
> +
> +static void restoreconsoleencoding(void)
> +{
> + SetConsoleCP(inputcp);
> + SetConsoleOutputCP(outputcp);
> +}
> +
> +static PyObject *forceconsoleencoding(PyObject *self, PyObject *args)
> +{
> + int cp;
> +
> + if (!PyArg_ParseTuple(args, "i", &cp))
> + return NULL;
> +
> + if (!inputcp && !outputcp && IsValidCodePage(cp)) {
> + inputcp = GetConsoleCP();
> + outputcp = GetConsoleOutputCP();
> +
> + SetConsoleCP(cp);
> + SetConsoleOutputCP(cp);
> +
> + atexit(restoreconsoleencoding);
> + return Py_True;
> + }
> +
> + return Py_False;
> +}
> +
> static PyObject *posixfile(PyObject *self, PyObject *args, PyObject *kwds)
> {
> static char *kwlist[] = {"name", "mode", "buffering", NULL};
> @@ -536,6 +566,8 @@
> {"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS,
> "list a directory\n"},
> #ifdef _WIN32
> + {"forceconsoleencoding", forceconsoleencoding, METH_VARARGS,
> + "Temporarily switch the console encoding, restored on exit.\n"},
> {"posixfile", (PyCFunction)posixfile, METH_VARARGS | METH_KEYWORDS,
> "Open a file with POSIX-like semantics.\n"
> "On error, this function may raise either a WindowsError or an IOError."},
> diff -r 56848e2bb0c5 -r 61ace80f43d6 mercurial/windows.py
> --- a/mercurial/windows.py Fri Jul 22 20:31:15 2011 -0300
> +++ b/mercurial/windows.py Fri Jul 29 03:51:22 2011 +0700
> @@ -8,6 +8,16 @@
> from i18n import _
> import osutil
> import errno, msvcrt, os, re, sys
> +import codecs, encoding
> +
> +# Temporarily switch the console encoding into an encoding actually used.
> +try:
> + cp = codecs.lookup(encoding.encoding).name
> + if cp.startswith('cp'):
> + cp = int(cp[2:])
> + osutil.forceconsoleencoding(cp)
> +except LookupError, ValueError:
> + pass
Is there a reason why this can't be done by using Python's ctypes
instead of C code? (see win32.py)
More information about the Mercurial-devel
mailing list