public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Keith Seitz <keiths@redhat.com>
To: gdb-patches@sourceware.org
Cc: Wendy.Peikes@netapp.com
Subject: [RFC PATCH 2/2] Allow and evaluate expressions in command arguments
Date: Wed, 25 Jan 2023 11:38:25 -0800	[thread overview]
Message-ID: <20230125193825.3665649-3-keiths@redhat.com> (raw)
In-Reply-To: <20230125193825.3665649-1-keiths@redhat.com>

This patch adds support for arbitrary expressions to be passed to
GDB commands, evaluated, and the results substituted into command
arguments.

This allows users to pass arbitrary expressions into commands which
currently do not support any way of doing this. This is especially
useful with, for example, convenience variables and functions.

Example:
$ export MYDIR="tmp"
$ export MYFILE="simple"
$ gdb -nx -q
(gdb) file $($_env("HOME"))/$($_env("MYDIR"))/$($_env("MYFILE"))
Reading symbols from /home/keiths/tmp/simple...
(gdb)

In order to mark the bounds of expressions to be evaluated, I've
introduced the (arbitrary) marker "$()". Everything contained inside
this marker will be passed to the expression parser, evaluated, printed
as a string, and then substituted for the original expression.
---
 gdb/top.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/gdb/top.c b/gdb/top.c
index 205eb360ba3..3f394b5b63c 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -57,6 +57,8 @@
 #include "gdbsupport/pathstuff.h"
 #include "cli/cli-style.h"
 #include "pager.h"
+#include "valprint.h"
+#include "cp-support.h" 	/* for find_toplevel_char  */
 
 /* readline include files.  */
 #include "readline/readline.h"
@@ -567,6 +569,60 @@ set_repeat_arguments (const char *args)
   repeat_arguments = args;
 }
 
+/* Evaluate and expand any expressions in the command line list of arguments
+   given by ORIG_ARGS.  All occurrences of "$(expr)" will be replaced with a
+   string representation of the evaluated EXPR.  */
+
+#define EVAL_START_STRING "$("
+#define EVAL_END_TOKEN ')'
+
+static std::string
+expand_command_arg (const char *orig_arg)
+{
+  std::string new_arg = orig_arg;
+  std::string::size_type n = new_arg.find (EVAL_START_STRING);
+
+  /* These needs adjustment to output "simple" strings.  For example,
+     if a char value is used, we end up with "97 'a'" instead of simply "a".  */
+  struct value_print_options opts;
+  get_user_print_options (&opts);
+
+  string_file stb;
+
+  while (n != std::string::npos)
+    {
+      const char *args = new_arg.c_str ();
+      const char *c = find_toplevel_char (args + n + 2, EVAL_END_TOKEN);
+
+      if (c != nullptr)
+	{
+	  std::string expr = new_arg.substr (n + 2, c - args - n - 2);
+	  struct value *val = parse_and_eval (expr.c_str ());
+
+	  value_print (val, &stb, &opts);
+
+	  /* If value_print returns a quote-enclosed string, remove the
+	     quote characters.  */
+	  std::string r = stb.release ();
+
+	  if (*r.begin () == '\"' && *r.rbegin () == '\"')
+	    {
+	      r.erase (r.begin ());
+	      r.pop_back ();
+	    }
+
+	  new_arg.replace (n, c - args - n + 1, r);
+	  n = new_arg.find (EVAL_START_STRING);
+	}
+    }
+
+#if 0
+  if (new_arg != orig_arg)
+    printf ("NEW_ARG = %s\n", new_arg.c_str ());
+#endif
+  return new_arg;
+}
+
 /* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
@@ -657,6 +713,15 @@ execute_command (const char *p, int from_tty)
       if (c->deprecated_warn_user)
 	deprecated_cmd_warning (line, cmdlist);
 
+      /* Do any expression substitutions on ARG.  */
+      std::string expanded_arg;
+
+      if (arg != nullptr)
+	{
+	  expanded_arg = expand_command_arg (arg);
+	  arg = expanded_arg.c_str ();
+	}
+
       /* c->user_commands would be NULL in the case of a python command.  */
       if (c->theclass == class_user && c->user_commands)
 	execute_user_command (c, arg);
-- 
2.38.1


  parent reply	other threads:[~2023-01-25 19:38 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <BYAPR06MB6117A6A68D09026F27C310D4E54C9@BYAPR06MB6117.namprd06.prod.outlook.com>
     [not found] ` <BYAPR06MB611721469E1454F0CD94259DE55D9@BYAPR06MB6117.namprd06.prod.outlook.com>
2022-10-05 23:19   ` [PATCH] gdb: allow env var specifications in cmds 'set log', 'source', 'shell' Peikes, Wendy
2022-10-05 23:19     ` Peikes, Wendy
2022-10-06 19:34     ` Keith Seitz
2022-10-26  0:25       ` Peikes, Wendy
2023-01-25 19:38         ` [RFC PATCH 0/2] Command expression evaulation substitution Keith Seitz
2023-01-25 19:38           ` [RFC PATCH 1/2] Add $_env convenience function Keith Seitz
2023-02-03 17:18             ` Andrew Burgess
2023-02-03 18:34               ` Keith Seitz
2023-01-25 19:38           ` Keith Seitz [this message]
2023-02-03 17:22             ` [RFC PATCH 2/2] Allow and evaluate expressions in command arguments Andrew Burgess
2023-02-03 18:49               ` Keith Seitz
2023-02-17 22:31             ` Pedro Alves
2023-01-25 20:21           ` [RFC PATCH 0/2] Command expression evaulation substitution Peikes, Wendy

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=20230125193825.3665649-3-keiths@redhat.com \
    --to=keiths@redhat.com \
    --cc=Wendy.Peikes@netapp.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).