diff --git a/Misc/NEWS.d/next/Build/2026-07-19-12-16-31.gh-issue-154070.f5da07.rst b/Misc/NEWS.d/next/Build/2026-07-19-12-16-31.gh-issue-154070.f5da07.rst new file mode 100644 index 000000000000000..31c6fd3ece35322 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-07-19-12-16-31.gh-issue-154070.f5da07.rst @@ -0,0 +1,4 @@ +Build the :mod:`curses` module against a wide-character capable ncurses +even when it is not named ``ncursesw`` -- for example the pkgsrc ncurses on +NetBSD and illumos, or the system ncurses on macOS. Such a library +previously produced a narrow build. diff --git a/configure b/configure index dd506e6899515b2..51259e192b482cf 100755 --- a/configure +++ b/configure @@ -29578,6 +29578,72 @@ fi PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') +if test "x$have_curses" = xno +then : + +else case e in #( + e) + save_curses_cppflags=$CPPFLAGS + as_fn_append CPPFLAGS " $CURSES_CFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether curses supports wide characters" >&5 +printf %s "checking whether curses supports wide characters... " >&6; } +if test ${ac_cv_curses_wide+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 +#elif defined(HAVE_NCURSESW_CURSES_H) +# include +#elif defined(HAVE_NCURSES_NCURSES_H) +# include +#elif defined(HAVE_NCURSES_CURSES_H) +# include +#elif defined(HAVE_NCURSES_H) +# include +#elif defined(HAVE_CURSES_H) +# include +#endif + +int +main (void) +{ + + cchar_t wcval; + setcchar(&wcval, L"x", A_NORMAL, 0, NULL); + add_wch(&wcval); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_curses_wide=yes +else case e in #( + e) ac_cv_curses_wide=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_curses_wide" >&5 +printf "%s\n" "$ac_cv_curses_wide" >&6; } + CPPFLAGS=$save_curses_cppflags + if test "x$ac_cv_curses_wide" = xyes +then : + printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h + +fi + ;; +esac +fi + # On Solaris, term.h requires curses.h ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" " #define NCURSES_OPAQUE 0 diff --git a/configure.ac b/configure.ac index 73d0bb48ea8f4f8..367234b6e9bf477 100644 --- a/configure.ac +++ b/configure.ac @@ -7194,6 +7194,33 @@ AS_VAR_IF([ac_sys_system], [Darwin], [ dnl pyconfig.h defines _XOPEN_SOURCE=700 PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') +dnl A curses that is not named "ncursesw" can still be wide-character capable: +dnl the system curses of NetBSD, or an ncurses built with --enable-widec that +dnl keeps the plain name (pkgsrc, macOS). Probe for the wide API and, if +dnl present, build the module wide by defining HAVE_NCURSESW. +AS_VAR_IF([have_curses], [no], [], [ + dnl Use the adjusted CURSES_CFLAGS (e.g. macOS's -D_XOPEN_SOURCE_EXTENDED) + dnl so the wide-character declarations are visible to the probe. This runs + dnl inside an outer WITH_SAVE_ENV, whose single CPPFLAGS save slot is not + dnl reentrant, so save and restore CPPFLAGS with a dedicated variable here. + save_curses_cppflags=$CPPFLAGS + AS_VAR_APPEND([CPPFLAGS], [" $CURSES_CFLAGS"]) + AC_CACHE_CHECK([whether curses supports wide characters], + [ac_cv_curses_wide], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM([_CURSES_INCLUDES], [[ + cchar_t wcval; + setcchar(&wcval, L"x", A_NORMAL, 0, NULL); + add_wch(&wcval); + ]])], + [ac_cv_curses_wide=yes], + [ac_cv_curses_wide=no])]) + CPPFLAGS=$save_curses_cppflags + dnl HAVE_NCURSESW marks the wide (cchar_t) curses API; its template comes + dnl from the ncursesw pkg-config check above, so no description here. + AS_VAR_IF([ac_cv_curses_wide], [yes], [AC_DEFINE([HAVE_NCURSESW], [1])]) +]) + # On Solaris, term.h requires curses.h AC_CHECK_HEADERS([term.h], [], [], _CURSES_INCLUDES)