OILS / pyext / line_input.c View on Github | oils.pub

1905 lines, 1135 significant
1/* This module makes GNU readline available to Python. It has ideas
2 * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
3 * Center. The completer interface was inspired by Lele Gaifax. More
4 * recently, it was largely rewritten by Guido van Rossum.
5 */
6
7/* Standard definitions */
8#include "Python.h"
9#include <setjmp.h>
10#include <signal.h>
11#include <errno.h>
12#include <sys/time.h>
13
14/* ------------------------------------------------------------------------- */
15
16/* OVM_MAIN: This section copied from autotool-generated pyconfig.h.
17 * We're not detecting any of it in Oil's configure script. They are for
18 * ancient readline versions.
19 * */
20
21/* Define if you have readline 2.1 */
22#define HAVE_RL_CALLBACK 1
23
24/* Define if you can turn off readline's signal handling. */
25#define HAVE_RL_CATCH_SIGNAL 1
26
27/* Define if you have readline 2.2 */
28#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1
29
30/* Define if you have readline 4.0 */
31#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1
32
33/* Define if you have readline 4.2 */
34#define HAVE_RL_COMPLETION_MATCHES 1
35
36/* Define if you have rl_completion_suppress_append */
37#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1
38
39/* Define if you have readline 4.0 */
40#define HAVE_RL_PRE_INPUT_HOOK 1
41
42/* Define if you have readline 4.0 */
43#define HAVE_RL_RESIZE_TERMINAL 1
44
45/* ------------------------------------------------------------------------- */
46
47#if defined(HAVE_SETLOCALE)
48/* GNU readline() mistakenly sets the LC_CTYPE locale.
49 * This is evil. Only the user or the app's main() should do this!
50 * We must save and restore the locale around the rl_initialize() call.
51 */
52#define SAVE_LOCALE
53#include <locale.h>
54#endif
55
56#ifdef SAVE_LOCALE
57# define RESTORE_LOCALE(sl) { setlocale(LC_CTYPE, sl); free(sl); }
58#else
59# define RESTORE_LOCALE(sl)
60#endif
61
62/* GNU readline definitions */
63#undef HAVE_CONFIG_H /* Else readline/chardefs.h includes strings.h */
64#include <readline/readline.h>
65#include <readline/history.h>
66
67#ifdef HAVE_RL_COMPLETION_MATCHES
68#define completion_matches(x, y) \
69 rl_completion_matches((x), ((rl_compentry_func_t *)(y)))
70#else
71#if defined(_RL_FUNCTION_TYPEDEF)
72extern char **completion_matches(char *, rl_compentry_func_t *);
73#else
74
75#if !defined(__APPLE__)
76extern char **completion_matches(char *, CPFunction *);
77#endif
78#endif
79#endif
80
81#ifdef __APPLE__
82/*
83 * It is possible to link the readline module to the readline
84 * emulation library of editline/libedit.
85 *
86 * On OSX this emulation library is not 100% API compatible
87 * with the "real" readline and cannot be detected at compile-time,
88 * hence we use a runtime check to detect if we're using libedit
89 *
90 * Currently there is one known API incompatibility:
91 * - 'get_history' has a 1-based index with GNU readline, and a 0-based
92 * index with older versions of libedit's emulation.
93 * - Note that replace_history and remove_history use a 0-based index
94 * with both implementations.
95 */
96static int using_libedit_emulation = 0;
97static const char libedit_version_tag[] = "EditLine wrapper";
98
99static int libedit_history_start = 0;
100#endif /* __APPLE__ */
101
102#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
103static void
104on_completion_display_matches_hook(char **matches,
105 int num_matches, int max_length);
106#endif
107
108/* Memory allocated for rl_completer_word_break_characters
109 (see issue #17289 for the motivation). */
110static char *completer_word_break_characters;
111
112/* Exported function to send one line to readline's init file parser */
113
114static PyObject *
115parse_and_bind(PyObject *self, PyObject *args)
116{
117 char *s, *copy;
118 int binding_result;
119
120 if (!PyArg_ParseTuple(args, "s:parse_and_bind", &s))
121 return NULL;
122 /* Make a copy -- rl_parse_and_bind() modifies its argument */
123 /* Bernard Herzog */
124 copy = malloc(1 + strlen(s));
125 if (copy == NULL)
126 return PyErr_NoMemory();
127 strcpy(copy, s);
128
129 binding_result = rl_parse_and_bind(copy);
130 free(copy); /* Free the copy */
131
132 if (binding_result != 0) {
133 PyErr_Format(PyExc_ValueError, "'%s': invalid binding", s);
134 return NULL;
135 }
136
137 Py_RETURN_NONE;
138}
139
140PyDoc_STRVAR(doc_parse_and_bind,
141"parse_and_bind(string) -> None\n\
142Bind a key sequence to a readline function (or a variable to a value).");
143
144
145
146/* Exported function to parse a readline init file */
147
148static PyObject *
149read_init_file(PyObject *self, PyObject *args)
150{
151 char *s = NULL;
152 if (!PyArg_ParseTuple(args, "|z:read_init_file", &s))
153 return NULL;
154 errno = rl_read_init_file(s);
155 if (errno)
156 return PyErr_SetFromErrno(PyExc_IOError);
157 Py_RETURN_NONE;
158}
159
160PyDoc_STRVAR(doc_read_init_file,
161"read_init_file([filename]) -> None\n\
162Execute a readline initialization file.\n\
163The default filename is the last filename used.");
164
165
166/* Exported function to load a readline history file */
167
168static PyObject *
169read_history_file(PyObject *self, PyObject *args)
170{
171 char *s = NULL;
172 if (!PyArg_ParseTuple(args, "|z:read_history_file", &s))
173 return NULL;
174 errno = read_history(s);
175 if (errno)
176 return PyErr_SetFromErrno(PyExc_IOError);
177 Py_RETURN_NONE;
178}
179
180static int _history_length = -1; /* do not truncate history by default */
181PyDoc_STRVAR(doc_read_history_file,
182"read_history_file([filename]) -> None\n\
183Load a readline history file.\n\
184The default filename is ~/.history.");
185
186
187/* Exported function to save a readline history file */
188
189static PyObject *
190write_history_file(PyObject *self, PyObject *args)
191{
192 char *s = NULL;
193 if (!PyArg_ParseTuple(args, "|z:write_history_file", &s))
194 return NULL;
195 errno = write_history(s);
196 if (!errno && _history_length >= 0)
197 history_truncate_file(s, _history_length);
198 if (errno)
199 return PyErr_SetFromErrno(PyExc_IOError);
200 Py_RETURN_NONE;
201}
202
203PyDoc_STRVAR(doc_write_history_file,
204"write_history_file([filename]) -> None\n\
205Save a readline history file.\n\
206The default filename is ~/.history.");
207
208
209/* Set history length */
210
211static PyObject*
212set_history_length(PyObject *self, PyObject *args)
213{
214 int length = _history_length;
215 if (!PyArg_ParseTuple(args, "i:set_history_length", &length))
216 return NULL;
217 _history_length = length;
218 Py_RETURN_NONE;
219}
220
221PyDoc_STRVAR(set_history_length_doc,
222"set_history_length(length) -> None\n\
223set the maximal number of lines which will be written to\n\
224the history file. A negative length is used to inhibit\n\
225history truncation.");
226
227
228/* Get history length */
229
230static PyObject*
231get_history_length(PyObject *self, PyObject *noarg)
232{
233 return PyInt_FromLong(_history_length);
234}
235
236PyDoc_STRVAR(get_history_length_doc,
237"get_history_length() -> int\n\
238return the maximum number of lines that will be written to\n\
239the history file.");
240
241
242/* Generic hook function setter */
243
244static PyObject *
245set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
246{
247 PyObject *function = Py_None;
248 char buf[80];
249 PyOS_snprintf(buf, sizeof(buf), "|O:set_%.50s", funcname);
250 if (!PyArg_ParseTuple(args, buf, &function))
251 return NULL;
252 if (function == Py_None) {
253 Py_CLEAR(*hook_var);
254 }
255 else if (PyCallable_Check(function)) {
256 PyObject *tmp = *hook_var;
257 Py_INCREF(function);
258 *hook_var = function;
259 Py_XDECREF(tmp);
260 }
261 else {
262 PyOS_snprintf(buf, sizeof(buf),
263 "set_%.50s(func): argument not callable",
264 funcname);
265 PyErr_SetString(PyExc_TypeError, buf);
266 return NULL;
267 }
268 Py_RETURN_NONE;
269}
270
271
272/* Exported functions to specify hook functions in Python */
273
274static PyObject *completion_display_matches_hook = NULL;
275static PyObject *startup_hook = NULL;
276static PyObject *bind_shell_command_hook = NULL;
277
278#ifdef HAVE_RL_PRE_INPUT_HOOK
279static PyObject *pre_input_hook = NULL;
280#endif
281
282static PyObject *
283set_completion_display_matches_hook(PyObject *self, PyObject *args)
284{
285 PyObject *result = set_hook("completion_display_matches_hook",
286 &completion_display_matches_hook, args);
287#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
288 /* We cannot set this hook globally, since it replaces the
289 default completion display. */
290 rl_completion_display_matches_hook =
291 completion_display_matches_hook ?
292#if defined(_RL_FUNCTION_TYPEDEF)
293 (rl_compdisp_func_t *)on_completion_display_matches_hook : 0;
294#else
295 (VFunction *)on_completion_display_matches_hook : 0;
296#endif
297#endif
298 return result;
299
300}
301
302PyDoc_STRVAR(doc_set_completion_display_matches_hook,
303"set_completion_display_matches_hook([function]) -> None\n\
304Set or remove the completion display function.\n\
305The function is called as\n\
306 function(substitution, [matches], longest_match_length)\n\
307once each time matches need to be displayed.");
308
309static PyObject *
310set_startup_hook(PyObject *self, PyObject *args)
311{
312 return set_hook("startup_hook", &startup_hook, args);
313}
314
315PyDoc_STRVAR(doc_set_startup_hook,
316"set_startup_hook([function]) -> None\n\
317Set or remove the function invoked by the rl_startup_hook callback.\n\
318The function is called with no arguments just\n\
319before readline prints the first prompt.");
320
321
322#ifdef HAVE_RL_PRE_INPUT_HOOK
323
324/* Set pre-input hook */
325
326static PyObject *
327set_pre_input_hook(PyObject *self, PyObject *args)
328{
329 return set_hook("pre_input_hook", &pre_input_hook, args);
330}
331
332PyDoc_STRVAR(doc_set_pre_input_hook,
333"set_pre_input_hook([function]) -> None\n\
334Set or remove the function invoked by the rl_pre_input_hook callback.\n\
335The function is called with no arguments after the first prompt\n\
336has been printed and just before readline starts reading input\n\
337characters.");
338
339#endif
340
341
342/* Exported function to specify a word completer in Python */
343
344static PyObject *completer = NULL;
345
346static PyObject *begidx = NULL;
347static PyObject *endidx = NULL;
348
349
350/* Get the completion type for the scope of the tab-completion */
351static PyObject *
352get_completion_type(PyObject *self, PyObject *noarg)
353{
354 return PyInt_FromLong(rl_completion_type);
355}
356
357PyDoc_STRVAR(doc_get_completion_type,
358"get_completion_type() -> int\n\
359Get the type of completion being attempted.");
360
361
362/* Set bind -x Python command hook */
363
364static PyObject *
365set_bind_shell_command_hook(PyObject *self, PyObject *args)
366{
367 return set_hook("bind_shell_command_hook", &bind_shell_command_hook, args);
368}
369
370PyDoc_STRVAR(doc_set_bind_shell_command_hook,
371"set_bind_shell_command_hook([function]) -> None\n\
372Set or remove the function invoked by the rl_bind_keyseq_in_map callback.\n\
373The function is called with three arguments: the string to parse and evaluate,\n\
374the contents of the readline buffer to put in the READLINE_LINE env var,\n\
375and the int of the cursor's point in the buffer to put in READLINE_POINT.\n\
376It must return the READLINE_* vars in a tuple.");
377
378
379/* Get the beginning index for the scope of the tab-completion */
380
381static PyObject *
382get_begidx(PyObject *self, PyObject *noarg)
383{
384 Py_INCREF(begidx);
385 return begidx;
386}
387
388PyDoc_STRVAR(doc_get_begidx,
389"get_begidx() -> int\n\
390get the beginning index of the completion scope");
391
392
393/* Get the ending index for the scope of the tab-completion */
394
395static PyObject *
396get_endidx(PyObject *self, PyObject *noarg)
397{
398 Py_INCREF(endidx);
399 return endidx;
400}
401
402PyDoc_STRVAR(doc_get_endidx,
403"get_endidx() -> int\n\
404get the ending index of the completion scope");
405
406
407/* Set the tab-completion word-delimiters that readline uses */
408
409static PyObject *
410set_completer_delims(PyObject *self, PyObject *args)
411{
412 char *break_chars;
413
414 if (!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) {
415 return NULL;
416 }
417 /* Keep a reference to the allocated memory in the module state in case
418 some other module modifies rl_completer_word_break_characters
419 (see issue #17289). */
420 break_chars = strdup(break_chars);
421 if (break_chars) {
422 free(completer_word_break_characters);
423 completer_word_break_characters = break_chars;
424 rl_completer_word_break_characters = break_chars;
425 Py_RETURN_NONE;
426 }
427 else
428 return PyErr_NoMemory();
429}
430
431PyDoc_STRVAR(doc_set_completer_delims,
432"set_completer_delims(string) -> None\n\
433set the word delimiters for completion");
434
435/* _py_free_history_entry: Utility function to free a history entry. */
436
437#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0500
438
439/* Readline version >= 5.0 introduced a timestamp field into the history entry
440 structure; this needs to be freed to avoid a memory leak. This version of
441 readline also introduced the handy 'free_history_entry' function, which
442 takes care of the timestamp. */
443
444static void
445_py_free_history_entry(HIST_ENTRY *entry)
446{
447 histdata_t data = free_history_entry(entry);
448 free(data);
449}
450
451#else
452
453/* No free_history_entry function; free everything manually. */
454
455static void
456_py_free_history_entry(HIST_ENTRY *entry)
457{
458 if (entry->line)
459 free((void *)entry->line);
460 if (entry->data)
461 free(entry->data);
462 free(entry);
463}
464
465#endif
466
467static PyObject *
468py_remove_history(PyObject *self, PyObject *args)
469{
470 int entry_number;
471 HIST_ENTRY *entry;
472
473 if (!PyArg_ParseTuple(args, "i:remove_history_item", &entry_number))
474 return NULL;
475 if (entry_number < 0) {
476 PyErr_SetString(PyExc_ValueError,
477 "History index cannot be negative");
478 return NULL;
479 }
480 entry = remove_history(entry_number);
481 if (!entry) {
482 PyErr_Format(PyExc_ValueError,
483 "No history item at position %d",
484 entry_number);
485 return NULL;
486 }
487 /* free memory allocated for the history entry */
488 _py_free_history_entry(entry);
489 Py_RETURN_NONE;
490}
491
492PyDoc_STRVAR(doc_remove_history,
493"remove_history_item(pos) -> None\n\
494remove history item given by its position");
495
496static PyObject *
497py_replace_history(PyObject *self, PyObject *args)
498{
499 int entry_number;
500 char *line;
501 HIST_ENTRY *old_entry;
502
503 if (!PyArg_ParseTuple(args, "is:replace_history_item", &entry_number,
504 &line)) {
505 return NULL;
506 }
507 if (entry_number < 0) {
508 PyErr_SetString(PyExc_ValueError,
509 "History index cannot be negative");
510 return NULL;
511 }
512 old_entry = replace_history_entry(entry_number, line, (void *)NULL);
513 if (!old_entry) {
514 PyErr_Format(PyExc_ValueError,
515 "No history item at position %d",
516 entry_number);
517 return NULL;
518 }
519 /* free memory allocated for the old history entry */
520 _py_free_history_entry(old_entry);
521 Py_RETURN_NONE;
522}
523
524PyDoc_STRVAR(doc_replace_history,
525"replace_history_item(pos, line) -> None\n\
526replaces history item given by its position with contents of line");
527
528/* Add a line to the history buffer */
529
530static PyObject *
531py_add_history(PyObject *self, PyObject *args)
532{
533 char *line;
534
535 if(!PyArg_ParseTuple(args, "s:add_history", &line)) {
536 return NULL;
537 }
538 add_history(line);
539 Py_RETURN_NONE;
540}
541
542PyDoc_STRVAR(doc_add_history,
543"add_history(string) -> None\n\
544add an item to the history buffer");
545
546
547/* Get the tab-completion word-delimiters that readline uses */
548
549static PyObject *
550get_completer_delims(PyObject *self, PyObject *noarg)
551{
552 return PyString_FromString(rl_completer_word_break_characters);
553}
554
555PyDoc_STRVAR(doc_get_completer_delims,
556"get_completer_delims() -> string\n\
557get the word delimiters for completion");
558
559
560/* Set the completer function */
561
562static PyObject *
563set_completer(PyObject *self, PyObject *args)
564{
565 return set_hook("completer", &completer, args);
566}
567
568PyDoc_STRVAR(doc_set_completer,
569"set_completer([function]) -> None\n\
570Set or remove the completer function.\n\
571The function is called as function(text, state),\n\
572for state in 0, 1, 2, ..., until it returns a non-string.\n\
573It should return the next possible completion starting with 'text'.");
574
575
576static PyObject *
577get_completer(PyObject *self, PyObject *noargs)
578{
579 if (completer == NULL) {
580 Py_RETURN_NONE;
581 }
582 Py_INCREF(completer);
583 return completer;
584}
585
586PyDoc_STRVAR(doc_get_completer,
587"get_completer() -> function\n\
588\n\
589Returns current completer function.");
590
591/* Private function to get current length of history. XXX It may be
592 * possible to replace this with a direct use of history_length instead,
593 * but it's not clear whether BSD's libedit keeps history_length up to date.
594 * See issue #8065.*/
595
596static int
597_py_get_history_length(void)
598{
599 HISTORY_STATE *hist_st = history_get_history_state();
600 int length = hist_st->length;
601 /* the history docs don't say so, but the address of hist_st changes each
602 time history_get_history_state is called which makes me think it's
603 freshly malloc'd memory... on the other hand, the address of the last
604 line stays the same as long as history isn't extended, so it appears to
605 be malloc'd but managed by the history package... */
606 free(hist_st);
607 return length;
608}
609
610/* Exported function to get any element of history */
611
612static PyObject *
613get_history_item(PyObject *self, PyObject *args)
614{
615 int idx = 0;
616 HIST_ENTRY *hist_ent;
617
618 if (!PyArg_ParseTuple(args, "i:get_history_item", &idx))
619 return NULL;
620#ifdef __APPLE__
621 if (using_libedit_emulation) {
622 /* Older versions of libedit's readline emulation
623 * use 0-based indexes, while readline and newer
624 * versions of libedit use 1-based indexes.
625 */
626 int length = _py_get_history_length();
627
628 idx = idx - 1 + libedit_history_start;
629
630 /*
631 * Apple's readline emulation crashes when
632 * the index is out of range, therefore
633 * test for that and fail gracefully.
634 */
635 if (idx < (0 + libedit_history_start)
636 || idx >= (length + libedit_history_start)) {
637 Py_RETURN_NONE;
638 }
639 }
640#endif /* __APPLE__ */
641 if ((hist_ent = history_get(idx)))
642 return PyString_FromString(hist_ent->line);
643 else {
644 Py_RETURN_NONE;
645 }
646}
647
648PyDoc_STRVAR(doc_get_history_item,
649"get_history_item() -> string\n\
650return the current contents of history item at index.");
651
652
653/* Exported function to get current length of history */
654
655static PyObject *
656get_current_history_length(PyObject *self, PyObject *noarg)
657{
658 return PyInt_FromLong((long)_py_get_history_length());
659}
660
661PyDoc_STRVAR(doc_get_current_history_length,
662"get_current_history_length() -> integer\n\
663return the current (not the maximum) length of history.");
664
665
666/* Exported function to read the current line buffer */
667
668static PyObject *
669get_line_buffer(PyObject *self, PyObject *noarg)
670{
671 return PyString_FromString(rl_line_buffer);
672}
673
674PyDoc_STRVAR(doc_get_line_buffer,
675"get_line_buffer() -> string\n\
676return the current contents of the line buffer.");
677
678
679#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
680
681/* Exported function to clear the current history */
682
683static PyObject *
684py_clear_history(PyObject *self, PyObject *noarg)
685{
686 clear_history();
687 Py_RETURN_NONE;
688}
689
690PyDoc_STRVAR(doc_clear_history,
691"clear_history() -> None\n\
692Clear the current readline history.");
693#endif
694
695/* Added for OSH. We need to call this in our SIGWINCH handler so global
696 * variables in readline get updated. */
697static PyObject *
698py_resize_terminal(PyObject *self, PyObject *noarg)
699{
700 rl_resize_terminal();
701 Py_RETURN_NONE;
702}
703
704/* Exported function to insert text into the line buffer */
705
706static PyObject *
707insert_text(PyObject *self, PyObject *args)
708{
709 char *s;
710 if (!PyArg_ParseTuple(args, "s:insert_text", &s))
711 return NULL;
712 rl_insert_text(s);
713 Py_RETURN_NONE;
714}
715
716PyDoc_STRVAR(doc_insert_text,
717"insert_text(string) -> None\n\
718Insert text into the line buffer at the cursor position.");
719
720
721/* Redisplay the line buffer */
722
723static PyObject *
724redisplay(PyObject *self, PyObject *noarg)
725{
726 rl_redisplay();
727 Py_RETURN_NONE;
728}
729
730PyDoc_STRVAR(doc_redisplay,
731"redisplay() -> None\n\
732Change what's displayed on the screen to reflect the current\n\
733contents of the line buffer.");
734
735
736/* Functions added to implement the 'bind' builtin in OSH */
737
738/* -x/-X command keymaps */
739static Keymap emacs_cmd_map;
740static Keymap vi_insert_cmd_map;
741static Keymap vi_movement_cmd_map;
742
743/*
744 These forcibly cast between a Keymap* and a rl_command_func_t*. Readline
745 uses an additional `.type` field to keep track of the pointer's true type.
746*/
747#define RL_KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
748#define RL_FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
749
750static void
751_init_command_maps(void)
752{
753 emacs_cmd_map = rl_make_bare_keymap();
754 vi_insert_cmd_map = rl_make_bare_keymap();
755 vi_movement_cmd_map = rl_make_bare_keymap();
756
757 /* Ensure that Esc- and Ctrl-X are also keymaps */
758 emacs_cmd_map[CTRL('X')].type = ISKMAP;
759 emacs_cmd_map[CTRL('X')].function = RL_KEYMAP_TO_FUNCTION(rl_make_bare_keymap());
760 emacs_cmd_map[ESC].type = ISKMAP;
761 emacs_cmd_map[ESC].function = RL_KEYMAP_TO_FUNCTION(rl_make_bare_keymap());
762}
763
764static Keymap
765_get_associated_cmd_map(Keymap kmap)
766{
767 if (emacs_cmd_map == NULL)
768 _init_command_maps();
769
770 if (kmap == emacs_standard_keymap)
771 return emacs_cmd_map;
772 else if (kmap == vi_insertion_keymap)
773 return vi_insert_cmd_map;
774 else if (kmap == vi_movement_keymap)
775 return vi_movement_cmd_map;
776 else if (kmap == emacs_meta_keymap)
777 return (RL_FUNCTION_TO_KEYMAP(emacs_cmd_map, ESC));
778 else if (kmap == emacs_ctlx_keymap)
779 return (RL_FUNCTION_TO_KEYMAP(emacs_cmd_map, CTRL('X')));
780
781 return (Keymap) NULL;
782}
783
784/* List binding functions */
785static PyObject*
786list_funmap_names(PyObject *self, PyObject *args)
787{
788 rl_list_funmap_names();
789 // printf ("Compiled w/ readline version: %s\n", rl_library_version ? rl_library_version : "unknown");
790 Py_RETURN_NONE;
791}
792
793PyDoc_STRVAR(doc_list_funmap_names,
794"list_funmap_names() -> None\n\
795Print all of the available readline functions.");
796
797/* Print readline functions and their bindings */
798
799static PyObject*
800function_dumper(PyObject *self, PyObject *args)
801{
802 int print_readably;
803
804 if (!PyArg_ParseTuple(args, "i:function_dumper", &print_readably))
805 return NULL;
806
807 rl_function_dumper(print_readably);
808 Py_RETURN_NONE;
809}
810
811PyDoc_STRVAR(doc_list_function_dumper,
812"function_dumper(bool) -> None\n\
813Print all readline functions and their bindings.");
814
815/* Print macros, their bindings, and their string outputs */
816
817static PyObject*
818macro_dumper(PyObject *self, PyObject *args)
819{
820 int print_readably;
821
822 if (!PyArg_ParseTuple(args, "i:macro_dumper", &print_readably))
823 return NULL;
824
825 rl_macro_dumper(print_readably);
826 Py_RETURN_NONE;
827}
828
829PyDoc_STRVAR(doc_list_macro_dumper,
830"macro_dumper(bool) -> None\n\
831Print all readline sequences bound to macros and the strings they output.");
832
833/* List readline variables */
834
835static PyObject*
836variable_dumper(PyObject *self, PyObject *args)
837{
838 int print_readably;
839
840 if (!PyArg_ParseTuple(args, "i:variable_dumper", &print_readably))
841 return NULL;
842
843 rl_variable_dumper(print_readably);
844 Py_RETURN_NONE;
845}
846
847PyDoc_STRVAR(doc_list_variable_dumper,
848"variable_dumper(bool) -> None\n\
849List readline variables and their values.");
850
851
852/* Query bindings for a function name */
853
854// readline returns null-terminated string arrays
855void _strvec_dispose(char **strvec) {
856 register int i;
857
858 if (strvec == NULL)
859 return;
860
861 for (i = 0; strvec[i]; i++) {
862 free(strvec[i]);
863 }
864
865 free(strvec);
866}
867
868// Nicely prints a strvec with commas and an and
869// like '"foo", "bar", and "moop"'
870void _pprint_strvec_list(char **strvec) {
871 int i;
872
873 for (i = 0; strvec[i]; i++) {
874 printf("\"%s\"", strvec[i]);
875 if (strvec[i + 1]) {
876 printf(", ");
877 if (!strvec[i + 2])
878 printf("and ");
879 }
880 }
881}
882
883/*
884NB: readline (and bash) have a bug where they don't see certain keyseqs, even
885if the bindings work. E.g., if you bind a number key like "\C-7", it will be
886bound, but reporting code like query_bindings and function_dumper won't count it.
887*/
888
889static PyObject*
890query_bindings(PyObject *self, PyObject *args)
891{
892 char *fn_name;
893 rl_command_func_t *cmd_fn;
894 char **key_seqs;
895
896 if (!PyArg_ParseTuple(args, "s:query_bindings", &fn_name))
897 return NULL;
898
899 cmd_fn = rl_named_function(fn_name);
900
901 if (cmd_fn == NULL) {
902 PyErr_Format(PyExc_ValueError, "`%s': unknown function name", fn_name);
903 return NULL;
904 }
905
906 key_seqs = rl_invoking_keyseqs(cmd_fn);
907
908 if (!key_seqs) {
909 // print to stdout, but return an error
910 printf("%s is not bound to any keys.\n", fn_name);
911 PyErr_SetNone(PyExc_ValueError);
912 return NULL;
913 }
914
915 printf("%s can be invoked via ", fn_name);
916 _pprint_strvec_list(key_seqs);
917 printf(".\n");
918
919 _strvec_dispose(key_seqs);
920
921 Py_RETURN_NONE;
922}
923
924PyDoc_STRVAR(doc_query_bindings,
925"query_bindings(str) -> None\n\
926Query bindings to see what's bound to a given function.");
927
928
929static PyObject*
930unbind_rl_function(PyObject *self, PyObject *args)
931{
932 char *fn_name;
933 rl_command_func_t *cmd_fn;
934
935 if (!PyArg_ParseTuple(args, "s:unbind_rl_function", &fn_name))
936 return NULL;
937
938 cmd_fn = rl_named_function(fn_name);
939 if (cmd_fn == NULL) {
940 PyErr_Format(PyExc_ValueError, "`%s': unknown function name", fn_name);
941 return NULL;
942 }
943
944 rl_unbind_function_in_map(cmd_fn, rl_get_keymap());
945 Py_RETURN_NONE;
946}
947
948PyDoc_STRVAR(doc_unbind_rl_function,
949"unbind_rl_function(function_name) -> None\n\
950Unbind all keys bound to the named readline function in the current keymap.");
951
952
953static PyObject*
954print_shell_cmd_map(PyObject *self, PyObject *noarg)
955{
956 Keymap curr_map, cmd_map;
957
958 curr_map = rl_get_keymap();
959 cmd_map = _get_associated_cmd_map(curr_map);
960
961 if (cmd_map == NULL) {
962 PyErr_SetString(PyExc_ValueError, "Could not get shell command map for current keymap");
963 return NULL;
964 }
965
966 rl_set_keymap(cmd_map);
967 rl_macro_dumper(1);
968 rl_set_keymap(curr_map);
969
970 Py_RETURN_NONE;
971}
972
973PyDoc_STRVAR(doc_print_shell_cmd_map,
974"print_shell_cmd_map() -> None\n\
975Print all bindings for shell commands in the current keymap.");
976
977
978/* Support fns for bind -x */
979
980static void
981debug_print(const char *fmt, ...) {
982 va_list args;
983 va_start(args, fmt);
984 printf("[osh_execute] ");
985 vprintf(fmt, args);
986 printf("\n");
987 va_end(args);
988}
989
990static void
991make_line_if_needed(char *new_line)
992{
993 if (strcmp(new_line, rl_line_buffer) != 0) {
994 rl_point = rl_end;
995
996 rl_add_undo(UNDO_BEGIN, 0, 0, 0);
997 rl_delete_text(0, rl_point);
998 rl_point = rl_end = rl_mark = 0;
999 rl_insert_text(new_line);
1000 rl_add_undo(UNDO_END, 0, 0, 0);
1001 }
1002}
1003
1004static char*
1005get_bound_command(Keymap cmd_map) {
1006 int type;
1007 char *cmd = (char *)rl_function_of_keyseq(rl_executing_keyseq, cmd_map, &type);
1008
1009 if (cmd == NULL || type != ISMACR) {
1010 PyErr_SetString(PyExc_RuntimeError,
1011 "Cannot find shell command bound to this key sequence");
1012 return NULL;
1013 }
1014
1015 // debug_print("Found bound command: '%s'", cmd);
1016 return cmd;
1017}
1018
1019static void
1020clear_current_line(int use_ce) {
1021 if (use_ce) {
1022 // debug_print("Clearing line with termcap 'ce'");
1023 rl_clear_visible_line();
1024 fflush(rl_outstream);
1025 } else {
1026 // debug_print("No termcap 'ce', using newline");
1027 rl_crlf();
1028 }
1029}
1030
1031
1032#if 0
1033/* Save readline state to Python variables */
1034static int
1035save_readline_state(void) {
1036 PyObject *line = NULL, *point = NULL;
1037
1038 debug_print("Saving readline state - line: '%s', point: %d",
1039 rl_line_buffer, rl_point);
1040
1041 /* Create Python string for readline line */
1042 line = PyString_FromString(rl_line_buffer);
1043 if (!line) {
1044 PyErr_SetString(PyExc_RuntimeError,
1045 "Failed to convert readline line to Python string");
1046 return 0;
1047 }
1048
1049 /* Create Python int for readline point */
1050 point = PyInt_FromLong(rl_point);
1051 if (!point) {
1052 Py_DECREF(line);
1053 PyErr_SetString(PyExc_RuntimeError,
1054 "Failed to convert readline point to Python int");
1055 return 0;
1056 }
1057
1058 /* Set the Python variables */
1059 if (PyDict_SetItemString(PyEval_GetGlobals(), "READLINE_LINE", line) < 0 ||
1060 PyDict_SetItemString(PyEval_GetGlobals(), "READLINE_POINT", point) < 0) {
1061 Py_DECREF(line);
1062 Py_DECREF(point);
1063 PyErr_SetString(PyExc_RuntimeError,
1064 "Failed to set READLINE_LINE/POINT variables");
1065 return 0;
1066 }
1067
1068 Py_DECREF(line);
1069 Py_DECREF(point);
1070 return 1;
1071}
1072
1073/* Update readline state from Python variables */
1074static int
1075restore_readline_state(void) {
1076 PyObject *line = NULL, *point = NULL;
1077 const char *new_line;
1078 long new_point;
1079
1080 debug_print("Restoring readline state from Python variables");
1081
1082 /* Get the Python variables */
1083 line = PyDict_GetItemString(PyEval_GetGlobals(), "READLINE_LINE");
1084 point = PyDict_GetItemString(PyEval_GetGlobals(), "READLINE_POINT");
1085
1086 if (line && PyString_Check(line)) {
1087 new_line = PyString_AsString(line);
1088 debug_print("Got new line from Python: '%s'", new_line);
1089
1090 /* Update if different */
1091 if (strcmp(new_line, rl_line_buffer) != 0) {
1092 debug_print("Line changed, updating readline buffer");
1093 make_line_if_needed((char *)new_line);
1094 }
1095 }
1096
1097 if (point && PyInt_Check(point)) {
1098 new_point = PyInt_AsLong(point);
1099 debug_print("Got new point from Python: %ld", new_point);
1100
1101 /* Validate and update point if needed */
1102 if (new_point != rl_point) {
1103 if (new_point > rl_end)
1104 new_point = rl_end;
1105 else if (new_point < 0)
1106 new_point = 0;
1107
1108 debug_print("Point changed, updating to: %ld", new_point);
1109 rl_point = new_point;
1110 }
1111 }
1112
1113 return 1;
1114}
1115#endif
1116
1117
1118/* Main entry point for executing shell commands. Based on bash_execute_unix_command */
1119
1120static int
1121on_bind_shell_command_hook(int count /* unused */, int key /* unused */) {
1122 char *cmd;
1123 int use_ce;
1124 Keymap cmd_map;
1125 PyObject *r = NULL;
1126 #ifdef WITH_THREAD
1127 PyGILState_STATE gilstate;
1128 #endif
1129 int cmd_return_code;
1130 char *line_buffer;
1131 char *point;
1132 int result;
1133
1134 debug_print("Starting shell command execution");
1135
1136#ifdef WITH_THREAD
1137 gilstate = PyGILState_Ensure();
1138#endif
1139
1140 if (bind_shell_command_hook == NULL) {
1141 PyErr_SetString(PyExc_RuntimeError, "No bind_shell_command_hook set");
1142 return 1;
1143 }
1144
1145 cmd_map = _get_associated_cmd_map(rl_get_keymap());
1146 cmd = get_bound_command(cmd_map);
1147 if (!cmd) {
1148 PyErr_SetString(PyExc_RuntimeError, "on_bind_shell_command_hook: Cannot find shell command in keymap");
1149 rl_crlf();
1150 rl_forced_update_display();
1151 return 1;
1152 }
1153
1154 use_ce = rl_get_termcap("ce") != NULL;
1155 clear_current_line(use_ce);
1156
1157 // debug_print("Preparing to execute shell command: '%s'", cmd);
1158 // debug_print("rl_line_buffer: '%s'", rl_line_buffer);
1159 // debug_print("rl_point: '%i'", rl_point);
1160
1161 r = PyObject_CallFunction(bind_shell_command_hook,
1162 "ssi", cmd, rl_line_buffer, rl_point);
1163 if (r == NULL) {
1164 PyErr_Print();
1165 result = 1;
1166 goto cleanup;
1167 }
1168 if (!PyArg_ParseTuple(r, "iss", &cmd_return_code, &line_buffer, &point)) {
1169 PyErr_SetString(PyExc_ValueError, "Expected (int, str, str) tuple from bind_shell_command_hook");
1170 result = 1;
1171 goto cleanup;
1172 }
1173
1174 // debug_print("Command return code: %d", cmd_return_code);
1175 // debug_print("New line buffer: '%s'", line_buffer);
1176 // debug_print("New point: '%s'", point);
1177
1178 // if (save_readline_state() != 1 || restore_readline_state() != 1) {
1179 // PyErr_SetString(PyExc_RuntimeError, "Failed to update readline state");
1180 // result = 1;
1181 // goto cleanup;
1182 // }
1183
1184
1185 /* Redraw the prompt */
1186 if (use_ce) // need to handle a `&& return code != 124` somehow
1187 rl_redraw_prompt_last_line();
1188 else
1189 rl_forced_update_display();
1190
1191 result = 0;
1192 // debug_print("Completed shell command execution");
1193
1194cleanup:
1195 Py_XDECREF(r);
1196#ifdef WITH_THREAD
1197 PyGILState_Release(gilstate);
1198#endif
1199
1200done:
1201 return result;
1202}
1203
1204
1205/* Binds a key sequence to arbitrary shell code, not readline fns */
1206static PyObject*
1207bind_shell_command(PyObject *self, PyObject *args) {
1208 const char *kseq;
1209 const char *cmd, *cparam;
1210 Keymap kmap, cmd_xmap;
1211
1212 if (!PyArg_ParseTuple(args, "ss:bind_shell_command", &kseq, &cparam)) {
1213 return NULL;
1214 }
1215
1216 /* readline will own the cmd string, so we need to make a copy */
1217 cmd = strdup(cparam);
1218 if (cmd == NULL) {
1219 return PyErr_NoMemory();
1220 }
1221
1222 kmap = rl_get_keymap();
1223 cmd_xmap = _get_associated_cmd_map(kmap);
1224
1225
1226 if (rl_generic_bind(ISMACR, kseq, (char *)cmd, cmd_xmap) != 0
1227 || rl_bind_keyseq_in_map (kseq, on_bind_shell_command_hook, kmap) != 0) {
1228 PyErr_Format(PyExc_RuntimeError, "Failed to bind key sequence '%s' to command '%s'", kseq, cmd);
1229 free(cmd);
1230 return NULL;
1231 }
1232
1233 Py_RETURN_NONE;
1234}
1235
1236PyDoc_STRVAR(doc_bind_shell_command,
1237"bind_shell_command(key_sequence, command) -> None\n\
1238Bind a key sequence to a shell command in the current keymap.");
1239
1240
1241/* Remove all bindings for a given keyseq */
1242
1243int
1244_unbind_shell_cmd(char *keyseq)
1245{
1246/* Unbind a key sequence from the current keymap's associated shell command map. */
1247Keymap cmd_map;
1248
1249 cmd_map = _get_associated_cmd_map(rl_get_keymap());
1250
1251 if (rl_bind_keyseq_in_map(keyseq, (rl_command_func_t *)NULL, cmd_map) != 0) {
1252 PyErr_Format(PyExc_ValueError, "'%s': can't unbind from shell command keymap", keyseq);
1253 return 0;
1254 }
1255
1256 return 1;
1257}
1258
1259static PyObject*
1260unbind_keyseq(PyObject *self, PyObject *args)
1261{
1262 char *seq, *keyseq;
1263 int kslen, type;
1264 rl_command_func_t *fn;
1265
1266 if (!PyArg_ParseTuple(args, "s:unbind_keyseq", &seq))
1267 return NULL;
1268
1269 /* Parse and check validity of keyseq */
1270 keyseq = (char *)malloc((2 * strlen(seq)) + 1);
1271 if (rl_translate_keyseq(seq, keyseq, &kslen) != 0) {
1272 free(keyseq);
1273 PyErr_Format(PyExc_ValueError, "'%s': invalid key sequence", seq);
1274 Py_RETURN_NONE;
1275 }
1276
1277 fn = rl_function_of_keyseq(keyseq, (Keymap)NULL, &type);
1278 free(keyseq);
1279
1280 if (!fn) {
1281 Py_RETURN_NONE;
1282 }
1283
1284 if (type == ISKMAP) {
1285 fn = ((Keymap)fn)[ANYOTHERKEY].function;
1286 }
1287
1288 if (rl_bind_keyseq(seq, (rl_command_func_t *)NULL) != 0) {
1289 PyErr_Format(PyExc_ValueError, "'%s': cannot unbind", seq);
1290 Py_RETURN_NONE;
1291 }
1292
1293 if (fn == on_bind_shell_command_hook) {
1294 _unbind_shell_cmd (seq);
1295 }
1296
1297 Py_RETURN_NONE;
1298}
1299
1300PyDoc_STRVAR(doc_unbind_keyseq,
1301"unbind_keyseq(sequence) -> None\n\
1302Unbind a key sequence from the current keymap.");
1303
1304
1305
1306/* Keymap toggling code */
1307static Keymap orig_keymap = NULL;
1308
1309static PyObject*
1310use_temp_keymap(PyObject *self, PyObject *args)
1311{
1312 char *keymap_name;
1313 Keymap new_keymap;
1314
1315 if (!PyArg_ParseTuple(args, "s:use_temp_keymap", &keymap_name))
1316 return NULL;
1317
1318 new_keymap = rl_get_keymap_by_name(keymap_name);
1319 if (new_keymap == NULL) {
1320 PyErr_Format(PyExc_ValueError, "`%s': unknown keymap name", keymap_name);
1321 return NULL;
1322 }
1323
1324 orig_keymap = rl_get_keymap();
1325 rl_set_keymap(new_keymap);
1326
1327 Py_RETURN_NONE;
1328}
1329
1330PyDoc_STRVAR(doc_use_temp_keymap,
1331"use_temp_keymap(keymap_name) -> None\n\
1332Temporarily switch to named keymap, saving the current one.");
1333
1334static PyObject*
1335restore_orig_keymap(PyObject *self, PyObject *args)
1336{
1337 if (orig_keymap != NULL) {
1338 rl_set_keymap(orig_keymap);
1339 orig_keymap = NULL;
1340 }
1341
1342 Py_RETURN_NONE;
1343}
1344
1345PyDoc_STRVAR(doc_restore_orig_keymap,
1346"restore_orig_keymap() -> None\n\
1347Restore the previously saved keymap if one exists.");
1348
1349/* Table of functions exported by the module */
1350
1351static struct PyMethodDef readline_methods[] = {
1352 {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind},
1353 {"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer},
1354 {"insert_text", insert_text, METH_VARARGS, doc_insert_text},
1355 {"redisplay", redisplay, METH_NOARGS, doc_redisplay},
1356 {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file},
1357 {"read_history_file", read_history_file,
1358 METH_VARARGS, doc_read_history_file},
1359 {"write_history_file", write_history_file,
1360 METH_VARARGS, doc_write_history_file},
1361 {"get_history_item", get_history_item,
1362 METH_VARARGS, doc_get_history_item},
1363 {"get_current_history_length", (PyCFunction)get_current_history_length,
1364 METH_NOARGS, doc_get_current_history_length},
1365 {"set_history_length", set_history_length,
1366 METH_VARARGS, set_history_length_doc},
1367 {"get_history_length", get_history_length,
1368 METH_NOARGS, get_history_length_doc},
1369 {"set_completer", set_completer, METH_VARARGS, doc_set_completer},
1370 {"get_completer", get_completer, METH_NOARGS, doc_get_completer},
1371 {"get_completion_type", get_completion_type,
1372 METH_NOARGS, doc_get_completion_type},
1373 {"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx},
1374 {"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx},
1375
1376 {"set_completer_delims", set_completer_delims,
1377 METH_VARARGS, doc_set_completer_delims},
1378 {"add_history", py_add_history, METH_VARARGS, doc_add_history},
1379 {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
1380 {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
1381 {"get_completer_delims", get_completer_delims,
1382 METH_NOARGS, doc_get_completer_delims},
1383
1384 {"set_completion_display_matches_hook", set_completion_display_matches_hook,
1385 METH_VARARGS, doc_set_completion_display_matches_hook},
1386 {"set_startup_hook", set_startup_hook,
1387 METH_VARARGS, doc_set_startup_hook},
1388 {"set_pre_input_hook", set_pre_input_hook,
1389 METH_VARARGS, doc_set_pre_input_hook},
1390 {"clear_history", py_clear_history, METH_NOARGS, doc_clear_history},
1391 {"resize_terminal", py_resize_terminal, METH_NOARGS, ""},
1392
1393 /* Functions added to implement the 'bind' builtin in OSH */
1394 {"list_funmap_names", list_funmap_names, METH_NOARGS, doc_list_funmap_names},
1395 {"function_dumper", function_dumper, METH_VARARGS, doc_list_function_dumper},
1396 {"macro_dumper", macro_dumper, METH_VARARGS, doc_list_macro_dumper},
1397 {"variable_dumper", variable_dumper, METH_VARARGS, doc_list_variable_dumper},
1398 {"query_bindings", query_bindings, METH_VARARGS, doc_query_bindings},
1399 {"unbind_rl_function", unbind_rl_function, METH_VARARGS, doc_unbind_rl_function},
1400 {"use_temp_keymap", use_temp_keymap, METH_VARARGS, doc_use_temp_keymap},
1401 {"restore_orig_keymap", restore_orig_keymap, METH_NOARGS, doc_restore_orig_keymap},
1402 {"print_shell_cmd_map", print_shell_cmd_map, METH_NOARGS, doc_print_shell_cmd_map},
1403 {"unbind_keyseq", unbind_keyseq, METH_VARARGS, doc_unbind_keyseq},
1404 {"bind_shell_command", bind_shell_command, METH_VARARGS, doc_bind_shell_command},
1405 {"set_bind_shell_command_hook", set_bind_shell_command_hook,
1406 METH_VARARGS, doc_set_bind_shell_command_hook},
1407 {0, 0}
1408};
1409
1410
1411/* C function to call the Python hooks. */
1412
1413static int
1414on_hook(PyObject *func)
1415{
1416 int result = 0;
1417 if (func != NULL) {
1418 PyObject *r;
1419#ifdef WITH_THREAD
1420 PyGILState_STATE gilstate = PyGILState_Ensure();
1421#endif
1422 r = PyObject_CallFunction(func, NULL);
1423 if (r == NULL)
1424 goto error;
1425 if (r == Py_None)
1426 result = 0;
1427 else {
1428 result = PyInt_AsLong(r);
1429 if (result == -1 && PyErr_Occurred())
1430 goto error;
1431 }
1432 Py_DECREF(r);
1433 goto done;
1434 error:
1435 PyErr_Clear();
1436 Py_XDECREF(r);
1437 done:
1438#ifdef WITH_THREAD
1439 PyGILState_Release(gilstate);
1440#endif
1441 return result;
1442 }
1443 return result;
1444}
1445
1446static int
1447#if defined(_RL_FUNCTION_TYPEDEF)
1448on_startup_hook(void)
1449#else
1450on_startup_hook()
1451#endif
1452{
1453 return on_hook(startup_hook);
1454}
1455
1456#ifdef HAVE_RL_PRE_INPUT_HOOK
1457static int
1458#if defined(_RL_FUNCTION_TYPEDEF)
1459on_pre_input_hook(void)
1460#else
1461on_pre_input_hook()
1462#endif
1463{
1464 return on_hook(pre_input_hook);
1465}
1466#endif
1467
1468
1469/* C function to call the Python completion_display_matches */
1470
1471#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
1472static void
1473on_completion_display_matches_hook(char **matches,
1474 int num_matches, int max_length)
1475{
1476 int i;
1477 PyObject *m=NULL, *s=NULL, *r=NULL;
1478#ifdef WITH_THREAD
1479 PyGILState_STATE gilstate = PyGILState_Ensure();
1480#endif
1481 m = PyList_New(num_matches);
1482 if (m == NULL)
1483 goto error;
1484 for (i = 0; i < num_matches; i++) {
1485 s = PyString_FromString(matches[i+1]);
1486 if (s == NULL)
1487 goto error;
1488 if (PyList_SetItem(m, i, s) == -1)
1489 goto error;
1490 }
1491
1492 r = PyObject_CallFunction(completion_display_matches_hook,
1493 "sOi", matches[0], m, max_length);
1494
1495 Py_DECREF(m); m=NULL;
1496
1497 if (r == NULL ||
1498 (r != Py_None && PyInt_AsLong(r) == -1 && PyErr_Occurred())) {
1499 goto error;
1500 }
1501 Py_XDECREF(r); r=NULL;
1502
1503 if (0) {
1504 error:
1505 PyErr_Clear();
1506 Py_XDECREF(m);
1507 Py_XDECREF(r);
1508 }
1509#ifdef WITH_THREAD
1510 PyGILState_Release(gilstate);
1511#endif
1512}
1513
1514#endif
1515
1516#ifdef HAVE_RL_RESIZE_TERMINAL
1517static volatile sig_atomic_t sigwinch_received;
1518static PyOS_sighandler_t sigwinch_ohandler;
1519
1520static void
1521readline_sigwinch_handler(int signum)
1522{
1523 sigwinch_received = 1;
1524 if (sigwinch_ohandler &&
1525 sigwinch_ohandler != SIG_IGN && sigwinch_ohandler != SIG_DFL)
1526 sigwinch_ohandler(signum);
1527}
1528#endif
1529
1530/* C function to call the Python completer. */
1531
1532static char *
1533on_completion(const char *text, int state)
1534{
1535 char *result = NULL;
1536 if (completer != NULL) {
1537 PyObject *r;
1538#ifdef WITH_THREAD
1539 PyGILState_STATE gilstate = PyGILState_Ensure();
1540#endif
1541 rl_attempted_completion_over = 1;
1542 r = PyObject_CallFunction(completer, "si", text, state);
1543 if (r == NULL)
1544 goto error;
1545 if (r == Py_None) {
1546 result = NULL;
1547 }
1548 else {
1549 char *s = PyString_AsString(r);
1550 if (s == NULL)
1551 goto error;
1552 result = strdup(s);
1553 }
1554 Py_DECREF(r);
1555 goto done;
1556 error:
1557 PyErr_Clear();
1558 Py_XDECREF(r);
1559 done:
1560#ifdef WITH_THREAD
1561 PyGILState_Release(gilstate);
1562#endif
1563 return result;
1564 }
1565 return result;
1566}
1567
1568
1569/* A more flexible constructor that saves the "begidx" and "endidx"
1570 * before calling the normal completer */
1571
1572static char **
1573flex_complete(const char *text, int start, int end)
1574{
1575#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1576 rl_completion_append_character ='\0';
1577#endif
1578#ifdef HAVE_RL_COMPLETION_SUPPRESS_APPEND
1579 rl_completion_suppress_append = 0;
1580#endif
1581 Py_XDECREF(begidx);
1582 Py_XDECREF(endidx);
1583 begidx = PyInt_FromLong((long) start);
1584 endidx = PyInt_FromLong((long) end);
1585 return completion_matches(text, *on_completion);
1586}
1587
1588
1589/* Helper to initialize GNU readline properly. */
1590
1591static void
1592setup_readline(void)
1593{
1594#ifdef SAVE_LOCALE
1595 char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
1596 if (!saved_locale)
1597 Py_FatalError("not enough memory to save locale");
1598#endif
1599
1600#ifdef __APPLE__
1601 /* the libedit readline emulation resets key bindings etc
1602 * when calling rl_initialize. So call it upfront
1603 */
1604 if (using_libedit_emulation)
1605 rl_initialize();
1606
1607 /* Detect if libedit's readline emulation uses 0-based
1608 * indexing or 1-based indexing.
1609 */
1610 add_history("1");
1611 if (history_get(1) == NULL) {
1612 libedit_history_start = 0;
1613 } else {
1614 libedit_history_start = 1;
1615 }
1616 clear_history();
1617#endif /* __APPLE__ */
1618
1619 using_history();
1620
1621 rl_readline_name = "oils";
1622#if defined(PYOS_OS2) && defined(PYCC_GCC)
1623 /* Allow $if term= in .inputrc to work */
1624 rl_terminal_name = getenv("TERM");
1625#endif
1626 /* Force rebind of TAB to insert-tab */
1627 rl_bind_key('\t', rl_insert);
1628 /* Bind both ESC-TAB and ESC-ESC to the completion function */
1629 rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
1630 rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
1631#ifdef HAVE_RL_RESIZE_TERMINAL
1632 /* Set up signal handler for window resize */
1633 sigwinch_ohandler = PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
1634#endif
1635 /* Set our hook functions */
1636 rl_startup_hook = on_startup_hook;
1637#ifdef HAVE_RL_PRE_INPUT_HOOK
1638 rl_pre_input_hook = on_pre_input_hook;
1639#endif
1640 /* Set our completion function */
1641 rl_attempted_completion_function = flex_complete;
1642 /* Set Python word break characters */
1643 completer_word_break_characters =
1644 rl_completer_word_break_characters =
1645 strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
1646 /* All nonalphanums except '.' */
1647
1648 begidx = PyInt_FromLong(0L);
1649 endidx = PyInt_FromLong(0L);
1650
1651#ifdef __APPLE__
1652 if (!using_libedit_emulation)
1653#endif
1654 {
1655 if (!isatty(STDOUT_FILENO)) {
1656 /* Issue #19884: stdout is not a terminal. Disable meta modifier
1657 keys to not write the ANSI sequence "\033[1034h" into stdout. On
1658 terminals supporting 8 bit characters like TERM=xterm-256color
1659 (which is now the default Fedora since Fedora 18), the meta key is
1660 used to enable support of 8 bit characters (ANSI sequence
1661 "\033[1034h").
1662
1663 With libedit, this call makes readline() crash. */
1664 rl_variable_bind ("enable-meta-key", "off");
1665 }
1666 }
1667
1668 /* Initialize (allows .inputrc to override)
1669 *
1670 * XXX: A bug in the readline-2.2 library causes a memory leak
1671 * inside this function. Nothing we can do about it.
1672 */
1673#ifdef __APPLE__
1674 if (using_libedit_emulation)
1675 rl_read_init_file(NULL);
1676 else
1677#endif /* __APPLE__ */
1678 rl_initialize();
1679
1680 RESTORE_LOCALE(saved_locale)
1681}
1682
1683/* Wrapper around GNU readline that handles signals differently. */
1684
1685
1686#if defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT)
1687
1688static char *completed_input_string;
1689static void
1690rlhandler(char *text)
1691{
1692 completed_input_string = text;
1693 rl_callback_handler_remove();
1694}
1695
1696static char *
1697readline_until_enter_or_signal(char *prompt, int *signal)
1698{
1699 char * not_done_reading = "";
1700 fd_set selectset;
1701
1702 *signal = 0;
1703#ifdef HAVE_RL_CATCH_SIGNAL
1704 rl_catch_signals = 0;
1705#endif
1706 /* OVM_MAIN: Oil is handling SIGWINCH, so readline shouldn't handle it.
1707 * Without this line, strace reveals that GNU readline is constantly
1708 * turning it on and off.
1709 * */
1710 rl_catch_sigwinch = 0;
1711
1712 rl_callback_handler_install (prompt, rlhandler);
1713 FD_ZERO(&selectset);
1714
1715 completed_input_string = not_done_reading;
1716
1717 while (completed_input_string == not_done_reading) {
1718 int has_input = 0;
1719
1720 while (!has_input)
1721 { struct timeval timeout = {0, 100000}; /* 0.1 seconds */
1722
1723 /* [Bug #1552726] Only limit the pause if an input hook has been
1724 defined. */
1725 struct timeval *timeoutp = NULL;
1726 if (PyOS_InputHook)
1727 timeoutp = &timeout;
1728#ifdef HAVE_RL_RESIZE_TERMINAL
1729 /* Update readline's view of the window size after SIGWINCH */
1730 if (sigwinch_received) {
1731 sigwinch_received = 0;
1732 rl_resize_terminal();
1733 }
1734#endif
1735 FD_SET(fileno(rl_instream), &selectset);
1736 /* select resets selectset if no input was available */
1737 has_input = select(fileno(rl_instream) + 1, &selectset,
1738 NULL, NULL, timeoutp);
1739 if(PyOS_InputHook) PyOS_InputHook();
1740 }
1741
1742 if(has_input > 0) {
1743 rl_callback_read_char();
1744 }
1745 else if (errno == EINTR) {
1746 int s;
1747#ifdef WITH_THREAD
1748 PyEval_RestoreThread(_PyOS_ReadlineTState);
1749#endif
1750 s = PyErr_CheckSignals();
1751#ifdef WITH_THREAD
1752 PyEval_SaveThread();
1753#endif
1754 if (s < 0) {
1755 rl_free_line_state();
1756#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0700
1757 rl_callback_sigcleanup();
1758#endif
1759 rl_cleanup_after_signal();
1760 rl_callback_handler_remove();
1761 *signal = 1;
1762 completed_input_string = NULL;
1763 }
1764 }
1765 }
1766
1767 return completed_input_string;
1768}
1769
1770
1771#else
1772
1773/* Interrupt handler */
1774
1775static jmp_buf jbuf;
1776
1777/* ARGSUSED */
1778static void
1779onintr(int sig)
1780{
1781 longjmp(jbuf, 1);
1782}
1783
1784
1785static char *
1786readline_until_enter_or_signal(char *prompt, int *signal)
1787{
1788 PyOS_sighandler_t old_inthandler;
1789 char *p;
1790
1791 *signal = 0;
1792
1793 old_inthandler = PyOS_setsig(SIGINT, onintr);
1794 if (setjmp(jbuf)) {
1795#ifdef HAVE_SIGRELSE
1796 /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
1797 sigrelse(SIGINT);
1798#endif
1799 PyOS_setsig(SIGINT, old_inthandler);
1800 *signal = 1;
1801 return NULL;
1802 }
1803 rl_event_hook = PyOS_InputHook;
1804 p = readline(prompt);
1805 PyOS_setsig(SIGINT, old_inthandler);
1806
1807 return p;
1808}
1809#endif /*defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT) */
1810
1811
1812static char *
1813call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
1814{
1815 size_t n;
1816 char *p, *q;
1817 int signal;
1818
1819#ifdef SAVE_LOCALE
1820 char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
1821 if (!saved_locale)
1822 Py_FatalError("not enough memory to save locale");
1823 setlocale(LC_CTYPE, "");
1824#endif
1825
1826 if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
1827 rl_instream = sys_stdin;
1828 rl_outstream = sys_stdout;
1829#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1830 rl_prep_terminal (1);
1831#endif
1832 }
1833
1834 p = readline_until_enter_or_signal(prompt, &signal);
1835
1836 /* we got an interrupt signal */
1837 if (signal) {
1838 RESTORE_LOCALE(saved_locale)
1839 return NULL;
1840 }
1841
1842 /* We got an EOF, return an empty string. */
1843 if (p == NULL) {
1844 p = PyMem_Malloc(1);
1845 if (p != NULL)
1846 *p = '\0';
1847 RESTORE_LOCALE(saved_locale)
1848 return p;
1849 }
1850
1851 /* we have a valid line */
1852 n = strlen(p);
1853 /* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and
1854 release the original. */
1855 q = p;
1856 p = PyMem_Malloc(n+2);
1857 if (p != NULL) {
1858 strncpy(p, q, n);
1859 p[n] = '\n';
1860 p[n+1] = '\0';
1861 }
1862 free(q);
1863 RESTORE_LOCALE(saved_locale)
1864 return p;
1865}
1866
1867
1868/* Initialize the module */
1869
1870PyDoc_STRVAR(doc_module,
1871"Importing this module enables command line editing using GNU readline.");
1872
1873#ifdef __APPLE__
1874PyDoc_STRVAR(doc_module_le,
1875"Importing this module enables command line editing using libedit readline.");
1876#endif /* __APPLE__ */
1877
1878PyMODINIT_FUNC
1879initline_input(void)
1880{
1881 PyObject *m;
1882
1883#ifdef __APPLE__
1884 if (strncmp(rl_library_version, libedit_version_tag, strlen(libedit_version_tag)) == 0) {
1885 using_libedit_emulation = 1;
1886 }
1887
1888 if (using_libedit_emulation)
1889 m = Py_InitModule4("line_input", readline_methods, doc_module_le,
1890 (PyObject *)NULL, PYTHON_API_VERSION);
1891 else
1892
1893#endif /* __APPLE__ */
1894
1895 m = Py_InitModule4("line_input", readline_methods, doc_module,
1896 (PyObject *)NULL, PYTHON_API_VERSION);
1897 if (m == NULL)
1898 return;
1899
1900 PyOS_ReadlineFunctionPointer = call_readline;
1901 setup_readline();
1902
1903 PyModule_AddIntConstant(m, "_READLINE_VERSION", RL_READLINE_VERSION);
1904 PyModule_AddIntConstant(m, "_READLINE_RUNTIME_VERSION", rl_readline_version);
1905}