gdb/python/py-gdb-readline.c - gdb

Functions defined

Source code

  1. /* Readline support for Python.

  2.    Copyright (C) 2012-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "python-internal.h"
  16. #include "top.h"
  17. #include "cli/cli-utils.h"
  18. /* Readline function suitable for PyOS_ReadlineFunctionPointer, which
  19.    is used for Python's interactive parser and raw_input.  In both
  20.    cases, sys_stdin and sys_stdout are always stdin and stdout
  21.    respectively, as far as I can tell; they are ignored and
  22.    command_line_input is used instead.  */

  23. static char *
  24. gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout,
  25. #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 4
  26.                         const char *prompt)
  27. #else
  28.                         char *prompt)
  29. #endif
  30. {
  31.   int n;
  32.   char *p = NULL, *q;
  33.   volatile struct gdb_exception except;

  34.   TRY_CATCH (except, RETURN_MASK_ALL)
  35.     p = command_line_input (prompt, 0, "python");

  36.   /* Detect user interrupt (Ctrl-C).  */
  37.   if (except.reason == RETURN_QUIT)
  38.     return NULL;

  39.   /* Handle errors by raising Python exceptions.  */
  40.   if (except.reason < 0)
  41.     {
  42.       /* The thread state is nulled during gdbpy_readline_wrapper,
  43.          with the original value saved in the following undocumented
  44.          variable (see Python's Parser/myreadline.c and
  45.          Modules/readline.c).  */
  46.       PyEval_RestoreThread (_PyOS_ReadlineTState);
  47.       gdbpy_convert_exception (except);
  48.       PyEval_SaveThread ();
  49.       return NULL;
  50.     }

  51.   /* Detect EOF (Ctrl-D).  */
  52.   if (p == NULL)
  53.     {
  54.       q = PyMem_Malloc (1);
  55.       if (q != NULL)
  56.         q[0] = '\0';
  57.       return q;
  58.     }

  59.   n = strlen (p);

  60.   /* Copy the line to Python and return.  */
  61.   q = PyMem_Malloc (n + 2);
  62.   if (q != NULL)
  63.     {
  64.       strncpy (q, p, n);
  65.       q[n] = '\n';
  66.       q[n + 1] = '\0';
  67.     }
  68.   return q;
  69. }

  70. /* Initialize Python readline support.  */

  71. void
  72. gdbpy_initialize_gdb_readline (void)
  73. {
  74.   /* Python's readline module conflicts with GDB's use of readline
  75.      since readline is not reentrant.  Ideally, a reentrant wrapper to
  76.      GDB's readline should be implemented to replace Python's readline
  77.      and prevent conflicts.  For now, this file implements a
  78.      sys.meta_path finder that simply fails to import the readline
  79.      module.  */
  80.   if (PyRun_SimpleString ("\
  81. import sys\n\
  82. \n\
  83. class GdbRemoveReadlineFinder:\n\
  84.   def find_module(self, fullname, path=None):\n\
  85.     if fullname == 'readline' and path is None:\n\
  86.       return self\n\
  87.     return None\n\
  88. \n\
  89.   def load_module(self, fullname):\n\
  90.     raise ImportError('readline module disabled under GDB')\n\
  91. \n\
  92. sys.meta_path.append(GdbRemoveReadlineFinder())\n\
  93. ") == 0)
  94.     PyOS_ReadlineFunctionPointer = gdbpy_readline_wrapper;
  95. }