From 8515fd79fef1ac16d7848cec5ec1797294cb5366 Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Wed, 17 Apr 2024 19:26:10 +1000 Subject: [PATCH] gh-117845: Detect libedit hook function signature in configure (#117870) Older libedit versions (like Apple's) use a different type signature for rl_startup_hook and rl_pre_input_hook. Add a configure check to determine which signature is accepted by introducing the Py_RL_STARTUP_HOOK_TAKES_ARGS macro in pyconfig.h. --- ...-04-15-08-35-06.gh-issue-117845.IowzyW.rst | 1 + Modules/readline.c | 4 +- configure | 50 +++++++++++++++++++ configure.ac | 15 ++++++ pyconfig.h.in | 3 ++ 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2024-04-15-08-35-06.gh-issue-117845.IowzyW.rst diff --git a/Misc/NEWS.d/next/Build/2024-04-15-08-35-06.gh-issue-117845.IowzyW.rst b/Misc/NEWS.d/next/Build/2024-04-15-08-35-06.gh-issue-117845.IowzyW.rst new file mode 100644 index 00000000000..02d62da15b2 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2024-04-15-08-35-06.gh-issue-117845.IowzyW.rst @@ -0,0 +1 @@ +Fix building against recent libedit versions by detecting readline hook signatures in :program:`configure`. diff --git a/Modules/readline.c b/Modules/readline.c index e29051c37f8..c5c34535de0 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1041,7 +1041,7 @@ on_hook(PyObject *func) } static int -#if defined(_RL_FUNCTION_TYPEDEF) +#if defined(_RL_FUNCTION_TYPEDEF) || !defined(Py_RL_STARTUP_HOOK_TAKES_ARGS) on_startup_hook(void) #else on_startup_hook(const char *Py_UNUSED(text), int Py_UNUSED(state)) @@ -1061,7 +1061,7 @@ on_startup_hook(const char *Py_UNUSED(text), int Py_UNUSED(state)) #ifdef HAVE_RL_PRE_INPUT_HOOK static int -#if defined(_RL_FUNCTION_TYPEDEF) +#if defined(_RL_FUNCTION_TYPEDEF) || !defined(Py_RL_STARTUP_HOOK_TAKES_ARGS) on_pre_input_hook(void) #else on_pre_input_hook(const char *Py_UNUSED(text), int Py_UNUSED(state)) diff --git a/configure b/configure index 6782d470aad..29a7d5b2b86 100755 --- a/configure +++ b/configure @@ -25367,6 +25367,56 @@ printf "%s\n" "#define HAVE_RL_COMPDISP_FUNC_T 1" >>confdefs.h fi + # Some editline versions declare rl_startup_hook as taking no args, others + # declare it as taking 2. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if rl_startup_hook takes arguments" >&5 +printf %s "checking if rl_startup_hook takes arguments... " >&6; } +if test ${ac_cv_readline_rl_startup_hook_takes_args+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + + extern int test_hook_func(const char *text, int state); +int +main (void) +{ +rl_startup_hook=test_hook_func; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_readline_rl_startup_hook_takes_args=yes +else $as_nop + ac_cv_readline_rl_startup_hook_takes_args=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_startup_hook_takes_args" >&5 +printf "%s\n" "$ac_cv_readline_rl_startup_hook_takes_args" >&6; } + if test "x$ac_cv_readline_rl_startup_hook_takes_args" = xyes +then : + + +printf "%s\n" "#define Py_RL_STARTUP_HOOK_TAKES_ARGS 1" >>confdefs.h + + +fi + CFLAGS=$save_CFLAGS diff --git a/configure.ac b/configure.ac index 51a0d35dbc3..7723c805b93 100644 --- a/configure.ac +++ b/configure.ac @@ -6341,6 +6341,21 @@ AS_VAR_IF([with_readline], [no], [ # in readline as well as newer editline (April 2023) AC_CHECK_TYPES([rl_compdisp_func_t], [], [], [readline_includes]) + # Some editline versions declare rl_startup_hook as taking no args, others + # declare it as taking 2. + AC_CACHE_CHECK([if rl_startup_hook takes arguments], [ac_cv_readline_rl_startup_hook_takes_args], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([readline_includes] + [extern int test_hook_func(const char *text, int state);], + [rl_startup_hook=test_hook_func;])], + [ac_cv_readline_rl_startup_hook_takes_args=yes], + [ac_cv_readline_rl_startup_hook_takes_args=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_startup_hook_takes_args], [yes], [ + AC_DEFINE([Py_RL_STARTUP_HOOK_TAKES_ARGS], [1], [Define if rl_startup_hook takes arguments]) + ]) + m4_undefine([readline_includes]) ])dnl WITH_SAVE_ENV() ]) diff --git a/pyconfig.h.in b/pyconfig.h.in index e28baef51d5..c279b147db3 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1659,6 +1659,9 @@ SipHash13: 3, externally defined: 0 */ #undef Py_HASH_ALGORITHM +/* Define if rl_startup_hook takes arguments */ +#undef Py_RL_STARTUP_HOOK_TAKES_ARGS + /* Define if you want to enable internal statistics gathering. */ #undef Py_STATS