/* This module makes GNU readline available to Python.  It has ideas
 * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
 * Center.  The completer interface was inspired by Lele Gaifax.
 *
 * More recently, it was largely rewritten by Guido van Rossum who is
 * now maintaining it.
 */

/* Standard definitions */
#include "Python.h"
#include <setjmp.h>
#include <signal.h>
#include <errno.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h> /* For isatty() */
#endif

/* GNU readline definitions */
/* If you have string.h, you might need to add yourself to this #if... [cjh] */
#if defined(__BEOS__)
#undef HAVE_CONFIG_H
/* At max warnings, we need protos for everything. [cjh] */
#include <readline/readline.h>
#include <readline/history.h>
#include <unistd.h>
#else
#include <readline/readline.h> /* You may need to add an -I option to Setup */

#ifdef __CYGWIN__
#include <readline/history.h>
#else /* !__CYGWIN__ */
extern int rl_parse_and_bind(char *);
extern int rl_read_init_file(char *);
extern int rl_insert_text(char *);
extern int rl_bind_key(int, Function *);
extern int rl_bind_key_in_map(int, Function *, Keymap);
extern int rl_initialize(void);
extern int add_history(char *);
extern int read_history(char *);
extern int write_history(char *);
extern int history_truncate_file(char *, int);
extern Function *rl_event_hook;
#endif /* !__CYGWIN__ */
#endif

/* Pointers needed from outside (but not declared in a header file). */
extern DL_IMPORT(int) (*PyOS_InputHook)(void);
extern DL_IMPORT(char) *(*PyOS_ReadlineFunctionPointer)(char *);


/* Exported function to send one line to readline's init file parser */

static PyObject *
parse_and_bind(PyObject *self, PyObject *args)
{
	char *s, *copy;
	if (!PyArg_ParseTuple(args, "s:parse_and_bind", &s))
		return NULL;
	/* Make a copy -- rl_parse_and_bind() modifies its argument */
	/* Bernard Herzog */
	copy = malloc(1 + strlen(s));
	if (copy == NULL)
		return PyErr_NoMemory();
	strcpy(copy, s);
	rl_parse_and_bind(copy);
	free(copy); /* Free the copy */
	Py_INCREF(Py_None);
	return Py_None;
}

static char doc_parse_and_bind[] = "\
parse_and_bind(string) -> None\n\
Parse and execute single line of a readline init file.\
";


/* Exported function to parse a readline init file */

static PyObject *
read_init_file(PyObject *self, PyObject *args)
{
	char *s = NULL;
	if (!PyArg_ParseTuple(args, "|z:read_init_file", &s))
		return NULL;
	errno = rl_read_init_file(s);
	if (errno)
		return PyErr_SetFromErrno(PyExc_IOError);
	Py_INCREF(Py_None);
	return Py_None;
}

static char doc_read_init_file[] = "\
read_init_file([filename]) -> None\n\
Parse a readline initialization file.\n\
The default filename is the last filename used.\
";


/* Exported function to load a readline history file */

static PyObject *
read_history_file(PyObject *self, PyObject *args)
{
	char *s = NULL;
	if (!PyArg_ParseTuple(args, "|z:read_history_file", &s))
		return NULL;
	errno = read_history(s);
	if (errno)
		return PyErr_SetFromErrno(PyExc_IOError);
	Py_INCREF(Py_None);
	return Py_None;
}

static int history_length = -1; /* do not truncate history by default */
static char doc_read_history_file[] = "\
read_history_file([filename]) -> None\n\
Load a readline history file.\n\
The default filename is ~/.history.\
";


/* Exported function to save a readline history file */

static PyObject *
write_history_file(PyObject *self, PyObject *args)
{
	char *s = NULL;
	if (!PyArg_ParseTuple(args, "|z:write_history_file", &s))
		return NULL;
	errno = write_history(s);
	if (!errno && history_length >= 0)
		history_truncate_file(s, history_length);
	if (errno)
		return PyErr_SetFromErrno(PyExc_IOError);
	Py_INCREF(Py_None);
	return Py_None;
}

static char doc_write_history_file[] = "\
write_history_file([filename]) -> None\n\
Save a readline history file.\n\
The default filename is ~/.history.\
";


static char set_history_length_doc[] = "\
set_history_length(length) -> None\n\
set the maximal number of items which will be written to\n\
the history file. A negative length is used to inhibit\n\
history truncation.\n\
";

static PyObject*
set_history_length(PyObject *self, PyObject *args)
{
    int length = history_length;
    if (!PyArg_ParseTuple(args, "i:set_history_length", &length))
	return NULL;
    history_length = length;
    Py_INCREF(Py_None);
    return Py_None;
}



static char get_history_length_doc[] = "\
get_history_length() -> int\n\
return the current history length value.\n\
";

static PyObject*
get_history_length(PyObject *self, PyObject *args)
{
	if (!PyArg_ParseTuple(args, ":get_history_length"))
		return NULL;
	return Py_BuildValue("i", history_length);
}



/* Exported function to specify a word completer in Python */

static PyObject *completer = NULL;
static PyThreadState *tstate = NULL;

static PyObject *begidx = NULL;
static PyObject *endidx = NULL;

/* get the beginning index for the scope of the tab-completion */
static PyObject *
get_begidx(PyObject *self, PyObject *args)
{
	if(!PyArg_NoArgs(args)) {
		return NULL;
	} 
	Py_INCREF(begidx);
	return begidx;
}

static char doc_get_begidx[] = "\
get_begidx() -> int\n\
get the beginning index of the readline tab-completion scope";

/* get the ending index for the scope of the tab-completion */
static PyObject *
get_endidx(PyObject *self, PyObject *args)
{
 	if(!PyArg_NoArgs(args)) {
		return NULL;
	} 
	Py_INCREF(endidx);
	return endidx;
}

static char doc_get_endidx[] = "\
get_endidx() -> int\n\
get the ending index of the readline tab-completion scope";


/* set the tab-completion word-delimiters that readline uses */

static PyObject *
set_completer_delims(PyObject *self, PyObject *args)
{
	char *break_chars;

	if(!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) {
		return NULL;
	}
	free(rl_completer_word_break_characters);
	rl_completer_word_break_characters = strdup(break_chars);
	Py_INCREF(Py_None);
	return Py_None;
}

static char doc_set_completer_delims[] = "\
set_completer_delims(string) -> None\n\
set the readline word delimiters for tab-completion";


/* get the tab-completion word-delimiters that readline uses */

static PyObject *
get_completer_delims(PyObject *self, PyObject *args)
{
	if(!PyArg_NoArgs(args)) {
		return NULL;
	}
	return PyString_FromString(rl_completer_word_break_characters);
}
	
static char doc_get_completer_delims[] = "\
get_completer_delims() -> string\n\
get the readline word delimiters for tab-completion";

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;
}

static char doc_set_completer[] = "\
set_completer([function]) -> None\n\
Set or remove the completer function.\n\
The function is called as function(text, state),\n\
for i in [0, 1, 2, ...] until it returns a non-string.\n\
It should return the next possible completion starting with 'text'.\
";

/* Exported function to read the current line buffer */

static PyObject *
get_line_buffer(PyObject *self, PyObject *args)
{
	if (!PyArg_NoArgs(args))
		return NULL;
	return PyString_FromString(rl_line_buffer);
}

static char doc_get_line_buffer[] = "\
get_line_buffer() -> string\n\
return the current contents of the line buffer.\
";

/* Exported function to insert text into the line buffer */

static PyObject *
insert_text(PyObject *self, PyObject *args)
{
	char *s;
	if (!PyArg_ParseTuple(args, "s:insert_text", &s))
		return NULL;
	rl_insert_text(s);
	Py_INCREF(Py_None);
	return Py_None;
}


static char doc_insert_text[] = "\
insert_text(string) -> None\n\
Insert text into the command line.\
";


/* Table of functions exported by the module */

static struct PyMethodDef readline_methods[] =
{
	{"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind},
	{"get_line_buffer", get_line_buffer, 
	 METH_OLDARGS, doc_get_line_buffer},
	{"insert_text", insert_text, METH_VARARGS, doc_insert_text},
	{"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file},
	{"read_history_file", read_history_file, 
	 METH_VARARGS, doc_read_history_file},
	{"write_history_file", write_history_file, 
	 METH_VARARGS, doc_write_history_file},
 	{"set_history_length", set_history_length, 
	 METH_VARARGS, set_history_length_doc},
 	{"get_history_length", get_history_length, 
	 METH_VARARGS, get_history_length_doc},
	{"set_completer", set_completer, METH_VARARGS, doc_set_completer},
	{"get_begidx", get_begidx, METH_OLDARGS, doc_get_begidx},
	{"get_endidx", get_endidx, METH_OLDARGS, doc_get_endidx},

	{"set_completer_delims", set_completer_delims, 
	 METH_VARARGS, doc_set_completer_delims},
	{"get_completer_delims", get_completer_delims, 
	 METH_OLDARGS, doc_get_completer_delims},
	{0, 0}
};

/* C function to call the Python completer. */

static char *
on_completion(char *text, int state)
{
	char *result = NULL;
	if (completer != 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(completer, "si", text, state);
		if (r == NULL)
			goto error;
		if (r == Py_None) {
			result = NULL;
		}
		else {
			char *s = PyString_AsString(r);
			if (s == NULL)
				goto error;
			result = strdup(s);
		}
		Py_DECREF(r);
		goto done;
	  error:
		PyErr_Clear();
		Py_XDECREF(r);
	  done:
		PyEval_SaveThread();
		PyThreadState_Swap(save_tstate);
	}
	return result;
}


/* a more flexible constructor that saves the "begidx" and "endidx"
 * before calling the normal completer */

char **
flex_complete(char *text, int start, int end)
{
	Py_XDECREF(begidx);
	Py_XDECREF(endidx);
	begidx = PyInt_FromLong((long) start);
	endidx = PyInt_FromLong((long) end);
	return completion_matches(text, *on_completion);
}

/* Helper to initialize GNU readline properly. */

static void
setup_readline(void)
{
	rl_readline_name = "python";
	/* Force rebind of TAB to insert-tab */
	rl_bind_key('\t', rl_insert);
	/* 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 completion function */
	rl_attempted_completion_function = (CPPFunction *)flex_complete;
	/* Set Python word break characters */
	rl_completer_word_break_characters =
		strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
		/* All nonalphanums except '.' */

	begidx = PyInt_FromLong(0L);
	endidx = PyInt_FromLong(0L);
	/* Initialize (allows .inputrc to override)
	 *
	 * XXX: A bug in the readline-2.2 library causes a memory leak
	 * inside this function.  Nothing we can do about it.
	 */
	rl_initialize();
}


/* Interrupt handler */

static jmp_buf jbuf;

/* ARGSUSED */
static void
onintr(int sig)
{
	longjmp(jbuf, 1);
}


/* Wrapper around GNU readline that handles signals differently. */

static char *
call_readline(char *prompt)
{
	size_t n;
	char *p, *q;
	PyOS_sighandler_t old_inthandler;
	
	old_inthandler = PyOS_setsig(SIGINT, onintr);
	if (setjmp(jbuf)) {
#ifdef HAVE_SIGRELSE
		/* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
		sigrelse(SIGINT);
#endif
		PyOS_setsig(SIGINT, old_inthandler);
		return NULL;
	}
	rl_event_hook = PyOS_InputHook;
	p = readline(prompt);
	PyOS_setsig(SIGINT, old_inthandler);

	/* We must return a buffer allocated with PyMem_Malloc. */
	if (p == NULL) {
		p = PyMem_Malloc(1);
		if (p != NULL)
			*p = '\0';
		return p;
	}
	n = strlen(p);
	if (n > 0)
		add_history(p);
	/* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and
	   release the original. */
	q = p;
	p = PyMem_Malloc(n+2);
	if (p != NULL) {
		strncpy(p, q, n);
		p[n] = '\n';
		p[n+1] = '\0';
	}
	free(q);
	return p;
}


/* Initialize the module */

static char doc_module[] =
"Importing this module enables command line editing using GNU readline.";

DL_EXPORT(void)
initreadline(void)
{
	PyObject *m;

	m = Py_InitModule4("readline", readline_methods, doc_module,
			   (PyObject *)NULL, PYTHON_API_VERSION);
	if (isatty(fileno(stdin))) {
		PyOS_ReadlineFunctionPointer = call_readline;
		setup_readline();
	}
}
