Repository: python/cpython
Pull request: gh-113565: Improve and harden detection of curses dependencies


<!-- gh-issue-number: gh-113565 -->
* Issue: gh-113565
<!-- /gh-issue-number -->


Problem statement:
configure prefers system install of ncurses over available pkg-config on macOS
# Feature or enhancement

### Proposal:

I have ncurses 6.4 installed locally with corresponding pkg-config files. I'd expect that `configure` will pick up that installation, but it seems to prefer the system installation.

I ended up running `configure` with explicit overrides for the CURSES and PANEL CFLAGS and LIBS variables:

```sh
 ../configure  ... CURSES_CFLAGS="$(pkg-config --cflags ncursesw)" CURSES_LIBS="$(pkg-config --libs ncursesw)" PANEL_CFLAGS="$(pkg-config --cflags panelw)" PANEL_LIBS="$(pkg-config --libs panelw)"
```

configure does pick up other local installs (sqlite, bz2, ...)

### Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

### Links to previous discussion of this feature:

_No response_

<!-- gh-linked-prs -->
### Linked PRs
* gh-119816
* gh-121202
* gh-121222
<!-- /gh-linked-prs -->

Hints from issue discussion:
It seems to me our configure checks are suboptimal in many cases when it comes to ncurses[w] and panel[w]. Some observations:

1. It does not make sense to not check for **ncursesw** or **npanelw** on macOS; we should remove the existing guards
2. `HAVE_NCURSESW` is automatically defined on macOS if `have_curses != no`; I'm not sure if we should keep this
3. A lot of curses feature checks do not use the pkg-config discovered CFLAGS/LIBS

I think we should rework it to first do the **ncursesw** and **panelw** checks; if not found, try **ncurses** and **panel**. Then, do the feature checks with discovered CFLAGS/LIBS applied.

Commit message: gh-113565: Use pkg-config to detect ncurses[w] and panel[w]

Patch to review:
diff --git a/configure b/configure
index 6cfe114fb2104c..ce4b6833b20063 100755
--- a/configure
+++ b/configure
@@ -829,8 +829,12 @@ SRCDIRS
 THREADHEADERS
 PANEL_LIBS
 PANEL_CFLAGS
-CURSES_LIBS
-CURSES_CFLAGS
+NCURSES_LIBS
+NCURSES_CFLAGS
+PANELW_LIBS
+PANELW_CFLAGS
+NCURSESW_LIBS
+NCURSESW_CFLAGS
 LIBEDIT_LIBS
 LIBEDIT_CFLAGS
 LIBREADLINE_LIBS
@@ -1169,8 +1173,12 @@ LIBREADLINE_CFLAGS
 LIBREADLINE_LIBS
 LIBEDIT_CFLAGS
 LIBEDIT_LIBS
-CURSES_CFLAGS
-CURSES_LIBS
+NCURSESW_CFLAGS
+NCURSESW_LIBS
+PANELW_CFLAGS
+PANELW_LIBS
+NCURSES_CFLAGS
+NCURSES_LIBS
 PANEL_CFLAGS
 PANEL_LIBS
 LIBB2_CFLAGS
@@ -2005,9 +2013,17 @@ Some influential environment variables:
               C compiler flags for LIBEDIT, overriding pkg-config
   LIBEDIT_LIBS
               linker flags for LIBEDIT, overriding pkg-config
-  CURSES_CFLAGS
-              C compiler flags for CURSES, overriding pkg-config
-  CURSES_LIBS linker flags for CURSES, overriding pkg-config
+  NCURSESW_CFLAGS
+              C compiler flags for NCURSESW, overriding pkg-config
+  NCURSESW_LIBS
+              linker flags for NCURSESW, overriding pkg-config
+  PANELW_CFLAGS
+              C compiler flags for PANELW, overriding pkg-config
+  PANELW_LIBS linker flags for PANELW, overriding pkg-config
+  NCURSES_CFLAGS
+              C compiler flags for NCURSES, overriding pkg-config
+  NCURSES_LIBS
+              linker flags for NCURSES, overriding pkg-config
   PANEL_CFLAGS
               C compiler flags for PANEL, overriding pkg-config
   PANEL_LIBS  linker flags for PANEL, overriding pkg-config
@@ -25868,31 +25884,16 @@ have_curses=no
 have_panel=no
 
 
-ac_fn_c_check_header_compile "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default"
-if test "x$ac_cv_header_curses_h" = xyes
-then :
-  printf "%s\n" "#define HAVE_CURSES_H 1" >>confdefs.h
-
-fi
-ac_fn_c_check_header_compile "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" "$ac_includes_default"
-if test "x$ac_cv_header_ncurses_h" = xyes
-then :
-  printf "%s\n" "#define HAVE_NCURSES_H 1" >>confdefs.h
-
-fi
 
 
-if test "x$ac_cv_header_ncurses_h" = xyes
-then :
 
-  if test "$ac_sys_system" != "Darwin"; then
 
 pkg_failed=no
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncursesw" >&5
 printf %s "checking for ncursesw... " >&6; }
 
-if test -n "$CURSES_CFLAGS"; then
-    pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS"
+if test -n "$NCURSESW_CFLAGS"; then
+    pkg_cv_NCURSESW_CFLAGS="$NCURSESW_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5
@@ -25900,7 +25901,7 @@ if test -n "$CURSES_CFLAGS"; then
   ac_status=$?
   printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncursesw" 2>/dev/null`
+  pkg_cv_NCURSESW_CFLAGS=`$PKG_CONFIG --cflags "ncursesw" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -25908,8 +25909,8 @@ fi
  else
     pkg_failed=untried
 fi
-if test -n "$CURSES_LIBS"; then
-    pkg_cv_CURSES_LIBS="$CURSES_LIBS"
+if test -n "$NCURSESW_LIBS"; then
+    pkg_cv_NCURSESW_LIBS="$NCURSESW_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5
@@ -25917,7 +25918,7 @@ if test -n "$CURSES_LIBS"; then
   ac_status=$?
   printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncursesw" 2>/dev/null`
+  pkg_cv_NCURSESW_LIBS=`$PKG_CONFIG --libs "ncursesw" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -25938,169 +25939,71 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1`
+	        NCURSESW_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1`
         else
-	        CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1`
+	        NCURSESW_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$CURSES_PKG_ERRORS" >&5
-
+	echo "$NCURSESW_PKG_ERRORS" >&5
 
-      save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
-        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5
-printf %s "checking for initscr in -lncursesw... " >&6; }
-if test ${ac_cv_lib_ncursesw_initscr+y}
+	       for ac_header in ncurses.h curses.h ncursesw/curses.h ncursesw/ncurses.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncursesw  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_ncursesw_initscr=yes
-else $as_nop
-  ac_cv_lib_ncursesw_initscr=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncursesw_initscr" >&6; }
-if test "x$ac_cv_lib_ncursesw_initscr" = xyes
-then :
-
-          printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
-          have_curses=ncursesw
-          CURSES_CFLAGS=${CURSES_CFLAGS-""}
-          CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}
-
+ have_curses=ncursesw
 fi
 
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
+done
 elif test $pkg_failed = untried; then
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
 printf "%s\n" "no" >&6; }
-
-      save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
-        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5
-printf %s "checking for initscr in -lncursesw... " >&6; }
-if test ${ac_cv_lib_ncursesw_initscr+y}
+	       for ac_header in ncurses.h curses.h ncursesw/curses.h ncursesw/ncurses.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncursesw  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_ncursesw_initscr=yes
-else $as_nop
-  ac_cv_lib_ncursesw_initscr=no
+ have_curses=ncursesw
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncursesw_initscr" >&6; }
-if test "x$ac_cv_lib_ncursesw_initscr" = xyes
-then :
-
-          printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
-          have_curses=ncursesw
-          CURSES_CFLAGS=${CURSES_CFLAGS-""}
-          CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
 
+done
 else
-	CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS
-	CURSES_LIBS=$pkg_cv_CURSES_LIBS
+	NCURSESW_CFLAGS=$pkg_cv_NCURSESW_CFLAGS
+	NCURSESW_LIBS=$pkg_cv_NCURSESW_LIBS
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 printf "%s\n" "yes" >&6; }
 
-      printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
-      have_curses=ncursesw
+printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
 
+   have_curses=ncursesw
+   CURSES_CFLAGS=$NCURSESW_CFLAGS
+   CURSES_LIBS=$NCURSESW_LIBS
 fi
-  fi
-
-  if test "x$have_curses" = xno
+if test "x$have_curses" = xncursesw
 then :
 
-
 pkg_failed=no
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses" >&5
-printf %s "checking for ncurses... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panelw" >&5
+printf %s "checking for panelw... " >&6; }
 
-if test -n "$CURSES_CFLAGS"; then
-    pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS"
+if test -n "$PANELW_CFLAGS"; then
+    pkg_cv_PANELW_CFLAGS="$PANELW_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "panelw") 2>&5
   ac_status=$?
   printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null`
+  pkg_cv_PANELW_CFLAGS=`$PKG_CONFIG --cflags "panelw" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -26108,16 +26011,16 @@ fi
  else
     pkg_failed=untried
 fi
-if test -n "$CURSES_LIBS"; then
-    pkg_cv_CURSES_LIBS="$CURSES_LIBS"
+if test -n "$PANELW_LIBS"; then
+    pkg_cv_PANELW_LIBS="$PANELW_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "panelw") 2>&5
   ac_status=$?
   printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null`
+  pkg_cv_PANELW_LIBS=`$PKG_CONFIG --libs "panelw" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -26138,204 +26041,76 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1`
+	        PANELW_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1`
         else
-	        CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1`
+	        PANELW_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$CURSES_PKG_ERRORS" >&5
-
-
-      save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
+	echo "$PANELW_PKG_ERRORS" >&5
 
-        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5
-printf %s "checking for initscr in -lncurses... " >&6; }
-if test ${ac_cv_lib_ncurses_initscr+y}
+	       for ac_header in panel.h ncursesw/panel.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncurses  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_ncurses_initscr=yes
-else $as_nop
-  ac_cv_lib_ncurses_initscr=no
+ have_panel=panelw
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncurses_initscr" >&6; }
-if test "x$ac_cv_lib_ncurses_initscr" = xyes
-then :
-
-          have_curses=ncurses
-          CURSES_CFLAGS=${CURSES_CFLAGS-""}
-          CURSES_LIBS=${CURSES_LIBS-"-lncurses"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
 
+done
 elif test $pkg_failed = untried; then
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
 printf "%s\n" "no" >&6; }
-
-      save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
-        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5
-printf %s "checking for initscr in -lncurses... " >&6; }
-if test ${ac_cv_lib_ncurses_initscr+y}
+	       for ac_header in panel.h ncursesw/panel.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncurses  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_ncurses_initscr=yes
-else $as_nop
-  ac_cv_lib_ncurses_initscr=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ have_panel=panelw
 fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncurses_initscr" >&6; }
-if test "x$ac_cv_lib_ncurses_initscr" = xyes
-then :
-
-          have_curses=ncurses
-          CURSES_CFLAGS=${CURSES_CFLAGS-""}
-          CURSES_LIBS=${CURSES_LIBS-"-lncurses"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
 
+done
 else
-	CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS
-	CURSES_LIBS=$pkg_cv_CURSES_LIBS
+	PANELW_CFLAGS=$pkg_cv_PANELW_CFLAGS
+	PANELW_LIBS=$pkg_cv_PANELW_LIBS
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 printf "%s\n" "yes" >&6; }
 
-      have_curses=ncurses
-
-fi
-
-fi
-
+printf "%s\n" "#define HAVE_PANELW 1" >>confdefs.h
 
+     have_panel=panelw
+     PANEL_CFLAGS=$PANELW_CFLAGS
+     PANEL_LIBS=$PANELW_LIBS
 fi
-CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
-
-if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then
-
-  as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1"
-  printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
 fi
 
 
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking curses module flags" >&5
-printf %s "checking curses module flags... " >&6; }
 if test "x$have_curses" = xno
 then :
 
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-
-else $as_nop
-
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&5
-printf "%s\n" "$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&6; }
-
-fi
-
-ac_fn_c_check_header_compile "$LINENO" "panel.h" "ac_cv_header_panel_h" "$ac_includes_default"
-if test "x$ac_cv_header_panel_h" = xyes
-then :
-  printf "%s\n" "#define HAVE_PANEL_H 1" >>confdefs.h
-
-fi
-
-
-if test "x$ac_cv_header_panel_h" = xyes
-then :
-
-
-  if test "$ac_sys_system" != "Darwin"; then
-        if test "x$have_curses" = xncursesw
-then :
 
 
 pkg_failed=no
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panelw" >&5
-printf %s "checking for panelw... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses" >&5
+printf %s "checking for ncurses... " >&6; }
 
-if test -n "$PANEL_CFLAGS"; then
-    pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS"
+if test -n "$NCURSES_CFLAGS"; then
+    pkg_cv_NCURSES_CFLAGS="$NCURSES_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "panelw") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
   ac_status=$?
   printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panelw" 2>/dev/null`
+  pkg_cv_NCURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -26343,16 +26118,16 @@ fi
  else
     pkg_failed=untried
 fi
-if test -n "$PANEL_LIBS"; then
-    pkg_cv_PANEL_LIBS="$PANEL_LIBS"
+if test -n "$NCURSES_LIBS"; then
+    pkg_cv_NCURSES_LIBS="$NCURSES_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "panelw") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
   ac_status=$?
   printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panelw" 2>/dev/null`
+  pkg_cv_NCURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -26373,151 +26148,57 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1`
+	        NCURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1`
         else
-	        PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1`
+	        NCURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$PANEL_PKG_ERRORS" >&5
+	echo "$NCURSES_PKG_ERRORS" >&5
 
-
-        save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
-          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5
-printf %s "checking for update_panels in -lpanelw... " >&6; }
-if test ${ac_cv_lib_panelw_update_panels+y}
+	       for ac_header in ncurses.h curses.h ncurses/curses.h ncurses/ncurses.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanelw  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char update_panels ();
-int
-main (void)
-{
-return update_panels ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_panelw_update_panels=yes
-else $as_nop
-  ac_cv_lib_panelw_update_panels=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panelw_update_panels" >&6; }
-if test "x$ac_cv_lib_panelw_update_panels" = xyes
-then :
-
-            have_panel=panelw
-            PANEL_CFLAGS=${PANEL_CFLAGS-""}
-            PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}
-
+ have_curses=ncurses
 fi
 
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
+done
 elif test $pkg_failed = untried; then
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
 printf "%s\n" "no" >&6; }
-
-        save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
-          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5
-printf %s "checking for update_panels in -lpanelw... " >&6; }
-if test ${ac_cv_lib_panelw_update_panels+y}
+	       for ac_header in ncurses.h curses.h ncurses/curses.h ncurses/ncurses.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanelw  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char update_panels ();
-int
-main (void)
-{
-return update_panels ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_panelw_update_panels=yes
-else $as_nop
-  ac_cv_lib_panelw_update_panels=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panelw_update_panels" >&6; }
-if test "x$ac_cv_lib_panelw_update_panels" = xyes
-then :
-
-            have_panel=panelw
-            PANEL_CFLAGS=${PANEL_CFLAGS-""}
-            PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}
-
+ have_curses=ncurses
 fi
 
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
+done
 else
-	PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS
-	PANEL_LIBS=$pkg_cv_PANEL_LIBS
+	NCURSES_CFLAGS=$pkg_cv_NCURSES_CFLAGS
+	NCURSES_LIBS=$pkg_cv_NCURSES_LIBS
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 printf "%s\n" "yes" >&6; }
 
-        have_panel=panelw
-
-fi
+printf "%s\n" "#define HAVE_NCURSES 1" >>confdefs.h
 
+   have_curses=ncurses
+   CURSES_CFLAGS=$NCURSES_CFLAGS
+   CURSES_LIBS=$NCURSES_LIBS
 fi
-  fi
-
-  if test "x$have_curses" = xncurses
+if test "x$have_curses" = xncurses
 then :
 
-
 pkg_failed=no
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panel" >&5
 printf %s "checking for panel... " >&6; }
@@ -26576,158 +26257,97 @@ fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$PANEL_PKG_ERRORS" >&5
 
-
-      save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
-        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5
-printf %s "checking for update_panels in -lpanel... " >&6; }
-if test ${ac_cv_lib_panel_update_panels+y}
+	       for ac_header in panel.h ncurses/panel.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanel  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char update_panels ();
-int
-main (void)
-{
-return update_panels ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_panel_update_panels=yes
-else $as_nop
-  ac_cv_lib_panel_update_panels=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panel_update_panels" >&6; }
-if test "x$ac_cv_lib_panel_update_panels" = xyes
-then :
-
-          have_panel=panel
-          PANEL_CFLAGS=${PANEL_CFLAGS-""}
-          PANEL_LIBS=${PANEL_LIBS-"-lpanel"}
-
+ have_panel=panel
 fi
 
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
+done
 elif test $pkg_failed = untried; then
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
 printf "%s\n" "no" >&6; }
-
-      save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
-        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5
-printf %s "checking for update_panels in -lpanel... " >&6; }
-if test ${ac_cv_lib_panel_update_panels+y}
+	       for ac_header in panel.h ncurses/panel.h
+do :
+  as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
 then :
-  printf %s "(cached) " >&6
-else $as_nop
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanel  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char update_panels ();
-int
-main (void)
-{
-return update_panels ();
-  ;
-  return 0;
-}
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
-  ac_cv_lib_panel_update_panels=yes
-else $as_nop
-  ac_cv_lib_panel_update_panels=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ have_panel=panel
 fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panel_update_panels" >&6; }
-if test "x$ac_cv_lib_panel_update_panels" = xyes
-then :
-
-          have_panel=panel
-          PANEL_CFLAGS=${PANEL_CFLAGS-""}
-          PANEL_LIBS=${PANEL_LIBS-"-lpanel"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
 
+done
 else
 	PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS
 	PANEL_LIBS=$pkg_cv_PANEL_LIBS
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 printf "%s\n" "yes" >&6; }
 
-      have_panel=panel
+printf "%s\n" "#define HAVE_PANEL 1" >>confdefs.h
 
+     have_panel=panel
+     PANEL_CFLAGS=$PANEL_CFLAGS
+     PANEL_LIBS=$PANEL_LIBS
 fi
-
 fi
 
 
 fi
-PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
+case $have_curses in #(
+  ncursesw) :
+    CURSES_CFLAGS=${CURSES_CFLAGS-""}
+         CURSES_LIBS=${CURSES_LIBS-"-lncursesw"} ;; #(
+  ncurses) :
+    CURSES_CFLAGS=${CURSES_CFLAGS-""}
+         CURSES_LIBS=${CURSES_LIBS-"-lncurses"} ;; #(
+  *) :
+     ;;
+esac
+case $have_panel in #(
+  panelw) :
+    PANEL_CFLAGS=${PANEL_CFLAGS-""}
+         PANEL_LIBS=${PANEL_LIBS-"-lpanelw"} ;; #(
+  panel) :
+    PANEL_CFLAGS=${PANEL_CFLAGS-""}
+         PANEL_LIBS=${PANEL_LIBS-"-lpanel"} ;; #(
+  *) :
+     ;;
+esac
+# TODO: rewrite these using AC_COMPILE_IFELSE
+#AS_IF([test "have_curses" != "no"],
+#      [WITH_SAVE_ENV([CPPFLAGS="$CURSES_CFLAGS $CPPFLAGS"
+#                      LDFLAGS="$CURSES_LIBS $LDFLAGS"
+#                      AC_CHECK_FUNC([initscr], [], [have_curses=no])])])
+#AS_IF([test "have_panel" != "no"],
+#      [WITH_SAVE_ENV([CPPFLAGS="$PANEL_CFLAGS $CPPFLAGS"
+#                      LDFLAGS="$PANEL_LIBS $LDFLAGS"
+#                      AC_CHECK_FUNC([update_panels], [], [have_panel=no])])])
 
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking panel flags" >&5
-printf %s "checking panel flags... " >&6; }
-if test "x$have_panel" = xno
+if test "have_curses" != "no"
 then :
 
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
+
+if test "x$ac_sys_system" = xDarwin
+then :
 
-else $as_nop
 
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&5
-printf "%s\n" "$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&6; }
+  as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1"
 
 fi
 
+
+PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
+
 # first curses header check
 ac_save_cppflags="$CPPFLAGS"
 if test "$cross_compiling" = no; then
@@ -27343,6 +26963,7 @@ fi
 
 CPPFLAGS=$ac_save_cppflags
 
+fi
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for device files" >&5
 printf "%s\n" "$as_me: checking for device files" >&6;}
 
diff --git a/configure.ac b/configure.ac
index 8657e09c9a7008..94fd269237f760 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6573,48 +6573,61 @@ dnl have_panel=[no, panelw, panel]
 have_curses=no
 have_panel=no
 
-AH_TEMPLATE([HAVE_NCURSESW], [Define to 1 if you have the `ncursesw' library.])
-AC_CHECK_HEADERS([curses.h ncurses.h])
-
-AS_VAR_IF([ac_cv_header_ncurses_h], [yes], [
-  if test "$ac_sys_system" != "Darwin"; then
-    dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
-    PKG_CHECK_MODULES([CURSES], [ncursesw], [
-      AC_DEFINE([HAVE_NCURSESW], [1])
-      have_curses=ncursesw
-    ], [
-      WITH_SAVE_ENV([
-        AC_CHECK_LIB([ncursesw], [initscr], [
-          AC_DEFINE([HAVE_NCURSESW], [1])
-          have_curses=ncursesw
-          CURSES_CFLAGS=${CURSES_CFLAGS-""}
-          CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}
-        ])
-      ])
-    ])
-  fi
-
-  AS_VAR_IF([have_curses], [no], [
-    PKG_CHECK_MODULES([CURSES], [ncurses], [
-      have_curses=ncurses
-    ], [
-      WITH_SAVE_ENV([
-        AC_CHECK_LIB([ncurses], [initscr], [
-          have_curses=ncurses
-          CURSES_CFLAGS=${CURSES_CFLAGS-""}
-          CURSES_LIBS=${CURSES_LIBS-"-lncurses"}
-        ])
-      ])
-    ])
-  ])
-
-])dnl ac_cv_header_ncurses_h = yes
-
+dnl PY_CHECK_CURSES(LIBCURSES, LIBPANEL)
+dnl Sets 'have_curses' and 'have_panel'.
+AC_DEFUN([PY_CHECK_CURSES], [dnl
+AS_VAR_PUSHDEF([curses_var], [m4_toupper([$1])])
+AS_VAR_PUSHDEF([panel_var], [m4_toupper([$2])])
+PKG_CHECK_MODULES(curses_var, [$1],
+  [AC_DEFINE([HAVE_]curses_var, [1], [Define if you have the '$1' library])
+   AS_VAR_SET([have_curses], [$1])
+   AS_VAR_SET([CURSES_CFLAGS], [$curses_var[_CFLAGS]])
+   AS_VAR_SET([CURSES_LIBS], [$curses_var[_LIBS]])],
+  [AC_CHECK_HEADERS([ncurses.h curses.h $1/curses.h $1/ncurses.h],
+                    [AS_VAR_SET([have_curses], [$1])])])
+AS_VAR_IF([have_curses], [$1],
+  [PKG_CHECK_MODULES(panel_var, [$2],
+    [AC_DEFINE([HAVE_]panel_var, [1], [Define if you hve the '$2' library])
+     AS_VAR_SET([have_panel], [$2])
+     AS_VAR_SET([PANEL_CFLAGS], [$panel_var[_CFLAGS]])
+     AS_VAR_SET([PANEL_LIBS], [$panel_var[_LIBS]])],
+    [AC_CHECK_HEADERS([panel.h $1/panel.h],
+                      [AS_VAR_SET([have_panel], [$2])])])])
+AS_VAR_POPDEF([curses_var])
+AS_VAR_POPDEF([panel_var])])
+
+PY_CHECK_CURSES([ncursesw], [panelw])
+AS_VAR_IF([have_curses], [no], [PY_CHECK_CURSES([ncurses], [panel])])
+AS_CASE([$have_curses],
+        [ncursesw],
+        [CURSES_CFLAGS=${CURSES_CFLAGS-""}
+         CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}],
+        [ncurses],
+        [CURSES_CFLAGS=${CURSES_CFLAGS-""}
+         CURSES_LIBS=${CURSES_LIBS-"-lncurses"}])
+AS_CASE([$have_panel],
+        [panelw],
+        [PANEL_CFLAGS=${PANEL_CFLAGS-""}
+         PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}],
+        [panel],
+        [PANEL_CFLAGS=${PANEL_CFLAGS-""}
+         PANEL_LIBS=${PANEL_LIBS-"-lpanel"}])
+# TODO: rewrite these using AC_COMPILE_IFELSE
+#AS_IF([test "have_curses" != "no"],
+#      [WITH_SAVE_ENV([CPPFLAGS="$CURSES_CFLAGS $CPPFLAGS"
+#                      LDFLAGS="$CURSES_LIBS $LDFLAGS"
+#                      AC_CHECK_FUNC([initscr], [], [have_curses=no])])])
+#AS_IF([test "have_panel" != "no"],
+#      [WITH_SAVE_ENV([CPPFLAGS="$PANEL_CFLAGS $CPPFLAGS"
+#                      LDFLAGS="$PANEL_LIBS $LDFLAGS"
+#                      AC_CHECK_FUNC([update_panels], [], [have_panel=no])])])
+
+AS_IF([test "have_curses" != "no"], [
 dnl remove _XOPEN_SOURCE macro from curses cflags. pyconfig.h sets
 dnl the macro to 700.
 CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
 
-if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then
+AS_VAR_IF([ac_sys_system], [Darwin], [
   dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
   dnl System-supplied ncurses combines libncurses/libpanel and supports wide
   dnl characters, so we can use it like ncursesw.
@@ -6624,66 +6637,13 @@ if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then
   dnl _XOPEN_SOURCE_EXTENDED here for ncurses wide char support.
 
   AS_VAR_APPEND([CURSES_CFLAGS], [" -D_XOPEN_SOURCE_EXTENDED=1"])
-  AC_DEFINE([HAVE_NCURSESW], [1])
-fi
-
-dnl TODO: detect "curses" and special cases tinfo, terminfo, or termcap
-
-AC_MSG_CHECKING([curses module flags])
-AS_VAR_IF([have_curses], [no], [
-  AC_MSG_RESULT([no])
-], [
-  AC_MSG_RESULT([$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)])
 ])
 
-dnl check for ncurses' panel/panelw library
-AC_CHECK_HEADERS([panel.h])
-
-AS_VAR_IF([ac_cv_header_panel_h], [yes], [
-
-  if test "$ac_sys_system" != "Darwin"; then
-    dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
-    AS_VAR_IF([have_curses], [ncursesw], [
-      PKG_CHECK_MODULES([PANEL], [panelw], [
-        have_panel=panelw
-      ], [
-        WITH_SAVE_ENV([
-          AC_CHECK_LIB([panelw], [update_panels], [
-            have_panel=panelw
-            PANEL_CFLAGS=${PANEL_CFLAGS-""}
-            PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}
-          ])
-        ])
-      ])
-    ])
-  fi
-
-  AS_VAR_IF([have_curses], [ncurses], [
-    PKG_CHECK_MODULES([PANEL], [panel], [
-      have_panel=panel
-    ], [
-      WITH_SAVE_ENV([
-        AC_CHECK_LIB([panel], [update_panels], [
-          have_panel=panel
-          PANEL_CFLAGS=${PANEL_CFLAGS-""}
-          PANEL_LIBS=${PANEL_LIBS-"-lpanel"}
-        ])
-      ])
-    ])
-  ])
-
-])dnl ac_cv_header_panel_h = yes
+dnl TODO: detect "curses" and special cases tinfo, terminfo, or termcap
 
 dnl pyconfig.h defines _XOPEN_SOURCE=700
 PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
 
-AC_MSG_CHECKING([panel flags])
-AS_VAR_IF([have_panel], [no], [
-  AC_MSG_RESULT([no])
-], [
-  AC_MSG_RESULT([$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)])
-])
-
 # first curses header check
 ac_save_cppflags="$CPPFLAGS"
 if test "$cross_compiling" = no; then
@@ -6774,6 +6734,7 @@ PY_CHECK_CURSES_FUNC([has_key])
 PY_CHECK_CURSES_FUNC([typeahead])
 PY_CHECK_CURSES_FUNC([use_env])
 CPPFLAGS=$ac_save_cppflags
+])dnl have_curses != no
 
 AC_MSG_NOTICE([checking for device files])
 
diff --git a/pyconfig.h.in b/pyconfig.h.in
index c279b147db3bdd..1bc1f9e8a11977 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -829,12 +829,33 @@
 /* Define to 1 if you have the `nanosleep' function. */
 #undef HAVE_NANOSLEEP
 
-/* Define to 1 if you have the `ncursesw' library. */
+/* Define if you have the 'ncurses' library */
+#undef HAVE_NCURSES
+
+/* Define if you have the 'ncursesw' library */
 #undef HAVE_NCURSESW
 
+/* Define to 1 if you have the <ncursesw/curses.h> header file. */
+#undef HAVE_NCURSESW_CURSES_H
+
+/* Define to 1 if you have the <ncursesw/ncurses.h> header file. */
+#undef HAVE_NCURSESW_NCURSES_H
+
+/* Define to 1 if you have the <ncursesw/panel.h> header file. */
+#undef HAVE_NCURSESW_PANEL_H
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#undef HAVE_NCURSES_CURSES_H
+
 /* Define to 1 if you have the <ncurses.h> header file. */
 #undef HAVE_NCURSES_H
 
+/* Define to 1 if you have the <ncurses/ncurses.h> header file. */
+#undef HAVE_NCURSES_NCURSES_H
+
+/* Define to 1 if you have the <ncurses/panel.h> header file. */
+#undef HAVE_NCURSES_PANEL_H
+
 /* Define to 1 if you have the <ndbm.h> header file. */
 #undef HAVE_NDBM_H
 
@@ -878,6 +899,12 @@
 /* Define to 1 if you have the `openpty' function. */
 #undef HAVE_OPENPTY
 
+/* Define if you hve the 'panel' library */
+#undef HAVE_PANEL
+
+/* Define if you hve the 'panelw' library */
+#undef HAVE_PANELW
+
 /* Define to 1 if you have the <panel.h> header file. */
 #undef HAVE_PANEL_H
 


Code review comments:
diff_hunk: @@ -829,8 +829,12 @@ SRCDIRS
 THREADHEADERS
 PANEL_LIBS
 PANEL_CFLAGS
-CURSES_LIBS
-CURSES_CFLAGS
+NCURSES_LIBS
+NCURSES_CFLAGS
+PANELW_LIBS
+PANELW_CFLAGS
+NCURSESW_LIBS
+NCURSESW_CFLAGS
path: configure
text: @author:
This is unfortunate, but it is autogenerated by the `PKG_CHECK_MODULES` macro.

@author:
Quoting from the `pkg-config` man page (emphasis mine):

> PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]])
> The macro PKG_CHECK_MODULES can be used in configure.ac to check whether modules exist. [...]
>
> This would result in MYSTUFF_LIBS and MYSTUFF_CFLAGS substitution variables, set to the libs and cflags for the given module list.  If a module is missing or has the wrong version, by default configure will abort with a message. To replace the default action, specify an ACTION-IF-NOT-FOUND. PKG_CHECK_MODULES will not print any error messages if you specify your own ACTION-IF-NOT-FOUND.  However, it will set the variable MYSTUFF_PKG_ERRORS, which you can use to display what went wrong.
>
> [...]
>
> **Also note that repeated usage of VARIABLE-PREFIX is not recommended.  After the first successful usage, subsequent calls with the same VARIABLE-PREFIX will simply use the _LIBS and _CFLAGS variables set from the previous usage without calling pkg-config again.**

We might work around this by explicitly unsetting `CURSES_LIBS` and `CURSES_CFLAGS` between calls. I _guess_ it would work, but it sure feels hacky. OTOH, it would make for a better `configure` user experience.

@author:
Getting back to this, I see now that we can safely call `PKG_CHECK_MODULES` with the same variable-prefix; the second call is only done if the first fails, and if the first fails, no variables are set.