return Py_BuildValue("i", history_length);
}
+/* Generic hook function setter */
+static PyObject *
+set_hook(const char * funcname, PyObject **hook_var, PyThreadState **tstate, PyObject *args)
+{
+ PyObject *function = Py_None;
+ char buf[80];
+ sprintf(buf, "|O:set_%s", funcname);
+ if (!PyArg_ParseTuple(args, buf, &function))
+ return NULL;
+ if (function == Py_None) {
+ Py_XDECREF(*hook_var);
+ *hook_var = NULL;
+ *tstate = NULL;
+ }
+ else if (PyCallable_Check(function)) {
+ PyObject *tmp = *hook_var;
+ Py_INCREF(function);
+ *hook_var = function;
+ Py_XDECREF(tmp);
+ *tstate = PyThreadState_Get();
+ }
+ else {
+ sprintf(buf, "set_%s(func): argument not callable", funcname);
+ PyErr_SetString(PyExc_TypeError, buf);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* Exported functions to specify hook functions in Python */
+
+static PyObject *startup_hook = NULL;
+static PyThreadState *startup_hook_tstate = NULL;
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+static PyObject *pre_input_hook = NULL;
+static PyThreadState *pre_input_hook_tstate = NULL;
+#endif
+
+static PyObject *
+set_startup_hook(PyObject *self, PyObject *args)
+{
+ return set_hook("startup_hook", &startup_hook, &startup_hook_tstate, args);
+}
+
+static char doc_set_startup_hook[] = "\
+set_startup_hook([function]) -> None\n\
+Set or remove the startup_hook function.\n\
+The function is called with no arguments just\n\
+before readline prints the first prompt.\n\
+";
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+static PyObject *
+set_pre_input_hook(PyObject *self, PyObject *args)
+{
+ return set_hook("pre_input_hook", &pre_input_hook, &pre_input_hook_tstate, args);
+}
+
+static char doc_set_pre_input_hook[] = "\
+set_pre_input_hook([function]) -> None\n\
+Set or remove the pre_input_hook function.\n\
+The function is called with no arguments after the first prompt\n\
+has been printed and just before readline starts reading input\n\
+characters.\n\
+";
+#endif
/* Exported function to specify a word completer in Python */
static PyObject *completer = NULL;
-static PyThreadState *tstate = NULL;
+static PyThreadState *completer_tstate = NULL;
static PyObject *begidx = NULL;
static PyObject *endidx = NULL;
static PyObject *
set_completer(PyObject *self, PyObject *args)
{
- PyObject *function = Py_None;
- if (!PyArg_ParseTuple(args, "|O:set_completer", &function))
- return NULL;
- if (function == Py_None) {
- Py_XDECREF(completer);
- completer = NULL;
- tstate = NULL;
- }
- else if (PyCallable_Check(function)) {
- PyObject *tmp = completer;
- Py_INCREF(function);
- completer = function;
- Py_XDECREF(tmp);
- tstate = PyThreadState_Get();
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "set_completer(func): argument not callable");
- return NULL;
- }
- Py_INCREF(Py_None);
- return Py_None;
+ return set_hook("completer", &completer, &completer_tstate, args);
}
static char doc_set_completer[] = "\
METH_VARARGS, doc_set_completer_delims},
{"get_completer_delims", get_completer_delims,
METH_OLDARGS, doc_get_completer_delims},
+
+ {"set_startup_hook", set_startup_hook, METH_VARARGS, doc_set_startup_hook},
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+ {"set_pre_input_hook", set_pre_input_hook, METH_VARARGS, doc_set_pre_input_hook},
+#endif
{0, 0}
};
+/* C function to call the Python hooks. */
+
+static int
+on_hook(PyObject *func, PyThreadState *tstate)
+{
+ int result = 0;
+ if (func != NULL) {
+ PyObject *r;
+ PyThreadState *save_tstate;
+ /* Note that readline is called with the interpreter
+ lock released! */
+ save_tstate = PyThreadState_Swap(NULL);
+ PyEval_RestoreThread(tstate);
+ r = PyObject_CallFunction(func, NULL);
+ if (r == NULL)
+ goto error;
+ if (r == Py_None)
+ result = 0;
+ else
+ result = PyInt_AsLong(r);
+ Py_DECREF(r);
+ goto done;
+ error:
+ PyErr_Clear();
+ Py_XDECREF(r);
+ done:
+ PyEval_SaveThread();
+ PyThreadState_Swap(save_tstate);
+ }
+ return result;
+}
+
+static int
+on_startup_hook(void)
+{
+ return on_hook(startup_hook, startup_hook_tstate);
+}
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+static int
+on_pre_input_hook(void)
+{
+ return on_hook(pre_input_hook, pre_input_hook_tstate);
+}
+#endif
+
/* C function to call the Python completer. */
static char *
/* Note that readline is called with the interpreter
lock released! */
save_tstate = PyThreadState_Swap(NULL);
- PyEval_RestoreThread(tstate);
+ PyEval_RestoreThread(completer_tstate);
r = PyObject_CallFunction(completer, "si", text, state);
if (r == NULL)
goto error;
/* Bind both ESC-TAB and ESC-ESC to the completion function */
rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
+ /* Set our hook functions */
+ rl_startup_hook = (Function *)on_startup_hook;
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+ rl_pre_input_hook = (Function *)on_pre_input_hook;
+#endif
/* Set our completion function */
rl_attempted_completion_function = (CPPFunction *)flex_complete;
/* Set Python word break characters */
fi
+# check for readline 4.0
+echo $ac_n "checking for rl_pre_input_hook in -lreadline""... $ac_c" 1>&6
+echo "configure:7033: checking for rl_pre_input_hook in -lreadline" >&5
+ac_lib_var=`echo readline'_'rl_pre_input_hook | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lreadline -ltermcap $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7041 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char rl_pre_input_hook();
+
+int main() {
+rl_pre_input_hook()
+; return 0; }
+EOF
+if { (eval echo configure:7052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_RL_PRE_INPUT_HOOK 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
# check for readline 4.2
echo $ac_n "checking for rl_completion_matches in -lreadline""... $ac_c" 1>&6
-echo "configure:7033: checking for rl_completion_matches in -lreadline" >&5
+echo "configure:7078: checking for rl_completion_matches in -lreadline" >&5
ac_lib_var=`echo readline'_'rl_completion_matches | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lreadline -ltermcap $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7041 "configure"
+#line 7086 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
rl_completion_matches()
; return 0; }
EOF
-if { (eval echo configure:7052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo $ac_n "checking for broken nice()""... $ac_c" 1>&6
-echo "configure:7077: checking for broken nice()" >&5
+echo "configure:7122: checking for broken nice()" >&5
if eval "test \"`echo '$''{'ac_cv_broken_nice'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_broken_nice=no
else
cat > conftest.$ac_ext <<EOF
-#line 7086 "configure"
+#line 7131 "configure"
#include "confdefs.h"
int main()
}
EOF
-if { (eval echo configure:7098: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_broken_nice=yes
else
#endif
EOF
echo $ac_n "checking for socklen_t""... $ac_c" 1>&6
-echo "configure:7129: checking for socklen_t" >&5
+echo "configure:7174: checking for socklen_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7134 "configure"
+#line 7179 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
SRCDIRS="Parser Grammar Objects Python Modules"
echo $ac_n "checking for build directories""... $ac_c" 1>&6
-echo "configure:7183: checking for build directories" >&5
+echo "configure:7228: checking for build directories" >&5
for dir in $SRCDIRS; do
if test ! -d $dir; then
mkdir $dir