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

Reply via email to