]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-154055: Gate optional curses functions absent on old SVr4 curses (GH-154057)
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 19 Jul 2026 12:26:47 +0000 (15:26 +0300)
committerGitHub <noreply@github.com>
Sun, 19 Jul 2026 12:26:47 +0000 (15:26 +0300)
Build hygiene so the curses modules build against a limited curses (e.g. the
native SVr4 curses of illumos/Solaris), matching how other optional functions
are already gated:

* Probe and #ifdef-gate the X/Open attr_t functions (window.attr_get/attr_set/
  attr_on/attr_off/color_set), the soft-label attribute functions
  (slk_attr_on/off/set, slk_color) and scr_set(); scr_set is probed separately
  from the scr_dump family, which SVr4 has without it.
* Stop gating update_lines_cols() on resizeterm(): it only reads LINES/COLS and
  is used unconditionally (e.g. by set_term()), so a build without resizeterm()
  failed to link.
* On Solaris/illumos define _BOOL (and include <stdbool.h>) so the SVr4
  <curses.h> "typedef char bool" does not clash with C's bool.

test.test_curses: skip or guard the tests that use the now-optional functions,
split test_attributes so its chtype-based part still runs, and treat the native
curses of NetBSD and illumos/Solaris as having broken newterm() (they crash on
repeated newterm()/delscreen(), like ncurses before 6.5).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Include/py_curses.h
Lib/test/test_curses.py
Misc/NEWS.d/next/Build/2026-07-19-07-48-43.gh-issue-154055.FemUJU.rst [new file with mode: 0644]
Modules/_cursesmodule.c
Modules/clinic/_cursesmodule.c.h
configure
configure.ac
pyconfig.h.in

index a5f5f3d76075827b360187ad5b2ed815fc6f3373..85a540086c8384496cb465278dace3090bd63852 100644 (file)
 #  define PDC_NCMOUSE
 #endif
 
+/* On Solaris/illumos, the SVr4 <curses.h> does "typedef char bool;", which
+   clashes with C's bool from <stdbool.h>.  Define _BOOL to suppress it, and
+   include <stdbool.h> for the bool the header then needs.  ncurses ignores
+   _BOOL. */
+#if defined(__sun) && !defined(_BOOL)
+#  include <stdbool.h>
+#  define _BOOL
+#endif
+
 #if defined(HAVE_NCURSESW_NCURSES_H)
 #  include <ncursesw/ncurses.h>
 #elif defined(HAVE_NCURSESW_CURSES_H)
index b0592d3f1d92b956bdc4207ee84759e85b6a9191..4ca5dd73f55afee78c8411a4de18976f2030362f 100644 (file)
@@ -84,10 +84,15 @@ def requires_colors(test):
 term = os.environ.get('TERM')
 SHORT_MAX = 0x7fff
 
-# ncurses before 6.5 can crash on repeated newterm().  Fall back to initscr()
-# and skip the tests that need several screens.
+# ncurses before 6.5, and the native curses of NetBSD and illumos/Solaris,
+# crash on repeated newterm()/delscreen(); fall back to initscr() and skip the
+# multi-screen tests.  The native ones are keyed off the platform so a fixed
+# version can be excluded later.
 _ncurses_version = getattr(curses, 'ncurses_version', None)
-BROKEN_NEWTERM = _ncurses_version is not None and _ncurses_version < (6, 5)
+if _ncurses_version is not None:
+    BROKEN_NEWTERM = _ncurses_version < (6, 5)
+else:
+    BROKEN_NEWTERM = sys.platform.startswith(('netbsd', 'sunos'))
 USE_NEWTERM = hasattr(curses, 'newterm') and not BROKEN_NEWTERM
 
 # Older macOS reports a variation selector as a spacing character (wcwidth()
@@ -1140,8 +1145,17 @@ class TestCurses(unittest.TestCase):
         win.standout()
         win.standend()
 
+        # attron()/attroff()/attrset() reject a bad attribute.
+        self.assertRaises(OverflowError, win.attron, 1 << 64)
+        self.assertRaises(OverflowError, win.attroff, -1)
+        self.assertRaises(OverflowError, win.attrset, 1 << 64)
+        self.assertRaises(TypeError, win.attron, 'x')
+
+    @requires_curses_window_meth('attr_set')
+    def test_attr(self):
         # The attr_*() family works on attr_t attributes paired with a color
         # pair, unlike the chtype-based attron()/attroff()/attrset().
+        win = curses.newwin(5, 15, 5, 2)
         win.attr_set(curses.A_BOLD | curses.A_UNDERLINE)
         attrs, pair = win.attr_get()
         self.assertTrue(attrs & curses.A_BOLD)
@@ -1167,13 +1181,9 @@ class TestCurses(unittest.TestCase):
         self.assertRaises(OverflowError, win.attr_set, -1)
         self.assertRaises(OverflowError, win.attr_on, -1)
         self.assertRaises(OverflowError, win.attr_set, 1 << 64)
-        # attron()/attroff()/attrset() reject a bad attribute too.
-        self.assertRaises(OverflowError, win.attron, 1 << 64)
-        self.assertRaises(OverflowError, win.attroff, -1)
-        self.assertRaises(OverflowError, win.attrset, 1 << 64)
-        self.assertRaises(TypeError, win.attron, 'x')
 
     @requires_colors
+    @requires_curses_window_meth('attr_set')
     def test_attr_color_pair(self):
         win = curses.newwin(5, 15, 5, 2)
         curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
@@ -1383,8 +1393,10 @@ class TestCurses(unittest.TestCase):
             stdscr.refresh()
             self.assertIsNone(curses.scr_restore(dump))
             # scr_init() and scr_set() also accept a dump file and return None.
+            # scr_set() is not available on every curses (e.g. old SVr4).
             self.assertIsNone(curses.scr_init(dump))
-            self.assertIsNone(curses.scr_set(dump))
+            if hasattr(curses, 'scr_set'):
+                self.assertIsNone(curses.scr_set(dump))
             # A bytes (path-like) filename is accepted too.
             curses.scr_dump(os.fsencode(dump))
             # Restoring from a missing file is an error.
@@ -1846,9 +1858,11 @@ class TestCurses(unittest.TestCase):
     def test_tabsize(self):
         tabsize = curses.get_tabsize()
         self.assertIsInstance(tabsize, int)
-        curses.set_tabsize(4)
-        self.assertEqual(curses.get_tabsize(), 4)
-        curses.set_tabsize(tabsize)
+        # set_tabsize() is not available on every curses (e.g. old SVr4).
+        if hasattr(curses, 'set_tabsize'):
+            curses.set_tabsize(4)
+            self.assertEqual(curses.get_tabsize(), 4)
+            curses.set_tabsize(tabsize)
 
     @requires_curses_func('getsyx')
     def test_getsyx(self):
diff --git a/Misc/NEWS.d/next/Build/2026-07-19-07-48-43.gh-issue-154055.FemUJU.rst b/Misc/NEWS.d/next/Build/2026-07-19-07-48-43.gh-issue-154055.FemUJU.rst
new file mode 100644 (file)
index 0000000..94fc967
--- /dev/null
@@ -0,0 +1,4 @@
+The :mod:`curses` and :mod:`curses.panel` modules can now be built against a
+curses library that lacks the X/Open ``attr_t`` and soft-label attribute
+functions, ``scr_set()`` or ``resizeterm()`` -- such as the native SVr4 curses
+of illumos and Solaris.  These functions are probed and used only when present.
index 2253d9ff3d704f392464c5ede87b235208892c3b..6df593001b8a1cb9af9c9f51afd7539f05863364 100644 (file)
@@ -2433,6 +2433,7 @@ _curses_window_attrset_impl(PyCursesWindowObject *self, attr_t attr)
     return curses_window_check_err(self, rtn, "wattrset", "attrset");
 }
 
+#ifdef HAVE_CURSES_WATTR_GET
 /*[clinic input]
 _curses.window.attr_get
 
@@ -2458,7 +2459,9 @@ _curses_window_attr_get_impl(PyCursesWindowObject *self)
     }
     return Py_BuildValue("(ki)", (unsigned long)attrs, (int)pair);
 }
+#endif /* HAVE_CURSES_WATTR_GET */
 
+#ifdef HAVE_CURSES_WATTR_SET
 /*[clinic input]
 _curses.window.attr_set
 
@@ -2482,7 +2485,9 @@ _curses_window_attr_set_impl(PyCursesWindowObject *self, attr_t attr,
 #endif
     return curses_window_check_err(self, rtn, "wattr_set", "attr_set");
 }
+#endif /* HAVE_CURSES_WATTR_SET */
 
+#ifdef HAVE_CURSES_WATTR_ON
 /*[clinic input]
 _curses.window.attr_on
 
@@ -2499,7 +2504,9 @@ _curses_window_attr_on_impl(PyCursesWindowObject *self, attr_t attr)
     int rtn = wattr_on(self->win, attr, NULL);
     return curses_window_check_err(self, rtn, "wattr_on", "attr_on");
 }
+#endif /* HAVE_CURSES_WATTR_ON */
 
+#ifdef HAVE_CURSES_WATTR_OFF
 /*[clinic input]
 _curses.window.attr_off
 
@@ -2516,7 +2523,9 @@ _curses_window_attr_off_impl(PyCursesWindowObject *self, attr_t attr)
     int rtn = wattr_off(self->win, attr, NULL);
     return curses_window_check_err(self, rtn, "wattr_off", "attr_off");
 }
+#endif /* HAVE_CURSES_WATTR_OFF */
 
+#ifdef HAVE_CURSES_WCOLOR_SET
 /*[clinic input]
 _curses.window.color_set
 
@@ -2538,6 +2547,7 @@ _curses_window_color_set_impl(PyCursesWindowObject *self, int pair)
 #endif
     return curses_window_check_err(self, rtn, "wcolor_set", "color_set");
 }
+#endif /* HAVE_CURSES_WCOLOR_SET */
 
 /*[clinic input]
 _curses.window.getattrs
@@ -6083,6 +6093,7 @@ _curses_scr_init(PyObject *module, PyObject *filename)
 /*[clinic end generated code: output=2e861d381d710419 input=81c45e4702124ef6]*/
 ScreenDumpFunctionBody(scr_init)
 
+#ifdef HAVE_CURSES_SCR_SET
 /*[clinic input]
 _curses.scr_set
 
@@ -6099,6 +6110,7 @@ static PyObject *
 _curses_scr_set(PyObject *module, PyObject *filename)
 /*[clinic end generated code: output=6056fdec12c5935f input=d248c20543cc289b]*/
 ScreenDumpFunctionBody(scr_set)
+#endif /* HAVE_CURSES_SCR_SET */
 #endif /* HAVE_CURSES_SCR_DUMP */
 
 /*[clinic input]
@@ -7462,9 +7474,10 @@ _curses_qiflush_impl(PyObject *module, int flag)
     Py_RETURN_NONE;
 }
 
-#if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)
 /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES
- * and _curses.COLS. Returns 1 on success and 0 on failure. */
+ * and _curses.COLS. Returns 1 on success and 0 on failure.  Used
+ * unconditionally (e.g. by set_term()), so it must not be gated on resizeterm().
+ */
 static int
 update_lines_cols(PyObject *private_module)
 {
@@ -7533,8 +7546,6 @@ _curses_update_lines_cols_impl(PyObject *module)
     Py_RETURN_NONE;
 }
 
-#endif
-
 /*[clinic input]
 _curses.raw
 
@@ -8371,6 +8382,7 @@ _curses_slk_attr_impl(PyObject *module)
 }
 #endif
 
+#ifdef HAVE_CURSES_SLK_ATTR_ON
 /*[clinic input]
 _curses.slk_attr_on
 
@@ -8388,7 +8400,9 @@ _curses_slk_attr_on_impl(PyObject *module, attr_t attr)
     return curses_check_err(module, slk_attr_on(attr, NULL),
                             "slk_attr_on", NULL);
 }
+#endif /* HAVE_CURSES_SLK_ATTR_ON */
 
+#ifdef HAVE_CURSES_SLK_ATTR_OFF
 /*[clinic input]
 _curses.slk_attr_off
 
@@ -8406,7 +8420,9 @@ _curses_slk_attr_off_impl(PyObject *module, attr_t attr)
     return curses_check_err(module, slk_attr_off(attr, NULL),
                             "slk_attr_off", NULL);
 }
+#endif /* HAVE_CURSES_SLK_ATTR_OFF */
 
+#ifdef HAVE_CURSES_SLK_ATTR_SET
 /*[clinic input]
 _curses.slk_attr_set
 
@@ -8430,7 +8446,9 @@ _curses_slk_attr_set_impl(PyObject *module, attr_t attr, int pair)
 #endif
     return curses_check_err(module, rtn, "slk_attr_set", NULL);
 }
+#endif /* HAVE_CURSES_SLK_ATTR_SET */
 
+#ifdef HAVE_CURSES_SLK_COLOR
 /*[clinic input]
 _curses.slk_color
 
@@ -8447,6 +8465,7 @@ _curses_slk_color_impl(PyObject *module, int pair)
     PyCursesStatefulInitialised(module);
     return curses_check_err(module, slk_color((short)pair), "slk_color", NULL);
 }
+#endif /* HAVE_CURSES_SLK_COLOR */
 
 #ifdef HAVE_CURSES_USE_ENV
 /*[clinic input]
index da1b97c0ea5ad8bb26af661dd433c1c751474159..70d99b4bf351a21aa22905c924eaee4366e625fc 100644 (file)
@@ -534,6 +534,8 @@ exit:
     return return_value;
 }
 
+#if defined(HAVE_CURSES_WATTR_GET)
+
 PyDoc_STRVAR(_curses_window_attr_get__doc__,
 "attr_get($self, /)\n"
 "--\n"
@@ -552,6 +554,10 @@ _curses_window_attr_get(PyObject *self, PyObject *Py_UNUSED(ignored))
     return _curses_window_attr_get_impl((PyCursesWindowObject *)self);
 }
 
+#endif /* defined(HAVE_CURSES_WATTR_GET) */
+
+#if defined(HAVE_CURSES_WATTR_SET)
+
 PyDoc_STRVAR(_curses_window_attr_set__doc__,
 "attr_set($self, attr, pair=0, /)\n"
 "--\n"
@@ -591,6 +597,10 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_WATTR_SET) */
+
+#if defined(HAVE_CURSES_WATTR_ON)
+
 PyDoc_STRVAR(_curses_window_attr_on__doc__,
 "attr_on($self, attr, /)\n"
 "--\n"
@@ -618,6 +628,10 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_WATTR_ON) */
+
+#if defined(HAVE_CURSES_WATTR_OFF)
+
 PyDoc_STRVAR(_curses_window_attr_off__doc__,
 "attr_off($self, attr, /)\n"
 "--\n"
@@ -645,6 +659,10 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_WATTR_OFF) */
+
+#if defined(HAVE_CURSES_WCOLOR_SET)
+
 PyDoc_STRVAR(_curses_window_color_set__doc__,
 "color_set($self, pair, /)\n"
 "--\n"
@@ -672,6 +690,8 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_WCOLOR_SET) */
+
 PyDoc_STRVAR(_curses_window_getattrs__doc__,
 "getattrs($self, /)\n"
 "--\n"
@@ -3104,7 +3124,7 @@ PyDoc_STRVAR(_curses_scr_init__doc__,
 
 #endif /* defined(HAVE_CURSES_SCR_DUMP) */
 
-#if defined(HAVE_CURSES_SCR_DUMP)
+#if defined(HAVE_CURSES_SCR_DUMP) && defined(HAVE_CURSES_SCR_SET)
 
 PyDoc_STRVAR(_curses_scr_set__doc__,
 "scr_set($module, filename, /)\n"
@@ -3120,7 +3140,7 @@ PyDoc_STRVAR(_curses_scr_set__doc__,
 #define _CURSES_SCR_SET_METHODDEF    \
     {"scr_set", (PyCFunction)_curses_scr_set, METH_O, _curses_scr_set__doc__},
 
-#endif /* defined(HAVE_CURSES_SCR_DUMP) */
+#endif /* defined(HAVE_CURSES_SCR_DUMP) && defined(HAVE_CURSES_SCR_SET) */
 
 PyDoc_STRVAR(_curses_halfdelay__doc__,
 "halfdelay($module, tenths, /)\n"
@@ -4752,8 +4772,6 @@ exit:
     return return_value;
 }
 
-#if (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM))
-
 PyDoc_STRVAR(_curses_update_lines_cols__doc__,
 "update_lines_cols($module, /)\n"
 "--\n"
@@ -4774,8 +4792,6 @@ _curses_update_lines_cols(PyObject *module, PyObject *Py_UNUSED(ignored))
     return _curses_update_lines_cols_impl(module);
 }
 
-#endif /* (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) */
-
 PyDoc_STRVAR(_curses_raw__doc__,
 "raw($module, flag=True, /)\n"
 "--\n"
@@ -5755,6 +5771,8 @@ _curses_slk_attr(PyObject *module, PyObject *Py_UNUSED(ignored))
 
 #endif /* (defined(NCURSES_EXT_FUNCS) || defined(PDCURSES)) */
 
+#if defined(HAVE_CURSES_SLK_ATTR_ON)
+
 PyDoc_STRVAR(_curses_slk_attr_on__doc__,
 "slk_attr_on($module, attr, /)\n"
 "--\n"
@@ -5782,6 +5800,10 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_SLK_ATTR_ON) */
+
+#if defined(HAVE_CURSES_SLK_ATTR_OFF)
+
 PyDoc_STRVAR(_curses_slk_attr_off__doc__,
 "slk_attr_off($module, attr, /)\n"
 "--\n"
@@ -5809,6 +5831,10 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_SLK_ATTR_OFF) */
+
+#if defined(HAVE_CURSES_SLK_ATTR_SET)
+
 PyDoc_STRVAR(_curses_slk_attr_set__doc__,
 "slk_attr_set($module, attr, pair=0, /)\n"
 "--\n"
@@ -5847,6 +5873,10 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_SLK_ATTR_SET) */
+
+#if defined(HAVE_CURSES_SLK_COLOR)
+
 PyDoc_STRVAR(_curses_slk_color__doc__,
 "slk_color($module, pair, /)\n"
 "--\n"
@@ -5874,6 +5904,8 @@ exit:
     return return_value;
 }
 
+#endif /* defined(HAVE_CURSES_SLK_COLOR) */
+
 #if defined(HAVE_CURSES_USE_ENV)
 
 PyDoc_STRVAR(_curses_use_env__doc__,
@@ -6003,6 +6035,26 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
     return _curses_has_extended_color_support_impl(module);
 }
 
+#ifndef _CURSES_WINDOW_ATTR_GET_METHODDEF
+    #define _CURSES_WINDOW_ATTR_GET_METHODDEF
+#endif /* !defined(_CURSES_WINDOW_ATTR_GET_METHODDEF) */
+
+#ifndef _CURSES_WINDOW_ATTR_SET_METHODDEF
+    #define _CURSES_WINDOW_ATTR_SET_METHODDEF
+#endif /* !defined(_CURSES_WINDOW_ATTR_SET_METHODDEF) */
+
+#ifndef _CURSES_WINDOW_ATTR_ON_METHODDEF
+    #define _CURSES_WINDOW_ATTR_ON_METHODDEF
+#endif /* !defined(_CURSES_WINDOW_ATTR_ON_METHODDEF) */
+
+#ifndef _CURSES_WINDOW_ATTR_OFF_METHODDEF
+    #define _CURSES_WINDOW_ATTR_OFF_METHODDEF
+#endif /* !defined(_CURSES_WINDOW_ATTR_OFF_METHODDEF) */
+
+#ifndef _CURSES_WINDOW_COLOR_SET_METHODDEF
+    #define _CURSES_WINDOW_COLOR_SET_METHODDEF
+#endif /* !defined(_CURSES_WINDOW_COLOR_SET_METHODDEF) */
+
 #ifndef _CURSES_WINDOW_ENCLOSE_METHODDEF
     #define _CURSES_WINDOW_ENCLOSE_METHODDEF
 #endif /* !defined(_CURSES_WINDOW_ENCLOSE_METHODDEF) */
@@ -6135,10 +6187,6 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
     #define _CURSES_MOUSEMASK_METHODDEF
 #endif /* !defined(_CURSES_MOUSEMASK_METHODDEF) */
 
-#ifndef _CURSES_UPDATE_LINES_COLS_METHODDEF
-    #define _CURSES_UPDATE_LINES_COLS_METHODDEF
-#endif /* !defined(_CURSES_UPDATE_LINES_COLS_METHODDEF) */
-
 #ifndef _CURSES_RESIZETERM_METHODDEF
     #define _CURSES_RESIZETERM_METHODDEF
 #endif /* !defined(_CURSES_RESIZETERM_METHODDEF) */
@@ -6163,6 +6211,22 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
     #define _CURSES_SLK_ATTR_METHODDEF
 #endif /* !defined(_CURSES_SLK_ATTR_METHODDEF) */
 
+#ifndef _CURSES_SLK_ATTR_ON_METHODDEF
+    #define _CURSES_SLK_ATTR_ON_METHODDEF
+#endif /* !defined(_CURSES_SLK_ATTR_ON_METHODDEF) */
+
+#ifndef _CURSES_SLK_ATTR_OFF_METHODDEF
+    #define _CURSES_SLK_ATTR_OFF_METHODDEF
+#endif /* !defined(_CURSES_SLK_ATTR_OFF_METHODDEF) */
+
+#ifndef _CURSES_SLK_ATTR_SET_METHODDEF
+    #define _CURSES_SLK_ATTR_SET_METHODDEF
+#endif /* !defined(_CURSES_SLK_ATTR_SET_METHODDEF) */
+
+#ifndef _CURSES_SLK_COLOR_METHODDEF
+    #define _CURSES_SLK_COLOR_METHODDEF
+#endif /* !defined(_CURSES_SLK_COLOR_METHODDEF) */
+
 #ifndef _CURSES_USE_ENV_METHODDEF
     #define _CURSES_USE_ENV_METHODDEF
 #endif /* !defined(_CURSES_USE_ENV_METHODDEF) */
@@ -6174,4 +6238,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
 #ifndef _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
     #define _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
 #endif /* !defined(_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=36fcacafc5044720 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=ae1359964feefd64 input=a9049054013a1b77]*/
index 9061cf905119c444f24b3f302fd74c065b1a7ff8..0fc2b0e819a120953b63054c0e635eca26e3f355 100755 (executable)
--- a/configure
+++ b/configure
 
 
 
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_get" >&5
+printf %s "checking for curses function wattr_get... " >&6; }
+if test ${ac_cv_lib_curses_wattr_get+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef wattr_get
+        void *x=wattr_get
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_wattr_get=yes
+else case e in #(
+  e) ac_cv_lib_curses_wattr_get=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_get" >&5
+printf "%s\n" "$ac_cv_lib_curses_wattr_get" >&6; }
+  if test "x$ac_cv_lib_curses_wattr_get" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_WATTR_GET 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_set" >&5
+printf %s "checking for curses function wattr_set... " >&6; }
+if test ${ac_cv_lib_curses_wattr_set+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef wattr_set
+        void *x=wattr_set
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_wattr_set=yes
+else case e in #(
+  e) ac_cv_lib_curses_wattr_set=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_set" >&5
+printf "%s\n" "$ac_cv_lib_curses_wattr_set" >&6; }
+  if test "x$ac_cv_lib_curses_wattr_set" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_WATTR_SET 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_on" >&5
+printf %s "checking for curses function wattr_on... " >&6; }
+if test ${ac_cv_lib_curses_wattr_on+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef wattr_on
+        void *x=wattr_on
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_wattr_on=yes
+else case e in #(
+  e) ac_cv_lib_curses_wattr_on=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_on" >&5
+printf "%s\n" "$ac_cv_lib_curses_wattr_on" >&6; }
+  if test "x$ac_cv_lib_curses_wattr_on" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_WATTR_ON 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_off" >&5
+printf %s "checking for curses function wattr_off... " >&6; }
+if test ${ac_cv_lib_curses_wattr_off+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef wattr_off
+        void *x=wattr_off
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_wattr_off=yes
+else case e in #(
+  e) ac_cv_lib_curses_wattr_off=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_off" >&5
+printf "%s\n" "$ac_cv_lib_curses_wattr_off" >&6; }
+  if test "x$ac_cv_lib_curses_wattr_off" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_WATTR_OFF 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wcolor_set" >&5
+printf %s "checking for curses function wcolor_set... " >&6; }
+if test ${ac_cv_lib_curses_wcolor_set+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef wcolor_set
+        void *x=wcolor_set
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_wcolor_set=yes
+else case e in #(
+  e) ac_cv_lib_curses_wcolor_set=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wcolor_set" >&5
+printf "%s\n" "$ac_cv_lib_curses_wcolor_set" >&6; }
+  if test "x$ac_cv_lib_curses_wcolor_set" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_WCOLOR_SET 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_attr_on" >&5
+printf %s "checking for curses function slk_attr_on... " >&6; }
+if test ${ac_cv_lib_curses_slk_attr_on+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef slk_attr_on
+        void *x=slk_attr_on
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_slk_attr_on=yes
+else case e in #(
+  e) ac_cv_lib_curses_slk_attr_on=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_attr_on" >&5
+printf "%s\n" "$ac_cv_lib_curses_slk_attr_on" >&6; }
+  if test "x$ac_cv_lib_curses_slk_attr_on" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_SLK_ATTR_ON 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_attr_off" >&5
+printf %s "checking for curses function slk_attr_off... " >&6; }
+if test ${ac_cv_lib_curses_slk_attr_off+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef slk_attr_off
+        void *x=slk_attr_off
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_slk_attr_off=yes
+else case e in #(
+  e) ac_cv_lib_curses_slk_attr_off=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_attr_off" >&5
+printf "%s\n" "$ac_cv_lib_curses_slk_attr_off" >&6; }
+  if test "x$ac_cv_lib_curses_slk_attr_off" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_SLK_ATTR_OFF 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_attr_set" >&5
+printf %s "checking for curses function slk_attr_set... " >&6; }
+if test ${ac_cv_lib_curses_slk_attr_set+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef slk_attr_set
+        void *x=slk_attr_set
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_slk_attr_set=yes
+else case e in #(
+  e) ac_cv_lib_curses_slk_attr_set=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_attr_set" >&5
+printf "%s\n" "$ac_cv_lib_curses_slk_attr_set" >&6; }
+  if test "x$ac_cv_lib_curses_slk_attr_set" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_SLK_ATTR_SET 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_color" >&5
+printf %s "checking for curses function slk_color... " >&6; }
+if test ${ac_cv_lib_curses_slk_color+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef slk_color
+        void *x=slk_color
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_slk_color=yes
+else case e in #(
+  e) ac_cv_lib_curses_slk_color=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_color" >&5
+printf "%s\n" "$ac_cv_lib_curses_slk_color" >&6; }
+  if test "x$ac_cv_lib_curses_slk_color" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_SLK_COLOR 1" >>confdefs.h
+
+fi
+
+
+
+
+
   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses variable ESCDELAY" >&5
 printf %s "checking for curses variable ESCDELAY... " >&6; }
 if test ${ac_cv_lib_curses_ESCDELAY+y}
 
 
 
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function scr_set" >&5
+printf %s "checking for curses function scr_set... " >&6; }
+if test ${ac_cv_lib_curses_scr_set+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef scr_set
+        void *x=scr_set
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_scr_set=yes
+else case e in #(
+  e) ac_cv_lib_curses_scr_set=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_scr_set" >&5
+printf "%s\n" "$ac_cv_lib_curses_scr_set" >&6; }
+  if test "x$ac_cv_lib_curses_scr_set" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_SCR_SET 1" >>confdefs.h
+
+fi
+
+
+
 CPPFLAGS=$ac_save_cppflags
 
 fi
index 97d2091dbf89a706a6a33c226644721b8304d44d..980ed2af50b13f7093c594d2b0d71750ed75a37e 100644 (file)
@@ -7345,6 +7345,17 @@ PY_CHECK_CURSES_FUNC([define_key])
 PY_CHECK_CURSES_FUNC([keyok])
 PY_CHECK_CURSES_FUNC([set_escdelay])
 PY_CHECK_CURSES_FUNC([set_tabsize])
+dnl The X/Open attr_t and soft-label attribute functions are absent on old
+dnl SVr4 curses (e.g. illumos).
+PY_CHECK_CURSES_FUNC([wattr_get])
+PY_CHECK_CURSES_FUNC([wattr_set])
+PY_CHECK_CURSES_FUNC([wattr_on])
+PY_CHECK_CURSES_FUNC([wattr_off])
+PY_CHECK_CURSES_FUNC([wcolor_set])
+PY_CHECK_CURSES_FUNC([slk_attr_on])
+PY_CHECK_CURSES_FUNC([slk_attr_off])
+PY_CHECK_CURSES_FUNC([slk_attr_set])
+PY_CHECK_CURSES_FUNC([slk_color])
 PY_CHECK_CURSES_VAR([ESCDELAY])
 PY_CHECK_CURSES_VAR([TABSIZE])
 
@@ -7360,9 +7371,10 @@ AS_VAR_IF([ac_cv_lib_curses_getmouse], [yes],
   [AC_DEFINE([HAVE_CURSES_GETMOUSE], [1],
     [Define if you have the 'getmouse' function with the X/Open signature.])])
 
-dnl scr_dump and its companions scr_restore/scr_init/scr_set are an inseparable
-dnl group; probing scr_dump alone gates the whole family.
+dnl scr_dump gates scr_dump/scr_restore/scr_init; scr_set is separate, since
+dnl old SVr4 curses (e.g. illumos) has the former but not scr_set.
 PY_CHECK_CURSES_FUNC([scr_dump])
+PY_CHECK_CURSES_FUNC([scr_set])
 CPPFLAGS=$ac_save_cppflags
 ])dnl have_curses != no
 ])dnl save env
index 2f9b2140d9f191acad0213b5e36bc022278e6548..e259eda7439761e400471dababa08cb1cff4e025 100644 (file)
 /* Define if you have the 'scr_dump' function. */
 #undef HAVE_CURSES_SCR_DUMP
 
+/* Define if you have the 'scr_set' function. */
+#undef HAVE_CURSES_SCR_SET
+
 /* Define if you have the 'set_escdelay' function. */
 #undef HAVE_CURSES_SET_ESCDELAY
 
 /* Define if you have the 'set_tabsize' function. */
 #undef HAVE_CURSES_SET_TABSIZE
 
+/* Define if you have the 'slk_attr_off' function. */
+#undef HAVE_CURSES_SLK_ATTR_OFF
+
+/* Define if you have the 'slk_attr_on' function. */
+#undef HAVE_CURSES_SLK_ATTR_ON
+
+/* Define if you have the 'slk_attr_set' function. */
+#undef HAVE_CURSES_SLK_ATTR_SET
+
+/* Define if you have the 'slk_color' function. */
+#undef HAVE_CURSES_SLK_COLOR
+
 /* Define if you have the 'syncok' function. */
 #undef HAVE_CURSES_SYNCOK
 
 /* Define if you have the 'use_window' function. */
 #undef HAVE_CURSES_USE_WINDOW
 
+/* Define if you have the 'wattr_get' function. */
+#undef HAVE_CURSES_WATTR_GET
+
+/* Define if you have the 'wattr_off' function. */
+#undef HAVE_CURSES_WATTR_OFF
+
+/* Define if you have the 'wattr_on' function. */
+#undef HAVE_CURSES_WATTR_ON
+
+/* Define if you have the 'wattr_set' function. */
+#undef HAVE_CURSES_WATTR_SET
+
 /* Define if you have the 'wchgat' function. */
 #undef HAVE_CURSES_WCHGAT
 
+/* Define if you have the 'wcolor_set' function. */
+#undef HAVE_CURSES_WCOLOR_SET
+
 /* Define to 1 if you have the <db.h> header file. */
 #undef HAVE_DB_H