public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH 4/5] Add "save skip" command
Date: Sun, 29 Jan 2023 09:21:04 -0700	[thread overview]
Message-ID: <20230129162105.526266-5-tom@tromey.com> (raw)
In-Reply-To: <20230129162105.526266-1-tom@tromey.com>

PR cli/17997 points out that it would sometimes be convenient to save
the current "skip"s to a file.  This patch implements this feature.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17997
---
 gdb/NEWS                        |  3 ++
 gdb/doc/gdb.texinfo             |  6 +++
 gdb/skip.c                      | 78 +++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/skip.exp | 12 +++++
 4 files changed, 99 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index 3b7d768732c..a5b6f8df2ff 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -17,6 +17,9 @@ maintenance print record-instruction [ N ]
   prints how GDB would undo the N-th previous instruction, and if N is
   positive, it prints how GDB will redo the N-th following instruction.
 
+save skip FILENAME
+  Save all current "skip"s to the given file.
+
 save user FILENAME
   Save all user-defined commands to the given file.
 
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 37db4785fd2..31f73c33894 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -6707,6 +6707,12 @@ Set whether to print the debug output about skipping files and functions.
 @item show debug skip
 Show whether the debug output about skipping files and functions is printed.
 
+@kindex save skip
+@item save skip @var{filename}
+Save all skips to the file @var{filename}.  This command writes out
+the skips as a script that can be re-read into @value{GDBN} using the
+@code{source} command.
+
 @end table
 
 @node Signals
diff --git a/gdb/skip.c b/gdb/skip.c
index f3b1bec9e4c..5f98df803f9 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -38,6 +38,8 @@
 #include <list>
 #include "cli/cli-style.h"
 #include "gdbsupport/buildargv.h"
+#include "safe-ctype.h"
+#include "readline/tilde.h"
 
 /* True if we want to print debug printouts related to file/function
    skipping. */
@@ -76,6 +78,9 @@ class skiplist_entry
   skiplist_entry (const skiplist_entry &) = delete;
   void operator= (const skiplist_entry &) = delete;
 
+  /* Print a gdb command that can be used to recreate this skip.  */
+  void print_recreate (ui_file *stream) const;
+
 private:
   /* Key that grants access to the constructor.  */
   struct private_key {};
@@ -160,6 +165,54 @@ skiplist_entry::add_entry (bool file_is_glob, std::string &&file,
   skiplist_entries.back ().m_number = ++highest_skiplist_entry_num;
 }
 
+/* A helper function for print_recreate that prints a correctly-quoted
+   string to STREAM.  */
+
+static void
+print_quoted (ui_file *stream, const std::string &str)
+{
+  gdb_putc ('"', stream);
+  for (char c : str)
+    {
+      if (ISSPACE (c) || c == '\\' || c == '\'' || c == '"')
+	gdb_putc ('\\', stream);
+      gdb_putc (c, stream);
+    }
+  gdb_putc ('"', stream);
+}
+
+void
+skiplist_entry::print_recreate (ui_file *stream) const
+{
+  if (!m_file_is_glob && !m_file.empty ()
+      && !m_function_is_regexp && m_function.empty ())
+    gdb_printf (stream, "skip file %s\n", m_file.c_str ());
+  else if (!m_file_is_glob && m_file.empty ()
+      && !m_function_is_regexp && !m_function.empty ())
+    gdb_printf (stream, "skip function %s\n", m_function.c_str ());
+  else
+    {
+      gdb_printf (stream, "skip ");
+      if (!m_file.empty ())
+	{
+	  if (m_file_is_glob)
+	    gdb_printf (stream, "-gfile ");
+	  else
+	    gdb_printf (stream, "-file ");
+	  print_quoted (stream, m_file);
+	}
+      if (!m_function.empty ())
+	{
+	  if (m_function_is_regexp)
+	    gdb_printf (stream, "-rfunction ");
+	  else
+	    gdb_printf (stream, "-function ");
+	  print_quoted (stream, m_function);
+	}
+      gdb_printf (stream, "\n");
+    }      
+}
+
 static void
 skip_file_command (const char *arg, int from_tty)
 {
@@ -657,6 +710,24 @@ complete_skip_number (cmd_list_element *cmd,
     }
 }
 
+/* Implementation of 'save skip' command.  */
+
+static void
+save_skip_command (const char *filename, int from_tty)
+{
+  if (filename == nullptr || *filename == '\0')
+    error (_("Argument required (file name in which to save)"));
+
+  gdb::unique_xmalloc_ptr<char> expanded_filename (tilde_expand (filename));
+  stdio_file fp;
+  if (!fp.open (expanded_filename.get (), "w"))
+    error (_("Unable to open file '%s' for saving (%s)"),
+	   expanded_filename.get (), safe_strerror (errno));
+
+  for (const auto &entry : skiplist_entries)
+    entry.print_recreate (&fp);
+}
+
 void _initialize_step_skip ();
 void
 _initialize_step_skip ()
@@ -737,4 +808,11 @@ Show whether the debug output about skipping files and functions is printed."),
 When non-zero, debug output about skipping files and functions is displayed."),
 			   NULL, NULL,
 			   &setdebuglist, &showdebuglist);
+
+  c = add_cmd ("skip", no_class, save_skip_command, _("\
+Save current skips as a script.\n\
+Usage: save skip FILE\n\
+Use the 'source' command in another debug session to restore them."),
+	       &save_cmdlist);
+  set_cmd_completer (c, filename_completer);
 }
diff --git a/gdb/testsuite/gdb.base/skip.exp b/gdb/testsuite/gdb.base/skip.exp
index 41c811b9769..4b4e890ea21 100644
--- a/gdb/testsuite/gdb.base/skip.exp
+++ b/gdb/testsuite/gdb.base/skip.exp
@@ -206,6 +206,9 @@ with_test_prefix "admin" {
 		    "4\\s+y\\s+n\\s+<none>\\s+n\\s+baz"] \
 	"info skip after enabling all"
 
+    gdb_test_no_output "save skip [standard_output_file skips]" \
+	"save skips to file"
+
     gdb_test "skip disable 4 2-3"
     gdb_test "info skip" \
 	[multi_line "Num\\s+Enb\\s+Glob\\s+File\\s+RE\\s+Function" \
@@ -337,3 +340,12 @@ with_test_prefix "skip delete completion" {
     test_gdb_complete_none "skip delete 2-33"
 }
 
+clean_restart
+gdb_test "source [standard_output_file skips]" "" \
+    "re-read saved skips"
+gdb_test "info skip" \
+    [multi_line "Num\\s+Enb\\s+Glob\\s+File\\s+RE\\s+Function" \
+	 "1\\s+y\\s+n\\s+<none>\\s+n\\s+main" \
+	 "2\\s+y\\s+n\\s+$srcfile1\\s+n\\s+<none>" \
+	 "3\\s+y\\s+n\\s+<none>\\s+n\\s+baz"] \
+    "info skip after re-reading"
-- 
2.39.1


  parent reply	other threads:[~2023-01-29 16:21 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-29 16:21 [PATCH 0/5] Additions to "save" command Tom Tromey
2023-01-29 16:21 ` [PATCH 1/5] Save breakpoints so they are automatically pending Tom Tromey
2023-01-31 15:14   ` Alexandra Petlanova Hajkova
2023-01-29 16:21 ` [PATCH 2/5] Move show_user_1 to cli-cmds.c Tom Tromey
2023-01-29 16:21 ` [PATCH 3/5] Add "save user" command Tom Tromey
2023-01-29 16:57   ` Eli Zaretskii
2023-01-30 14:53   ` Pedro Alves
2023-01-30 23:35     ` Tom Tromey
2023-01-29 16:21 ` Tom Tromey [this message]
2023-01-29 16:54   ` [PATCH 4/5] Add "save skip" command Eli Zaretskii
2023-01-29 16:21 ` [PATCH 5/5] Add "save history" command Tom Tromey
2023-01-29 16:56   ` Eli Zaretskii
2023-01-30 14:50   ` Pedro Alves
2023-01-30 15:12     ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230129162105.526266-5-tom@tromey.com \
    --to=tom@tromey.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).