Allow "source" to load python scripts.
authorJoel Brobecker <brobecker@gnat.com>
Mon, 18 Jan 2010 06:25:22 +0000 (06:25 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Mon, 18 Jan 2010 06:25:22 +0000 (06:25 +0000)
        * exceptions.h (enum errors): Add UNSUPPORTED_ERROR.
        * python/python.c (source_python_script): New function.
        * python/python.h (source_python_script): Add declaration.
        * cli/cli-cmds.c: #include exceptions.h and python/python.h.
        (script_ext_off, script_ext_soft, script_ext_strict)
        (script_ext_enums, script_ext_mode): New static constants.
        (show_script_ext_mode, find_and_open_script): New functions.
        (source_script): Enhance to handle Python scripts.
        (init_cli_cmds): Add set/show script-extension commands.

gdb/ChangeLog
gdb/cli/cli-cmds.c
gdb/exceptions.h
gdb/python/python.c
gdb/python/python.h

index 6bbc5da2e743b28fcf7d959f25669376ad85c6ef..0e804f6e9024dce774613ec0c749f8a6c8fd6c5b 100644 (file)
@@ -1,3 +1,17 @@
+2010-01-18  Tom Tromey  <tromey@redhat.com>
+           Thiago Jung Bauermann  <bauerman@br.ibm.com>
+
+       Allow "source" to load python scripts.
+       * exceptions.h (enum errors): Add UNSUPPORTED_ERROR.
+       * python/python.c (source_python_script): New function.
+       * python/python.h (source_python_script): Add declaration.
+       * cli/cli-cmds.c: #include exceptions.h and python/python.h.
+       (script_ext_off, script_ext_soft, script_ext_strict)
+       (script_ext_enums, script_ext_mode): New static constants.
+       (show_script_ext_mode, find_and_open_script): New functions.
+       (source_script): Enhance to handle Python scripts.
+       (init_cli_cmds): Add set/show script-extension commands.
+
 2010-01-16  Stan Shebs  <stan@codesourcery.com>
 
        * tracepoint.h (struct trace_status): Use unsigned long long
index 483389848d86534ce4ab131bebebbfb06e9e45ee..74009673757381a26fc0a4acea1b04c157d9b0df 100644 (file)
@@ -19,6 +19,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "exceptions.h"
 #include "arch-utils.h"
 #include "readline/readline.h"
 #include "readline/tilde.h"
@@ -47,6 +48,8 @@ extern void disconnect_or_stop_tracing (int from_tty);
 #include "cli/cli-setshow.h"
 #include "cli/cli-cmds.h"
 
+#include "python/python.h"
+
 #ifdef TUI
 #include "tui/tui.h"           /* For tui_active et.al.   */
 #endif
@@ -187,6 +190,21 @@ struct cmd_list_element *showchecklist;
 int source_verbose = 0;
 int trace_commands = 0;
 \f
+/* 'script-extension' option support.  */
+
+static const char script_ext_off[] = "off";
+static const char script_ext_soft[] = "soft";
+static const char script_ext_strict[] = "strict";
+
+static const char *script_ext_enums[] = {
+  script_ext_off,
+  script_ext_soft,
+  script_ext_strict,
+  NULL
+};
+
+static const char *script_ext_mode = script_ext_soft;
+\f
 /* Utility used everywhere when at least one argument is needed and
    none is supplied. */
 
@@ -441,18 +459,25 @@ cd_command (char *dir, int from_tty)
     pwd_command ((char *) 0, 1);
 }
 \f
-void
-source_script (char *file, int from_tty)
+/* Show the current value of the 'script-extension' option.  */
+
+static void
+show_script_ext_mode (struct ui_file *file, int from_tty,
+                    struct cmd_list_element *c, const char *value)
 {
-  FILE *stream;
-  struct cleanup *old_cleanups;
+  fprintf_filtered (file, _("\
+Script filename extension recognition is \"%s\".\n"),
+                   value);
+}
+
+static int
+find_and_open_script (int from_tty, char **filep, FILE **streamp,
+                     struct cleanup **cleanupp)
+{
+  char *file = *filep;
   char *full_pathname = NULL;
   int fd;
-
-  if (file == NULL || *file == 0)
-    {
-      error (_("source command requires file name of file to source."));
-    }
+  struct cleanup *old_cleanups;
 
   file = tilde_expand (file);
   old_cleanups = make_cleanup (xfree, file);
@@ -476,12 +501,58 @@ source_script (char *file, int from_tty)
       else
        {
          do_cleanups (old_cleanups);
-         return;
+         return 0;
        }
     }
 
-  stream = fdopen (fd, FOPEN_RT);
-  script_from_file (stream, file);
+  *streamp = fdopen (fd, FOPEN_RT);
+  *filep = file;
+  *cleanupp = old_cleanups;
+
+  return 1;
+}
+
+void
+source_script (char *file, int from_tty)
+{
+  FILE *stream;
+  struct cleanup *old_cleanups;
+
+  if (file == NULL || *file == 0)
+    {
+      error (_("source command requires file name of file to source."));
+    }
+
+  if (!find_and_open_script (from_tty, &file, &stream, &old_cleanups))
+    return;
+
+  if (script_ext_mode != script_ext_off
+      && strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py"))
+    {
+      volatile struct gdb_exception e;
+
+      TRY_CATCH (e, RETURN_MASK_ERROR)
+       {
+         source_python_script (stream, file);
+       }
+      if (e.reason < 0)
+       {
+         /* Should we fallback to ye olde GDB script mode?  */
+         if (script_ext_mode == script_ext_soft
+             && e.reason == RETURN_ERROR && e.error == UNSUPPORTED_ERROR)
+           {
+             if (!find_and_open_script (from_tty, &file, &stream, &old_cleanups))
+               return;
+
+             script_from_file (stream, file);
+           }
+         else
+           /* Nope, just punt.  */
+           throw_exception (e);
+       }
+    }
+  else
+    script_from_file (stream, file);
 
   do_cleanups (old_cleanups);
 }
@@ -1314,6 +1385,19 @@ when GDB is started."), gdbinit);
               source_help_text, &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  add_setshow_enum_cmd ("script-extension", class_support,
+                       script_ext_enums, &script_ext_mode, _("\
+Set mode for script filename extension recognition."), _("\
+Show mode for script filename extension recognition."), _("\
+off  == no filename extension recognition (all sourced files are GDB scripts)\n\
+soft == evaluate script according to filename extension, fallback to GDB script"
+  "\n\
+strict == evaluate script according to filename extension, error if not supported"
+  ),
+                       NULL,
+                       show_script_ext_mode,
+                       &setlist, &showlist);
+
   add_com ("quit", class_support, quit_command, _("Exit gdb."));
   c = add_com ("help", class_support, help_command,
               _("Print list of commands."));
index 84a9f0120b15e5d9f554b260da5f6d30a8c74327..6b3cbeb24266453c7da9e2dde7b61bd25658f739 100644 (file)
@@ -75,6 +75,9 @@ enum errors {
   /* Error accessing memory.  */
   MEMORY_ERROR,
 
+  /* Feature is not supported in this copy of GDB.  */
+  UNSUPPORTED_ERROR,
+
   /* Add more errors here.  */
   NR_ERRORS
 };
index 827372c0cb495d50d75ddd3d5674a3d8b7aa4162..1f1ae729fb3d3516fe327443646329425047bb63 100644 (file)
@@ -343,6 +343,22 @@ gdbpy_parse_and_eval (PyObject *self, PyObject *args)
   return value_to_value_object (result);
 }
 
+/* Read a file as Python code.  STREAM is the input file; FILE is the
+   name of the file.  */
+
+void
+source_python_script (FILE *stream, char *file)
+{
+  PyGILState_STATE state;
+
+  state = PyGILState_Ensure ();
+
+  PyRun_SimpleFile (stream, file);
+
+  fclose (stream);
+  PyGILState_Release (state);
+}
+
 \f
 
 /* Printing.  */
@@ -525,6 +541,14 @@ 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 *stream, char *file)
+{
+  fclose (stream);
+  throw_error (UNSUPPORTED_ERROR,
+              _("Python scripting is not supported in this copy of GDB."));
+}
+
 #endif /* HAVE_PYTHON */
 
 \f
index f35827bbbd5710ce6c4055adb703adf32e9087e7..5d93f67962b8b6297d85414e945547cdcfb9df09 100644 (file)
@@ -24,6 +24,8 @@
 
 void eval_python_from_control_command (struct command_line *);
 
+void source_python_script (FILE *stream, char *file);
+
 int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
                              int embedded_offset, CORE_ADDR address,
                              struct ui_file *stream, int recurse,