public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFC][PATCH] GDB->Python API changes in preparation for Guile support
@ 2013-11-25  3:40 Doug Evans
  2013-11-28 13:12 ` Pedro Alves
  0 siblings, 1 reply; 3+ messages in thread
From: Doug Evans @ 2013-11-25  3:40 UTC (permalink / raw)
  To: gdb-patches; +Cc: guile-user, sivachandra

Hi.

I almost have a patch set ready to submit that adds Guile scripting
support.

It's in two separate sets.

1) The first set basically adds an API for calling from GDB into python/*.c
(where gdb needs to do so directly).
The patch appended below is the core of the change.
It adds the traditional "ops" vector, and calls from GDB to the
scripting language are through this vector.
The vector is split into two (script_language_ops and
script_language_script_ops) because gdb's own scripting language
can make use of the latter.

I didn't handle varobj because it's got Python more tightly embedded
in it, and I think adding it can wait until there's an actual need.

One nice property of this API is that all the stubs that get compiled
in when !HAVE_PYTHON are gone.  And #ifdef HAVE_PYTHON is gone from
all py-*.c files except python.c.

2) Once the first patch set is in, adding Guile scripting is straightforward.

I'm not intending to make any major changes before 7.7 is branched
of course.

Comments welcome.

The patch below itself needs to be split into multiple pieces, and is only
part of the whole, but for the purpose of understanding the core of the change
it should be sufficient.  And for those that want to wait, a full patch
set will follow hopefully by next weekend.

2013-11-24  Doug Evans  <xdje42@gmail.com>

	Call into Python via script_language API.
	* scripting.c: New file.
	* scripting.h: New file.
	* python/python-internal.h: #include "scripting.h"
	(gdbpy_auto_load_enabled): Declare.
	(gdbpy_apply_val_pretty_printer, gdbpy_apply_frame_filter): Declare.
	(gdbpy_preserve_values, gdbpy_breakpoint_cond_says_stop): Declare.
	* python/python.h: Remove #include of value.h, mi/mi-cmds.h.
	#include "scripting.h".
	(py_bt_status): Moved to scripting.h and renamed to script_bt_status.
	(frame_filter_flags): Moved to scripting.h.
	(py_frame_args): Moved to scripting.h and renamed to script_frame_args.
	(*): Delete everything else.
	(script_lang_python): Declare.
	* python/python.c (python_scripting_script_ops): New global.
	(python_scripting_ops): New global.
	(gdbpy_clear_quit_flag): Renamed from clear_quit_flag, make static.
	New arg slang.
	(gdbpy_set_quit_flag): Renamed from set_quit_flag, make static.
	New arg slang.
	(gdbpy_check_quit_flag): Renamed from check_quit_flag, make static.
	New arg slang.
	(gdbpy_eval_from_control_command): Renamed from
	eval_python_from_control_command, make static.  New arg slang.
	(gdbpy_source_script): Renamed from source_python_script, make static.
	New arg slang.
	(gdbpy_source_objfile_script): Renamed from
	source_python_script_for_objfile, make static.  New arg slang.
	(gdbpy_source_section_script): New function.
	(gdbpy_start_type_printers): Renamed from start_type_printers,
	make static.  New arg slang.  Result is now "void", printers_obj
	is now stored in slang_printers->py_type_printers.
	(gdbpy_apply_type_printers): Renamed from apply_type_printers,
	make static.  New arg slang.
	(gdbpy_free_type_printers): Renamed from free_type_printers,
	make static.  New arg slang.
	(!HAVE_PYTHON, eval_python_from_control_command): Delete.
	(!HAVE_PYTHON, source_python_script): Delete.
	(!HAVE_PYTHON, gdbpy_should_stop): Delete.
	(!HAVE_PYTHON, gdbpy_breakpoint_has_py_cond): Delete.
	(!HAVE_PYTHON, start_type_printers): Delete.
	(!HAVE_PYTHON, apply_type_printers): Delete.
	(!HAVE_PYTHON, free_type_printers): Delete.
	(!HAVE_PYTHON, apply_frame_filter): Delete.
	(gdbpy_finish_initialization): Renamed from
	finish_python_initialization, make static.  New arg slang.
	(gdbpy_initialized): New function.

diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 7d8c4ad..fe42740 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -20,6 +20,8 @@
 #ifndef GDB_PYTHON_INTERNAL_H
 #define GDB_PYTHON_INTERNAL_H
 
+#include "scripting.h"
+
 /* These WITH_* macros are defined by the CPython API checker that
    comes with the Python plugin for GCC.  See:
    https://gcc-python-plugin.readthedocs.org/en/latest/cpychecker.html
@@ -279,7 +281,24 @@ typedef struct
 
 extern struct cmd_list_element *set_python_list;
 extern struct cmd_list_element *show_python_list;
-
+\f
+/* script_language_ops "methods".  */
+
+extern int gdbpy_auto_load_enabled (void);
+extern int gdbpy_apply_val_pretty_printer
+  (struct type *type, const gdb_byte *valaddr,
+   int embedded_offset, CORE_ADDR address,
+   struct ui_file *stream, int recurse,
+   const struct value *val,
+   const struct value_print_options *options,
+   const struct language_defn *language);
+extern enum script_bt_status gdbpy_apply_frame_filter
+  (struct frame_info *frame, int flags, enum script_frame_args args_type,
+   struct ui_out *out, int frame_low, int frame_high);
+extern void gdbpy_preserve_values (struct objfile *objfile,
+				   htab_t copied_types);
+extern int gdbpy_breakpoint_cond_says_stop (struct breakpoint *);
+\f
 PyObject *gdbpy_history (PyObject *self, PyObject *args);
 PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
 PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 7cdf8a7..a88f600 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -57,6 +57,33 @@ static const char *const python_excp_enums[] =
 static const char *gdbpy_should_print_stack = python_excp_message;
 
 #ifdef HAVE_PYTHON
+/* Forward decls, these are defined later.  */
+static const struct script_language_script_ops python_scripting_script_ops;
+static const struct script_language_ops python_scripting_ops;
+#endif
+
+/* The main struct describing GDB's interface to the Python
+   scripting language.  */
+const struct script_language script_lang_python =
+{
+  "python",
+  "Python",
+
+  ".py",
+  "-gdb.py",
+
+  python_control,
+
+#ifdef HAVE_PYTHON
+  &python_scripting_script_ops,
+  &python_scripting_ops
+#else
+  NULL,
+  NULL
+#endif
+};
+\f
+#ifdef HAVE_PYTHON
 
 #include "libiberty.h"
 #include "cli/cli-decode.h"
@@ -104,6 +131,60 @@ PyObject *gdbpy_gdb_error;
 /* The `gdb.MemoryError' exception.  */
 PyObject *gdbpy_gdb_memory_error;
 
+static script_sourcer_func gdbpy_source_script;
+static objfile_script_sourcer_func gdbpy_source_objfile_script;
+static section_script_sourcer_func gdbpy_source_section_script;
+static void gdbpy_finish_initialization (const struct script_language *);
+static int gdbpy_initialized (const struct script_language *);
+static void gdbpy_eval_from_control_command (const struct script_language *,
+					     struct command_line *cmd);
+static void gdbpy_start_type_printers (const struct script_language *,
+				       struct script_type_printers *);
+static char *gdbpy_apply_type_printers (const struct script_language *,
+					const struct script_type_printers *,
+					struct type *);
+static void gdbpy_free_type_printers (const struct script_language *,
+				      struct script_type_printers *);
+static int gdbpy_check_quit_flag (const struct script_language *);
+static void gdbpy_clear_quit_flag (const struct script_language *);
+static void gdbpy_set_quit_flag (const struct script_language *);
+
+/* The interface between gdb proper and loading of python scripts.  */
+
+static const struct script_language_script_ops python_scripting_script_ops =
+{
+  gdbpy_source_script,
+  gdbpy_source_objfile_script,
+  gdbpy_source_section_script,
+  gdbpy_auto_load_enabled_p
+};
+
+/* The interface between gdb proper and python scripting.  */
+
+static const struct script_language_ops python_scripting_ops =
+{
+  gdbpy_finish_initialization,
+  gdbpy_initialized,
+
+  gdbpy_eval_from_control_command,
+
+  gdbpy_start_type_printers,
+  gdbpy_apply_type_printers,
+  gdbpy_free_type_printers,
+
+  gdbpy_apply_val_pretty_printer,
+
+  gdbpy_apply_frame_filter,
+
+  gdbpy_preserve_values,
+
+  gdbpy_breakpoint_cond_says_stop,
+
+  gdbpy_check_quit_flag,
+  gdbpy_clear_quit_flag,
+  gdbpy_set_quit_flag,
+};
+
 /* Architecture and language to be used in callbacks from
    the Python interpreter.  */
 struct gdbarch *python_gdbarch;
@@ -169,8 +250,8 @@ ensure_python_env (struct gdbarch *gdbarch,
 
 /* Clear the quit flag.  */
 
-void
-clear_quit_flag (void)
+static void
+gdbpy_clear_quit_flag (const struct script_language *slang)
 {
   /* This clears the flag as a side effect.  */
   PyOS_InterruptOccurred ();
@@ -178,16 +259,16 @@ clear_quit_flag (void)
 
 /* Set the quit flag.  */
 
-void
-set_quit_flag (void)
+static void
+gdbpy_set_quit_flag (const struct script_language *slang)
 {
   PyErr_SetInterrupt ();
 }
 
 /* Return true if the quit flag has been set, false otherwise.  */
 
-int
-check_quit_flag (void)
+static int
+gdbpy_check_quit_flag (const struct script_language *slang)
 {
   return PyOS_InterruptOccurred ();
 }
@@ -343,8 +424,9 @@ compute_python_string (struct command_line *l)
 /* Take a command line structure representing a 'python' command, and
    evaluate its body using the Python interpreter.  */
 
-void
-eval_python_from_control_command (struct command_line *cmd)
+static void
+gdbpy_eval_from_control_command (const struct script_language *slang,
+				 struct command_line *cmd)
 {
   int ret;
   char *script;
@@ -765,12 +847,14 @@ gdbpy_find_pc_line (PyObject *self, PyObject *args)
 }
 
 /* Read a file as Python code.
+   This is the script_language_script_ops.script_sourcer "method".
    FILE is the file to run.  FILENAME is name of the file FILE.
    This does not throw any errors.  If an exception occurs python will print
    the traceback and clear the error indicator.  */
 
-void
-source_python_script (FILE *file, const char *filename)
+static void
+gdbpy_source_script (const struct script_language *slang,
+		     FILE *file, const char *filename)
 {
   struct cleanup *cleanup;
 
@@ -1158,16 +1242,18 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
 
 /* The "current" objfile.  This is set when gdb detects that a new
    objfile has been loaded.  It is only set for the duration of a call to
-   source_python_script_for_objfile; it is NULL at other times.  */
+   gdbpy_source_objfile_script; it is NULL at other times.  */
 static struct objfile *gdbpy_current_objfile;
 
 /* Set the current objfile to OBJFILE and then read FILE named FILENAME
    as Python code.  This does not throw any errors.  If an exception
-   occurs python will print the traceback and clear the error indicator.  */
+   occurs python will print the traceback and clear the error indicator.
+   This is the script_language_script_ops.objfile_script_sourcer "method".  */
 
-void
-source_python_script_for_objfile (struct objfile *objfile, FILE *file,
-                                  const char *filename)
+static void
+gdbpy_source_objfile_script (const struct script_language *slang,
+			     struct objfile *objfile, FILE *file,
+			     const char *filename)
 {
   struct cleanup *cleanups;
 
@@ -1183,6 +1269,24 @@ source_python_script_for_objfile (struct objfile *objfile, FILE *file,
   gdbpy_current_objfile = NULL;
 }
 
+/* Set the current objfile to OBJFILE and the process the .debug_gdb_scripts
+   record specified by RECORD, RECORD_SIZE.  RECORD begins at the leading
+   type byte, and RECORD_SIZE includes this byte and trailing NUL if there
+   is one.
+   This is the script_language_script_ops.section_script_sourcer "method".  */
+
+static void
+gdbpy_source_section_script (const struct script_language *slang,
+			     struct objfile *objfile, const char *section_name,
+			     const char *record, size_t record_size)
+{
+  gdb_assert (*record == SECTION_SCRIPT_ID_PYTHON);
+  gdb_assert (record[record_size - 1] == '\0');
+
+  auto_load_objfile_script_from_section (objfile, section_name, record + 1,
+					 slang, gdbpy_source_objfile_script);
+}
+
 /* Return the current Objfile, or None if there isn't one.  */
 
 static PyObject *
@@ -1225,18 +1329,20 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
   return list;
 }
 
-/* Compute the list of active type printers and return it.  The result
-   of this function can be passed to apply_type_printers, and should
-   be freed by free_type_printers.  */
+/* Compute the list of active python type printers and store them in
+   SLANG_PRINTERS->py_type_printers.  The product of this function is used by
+   gdbpy_apply_type_printers, and freed by gdbpy_free_type_printers.
+   This is the script_language_ops.start_type_printers "method".  */
 
-void *
-start_type_printers (void)
+static void
+gdbpy_start_type_printers (const struct script_language *slang,
+			   struct script_type_printers *slang_printers)
 {
   struct cleanup *cleanups;
-  PyObject *type_module, *func = NULL, *result_obj = NULL;
+  PyObject *type_module, *func = NULL, *printers_obj = NULL;
 
   if (!gdb_python_initialized)
-    return NULL;
+    return;
 
   cleanups = ensure_python_env (get_current_arch (), current_language);
 
@@ -1254,32 +1360,32 @@ start_type_printers (void)
       goto done;
     }
 
-  result_obj = PyObject_CallFunctionObjArgs (func, (char *) NULL);
-  if (result_obj == NULL)
+  printers_obj = PyObject_CallFunctionObjArgs (func, (char *) NULL);
+  if (printers_obj == NULL)
     gdbpy_print_stack ();
+  else
+    slang_printers->py_type_printers = printers_obj;
 
  done:
   Py_XDECREF (type_module);
   Py_XDECREF (func);
   do_cleanups (cleanups);
-  return result_obj;
 }
 
 /* If TYPE is recognized by some type printer, return a newly
    allocated string holding the type's replacement name.  The caller
    is responsible for freeing the string.  Otherwise, return NULL.
+   This is the script_language_ops.apply_type_printers "method".  */
 
-   This function has a bit of a funny name, since it actually applies
-   recognizers, but this seemed clearer given the start_type_printers
-   and free_type_printers functions.  */
-
-char *
-apply_type_printers (void *printers, struct type *type)
+static char *
+gdbpy_apply_type_printers (const struct script_language *slang,
+			   const struct script_type_printers *slang_printers,
+			   struct type *type)
 {
   struct cleanup *cleanups;
   PyObject *type_obj, *type_module = NULL, *func = NULL;
   PyObject *result_obj = NULL;
-  PyObject *printers_obj = printers;
+  PyObject *printers_obj = slang_printers->py_type_printers;
   char *result = NULL;
 
   if (printers_obj == NULL)
@@ -1335,13 +1441,15 @@ apply_type_printers (void *printers, struct type *type)
   return result;
 }
 
-/* Free the result of start_type_printers.  */
+/* Free the result of start_type_printers.
+   This is the script_language_ops.free_type_printers "method".  */
 
-void
-free_type_printers (void *arg)
+static void
+gdbpy_free_type_printers (const struct script_language *slang,
+			  struct script_type_printers *slang_printers)
 {
   struct cleanup *cleanups;
-  PyObject *printers = arg;
+  PyObject *printers = slang_printers->py_type_printers;
 
   if (printers == NULL)
     return;
@@ -1381,61 +1489,6 @@ python_command (char *arg, int from_tty)
   python_interactive_command (arg, from_tty);
 }
 
-void
-eval_python_from_control_command (struct command_line *cmd)
-{
-  error (_("Python scripting is not supported in this copy of GDB."));
-}
-
-void
-source_python_script (FILE *file, const char *filename)
-{
-  throw_error (UNSUPPORTED_ERROR,
-	       _("Python scripting is not supported in this copy of GDB."));
-}
-
-int
-gdbpy_should_stop (struct breakpoint_object *bp_obj)
-{
-  internal_error (__FILE__, __LINE__,
-		  _("gdbpy_should_stop called when Python scripting is  " \
-		    "not supported."));
-}
-
-int
-gdbpy_breakpoint_has_py_cond (struct breakpoint_object *bp_obj)
-{
-  internal_error (__FILE__, __LINE__,
-		  _("gdbpy_breakpoint_has_py_cond called when Python " \
-		    "scripting is not supported."));
-}
-
-void *
-start_type_printers (void)
-{
-  return NULL;
-}
-
-char *
-apply_type_printers (void *ignore, struct type *type)
-{
-  return NULL;
-}
-
-void
-free_type_printers (void *arg)
-{
-}
-
-enum py_bt_status
-apply_frame_filter (struct frame_info *frame, int flags,
-		    enum py_frame_args args_type,
-		    struct ui_out *out, int frame_low,
-		    int frame_high)
-{
-  return PY_BT_NO_FILTERS;
-}
-
 #endif /* HAVE_PYTHON */
 
 \f
@@ -1733,10 +1786,11 @@ message == an error message without a stack will be printed."),
 /* Perform the remaining python initializations.
    These must be done after GDB is at least mostly initialized.
    E.g., The "info pretty-printer" command needs the "info" prefix
-   command installed.  */
+   command installed.
+   This is the script_language_ops.finish_initialization "method".  */
 
-void
-finish_python_initialization (void)
+static void
+gdbpy_finish_initialization (const struct script_language *slang)
 {
   PyObject *m;
   char *gdb_pythondir;
@@ -1815,6 +1869,15 @@ finish_python_initialization (void)
   do_cleanups (cleanup);
 }
 
+/* Return non-zero if Python has successfully initialized.
+   This is the script_languages_ops.initialized "method".  */
+
+static int
+gdbpy_initialized (const struct script_language *slang)
+{
+  return gdb_python_initialized;
+}
+
 #endif /* HAVE_PYTHON */
 
 \f
diff --git a/gdb/python/python.h b/gdb/python/python.h
index 1a1e5c2..6ed5b2a 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
@@ -20,105 +20,8 @@
 #ifndef GDB_PYTHON_H
 #define GDB_PYTHON_H
 
-#include "value.h"
-#include "mi/mi-cmds.h"
+#include "scripting.h"
 
-struct breakpoint_object;
-
-/* The suffix of per-objfile scripts to auto-load.
-   E.g. When the program loads libfoo.so, look for libfoo-gdb.py.  */
-#define GDBPY_AUTO_FILE_NAME "-gdb.py"
-
-/* Python frame-filter status return values.  */
-enum py_bt_status
-  {
-    /* Return when an error has occurred in processing frame filters,
-       or when printing the stack.  */
-    PY_BT_ERROR = -1,
-
-    /* Return from internal routines to indicate that the function
-       succeeded.  */
-    PY_BT_OK = 1,
-
-    /* Return when the frame filter process is complete, and all
-       operations have succeeded.  */
-    PY_BT_COMPLETED = 2,
-
-    /* Return when the frame filter process is complete, but there
-       were no filter registered and enabled to process. */
-    PY_BT_NO_FILTERS = 3
-  };
-
-/* Flags to pass to apply_frame_filter.  */
-
-enum frame_filter_flags
-  {
-    /* Set this flag if frame level is to be printed.  */
-    PRINT_LEVEL = 1,
-
-    /* Set this flag if frame information is to be printed.  */
-    PRINT_FRAME_INFO = 2,
-
-    /* Set this flag if frame arguments are to be printed.  */
-    PRINT_ARGS = 4,
-
-    /* Set this flag if frame locals are to be printed.  */
-    PRINT_LOCALS = 8,
-  };
-
-/* A choice of the different frame argument printing strategies that
-   can occur in different cases of frame filter instantiation.  */
-typedef enum py_frame_args
-{
-  /* Print no values for arguments when invoked from the MI. */
-  NO_VALUES = PRINT_NO_VALUES,
-
-  MI_PRINT_ALL_VALUES = PRINT_ALL_VALUES,
-
-  /* Print only simple values (what MI defines as "simple") for
-     arguments when invoked from the MI. */
-  MI_PRINT_SIMPLE_VALUES = PRINT_SIMPLE_VALUES,
-
-
-  /* Print only scalar values for arguments when invoked from the
-     CLI. */
-  CLI_SCALAR_VALUES,
-
-  /* Print all values for arguments when invoked from the
-     CLI. */
-  CLI_ALL_VALUES
-} py_frame_args;
-
-extern void finish_python_initialization (void);
-
-void eval_python_from_control_command (struct command_line *);
-
-void source_python_script (FILE *file, const char *filename);
-
-int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
-			      int embedded_offset, CORE_ADDR address,
-			      struct ui_file *stream, int recurse,
-			      const struct value *val,
-			      const struct value_print_options *options,
-			      const struct language_defn *language);
-
-enum py_bt_status apply_frame_filter (struct frame_info *frame, int flags,
-				      enum py_frame_args args_type,
-				      struct ui_out *out, int frame_low,
-				      int frame_high);
-
-void preserve_python_values (struct objfile *objfile, htab_t copied_types);
-
-void gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile);
-
-int gdbpy_should_stop (struct breakpoint_object *bp_obj);
-
-int gdbpy_breakpoint_has_py_cond (struct breakpoint_object *bp_obj);
-
-void *start_type_printers (void);
-
-char *apply_type_printers (void *, struct type *type);
-
-void free_type_printers (void *arg);
+extern const struct script_language script_lang_python;
 
 #endif /* GDB_PYTHON_H */
diff --git a/gdb/scripting.c b/gdb/scripting.c
new file mode 100644
index 0000000..0fe7d40
--- /dev/null
+++ b/gdb/scripting.c
@@ -0,0 +1,631 @@
+/* Interface between gdb and its scripting languages.
+
+   Copyright (C) 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Note: With few exceptions, external functions and variables in this file
+   have "script" in the name, and no other symbol in gdb does.  */
+
+#include "defs.h"
+#include "auto-load.h"
+#include "breakpoint.h"
+#include "scripting.h"
+#include "cli/cli-script.h"
+#include "python/python.h"
+
+static script_sourcer_func source_gdb_script;
+static objfile_script_sourcer_func source_gdb_objfile_script;
+static section_script_sourcer_func source_gdb_section_script;
+
+/* GDB's own scripting language.
+   This exists, in part, to support auto-loading ${prog}-gdb.gdb scripts.  */
+
+static const struct script_language_script_ops script_lang_gdb_script_ops =
+{
+  source_gdb_script,
+  source_gdb_objfile_script,
+  source_gdb_section_script,
+  auto_load_gdb_scripts_enabled_p
+};
+
+static const struct script_language script_lang_gdb =
+{
+  "gdb",
+  "GDB",
+
+  /* We fall back to interpreting a script as a GDB script if it doesn't
+     match the other scripting languages, but for consistency's sake
+     give it a formal suffix.  */
+  ".gdb",
+  "-gdb.gdb",
+
+  /* cli_control_type: This is never used: GDB's own scripting language
+     has a variety of control types (if, while, etc.).  */
+  commands_control,
+
+  &script_lang_gdb_script_ops,
+
+  /* The rest of the scripting interface isn't supported by GDB's own
+     scripting language.  */
+  NULL
+};
+
+/* Table of all external (non-native) scripting languages.  */
+
+static const struct script_language * const external_scripting_languages[] =
+{
+  &script_lang_python,
+  NULL
+};
+
+/* Return the script_language definition of GDB's own scripting language.  */
+
+const struct script_language *
+get_script_lang_gdb (void)
+{
+  return &script_lang_gdb;
+}
+
+/* Return the script_language definition for Python.  */
+
+const struct script_language *
+get_script_lang_python (void)
+{
+  return &script_lang_python;
+}
+\f
+/* Methods for GDB's own scripting language.  */
+
+/* The script_language_script_ops.script_sourcer "method".  */
+
+static void
+source_gdb_script (const struct script_language *slang,
+		   FILE *stream, const char *file)
+{
+  script_from_file (stream, file);
+}
+
+/* The script_language_script_ops.objfile_script_sourcer "method".  */
+
+static void
+source_gdb_objfile_script (const struct script_language *slang,
+			   struct objfile *objfile,
+			   FILE *stream, const char *file)
+{
+  script_from_file (stream, file);
+}
+
+/* The script_language_script_ops.section_script_sourcer "method".  */
+
+static void
+source_gdb_section_script (const struct script_language *slang,
+			   struct objfile *objfile, const char *section_name,
+			   const char *record, size_t record_size)
+{
+  /* This is currently not implemented.  */
+  throw_error (UNSUPPORTED_ERROR,
+	       _("Loading a GDB script from .debug_gdb_scripts"
+		 " is not supported."));
+}
+\f
+/* Accessors for "public" attributes of struct script_language.
+
+   IWBN if we could use slang_foo here and elsewhere, but we can't for fear of
+   confusing someone into thinking we might be referring to the Slang
+   programming language.  */
+
+/* Return the "name" field of SLANG.  */
+
+const char *
+script_lang_name (const struct script_language *slang)
+{
+  return slang->name;
+}
+
+/* Return the "capitalized_name" field of SLANG.  */
+
+const char *
+script_lang_capitalized_name (const struct script_language *slang)
+{
+  return slang->capitalized_name;
+}
+
+/* Return the "suffix" field of SLANG.  */
+
+const char *
+script_lang_suffix (const struct script_language *slang)
+{
+  return slang->suffix;
+}
+
+/* Return the "auto_load_suffix" field of SLANG.  */
+
+const char *
+script_lang_auto_load_suffix (const struct script_language *slang)
+{
+  return slang->auto_load_suffix;
+}
+\f
+/* script_language_script_ops wrappers.  */
+
+static void
+throw_unsupported (const struct script_language *slang)
+{
+  throw_error (UNSUPPORTED_ERROR,
+	       _("Scripting in the \"%s\" language is not supported"
+		 " in this copy of GDB.")
+	       slang->capitalized_name);
+}
+
+/* Throw UNSUPPORTED_ERROR if called.
+   This is used to implement script_ext_{soft,hard}.  */
+
+static void
+source_script_unsupported (const struct script_language *slang,
+			   FILE *stream, const char *file)
+{
+  throw_unsupported (slang);
+}
+
+/* Return TRUE if FILE has extension EXTENSION.  */
+
+static int
+has_extension (const char *file, const char *extension)
+{
+  int file_len = strlen (file);
+  int extension_len = strlen (extension);
+
+  return (file_len > extension_len
+	  && strcmp (&file[file_len - extension_len], extension) == 0);
+}
+
+/* Return a function to load FILE.
+   If FILE specifies a scripting language we support but which is not
+   enabled then return a function that throws UNSUPPORTED_ERROR.
+   Otherwise return NULL.
+
+   Note: This could be a lot cleaner if not for script_ext_soft.  */
+
+script_sourcer_func *
+get_script_sourcer (const char *file)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (has_extension (file, slang->suffix))
+	{
+	  script_sourcer_func *func = script_lang_sourcer;
+
+	  if (func != NULL)
+	    return func;
+	  return source_script_unsupported;
+	}
+    }
+
+  return NULL;
+}
+
+/* Return the script "sourcer" function for SLANG.
+   This is the function that loads and processes a script.  */
+
+script_sourcer_func *
+script_lang_sourcer (const struct script_language *slang)
+{
+  if (slang->script_ops == NULL)
+    return NULL;
+  return slang->script_ops->script_sourcer;
+}
+
+/* Return the objfile script "sourcer" function for SLANG.
+   This is the function that loads and processes a script for a particular
+   objfile.  */
+
+objfile_script_sourcer_func *
+script_lang_objfile_sourcer (const struct script_language *slang)
+{
+  if (slang->script_ops == NULL)
+    return NULL;
+  return slang->script_ops->objfile_script_sourcer;
+}
+
+/* Return the section script "sourcer" function for SLANG.
+   This is the function that processes a record in .debug_gdb_scripts.  */
+
+section_script_sourcer_func *
+script_lang_section_sourcer (const struct script_language *slang)
+{
+  if (slang->script_ops == NULL)
+    return NULL;
+  return slang->script_ops->section_script_sourcer;
+}
+
+/* Return non-zero if auto-loading of SLANG scripts is enabled.  */
+
+int
+script_lang_auto_load_enabled (const struct script_language *slang)
+{
+  if (slang->script_ops == NULL)
+    return 0;
+  return slang->ops->auto_load_enabled (slang);
+}
+\f
+/* Functions that iterate over all (external) scripting languages.  */
+
+/* Iterate over all external scripting languages, regardless of whether the
+   support has been compiled in or not.  */
+#define ALL_EXT_SCRIPTING_LANGUAGES(i, slang) \
+  for (/*int*/ i = 0, slang = external_scripting_languages[0]; \
+       slang != NULL; \
+       slang = external_scripting_languages[++i])
+
+/* Iterate over all external scripting languages that are supported.  */
+#define ALL_ENABLED_EXT_SCRIPTING_LANGUAGES(i, slang) \
+  for (/*int*/ i = 0, slang = external_scripting_languages[0]; \
+       slang != NULL; \
+       slang = external_scripting_languages[++i]) \
+    if (slang->ops != NULL)
+
+/* Wrapper to call the script_language_ops.finish_initialization "method"
+   for each compiled-in scripting language.  */
+
+void
+finish_script_initialization (void)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->finish_initialization != NULL)
+	slang->ops->finish_initialization (slang);
+    }
+}
+
+/* Return the scripting language specified by CMD.
+   Note the difference between this function and
+   eval_script_from_control_command is that we loop on
+   ALL_EXT_SCRIPTING_LANGUAGES whereas the latter loops on
+   ALL_ENABLED_EXT_SCRIPTING_LANGUAGES.  */
+
+static const struct script_language *
+script_lang_from_control_command (struct command_line *cmd)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->cli_control_type == cmd->control_type)
+	return slang;
+    }
+
+  gdb_assert_not_reached ("invalid scripting language in cli command");
+}
+
+/* Evaluate the commands in CMD, which specifies a sequence of commands
+   in an external scripting language.  */
+
+void
+eval_script_from_control_command (struct command_line *cmd)
+{
+  int i;
+  const struct script_language *slang;
+  const char *script_lang_name;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->cli_control_type == cmd->control_type
+	  && slang->ops->eval_from_control_command != NULL)
+	{
+	  slang->ops->eval_from_control_command (slang, cmd);
+	  return;
+	}
+    }
+
+  /* The requested scripting language is not supported in this GDB.  */
+  throw_unsupported (script_lang_from_control_command (cmd));
+}
+
+/* Load scripts for OBJFILE written in external languages.  */
+
+void
+auto_load_scripts_for_objfile (struct objfile *objfile)
+{
+  int i;
+  const struct script_language *slang;
+
+  slang = &script_lang_gdb;
+  if (script_lang_auto_load_enabled (slang))
+    auto_load_objfile_script (objfile, slang);
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (script_lang_auto_load_enabled (slang))
+	auto_load_objfile_script (objfile, slang);
+    }
+}
+\f
+/* Interface to type pretty-printers implemented in an external
+   scripting language.  */
+
+/* Call this at the start when preparing to pretty-print a type.
+   The result is a pointer to an opaque object (to the caller) to be passed
+   to apply_script_type_printers and free_script_type_printers.  */
+
+struct script_type_printers *
+start_script_type_printers (void)
+{
+  struct script_type_printers *printers =
+    XZALLOC (struct script_type_printers);
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->start_type_printers != NULL)
+	slang->ops->start_type_printers (slang, printers);
+    }
+
+  return printers;
+}
+
+/* Iteratively try the type pretty-printers specified by PRINTERS,
+   returning the result of the first one that succeeds.  If no printer
+   succeeds then NULL is returned.  */
+
+char *
+apply_script_type_printers (struct script_type_printers *printers,
+			    struct type *type)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      char *result = NULL;
+
+      if (slang->ops->apply_type_printers != NULL)
+	result = slang->ops->apply_type_printers (slang, printers, type);
+
+      if (result != NULL)
+	return result;
+    }
+
+  return NULL;
+}
+
+/* Call this after pretty-printing a type to release all memory held
+   by PRINTERS.  */
+
+void
+free_script_type_printers (struct script_type_printers *printers)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->free_type_printers != NULL)
+	slang->ops->free_type_printers (slang, printers);
+    }
+
+  xfree (printers);
+}
+\f
+/* Try to pretty-print a value of type TYPE located at VALADDR
+   + EMBEDDED_OFFSET, which came from the inferior at address ADDRESS
+   + EMBEDDED_OFFSET, onto stdio stream STREAM according to OPTIONS.
+   VAL is the whole object that came from ADDRESS.  VALADDR must point to
+   the head of VAL's contents buffer.
+   Returns non-zero if the value was successfully pretty-printed.  */
+
+int
+apply_val_script_pretty_printer (struct type *type, const gdb_byte *valaddr,
+				 int embedded_offset, CORE_ADDR address,
+				 struct ui_file *stream, int recurse,
+				 const struct value *val,
+				 const struct value_print_options *options,
+				 const struct language_defn *language)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->apply_val_pretty_printer (slang, type, valaddr,
+						embedded_offset, address,
+						stream, recurse, val,
+						options, language))
+	return 1;
+    }
+
+  return 0;
+}
+
+/* GDB access to the "frame filter" feature.
+   FRAME is the source frame to start frame-filter invocation.  FLAGS is an
+   integer holding the flags for printing.  The following elements of
+   the FRAME_FILTER_FLAGS enum denotes the make-up of FLAGS:
+   PRINT_LEVEL is a flag indicating whether to print the frame's
+   relative level in the output.  PRINT_FRAME_INFO is a flag that
+   indicates whether this function should print the frame
+   information, PRINT_ARGS is a flag that indicates whether to print
+   frame arguments, and PRINT_LOCALS, likewise, with frame local
+   variables.  ARGS_TYPE is an enumerator describing the argument
+   format, OUT is the output stream to print.  FRAME_LOW is the
+   beginning of the slice of frames to print, and FRAME_HIGH is the
+   upper limit of the frames to count.  Returns SCR_BT_ERROR on error,
+   or SCR_BT_COMPLETED on success.  */
+
+enum script_bt_status
+apply_script_frame_filter (struct frame_info *frame, int flags,
+			   enum script_frame_args args_type,
+			   struct ui_out *out,
+			   int frame_low, int frame_high)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      enum script_bt_status status;
+
+      if (slang->ops->apply_frame_filter == NULL)
+	continue;
+      status = slang->ops->apply_frame_filter (slang, frame, flags,
+					       args_type, out,
+					       frame_low, frame_high);
+      /* We use the filters from the first scripting language that has
+	 applicable filters.  */
+      if (status != SCR_BT_NO_FILTERS)
+	return status;
+    }
+
+  return SCR_BT_NO_FILTERS;
+}
+
+/* Update values held by the scripting language when OBJFILE is discarded.
+   New global types must be created for every such value, which must then be
+   updated to use the new types.
+   The function typically just iterates over all appropriate values and
+   calls preserve_one_value for each one.
+   COPIED_TYPES is used to prevent cycles / duplicates and is passed to
+   preserve_one_value.  */
+
+void
+preserve_script_values (struct objfile *objfile, htab_t copied_types)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->preserve_values != NULL)
+	slang->ops->preserve_values (slang, objfile, copied_types);
+    }
+}
+
+/* Return non-zero if there is a stop condition for the breakpoint,
+   and it indicates the program should stop.  */
+
+int
+breakpoint_script_cond_says_stop (struct breakpoint *b)
+{
+  int i;
+  const struct script_language *slang;
+  int stop = 0;
+
+  /* N.B.: All conditions must be executed, even if, e.g., the first one
+     says "stop".  Conditions may have side-effects.  */
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      /* Python hacks in "finish breakpoints" on top of the "stop" check,
+	 so we always have to call this, even if we could first determine
+	 whether a "stop" method exists.  */
+      if (slang->ops->breakpoint_cond_says_stop != NULL)
+	stop |= slang->ops->breakpoint_cond_says_stop (slang, b);
+    }
+
+  return stop;
+}
+\f
+/* ^C/SIGINT support.
+   This requires cooperation with the scripting languages so the support
+   is defined here.
+   The prototypes for these are in defs.h.  */
+
+/* Nonzero means a quit has been requested.
+   This flag tracks quit requests but it's only used if the scripting language
+   doesn't provide the necessary support.  */
+static int quit_flag;
+
+/* Clear the quit flag.  */
+
+void
+clear_quit_flag (void)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->clear_quit_flag != NULL)
+	slang->ops->clear_quit_flag (slang);
+    }
+
+  quit_flag = 0;
+}
+
+/* Set the quit flag.  */
+
+void
+set_quit_flag (void)
+{
+  int i;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->set_quit_flag != NULL)
+	slang->ops->set_quit_flag (slang);
+    }
+
+  quit_flag = 1;
+}
+
+/* Return true if the quit flag has been set, false otherwise.
+   Scripting languages may need their own control over whether SIGINT has
+   been seen.  */
+
+int
+check_quit_flag (void)
+{
+  int i, result = 0;
+  const struct script_language *slang;
+
+  ALL_ENABLED_EXT_SCRIPTING_LANGUAGES (i, slang)
+    {
+      if (slang->ops->check_quit_flag != NULL)
+	if (slang->ops->check_quit_flag (slang) != 0)
+	  result = 1;
+    }
+
+  /* This is written in a particular way to avoid races.  */
+  if (quit_flag)
+    {
+      quit_flag = 0;
+      result = 1;
+    }
+
+  return result;
+}
+\f
+/* Some code (e.g., MI) wants to know if a particular scripting language
+   successfully initialized.  */
+
+/* Return non-zero if Python scripting successfully initialized.  */
+
+int
+script_lang_python_initialized (void)
+{
+  if (script_lang_python.ops != NULL)
+    return script_lang_python.ops->initialized ();
+  return 0;
+}
diff --git a/gdb/scripting.h b/gdb/scripting.h
new file mode 100644
index 0000000..aa0bd1e
--- /dev/null
+++ b/gdb/scripting.h
@@ -0,0 +1,354 @@
+/* Interface between gdb and its scripting languages.
+
+   Copyright (C) 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef SCRIPTING_H
+#define SCRIPTING_H
+
+#include "mi/mi-cmds.h" /* For PRINT_NO_VALUES, etc.  */
+
+struct breakpoint;
+struct command_line;
+struct frame_info;
+struct language_defn;
+struct objfile;
+struct script_language;
+struct type;
+struct ui_file;
+struct ui_out;
+struct value;
+struct value_print_options;
+
+/* A function to load and process a script file.
+   The file has been opened and is ready to be read from the beginning.
+   Any exceptions are not caught, and are passed to the caller.  */
+typedef void script_sourcer_func (const struct script_language *,
+				  FILE *, const char *);
+
+/* A function to load and process a script for an objfile.
+   The file has been opened and is ready to be read from the beginning.
+   Any exceptions are not caught, and are passed to the caller.  */
+typedef void objfile_script_sourcer_func (const struct script_language *,
+					  struct objfile *,
+					  FILE *, const char *);
+
+/* A function to process a record in section .debug_gdb_scripts.
+   RECORD points to the leading type byte.
+   RECORD_SIZE includes the leading type byte and trailing NUL if there is one.
+   Any exceptions are not caught, and are passed to the caller.  */
+typedef void section_script_sourcer_func (const struct script_language *,
+					  struct objfile *,
+					  const char *section_name,
+					  const char *record,
+					  size_t record_size);
+
+/* Script frame-filter status return values.  */
+
+enum script_bt_status
+  {
+    /* Return when an error has occurred in processing frame filters,
+       or when printing the stack.  */
+    SCR_BT_ERROR = -1,
+
+    /* Return from internal routines to indicate that the function
+       succeeded.  */
+    SCR_BT_OK = 1,
+
+    /* Return when the frame filter process is complete, and all
+       operations have succeeded.  */
+    SCR_BT_COMPLETED = 2,
+
+    /* Return when the frame filter process is complete, but there
+       were no filter registered and enabled to process. */
+    SCR_BT_NO_FILTERS = 3
+  };
+
+/* Flags to pass to apply_frame_filter.  */
+
+enum frame_filter_flags
+  {
+    /* Set this flag if frame level is to be printed.  */
+    PRINT_LEVEL = 1,
+
+    /* Set this flag if frame information is to be printed.  */
+    PRINT_FRAME_INFO = 2,
+
+    /* Set this flag if frame arguments are to be printed.  */
+    PRINT_ARGS = 4,
+
+    /* Set this flag if frame locals are to be printed.  */
+    PRINT_LOCALS = 8,
+  };
+
+/* A choice of the different frame argument printing strategies that
+   can occur in different cases of frame filter instantiation.  */
+
+enum script_frame_args
+  {
+    /* Print no values for arguments when invoked from the MI. */
+    NO_VALUES = PRINT_NO_VALUES,
+
+    MI_PRINT_ALL_VALUES = PRINT_ALL_VALUES,
+
+    /* Print only simple values (what MI defines as "simple") for
+       arguments when invoked from the MI. */
+    MI_PRINT_SIMPLE_VALUES = PRINT_SIMPLE_VALUES,
+
+    /* Print only scalar values for arguments when invoked from the CLI. */
+    CLI_SCALAR_VALUES,
+
+    /* Print all values for arguments when invoked from the CLI. */
+    CLI_ALL_VALUES
+  };
+
+/* Table of type printers associated with the global typedef table.  */
+
+struct script_type_printers
+{
+  /* Type-printers from Python.  */
+  void *py_type_printers;
+};
+\f
+/* High level description of a scripting language.
+   An entry for each is compiled into GDB regardless of whether the support
+   is present.  This is done so that we can issue meaningful errors if the
+   support is not compiled in.  */
+
+struct script_language
+{
+  /* The name of the scripting language.  E.g., python.  */
+  const char *name;
+
+  /* The capitalized name of the scripting language.  E.g., Python.  */
+  const char *capitalized_name;
+
+  /* The file suffix for this scripting language.  E.g., ".py".  */
+  const char *suffix;
+
+  /* The suffix of per-objfile scripts to auto-load scripts.
+     E.g., When the program loads libfoo.so, look for libfoo.so-gdb.py.  */
+  const char *auto_load_suffix;
+
+  /* We support embedding external scripting language code in GDB's own
+     scripting language.  We do this by having a special command that begins
+     the external language snippet, and terminate it with "end".
+     This specifies the control type used to implement this.  */
+  enum command_control_type cli_control_type;
+
+  /* A pointer to the "methods" to load scripts in this language,
+     or NULL if the support is not compiled into GDB.  */
+  struct script_language_script_ops *script_ops;
+
+  /* Either a pointer to the "methods" of the scripting language interface
+     or NULL if the support is not compiled into GDB.
+     This is also NULL for GDB's own scripting language which is relatively
+     primitive, and doesn't provide these features.  */
+  const struct script_language_ops *ops;
+};
+
+/* The interface for loading scripts from external scripting languages,
+   as well as GDB's own scripting language.  */
+
+struct script_language_script_ops
+{
+  /* Load a script.  This is called, e.g., via the "source" command.  */
+  script_sourcer_func *script_sourcer;
+
+  /* Load a script attached to an objfile.  */
+  objfile_script_sourcer_func *objfile_script_sourcer;
+
+  /* Load a script contained in the .debug_gdb_scripts section.
+     Note: If new kinds of records are added to .debug_gdb_scripts for this
+     language, this function is intended to handle them as well.  */
+  section_script_sourcer_func *section_script_sourcer;
+
+  /* Return non-zero if auto-loading scripts in this scripting language
+     is enabled.  */
+  int (*auto_load_enabled) (const struct script_language *);
+};
+
+/* The interface for making calls from GDB to an external scripting
+   language.  This is for non-script-loading related functionality,
+   like pretty-printing, etc.  The reason these are separated out as
+   GDB's own scripting language makes use of script_language_script_opts,
+   but it makes no use of these.  There is no (current) intention to split
+   script_language_ops up any further.  */
+
+struct script_language_ops
+{
+  /* Called at the end of gdb initialization to give the scripting language
+     an opportunity to finish up.  This is useful for things like adding
+     new commands where one has to wait until gdb itself is initialized.  */
+  void (*finish_initialization) (const struct script_language *);
+
+  /* Return non-zero if the scripting language successfully initialized.  */
+  int (*initialized) (const struct script_language *);
+
+  /* Process a sequence of commands embedded in gdb's own scripting language.
+     E.g.,
+     python
+     print 42
+     end  */
+  void (*eval_from_control_command) (const struct script_language *,
+				     struct command_line *);
+
+  /* Called before printing a type.  */
+  void (*start_type_printers) (const struct script_language *,
+			       struct script_type_printers *);
+
+  /* Try to pretty-print TYPE.  If successful the pretty-printed type is
+     returned.  Otherwise NULL is returned.
+     This function has a bit of a funny name, since it actually applies
+     recognizers, but this seemed clearer given the start_type_printers
+     and free_type_printers functions.  */
+  char *(*apply_type_printers) (const struct script_language *,
+				const struct script_type_printers *,
+				struct type *);
+
+  /* Called after a type has been printed to give the type pretty-printer
+     mechanism an opportunity to clean up.  */
+  void (*free_type_printers) (const struct script_language *,
+			      struct script_type_printers *);
+
+  /* Try to pretty-print a value of type TYPE located at VALADDR
+     + EMBEDDED_OFFSET, which came from the inferior at address ADDRESS
+     + EMBEDDED_OFFSET, onto stdio stream STREAM according to OPTIONS.
+     VAL is the whole object that came from ADDRESS.  VALADDR must point to
+     the head of VAL's contents buffer.
+     Returns non-zero if the value was successfully pretty-printed.  */
+  int (*apply_val_pretty_printer)
+    (const struct script_language *,
+     struct type *type, const gdb_byte *valaddr,
+     int embedded_offset, CORE_ADDR address,
+     struct ui_file *stream, int recurse,
+     const struct value *val, const struct value_print_options *options,
+     const struct language_defn *language);
+
+  /* GDB access to the "frame filter" feature.
+     FRAME is the source frame to start frame-filter invocation.  FLAGS is an
+     integer holding the flags for printing.  The following elements of
+     the FRAME_FILTER_FLAGS enum denotes the make-up of FLAGS:
+     PRINT_LEVEL is a flag indicating whether to print the frame's
+     relative level in the output.  PRINT_FRAME_INFO is a flag that
+     indicates whether this function should print the frame
+     information, PRINT_ARGS is a flag that indicates whether to print
+     frame arguments, and PRINT_LOCALS, likewise, with frame local
+     variables.  ARGS_TYPE is an enumerator describing the argument
+     format, OUT is the output stream to print.  FRAME_LOW is the
+     beginning of the slice of frames to print, and FRAME_HIGH is the
+     upper limit of the frames to count.  Returns SCR_BT_ERROR on error,
+     or SCR_BT_COMPLETED on success.  */
+  enum script_bt_status (*apply_frame_filter)
+    (const struct script_language *,
+     struct frame_info *frame, int flags, enum script_frame_args args_type,
+     struct ui_out *out, int frame_low, int frame_high);
+
+  /* Update values held by the scripting language when OBJFILE is discarded.
+     New global types must be created for every such value, which must then be
+     updated to use the new types.
+     The function typically just iterates over all appropriate values and
+     calls preserve_one_value for each one.
+     COPIED_TYPES is used to prevent cycles / duplicates and is passed to
+     preserve_one_value.  */
+  void (*preserve_values) (const struct script_language *,
+			   struct objfile *objfile, htab_t copied_types);
+
+  /* Return non-zero if there is a stop condition for the breakpoint,
+     and it indicates the program should stop.  */
+  int (*breakpoint_cond_says_stop) (const struct script_language *,
+				    struct breakpoint *);
+
+  /* The next three are used to connect gdb's SIGINT handling with the
+     scripting language's.  */
+
+  /* Clear the SIGINT indicator.  */
+  void (*clear_quit_flag) (const struct script_language *);
+
+  /* Set the SIGINT indicator.  */
+  void (*set_quit_flag) (const struct script_language *);
+
+  /* Return non-zero if a SIGINT has occurred.
+     This is expected to also clear the indicator.  */
+  int (*check_quit_flag) (const struct script_language *);
+};
+\f
+/* Return a pointer to the script_language definition.  */
+extern const struct script_language *get_script_lang_gdb (void);
+extern const struct script_language *get_script_lang_python (void);
+
+/* Return non-zero if Python scripting successfully initialized.  */
+extern int script_lang_python_initialized (void);
+
+/* Accessors for "public" attributes of the scripting language definition.  */
+
+extern const char *script_lang_name (const struct script_language *);
+
+extern const char *script_lang_capitalized_name
+  (const struct script_language *);
+
+extern const char *script_lang_suffix (const struct script_language *);
+
+extern const char *script_lang_auto_load_suffix
+  (const struct script_language *);
+
+extern script_sourcer_func *script_lang_sourcer
+   (const struct script_language *);
+
+extern objfile_script_sourcer_func *script_lang_objfile_sourcer
+   (const struct script_language *);
+
+extern section_script_sourcer_func *script_lang_section_sourcer
+   (const struct script_language *);
+
+extern int script_lang_auto_load_enabled (const struct script_language *);
+
+/* Return the function that can load(source) FILE.  */
+extern script_sourcer_func *get_script_sourcer (const char *file);
+
+/* Wrappers for each scripting API function that iterate over all
+   (external) scripting languages.  */
+
+extern void finish_script_initialization (void);
+
+extern void eval_script_from_control_command (struct command_line *cmd);
+
+extern void auto_load_scripts_for_objfile (struct objfile *);
+
+extern struct script_type_printers *start_script_type_printers (void);
+
+extern char *apply_script_type_printers (struct script_type_printers *,
+					 struct type *);
+
+extern void free_script_type_printers (struct script_type_printers *);
+
+extern int apply_val_script_pretty_printer
+  (struct type *type, const gdb_byte *valaddr,
+   int embedded_offset, CORE_ADDR address,
+   struct ui_file *stream, int recurse,
+   const struct value *val, const struct value_print_options *options,
+   const struct language_defn *language);
+
+extern enum script_bt_status apply_script_frame_filter
+  (struct frame_info *frame, int flags, enum script_frame_args args_type,
+   struct ui_out *out, int frame_low, int frame_high);
+
+extern void preserve_script_values (struct objfile *, htab_t copied_types);
+
+extern int breakpoint_script_cond_says_stop (struct breakpoint *);
+
+#endif /* SCRIPTING_H */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC][PATCH] GDB->Python API changes in preparation for Guile support
  2013-11-25  3:40 [RFC][PATCH] GDB->Python API changes in preparation for Guile support Doug Evans
@ 2013-11-28 13:12 ` Pedro Alves
  2013-11-28 16:18   ` Yao Qi
  0 siblings, 1 reply; 3+ messages in thread
From: Pedro Alves @ 2013-11-28 13:12 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches, guile-user, sivachandra

On 11/25/2013 03:09 AM, Doug Evans wrote:
> 
> I didn't handle varobj because it's got Python more tightly embedded
> in it, and I think adding it can wait until there's an actual need.

Sounds like this series might be useful for you too then, as
it generalizes dynamic varobjs, decoupling them from python:

 https://sourceware.org/ml/gdb-patches/2013-11/msg00739.html

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC][PATCH] GDB->Python API changes in preparation for Guile support
  2013-11-28 13:12 ` Pedro Alves
@ 2013-11-28 16:18   ` Yao Qi
  0 siblings, 0 replies; 3+ messages in thread
From: Yao Qi @ 2013-11-28 16:18 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Doug Evans, gdb-patches, guile-user, sivachandra

On 11/28/2013 08:24 PM, Pedro Alves wrote:
> Sounds like this series might be useful for you too then, as
> it generalizes dynamic varobjs, decoupling them from python:
>
>   https://sourceware.org/ml/gdb-patches/2013-11/msg00739.html

Yeah, patch #1 ~ #4 are about the generalization.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-11-28 12:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-25  3:40 [RFC][PATCH] GDB->Python API changes in preparation for Guile support Doug Evans
2013-11-28 13:12 ` Pedro Alves
2013-11-28 16:18   ` Yao Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).