http://www.mediawiki.org/wiki/Special:Code/pywikipedia/10042
Revision: 10042
Author: valhallasw
Date: 2012-03-25 23:58:52 +0000 (Sun, 25 Mar 2012)
Log Message:
-----------
Added basic stdin support (only full line reads are supported, currently, but that is all
we need)
Modified Paths:
--------------
trunk/pywikipedia/userinterfaces/win32_unicode.py
Modified: trunk/pywikipedia/userinterfaces/win32_unicode.py
===================================================================
--- trunk/pywikipedia/userinterfaces/win32_unicode.py 2012-03-25 23:57:58 UTC (rev 10041)
+++ trunk/pywikipedia/userinterfaces/win32_unicode.py 2012-03-25 23:58:52 UTC (rev 10042)
@@ -14,12 +14,22 @@
# [5]
http://stackoverflow.com/users/393146
#
################################################
+#
+# stdin support added by Merlijn van Deen <valhallasw(a)gmail.com>om>, march 2012
+# Licensed under both CC-BY-SA as the MIT license.
+#
+################################################
import sys
if sys.platform == "win32":
import codecs
- from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int
- from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID
+ from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int, \
+ create_unicode_buffer
+ from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR
+ try:
+ from ctypes.wintypes import LPVOID
+ except ImportError:
+ from ctypes import c_void_p as LPVOID
original_stderr = sys.stderr
@@ -50,6 +60,7 @@
# BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode);
GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle",
windll.kernel32))
+ STD_INPUT_HANDLE = DWORD(-10)
STD_OUTPUT_HANDLE = DWORD(-11)
STD_ERROR_HANDLE = DWORD(-12)
GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType",
windll.kernel32))
@@ -65,18 +76,29 @@
return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR
or GetConsoleMode(handle, byref(DWORD())) == 0)
+ old_stdin_fileno = None
old_stdout_fileno = None
old_stderr_fileno = None
+
+ if hasattr(sys.stdin, 'fileno'):
+ old_stdin_fileno = sys.stdin.fileno()
if hasattr(sys.stdout, 'fileno'):
old_stdout_fileno = sys.stdout.fileno()
if hasattr(sys.stderr, 'fileno'):
old_stderr_fileno = sys.stderr.fileno()
+ STDIN_FILENO = 0
STDOUT_FILENO = 1
STDERR_FILENO = 2
+ real_stdin = (old_stdin_fileno == STDIN_FILENO)
real_stdout = (old_stdout_fileno == STDOUT_FILENO)
real_stderr = (old_stderr_fileno == STDERR_FILENO)
+ if real_stdin:
+ hStdin = GetStdHandle(STD_INPUT_HANDLE)
+ if not_a_console(hStdin):
+ real_stdin = False
+
if real_stdout:
hStdout = GetStdHandle(STD_OUTPUT_HANDLE)
if not_a_console(hStdout):
@@ -87,6 +109,27 @@
if not_a_console(hStderr):
real_stderr = False
+ if real_stdin:
+ ReadConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPVOID, DWORD, POINTER(DWORD), \
+ LPVOID)(("ReadConsoleW",
windll.kernel32))
+
+ class UnicodeInput:
+ def __init__(self, hConsole, name, bufsize=1024):
+ self._hConsole = hConsole
+ self.bufsize = bufsize
+ self.buffer = create_unicode_buffer(bufsize)
+ self.name = name
+ self.encoding = 'utf-8'
+
+ def readline(self):
+ maxnum = DWORD(self.bufsize-1)
+ numrecv = DWORD(0)
+ result = ReadConsoleW(self._hConsole, self.buffer, maxnum,
byref(numrecv), None)
+ if not result:
+ raise Exception("stdin failure")
+ return self.buffer.value[:numrecv.value].encode(self.encoding)
+
+
if real_stdout or real_stderr:
# BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars,
# LPDWORD lpCharsWritten, LPVOID lpReserved);
@@ -158,18 +201,23 @@
_complain("%s.writelines: %r" % (self.name, e))
raise
+ if real_stdin:
+ stdin = UnicodeInput(hStdin, name='<Unicode console
stdin>')
+ else:
+ stdin = sys.stdin
+
if real_stdout:
- sys.stdout = UnicodeOutput(hStdout, None, STDOUT_FILENO,
+ stdout = UnicodeOutput(hStdout, None, STDOUT_FILENO,
'<Unicode console stdout>')
else:
- sys.stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno,
+ stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno,
'<Unicode redirected stdout>')
if real_stderr:
- sys.stderr = UnicodeOutput(hStderr, None, STDERR_FILENO,
+ stderr = UnicodeOutput(hStderr, None, STDERR_FILENO,
'<Unicode console stderr>')
else:
- sys.stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno,
+ stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno,
'<Unicode redirected stderr>')
except Exception, e:
_complain("exception %r while fixing up sys.stdout and sys.stderr" %
(e,))
@@ -207,5 +255,8 @@
argv[0] = u'-c'
break
- # if you like:
- sys.argv = argv
\ No newline at end of file
+else:
+ stdin = sys.stdin
+ stdout = sys.stdout
+ stderr = sys.stderr
+ argv = sys.argv
\ No newline at end of file