Author: Mark Young <marky1...@gmail.com> Branch: py3k_add_terminal_size Changeset: r86521:7cf5e409328e Date: 2016-08-23 19:41 -0400 http://bitbucket.org/pypy/pypy/changeset/7cf5e409328e/
Log: Posting what I have so far. diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -74,6 +74,7 @@ 'abort': 'interp_posix.abort', 'urandom': 'interp_posix.urandom', 'device_encoding': 'interp_posix.device_encoding', + 'get_terminal_size': 'interp_posix.get_terminal_size' } if hasattr(os, 'chown'): diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -2142,3 +2142,49 @@ have_functions.append("HAVE_%s" % name) if _WIN32: have_functions.append("HAVE_MS_WINDOWS") + +def get_terminal_size(space, w_fd=None): + if w_fd is None: + w_stdout = space.sys.getdictvalue(space, 'stdout') + fd = space.int_w(w_stdout.fileno_w(space)) + else: + if not space.isinstance_w(w_fd, space.w_int): + raise oefmt(space.w_TypeError, + "an integer is required, got %T", w_fd) + else: + fd = space.c_int_w(w_fd) + + if _WIN32: + if fd == 0: + handle_id = rwin32.STD_INPUT_HANDLE + elif fd == 1: + handle_id = rwin32.STD_OUTPUT_HANDLE + elif fd == 2: + handle_id = rwin32.STD_ERROR_HANDLE + else: + raise oefmt(space.w_ValueError, "bad file descriptor") + + handle = rwin32.GetStdHandle(handle_id) + + if handle == rwin32.NULL_HANDLE: + raise oefmt(OSError, "handle cannot be retrieved") + elif handle == rwin32.INVALID_HANDLE_VALUE: + raise rwin32.lastSavedWindowsError() + with lltype.scoped_alloc(CONSOLE_SCREEN_BUFFER_INFO) as buffer_info: + success = GetConsoleScreenBufferInfo(handle, buffer_info) + if not success: + raise rwin32.lastSavedWindowsError() + columns = buffer_info.srWindow.Right - buffer_info.srWindow.Left + 1 + lines = buffer_info.srWindow.Bottom - buffer_info.srWindow.Top + 1 + else: + # Assuming that all supported platforms will have ioctl at least + with lltype.scoped_alloc(rposix.WINSIZE) as winsize: + failed = c_ioctl_voidp(fd, rposix.TIOCGWINSZ, winsize) + if failed: + raise exception_from_saved_errno(space, space.w_OSError) + + # TODO: Wrap this into a python_lvel int (somehow) + columns = space.wrap(winsize.c_ws_col) + lines = space.wrap(winsize.c_ws_row) + + return space.newtuple([columns, lines]) diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -258,6 +258,7 @@ if not _WIN32: UID_T = rffi_platform.SimpleType('uid_t', rffi.UINT) GID_T = rffi_platform.SimpleType('gid_t', rffi.UINT) + TIOCGWINSZ = rffi_platform.DefinedConstantInteger('TIOCGWINSZ') TMS = rffi_platform.Struct( 'struct tms', [('tms_utime', rffi.INT), @@ -265,6 +266,14 @@ ('tms_cutime', rffi.INT), ('tms_cstime', rffi.INT)]) + WINSIZE = rffi_platform.Struct( + 'struct winsize', [('ws_row', rffi.USHORT), + ('ws_col', rffi.USHORT), + ('ws_xpixel', rffi.USHORT), + ('ws_ypixel', rffi.USHORT)]) + + + GETPGRP_HAVE_ARG = rffi_platform.Has("getpgrp(0)") SETPGRP_HAVE_ARG = rffi_platform.Has("setpgrp(0, 0)") diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -59,6 +59,24 @@ SYSTEMTIME = rffi_platform.Struct('SYSTEMTIME', []) + Struct = rffi_platform.Struct + COORD = Struct("COORD", + [("X", rffi.SHORT), + ("Y", rffi.SHORT)]) + + SMALL_RECT = Struct("SMALL_RECT", + [("Left", rffi.SHORT), + ("Top", rffi.SHORT), + ("Right", rffi.SHORT), + ("Bottom", rffi.SHORT)]) + + CONSOLE_SCREEN_BUFFER_INFO = Struct("CONSOLE_SCREEN_BUFFER_INFO", + [("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", WORD), + ("srWindow", SMALL_RECT), + ("dwMaximumWindowSize", COORD)]) + OSVERSIONINFOEX = rffi_platform.Struct( 'OSVERSIONINFOEX', [('dwOSVersionInfoSize', rffi.UINT), @@ -93,7 +111,8 @@ PROCESS_VM_WRITE CTRL_C_EVENT CTRL_BREAK_EVENT MB_ERR_INVALID_CHARS ERROR_NO_UNICODE_TRANSLATION - WC_NO_BEST_FIT_CHARS + WC_NO_BEST_FIT_CHARS STD_INPUT_HANDLE STD_OUTPUT_HANDLE + STD_ERROR_HANDLE """ from rpython.translator.platform import host_factory static_platform = host_factory() @@ -444,3 +463,13 @@ return rffi.cast(lltype.Signed, _GetConsoleOutputCP()) _wenviron_items, _wgetenv, _wputenv = make_env_impls(win32=True) + + + _GetStdHandle = winexternal( + 'GetStdHandle', [DWORD], HANDLE) + + def GetStdHandle(handle_id): + return _GetStdHandle(handle_id) + + _GetConsoleScreenBufferInfo = winexternal( + "GetConsoleScreenBufferInfo", [HANDLE, csbi], BOOL) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit