summaryrefslogtreecommitdiffstats
path: root/Modules/readline.c
blob: a1ba13d5ef72587a2e167287246ff587b491ba17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* The readline module makes GNU readline available to Python.  It
 * has ideas contributed by Lee Busby, LLNL, and William Magro,
 * Cornell Theory Center.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include "Python.h"
#include <setjmp.h>
#include <signal.h>

/* Routines needed from outside (but not declared in a header file). */
extern int (*PyOS_InputHook)();
extern char *readline();
extern int rl_initialize();
extern int rl_insert();
extern int rl_bind_key();
extern void add_history();
extern char *rl_readline_name;
extern int (*rl_event_hook)();
extern char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *));

/* This module's initialization routine */
void initreadline (void);

static void PyOS_ReadlineInit();
static RETSIGTYPE onintr();
static char *PyOS_GnuReadline();
static jmp_buf jbuf;
static PyObject *ReadlineError;
static int already_initialized = 0;
static char readline_module_documentation[] =
"Readline Module, version0.0"
;

static struct PyMethodDef readline_methods[] =
{ 
  { 0, 0 }
};

/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */

/* Initialize the module.  Actually, that's all you can or need to do. */
void initreadline (void)
{
  PyObject *m, *d;

  if (already_initialized)
    return;
  m = Py_InitModule4 ("readline", readline_methods,
		      readline_module_documentation,
		      (PyObject *) 0, PYTHON_API_VERSION);
  d = PyModule_GetDict (m);
  ReadlineError = PyString_FromString ("Readline.error");
  PyDict_SetItemString (d, "error", ReadlineError);
  if (PyErr_Occurred ()) {
    Py_FatalError ("Cannot initialize module readline");
  }
  if (isatty(fileno(stdin))){
    PyOS_ReadlineFunctionPointer = PyOS_GnuReadline;
    PyOS_ReadlineInit();
  }
  already_initialized = 1;
}

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

static void
PyOS_ReadlineInit()
{
    /* Force rebind of TAB to insert-tab */
    rl_readline_name = "python";
    rl_initialize();
    rl_bind_key('\t', rl_insert);
}

static char *
PyOS_GnuReadline(prompt)
	char *prompt;
{
	int n;
	char *p;
	RETSIGTYPE (*old_inthandler)();
	old_inthandler = signal(SIGINT, onintr);
	if (setjmp(jbuf)) {
#ifdef HAVE_SIGRELSE
		/* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
		sigrelse(SIGINT);
#endif
		signal(SIGINT, old_inthandler);
		return NULL;
	}
	rl_event_hook = PyOS_InputHook;
	p = readline(prompt);
	signal(SIGINT, old_inthandler);
	if (p == NULL) {
		p = malloc(1);
		if (p != NULL)
			*p = '\0';
		return p;
	}
	n = strlen(p);
	if (n > 0)
		add_history(p);
	if ((p = realloc(p, n+2)) != NULL) {
		p[n] = '\n';
		p[n+1] = '\0';
	}
	return p;
}

#ifdef __cplusplus
}
#endif