home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / py2s152.zip / Modules / readline.c < prev    next >
C/C++ Source or Header  |  1999-06-27  |  8KB  |  324 lines

  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.
  4.  *
  5.  * More recently, it was largely rewritten by Guido van Rossum who is
  6.  * now maintaining it.
  7.  */
  8.  
  9. /* Standard definitions */
  10. #include "Python.h"
  11. #include <setjmp.h>
  12. #include <signal.h>
  13. #include <errno.h>
  14.  
  15. #ifdef HAVE_UNISTD_H
  16. #include <unistd.h> /* For isatty() */
  17. #endif
  18.  
  19. /* GNU readline definitions */
  20. /* If you have string.h, you might need to add yourself to this #if... [cjh] */
  21. #if defined(__BEOS__)
  22. #undef HAVE_CONFIG_H
  23. /* At max warnings, we need protos for everything. [cjh] */
  24. #include <readline/readline.h>
  25. #include <readline/history.h>
  26. #include <unistd.h>
  27. #else
  28. #include <readline/readline.h> /* You may need to add an -I option to Setup */
  29.  
  30. extern int rl_parse_and_bind();
  31. extern int rl_read_init_file();
  32. extern int rl_insert_text();
  33. extern int rl_bind_key();
  34. extern int rl_bind_key_in_map();
  35. extern int rl_initialize();
  36. extern int add_history();
  37. extern Function *rl_event_hook;
  38. #endif
  39.  
  40. /* Pointers needed from outside (but not declared in a header file). */
  41. extern int (*PyOS_InputHook)();
  42. extern char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *));
  43.  
  44.  
  45. /* Exported function to send one line to readline's init file parser */
  46.  
  47. static PyObject *
  48. parse_and_bind(self, args)
  49.     PyObject *self;
  50.     PyObject *args;
  51. {
  52.     char *s, *copy;
  53.     if (!PyArg_ParseTuple(args, "s", &s))
  54.         return NULL;
  55.     /* Make a copy -- rl_parse_and_bind() modifies its argument */
  56.     /* Bernard Herzog */
  57.     copy = malloc(1 + strlen(s));
  58.     if (copy == NULL)
  59.         return PyErr_NoMemory();
  60.     strcpy(copy, s);
  61.     rl_parse_and_bind(copy);
  62.     free(copy); /* Free the copy */
  63.     Py_INCREF(Py_None);
  64.     return Py_None;
  65. }
  66.  
  67. static char doc_parse_and_bind[] = "\
  68. parse_and_bind(string) -> None\n\
  69. Parse and execute single line of a readline init file.\
  70. ";
  71.  
  72.  
  73. /* Exported function to parse a readline init file */
  74.  
  75. static PyObject *
  76. read_init_file(self, args)
  77.     PyObject *self;
  78.     PyObject *args;
  79. {
  80.     char *s = NULL;
  81.     if (!PyArg_ParseTuple(args, "|z", &s))
  82.         return NULL;
  83.     errno = rl_read_init_file(s);
  84.     if (errno)
  85.         return PyErr_SetFromErrno(PyExc_IOError);
  86.     Py_INCREF(Py_None);
  87.     return Py_None;
  88. }
  89.  
  90. static char doc_read_init_file[] = "\
  91. read_init_file([filename]) -> None\n\
  92. Parse a readline initialization file.\n\
  93. The default filename is the last filename used.\
  94. ";
  95.  
  96.  
  97. /* Exported function to specify a word completer in Python */
  98.  
  99. static PyObject *completer = NULL;
  100. static PyThreadState *tstate = NULL;
  101.  
  102. static PyObject *
  103. set_completer(self, args)
  104.     PyObject *self;
  105.     PyObject *args;
  106. {
  107.     PyObject *function = Py_None;
  108.     if (!PyArg_ParseTuple(args, "|O", &function))
  109.         return NULL;
  110.     if (function == Py_None) {
  111.         Py_XDECREF(completer);
  112.         completer = NULL;
  113.         tstate = NULL;
  114.     }
  115.     else if (PyCallable_Check(function)) {
  116.         PyObject *tmp = completer;
  117.         Py_INCREF(function);
  118.         completer = function;
  119.         Py_XDECREF(tmp);
  120.         tstate = PyThreadState_Get();
  121.     }
  122.     else {
  123.         PyErr_SetString(PyExc_TypeError,
  124.                 "set_completer(func): argument not callable");
  125.         return NULL;
  126.     }
  127.     Py_INCREF(Py_None);
  128.     return Py_None;
  129. }
  130.  
  131. static char doc_set_completer[] = "\
  132. set_completer([function]) -> None\n\
  133. Set or remove the completer function.\n\
  134. The function is called as function(text, state),\n\
  135. for i in [0, 1, 2, ...] until it returns a non-string.\n\
  136. It should return the next possible completion starting with 'text'.\
  137. ";
  138.  
  139. /* Exported function to read the current line buffer */
  140.  
  141. static PyObject *
  142. get_line_buffer(self, args)
  143.     PyObject *self;
  144.         PyObject *args;
  145. {
  146.     if (PyArg_NoArgs(args))
  147.         return NULL;
  148.     return PyString_FromString(rl_line_buffer);
  149. }
  150.  
  151. static char doc_get_line_buffer[] = "\
  152. get_line_buffer() -> string\n\
  153. return the current contents of the line buffer.\
  154. ";
  155.  
  156. /* Exported function to insert text into the line buffer */
  157.  
  158. static PyObject *
  159. insert_text(self, args)
  160.     PyObject *self;
  161.     PyObject *args;
  162. {
  163.     char *s;
  164.     if (!PyArg_ParseTuple(args, "s", &s))
  165.         return NULL;
  166.     rl_insert_text(s);
  167.     Py_INCREF(Py_None);
  168.     return Py_None;
  169. }
  170.  
  171.  
  172. static char doc_insert_text[] = "\
  173. insert_text(string) -> None\n\
  174. Insert text into the command line.\
  175. ";
  176.  
  177.  
  178. /* Table of functions exported by the module */
  179.  
  180. static struct PyMethodDef readline_methods[] =
  181. {
  182.     {"parse_and_bind", parse_and_bind, 1, doc_parse_and_bind},
  183.     {"get_line_buffer", get_line_buffer, 1, doc_get_line_buffer},
  184.     {"insert_text", insert_text, 1, doc_insert_text},
  185.     {"read_init_file", read_init_file, 1, doc_read_init_file},
  186.     {"set_completer", set_completer, 1, doc_set_completer},
  187.     {0, 0}
  188. };
  189.  
  190. /* C function to call the Python completer. */
  191.  
  192. static char *
  193. on_completion(text, state)
  194.     char *text;
  195.     int state;
  196. {
  197.     char *result = NULL;
  198.     if (completer != NULL) {
  199.         PyObject *r;
  200.         PyThreadState *save_tstate;
  201.         /* Note that readline is called with the interpreter
  202.            lock released! */
  203.         save_tstate = PyThreadState_Swap(NULL);
  204.         PyEval_RestoreThread(tstate);
  205.         r = PyObject_CallFunction(completer, "si", text, state);
  206.         if (r == NULL)
  207.             goto error;
  208.         if (r == Py_None) {
  209.             result = NULL;
  210.         }
  211.         else {
  212.             char *s = PyString_AsString(r);
  213.             if (s == NULL)
  214.                 goto error;
  215.             result = strdup(s);
  216.         }
  217.         Py_DECREF(r);
  218.         goto done;
  219.       error:
  220.         PyErr_Clear();
  221.         Py_XDECREF(r);
  222.       done:
  223.         PyEval_SaveThread();
  224.         PyThreadState_Swap(save_tstate);
  225.     }
  226.     return result;
  227. }
  228.  
  229.  
  230. /* Helper to initialize GNU readline properly. */
  231.  
  232. static void
  233. setup_readline()
  234. {
  235.     rl_readline_name = "python";
  236.     /* Force rebind of TAB to insert-tab */
  237.     rl_bind_key('\t', rl_insert);
  238.     /* Bind both ESC-TAB and ESC-ESC to the completion function */
  239.     rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
  240.     rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
  241.     /* Set our completion function */
  242.     rl_completion_entry_function = (Function *) on_completion;
  243.     /* Set Python word break characters */
  244.     rl_completer_word_break_characters =
  245.         " \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?";
  246.         /* All nonalphanums except '.' */
  247.     /* Initialize (allows .inputrc to override)
  248.      *
  249.      * XXX: A bug in the readline-2.2 library causes a memory leak
  250.      * inside this function.  Nothing we can do about it.
  251.      */
  252.     rl_initialize();
  253. }
  254.  
  255.  
  256. /* Interrupt handler */
  257.  
  258. static jmp_buf jbuf;
  259.  
  260. /* ARGSUSED */
  261. static RETSIGTYPE
  262. onintr(sig)
  263.     int sig;
  264. {
  265.     longjmp(jbuf, 1);
  266. }
  267.  
  268.  
  269. /* Wrapper around GNU readline that handles signals differently. */
  270.  
  271. static char *
  272. call_readline(prompt)
  273.     char *prompt;
  274. {
  275.     int n;
  276.     char *p;
  277.     RETSIGTYPE (*old_inthandler)();
  278.     old_inthandler = signal(SIGINT, onintr);
  279.     if (setjmp(jbuf)) {
  280. #ifdef HAVE_SIGRELSE
  281.         /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
  282.         sigrelse(SIGINT);
  283. #endif
  284.         signal(SIGINT, old_inthandler);
  285.         return NULL;
  286.     }
  287.     rl_event_hook = PyOS_InputHook;
  288.     p = readline(prompt);
  289.     signal(SIGINT, old_inthandler);
  290.     if (p == NULL) {
  291.         p = malloc(1);
  292.         if (p != NULL)
  293.             *p = '\0';
  294.         return p;
  295.     }
  296.     n = strlen(p);
  297.     if (n > 0)
  298.         add_history(p);
  299.     if ((p = realloc(p, n+2)) != NULL) {
  300.         p[n] = '\n';
  301.         p[n+1] = '\0';
  302.     }
  303.     return p;
  304. }
  305.  
  306.  
  307. /* Initialize the module */
  308.  
  309. static char doc_module[] =
  310. "Importing this module enables command line editing using GNU readline.";
  311.  
  312. DL_EXPORT(void)
  313. initreadline()
  314. {
  315.     PyObject *m;
  316.  
  317.     m = Py_InitModule4("readline", readline_methods, doc_module,
  318.                (PyObject *)NULL, PYTHON_API_VERSION);
  319.     if (isatty(fileno(stdin))) {
  320.         PyOS_ReadlineFunctionPointer = call_readline;
  321.         setup_readline();
  322.     }
  323. }
  324.