[Python-checkins] bpo-25720: Fix the method for checking pad state of curses WINDOW (#4164)

Serhiy Storchaka webhook-mailer at python.org
Wed Nov 1 08:05:29 EDT 2017


https://github.com/python/cpython/commit/8bc7d63560024681dce9f40445f2877b2987e92c
commit: 8bc7d63560024681dce9f40445f2877b2987e92c
branch: master
author: Masayuki Yamamoto <ma3yuki.8mamo10 at gmail.com>
committer: Serhiy Storchaka <storchaka at gmail.com>
date: 2017-11-01T14:05:26+02:00
summary:

bpo-25720: Fix the method for checking pad state of curses WINDOW (#4164)

Modify the code to use ncurses is_pad() instead of checking WINDOW
_flags field.  If your platform does not provide the is_pad(), the
existing way that checks the field will be enabled.

Note: This change does not drop support for platforms where do not
have both WINDOW _flags field and is_pad().

files:
A Misc/NEWS.d/next/Library/2017-10-29-17-52-40.bpo-25720.vSvb5h.rst
M Include/py_curses.h
M Modules/_cursesmodule.c
M configure
M configure.ac
M pyconfig.h.in

diff --git a/Include/py_curses.h b/Include/py_curses.h
index 2e88112259a..597f419eaca 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -10,11 +10,6 @@
 #ifdef _BSD_WCHAR_T_DEFINED_
 #define _WCHAR_T
 #endif
-
-/* the following define is necessary for OS X 10.6; without it, the
-   Apple-supplied ncurses.h sets NCURSES_OPAQUE to 1, and then Python
-   can't get at the WINDOW flags field. */
-#define NCURSES_OPAQUE 0
 #endif /* __APPLE__ */
 
 #ifdef __FreeBSD__
@@ -44,6 +39,13 @@
 #endif
 #endif
 
+#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS)
+/* The following definition is necessary for ncurses 5.7; without it,
+   some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python
+   can't get at the WINDOW flags field. */
+#define NCURSES_OPAQUE 0
+#endif
+
 #ifdef HAVE_NCURSES_H
 #include <ncurses.h>
 #else
@@ -52,10 +54,13 @@
 
 #ifdef HAVE_NCURSES_H
 /* configure was checking <curses.h>, but we will
-   use <ncurses.h>, which has all these features. */
-#ifndef WINDOW_HAS_FLAGS
+   use <ncurses.h>, which has some or all these features. */
+#if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0)
 #define WINDOW_HAS_FLAGS 1
 #endif
+#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906
+#define HAVE_CURSES_IS_PAD 1
+#endif
 #ifndef MVWDELCH_IS_EXPRESSION
 #define MVWDELCH_IS_EXPRESSION 1
 #endif
diff --git a/Misc/NEWS.d/next/Library/2017-10-29-17-52-40.bpo-25720.vSvb5h.rst b/Misc/NEWS.d/next/Library/2017-10-29-17-52-40.bpo-25720.vSvb5h.rst
new file mode 100644
index 00000000000..a405cd4b544
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-10-29-17-52-40.bpo-25720.vSvb5h.rst
@@ -0,0 +1,2 @@
+Fix the method for checking pad state of curses WINDOW. Patch by Masayuki
+Yamamoto.
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index d30bd1ab20f..2a2eed2c487 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -934,6 +934,12 @@ int py_mvwdelch(WINDOW *w, int y, int x)
 }
 #endif
 
+#if defined(HAVE_CURSES_IS_PAD)
+#define py_is_pad(win)      is_pad(win)
+#elif defined(WINDOW_HAS_FLAGS)
+#define py_is_pad(win)      ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
+#endif
+
 /* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
 
 static PyObject *
@@ -1073,10 +1079,11 @@ PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
     if (!PyCurses_ConvertToChtype(self, temp, &ch))
         return NULL;
 
-#ifdef WINDOW_HAS_FLAGS
-    if (self->win->_flags & _ISPAD)
+#ifdef py_is_pad
+    if (py_is_pad(self->win)) {
         return PyCursesCheckERR(pechochar(self->win, ch | attr),
                                 "echochar");
+    }
     else
 #endif
         return PyCursesCheckERR(wechochar(self->win, ch | attr),
@@ -1603,10 +1610,10 @@ PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
     int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
     int rtn;
 
-#ifndef WINDOW_HAS_FLAGS
+#ifndef py_is_pad
     if (0)
 #else
-        if (self->win->_flags & _ISPAD)
+        if (py_is_pad(self->win))
 #endif
         {
             switch(PyTuple_Size(args)) {
@@ -1766,10 +1773,10 @@ PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
     int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
     int rtn;
 
-#ifndef WINDOW_HAS_FLAGS
+#ifndef py_is_pad
     if (0)
 #else
-        if (self->win->_flags & _ISPAD)
+        if (py_is_pad(self->win))
 #endif
         {
             switch(PyTuple_Size(args)) {
@@ -1835,9 +1842,10 @@ PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
     }
 
     /* printf("Subwin: %i %i %i %i   \n", nlines, ncols, begin_y, begin_x); */
-#ifdef WINDOW_HAS_FLAGS
-    if (self->win->_flags & _ISPAD)
+#ifdef py_is_pad
+    if (py_is_pad(self->win)) {
         win = subpad(self->win, nlines, ncols, begin_y, begin_x);
+    }
     else
 #endif
         win = subwin(self->win, nlines, ncols, begin_y, begin_x);
diff --git a/configure b/configure
index bb7cc51407a..00cfd64a2bd 100755
--- a/configure
+++ b/configure
@@ -15699,6 +15699,10 @@ $as_echo "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h
 
 fi
 
+# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
+# structs since version 5.7.  If the macro is defined as zero before including
+# [n]curses.h, ncurses will expose fields of the structs regardless of the
+# configuration.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5
 $as_echo_n "checking whether WINDOW has _flags... " >&6; }
 if ${ac_cv_window_has_flags+:} false; then :
@@ -15706,7 +15710,10 @@ if ${ac_cv_window_has_flags+:} false; then :
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <curses.h>
+
+  #define NCURSES_OPAQUE 0
+  #include <curses.h>
+
 int
 main ()
 {
@@ -15737,6 +15744,36 @@ $as_echo "#define WINDOW_HAS_FLAGS 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_pad" >&5
+$as_echo_n "checking for is_pad... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef is_pad
+void *x=is_pad
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_IS_PAD 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_term_resized" >&5
 $as_echo_n "checking for is_term_resized... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
diff --git a/configure.ac b/configure.ac
index 8c687d731d5..724f7ce64c4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4955,9 +4955,16 @@ then
   [Define if mvwdelch in curses.h is an expression.])
 fi
 
+# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
+# structs since version 5.7.  If the macro is defined as zero before including
+# [n]curses.h, ncurses will expose fields of the structs regardless of the
+# configuration.
 AC_MSG_CHECKING(whether WINDOW has _flags)
 AC_CACHE_VAL(ac_cv_window_has_flags,
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+  #define NCURSES_OPAQUE 0
+  #include <curses.h>
+]], [[
   WINDOW *w;
   w->_flags = 0;
 ]])],
@@ -4972,6 +4979,17 @@ then
   [Define if WINDOW in curses.h offers a field _flags.])
 fi
 
+AC_MSG_CHECKING(for is_pad)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef is_pad
+void *x=is_pad
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_IS_PAD, 1, Define if you have the 'is_pad' function or macro.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
 AC_MSG_CHECKING(for is_term_resized)
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[void *x=is_term_resized]])],
   [AC_DEFINE(HAVE_CURSES_IS_TERM_RESIZED, 1, Define if you have the 'is_term_resized' function.)
diff --git a/pyconfig.h.in b/pyconfig.h.in
index afd161c15f0..f63022449f3 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -158,6 +158,9 @@
 /* Define if you have the 'immedok' function. */
 #undef HAVE_CURSES_IMMEDOK
 
+/* Define if you have the 'is_pad' function or macro. */
+#undef HAVE_CURSES_IS_PAD
+
 /* Define if you have the 'is_term_resized' function. */
 #undef HAVE_CURSES_IS_TERM_RESIZED
 



More information about the Python-checkins mailing list