Replace most calls to help_list and cmd_show_list
[deliverable/binutils-gdb.git] / gdb / guile / guile.c
index 3a19eecc2a7c95e49ad4121e9f51360ac2784024..2b82f82820fe3612451214f1c1b5f6c625a55d56 100644 (file)
@@ -1,6 +1,6 @@
 /* General GDB/Guile code.
 
-   Copyright (C) 2014-2016 Free Software Foundation, Inc.
+   Copyright (C) 2014-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "top.h"
 #include "extension-priv.h"
 #include "utils.h"
-#include "version.h"
+#include "gdbsupport/version.h"
 #ifdef HAVE_GUILE
 #include "guile.h"
 #include "guile-internal.h"
 #endif
 #include <signal.h>
+#include "gdbsupport/block-signals.h"
 
 /* The Guile version we're using.
    We *could* use the macros in libguile/version.h but that would preclude
@@ -46,8 +47,10 @@ int gdbscm_guile_major_version;
 int gdbscm_guile_minor_version;
 int gdbscm_guile_micro_version;
 
+#ifdef HAVE_GUILE
 /* The guile subdirectory within gdb's data-directory.  */
 static const char *guile_datadir;
+#endif
 
 /* Declared constants and enum for guile exception printing.  */
 const char gdbscm_print_excp_none[] = "none";
@@ -69,33 +72,6 @@ static const char *const guile_print_excp_enums[] =
    the default.  */
 const char *gdbscm_print_excp = gdbscm_print_excp_message;
 
-#ifdef HAVE_GUILE
-/* Forward decls, these are defined later.  */
-extern const struct extension_language_script_ops guile_extension_script_ops;
-extern const struct extension_language_ops guile_extension_ops;
-#endif
-
-/* The main struct describing GDB's interface to the Guile
-   extension language.  */
-extern const struct extension_language_defn extension_language_guile =
-{
-  EXT_LANG_GUILE,
-  "guile",
-  "Guile",
-
-  ".scm",
-  "-gdb.scm",
-
-  guile_control,
-
-#ifdef HAVE_GUILE
-  &guile_extension_script_ops,
-  &guile_extension_ops
-#else
-  NULL,
-  NULL
-#endif
-};
 \f
 #ifdef HAVE_GUILE
 
@@ -124,7 +100,7 @@ static const char boot_scm_filename[] = "boot.scm";
 
 /* The interface between gdb proper and loading of python scripts.  */
 
-const struct extension_language_script_ops guile_extension_script_ops =
+static const struct extension_language_script_ops guile_extension_script_ops =
 {
   gdbscm_source_script,
   gdbscm_source_objfile_script,
@@ -134,7 +110,7 @@ const struct extension_language_script_ops guile_extension_script_ops =
 
 /* The interface between gdb proper and guile scripting.  */
 
-const struct extension_language_ops guile_extension_ops =
+static const struct extension_language_ops guile_extension_ops =
 {
   gdbscm_finish_initialization,
   gdbscm_initialized,
@@ -157,16 +133,37 @@ const struct extension_language_ops guile_extension_ops =
   NULL, /* gdbscm_check_quit_flag, */
   NULL, /* gdbscm_set_quit_flag, */
 };
+#endif
+
+/* The main struct describing GDB's interface to the Guile
+   extension language.  */
+extern const struct extension_language_defn extension_language_guile =
+{
+  EXT_LANG_GUILE,
+  "guile",
+  "Guile",
 
+  ".scm",
+  "-gdb.scm",
+
+  guile_control,
+
+#ifdef HAVE_GUILE
+  &guile_extension_script_ops,
+  &guile_extension_ops
+#else
+  NULL,
+  NULL
+#endif
+};
+
+#ifdef HAVE_GUILE
 /* Implementation of the gdb "guile-repl" command.  */
 
 static void
-guile_repl_command (char *arg, int from_tty)
+guile_repl_command (const char *arg, int from_tty)
 {
-  struct cleanup *cleanup;
-
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
   arg = skip_spaces (arg);
 
@@ -183,8 +180,6 @@ guile_repl_command (char *arg, int from_tty)
       dont_repeat ();
       gdbscm_enter_repl ();
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Implementation of the gdb "guile" command.
@@ -194,34 +189,25 @@ guile_repl_command (char *arg, int from_tty)
    TODO: Add the result to Guile's history?  */
 
 static void
-guile_command (char *arg, int from_tty)
+guile_command (const char *arg, int from_tty)
 {
-  struct cleanup *cleanup;
-
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
   arg = skip_spaces (arg);
 
   if (arg && *arg)
     {
-      char *msg = gdbscm_safe_eval_string (arg, 1);
+      gdb::unique_xmalloc_ptr<char> msg = gdbscm_safe_eval_string (arg, 1);
 
       if (msg != NULL)
-       {
-         make_cleanup (xfree, msg);
-         error ("%s", msg);
-       }
+       error ("%s", msg.get ());
     }
   else
     {
-      struct command_line *l = get_command_line (guile_control, "");
+      counted_command_line l = get_command_line (guile_control, "");
 
-      make_cleanup_free_command_lines (&l);
-      execute_control_command_untraced (l);
+      execute_control_command_untraced (l.get ());
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Given a command_line, return a command string suitable for passing
@@ -262,24 +248,16 @@ static void
 gdbscm_eval_from_control_command
   (const struct extension_language_defn *extlang, struct command_line *cmd)
 {
-  char *script, *msg;
-  struct cleanup *cleanup;
+  char *script;
 
-  if (cmd->body_count != 1)
+  if (cmd->body_list_1 != nullptr)
     error (_("Invalid \"guile\" block structure."));
 
-  cleanup = make_cleanup (null_cleanup, NULL);
-
-  script = compute_scheme_string (cmd->body_list[0]);
-  msg = gdbscm_safe_eval_string (script, 0);
+  script = compute_scheme_string (cmd->body_list_0.get ());
+  gdb::unique_xmalloc_ptr<char> msg = gdbscm_safe_eval_string (script, 0);
   xfree (script);
   if (msg != NULL)
-    {
-      make_cleanup (xfree, msg);
-      error ("%s", msg);
-    }
-
-  do_cleanups (cleanup);
+    error ("%s", msg.get ());
 }
 
 /* Read a file as Scheme code.
@@ -311,56 +289,33 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest)
   int from_tty = 0, to_string = 0;
   const SCM keywords[] = { from_tty_keyword, to_string_keyword, SCM_BOOL_F };
   char *command;
-  char *result = NULL;
-  struct cleanup *cleanups;
-  struct gdb_exception except = exception_none;
 
   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#tt",
                              command_scm, &command, rest,
                              &from_tty_arg_pos, &from_tty,
                              &to_string_arg_pos, &to_string);
 
-  /* Note: The contents of "command" may get modified while it is
-     executed.  */
-  cleanups = make_cleanup (xfree, command);
-
-  TRY
+  return gdbscm_wrap ([=]
     {
-      struct cleanup *inner_cleanups;
+      gdb::unique_xmalloc_ptr<char> command_holder (command);
+      std::string to_string_res;
 
-      inner_cleanups = make_cleanup_restore_integer (&current_ui->async);
-      current_ui->async = 0;
+      scoped_restore restore_async = make_scoped_restore (&current_ui->async,
+                                                         0);
 
-      prevent_dont_repeat ();
+      scoped_restore preventer = prevent_dont_repeat ();
       if (to_string)
-       result = execute_command_to_string (command, from_tty);
+       to_string_res = execute_command_to_string (command, from_tty, false);
       else
-       {
-         execute_command (command, from_tty);
-         result = NULL;
-       }
+       execute_command (command, from_tty);
 
       /* Do any commands attached to breakpoint we stopped at.  */
       bpstat_do_actions ();
 
-      do_cleanups (inner_cleanups);
-    }
-  CATCH (ex, RETURN_MASK_ALL)
-    {
-      except = ex;
-    }
-  END_CATCH
-
-  do_cleanups (cleanups);
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
-
-  if (result)
-    {
-      SCM r = gdbscm_scm_from_c_string (result);
-      xfree (result);
-      return r;
-    }
-  return SCM_UNSPECIFIED;
+      if (to_string)
+       return gdbscm_scm_from_c_string (to_string_res.c_str ());
+      return SCM_UNSPECIFIED;
+    });
 }
 
 /* (data-directory) -> string */
@@ -368,7 +323,7 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest)
 static SCM
 gdbscm_data_directory (void)
 {
-  return gdbscm_scm_from_c_string (gdb_datadir);
+  return gdbscm_scm_from_c_string (gdb_datadir.c_str ());
 }
 
 /* (guile-data-directory) -> string */
@@ -409,7 +364,7 @@ gdbscm_target_config (void)
    commands. */
 
 static void
-guile_repl_command (char *arg, int from_tty)
+guile_repl_command (const char *arg, int from_tty)
 {
   arg = skip_spaces (arg);
   if (arg && *arg)
@@ -418,7 +373,7 @@ guile_repl_command (char *arg, int from_tty)
 }
 
 static void
-guile_command (char *arg, int from_tty)
+guile_command (const char *arg, int from_tty)
 {
   arg = skip_spaces (arg);
   if (arg && *arg)
@@ -427,11 +382,9 @@ guile_command (char *arg, int from_tty)
     {
       /* Even if Guile isn't enabled, we still have to slurp the
         command list to the corresponding "end".  */
-      struct command_line *l = get_command_line (guile_control, "");
-      struct cleanup *cleanups = make_cleanup_free_command_lines (&l);
+      counted_command_line l = get_command_line (guile_control, "");
 
-      execute_control_command_untraced (l);
-      do_cleanups (cleanups);
+      execute_control_command_untraced (l.get ());
     }
 }
 
@@ -443,33 +396,6 @@ static struct cmd_list_element *set_guile_list;
 static struct cmd_list_element *show_guile_list;
 static struct cmd_list_element *info_guile_list;
 
-/* Function for use by 'set guile' prefix command.  */
-
-static void
-set_guile_command (char *args, int from_tty)
-{
-  help_list (set_guile_list, "set guile ", all_commands, gdb_stdout);
-}
-
-/* Function for use by 'show guile' prefix command.  */
-
-static void
-show_guile_command (char *args, int from_tty)
-{
-  cmd_show_list (show_guile_list, from_tty, "");
-}
-
-/* The "info scheme" command is defined as a prefix, with
-   allow_unknown 0.  Therefore, its own definition is called only for
-   "info scheme" with no args.  */
-
-static void
-info_guile_command (char *args, int from_tty)
-{
-  printf_unfiltered (_("\"info guile\" must be followed"
-                      " by the name of an info command.\n"));
-  help_list (info_guile_list, "info guile ", all_commands, gdb_stdout);
-}
 \f
 /* Initialization.  */
 
@@ -613,7 +539,7 @@ handle_boot_error (void *boot_scm_file, SCM key, SCM args)
   warning (_("Could not complete Guile gdb module initialization from:\n"
             "%s.\n"
             "Limited Guile support is available.\n"
-            "Suggest passing --data-directory=/path/to/gdb/data-directory.\n"),
+            "Suggest passing --data-directory=/path/to/gdb/data-directory."),
           (const char *) boot_scm_file);
 
   return SCM_UNSPECIFIED;
@@ -626,9 +552,9 @@ static void
 initialize_scheme_side (void)
 {
   char *boot_scm_path;
-  char *msg;
 
-  guile_datadir = concat (gdb_datadir, SLASH_STRING, "guile", (char *) NULL);
+  guile_datadir = concat (gdb_datadir.c_str (), SLASH_STRING, "guile",
+                         (char *) NULL);
   boot_scm_path = concat (guile_datadir, SLASH_STRING, "gdb",
                          SLASH_STRING, boot_scm_filename, (char *) NULL);
 
@@ -746,6 +672,9 @@ gdbscm_set_backtrace (int enable)
 
 #endif /* HAVE_GUILE */
 
+/* See guile.h.  */
+cmd_list_element *guile_cmd_element = nullptr;
+
 /* Install the various gdb commands used by Guile.  */
 
 static void
@@ -771,7 +700,7 @@ This command is only a placeholder.")
 
   /* Since "help guile" is easy to type, and intuitive, we add general help
      in using GDB+Guile to this command.  */
-  add_com ("guile", class_obscure, guile_command,
+  guile_cmd_element = add_com ("guile", class_obscure, guile_command,
 #ifdef HAVE_GUILE
           _("\
 Evaluate one or more Guile expressions.\n\
@@ -805,22 +734,22 @@ This command is only a placeholder.")
           );
   add_com_alias ("gu", "guile", class_obscure, 1);
 
-  add_prefix_cmd ("guile", class_obscure, set_guile_command,
-                 _("Prefix command for Guile preference settings."),
-                 &set_guile_list, "set guile ", 0,
-                 &setlist);
+  add_basic_prefix_cmd ("guile", class_obscure,
+                       _("Prefix command for Guile preference settings."),
+                       &set_guile_list, "set guile ", 0,
+                       &setlist);
   add_alias_cmd ("gu", "guile", class_obscure, 1, &setlist);
 
-  add_prefix_cmd ("guile", class_obscure, show_guile_command,
-                 _("Prefix command for Guile preference settings."),
-                 &show_guile_list, "show guile ", 0,
-                 &showlist);
+  add_show_prefix_cmd ("guile", class_obscure,
+                      _("Prefix command for Guile preference settings."),
+                      &show_guile_list, "show guile ", 0,
+                      &showlist);
   add_alias_cmd ("gu", "guile", class_obscure, 1, &showlist);
 
-  add_prefix_cmd ("guile", class_obscure, info_guile_command,
-                 _("Prefix command for Guile info displays."),
-                 &info_guile_list, "info guile ", 0,
-                 &infolist);
+  add_basic_prefix_cmd ("guile", class_obscure,
+                       _("Prefix command for Guile info displays."),
+                       &info_guile_list, "info guile ", 0,
+                       &infolist);
   add_info_alias ("gu", "guile", 1);
 
   /* The name "print-stack" is carried over from Python.
@@ -836,20 +765,14 @@ message == an error message without a stack will be printed."),
                        &set_guile_list, &show_guile_list);
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_guile;
-
+void _initialize_guile ();
 void
-_initialize_guile (void)
+_initialize_guile ()
 {
   install_gdb_commands ();
 
 #if HAVE_GUILE
   {
-#ifdef HAVE_SIGPROCMASK
-    sigset_t sigchld_mask, prev_mask;
-#endif
-
     /* The Python support puts the C side in module "_gdb", leaving the Python
        side to define module "gdb" which imports "_gdb".  There is evidently no
        similar convention in Guile so we skip this.  */
@@ -861,25 +784,20 @@ _initialize_guile (void)
     scm_set_automatic_finalization_enabled (0);
 #endif
 
-#ifdef HAVE_SIGPROCMASK
-    /* Before we initialize Guile, block SIGCHLD.
+    /* Before we initialize Guile, block signals needed by gdb
+       (especially SIGCHLD).
        This is done so that all threads created during Guile initialization
        have SIGCHLD blocked.  PR 17247.
        Really libgc and Guile should do this, but we need to work with
        libgc 7.4.x.  */
-    sigemptyset (&sigchld_mask);
-    sigaddset (&sigchld_mask, SIGCHLD);
-    sigprocmask (SIG_BLOCK, &sigchld_mask, &prev_mask);
-#endif
-
-    /* scm_with_guile is the most portable way to initialize Guile.
-       Plus we need to initialize the Guile support while in Guile mode
-       (e.g., called from within a call to scm_with_guile).  */
-    scm_with_guile (call_initialize_gdb_module, NULL);
+    {
+      gdb::block_signals blocker;
 
-#ifdef HAVE_SIGPROCMASK
-    sigprocmask (SIG_SETMASK, &prev_mask, NULL);
-#endif
+      /* scm_with_guile is the most portable way to initialize Guile.
+        Plus we need to initialize the Guile support while in Guile mode
+        (e.g., called from within a call to scm_with_guile).  */
+      scm_with_guile (call_initialize_gdb_module, NULL);
+    }
 
     /* Set Guile's backtrace to match the "set guile print-stack" default.
        [N.B. The two settings are still separate.]
This page took 0.054307 seconds and 4 git commands to generate.