* [PATCH 0/2] Tab complete convenience variables @ 2024-08-22 15:47 Antonio Rische 2024-08-22 15:47 ` [PATCH 1/2] gdb: Do not create variables when parsing expressions Antonio Rische 2024-08-22 15:47 ` [PATCH 2/2] gdb: Tab complete internalvars in expressions Antonio Rische 0 siblings, 2 replies; 7+ messages in thread From: Antonio Rische @ 2024-08-22 15:47 UTC (permalink / raw) To: gdb-patches; +Cc: Antonio Rische Implement tab completion for convenience variables. This has been something that annoyed me about gdb for years. Antonio Rische (2): gdb: Do not create variables when parsing expressions gdb: Tab complete internalvars in expressions gdb/ax-gdb.c | 25 +++++++++++++++++++++++ gdb/cli/cli-utils.c | 2 +- gdb/completer.c | 10 ++++++++++ gdb/expop.h | 48 ++++++++++++++++++++++++++++++++++++++++++++- gdb/parse.c | 3 +-- 5 files changed, 84 insertions(+), 4 deletions(-) -- 2.46.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] gdb: Do not create variables when parsing expressions 2024-08-22 15:47 [PATCH 0/2] Tab complete convenience variables Antonio Rische @ 2024-08-22 15:47 ` Antonio Rische 2024-08-22 15:47 ` [PATCH 2/2] gdb: Tab complete internalvars in expressions Antonio Rische 1 sibling, 0 replies; 7+ messages in thread From: Antonio Rische @ 2024-08-22 15:47 UTC (permalink / raw) To: gdb-patches; +Cc: Antonio Rische This is not particularly useful on its own, but allows us to parse expressions without having side-effects on the set of internalvars. This will then allow us to tab-complete internalvars in expressions without creating new internalvars, which would otherwise defeat the purpose of tab completion (completing only variables that have been set). --- gdb/ax-gdb.c | 25 +++++++++++++++++++++++ gdb/cli/cli-utils.c | 2 +- gdb/expop.h | 48 ++++++++++++++++++++++++++++++++++++++++++++- gdb/parse.c | 3 +-- 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 3d619012b..7853aa444 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -1668,6 +1668,31 @@ register_operation::do_generate_ax (struct expression *exp, value->type = register_type (ax->gdbarch, reg); } +void +uninit_internalvar_operation::do_generate_ax (struct expression *exp, + struct agent_expr *ax, + struct axs_value *value, + struct type *cast_type) +{ + const char *name = get_name (); + struct internalvar *var = lookup_only_internalvar(name); + struct trace_state_variable *tsv; + + tsv = find_trace_state_variable (name); + if (tsv) + { + ax_tsv (ax, aop_getv, tsv->number); + if (ax->tracing) + ax_tsv (ax, aop_tracev, tsv->number); + /* Trace state variables are always 64-bit integers. */ + value->kind = axs_rvalue; + value->type = builtin_type (ax->gdbarch)->builtin_long_long; + } + else if (! compile_internalvar_to_ax (var, ax, value)) + error (_("$%s is not a trace state variable; GDB agent " + "expressions cannot use convenience variables."), name); +} + void internalvar_operation::do_generate_ax (struct expression *exp, struct agent_expr *ax, diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c index 45b30842e..7dedb3829 100644 --- a/gdb/cli/cli-utils.c +++ b/gdb/cli/cli-utils.c @@ -49,7 +49,7 @@ get_ulongest (const char **pp, int trailer) while (isalnum (*p) || *p == '_') p++; std::string varname (start, p - start); - if (!get_internalvar_integer (lookup_internalvar (varname.c_str ()), + if (!get_internalvar_integer (lookup_only_internalvar (varname.c_str ()), &retval)) error (_("Convenience variable $%s does not have integer value."), varname.c_str ()); diff --git a/gdb/expop.h b/gdb/expop.h index 2d46a9dad..f0cc8dbb1 100644 --- a/gdb/expop.h +++ b/gdb/expop.h @@ -878,6 +878,42 @@ class bool_operation { return true; } }; +/* Reference to a variable that had not been defined at parse time. */ +class uninit_internalvar_operation + : public tuple_holding_operation<std::string> +{ +public: + + using tuple_holding_operation::tuple_holding_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override + { + internalvar* iv = lookup_only_internalvar(std::get<0> (m_storage).c_str ()); + if (!iv) { + return value::allocate (builtin_type (exp->gdbarch)->builtin_void); + } + return value_of_internalvar (exp->gdbarch, iv); + } + + const char *get_name () const + { + return std::get<0> (m_storage).c_str (); + } + + enum exp_opcode opcode () const override + { return OP_INTERNALVAR; } + +protected: + + void do_generate_ax (struct expression *exp, + struct agent_expr *ax, + struct axs_value *value, + struct type *cast_type) + override; +}; + class internalvar_operation : public tuple_holding_operation<internalvar *> { @@ -1891,7 +1927,17 @@ class assign_operation struct expression *exp, enum noside noside) override { - value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); + operation *lhs_op = std::get<0> (m_storage).get(); + + /* If the operation is an internalvar that was not initialized at + parse time, ensure that it exists. */ + auto *uninit_var_op = dynamic_cast<uninit_internalvar_operation *> (lhs_op); + if (uninit_var_op) { + lookup_internalvar (uninit_var_op->get_name()); + } + + value *lhs = lhs_op->evaluate (nullptr, exp, noside); + /* Special-case assignments where the left-hand-side is a convenience variable -- in these, don't bother setting an expected type. This avoids a weird case where re-assigning a diff --git a/gdb/parse.c b/gdb/parse.c index e0837de7b..19e2504f9 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -242,8 +242,7 @@ parser_state::push_dollar (struct stoken str) /* Any other names are assumed to be debugger internal variables. */ - push_new<expr::internalvar_operation> - (create_internalvar (copy.c_str () + 1)); + push_new<expr::uninit_internalvar_operation> (copy.c_str () + 1); } /* See parser-defs.h. */ -- 2.46.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] gdb: Tab complete internalvars in expressions 2024-08-22 15:47 [PATCH 0/2] Tab complete convenience variables Antonio Rische 2024-08-22 15:47 ` [PATCH 1/2] gdb: Do not create variables when parsing expressions Antonio Rische @ 2024-08-22 15:47 ` Antonio Rische 2024-08-22 19:41 ` nt8r 1 sibling, 1 reply; 7+ messages in thread From: Antonio Rische @ 2024-08-22 15:47 UTC (permalink / raw) To: gdb-patches; +Cc: Antonio Rische For example, 'print $f<tab>' after running 'set $foo=0' now tab completes. 'print $_siginf<tab>' also now tab completes. --- gdb/completer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gdb/completer.c b/gdb/completer.c index 1008ec23b..6476ddf79 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -1099,6 +1099,16 @@ complete_expression (completion_tracker &tracker, && expr_completer->complete (exp.get (), tracker)) return; + if (text[0] == '$') + { + tracker.advance_custom_word_point_by (1); + /* We don't support completion of history indices. */ + if (!isdigit (text[1])) + complete_internalvar (tracker, &text[1]); + tracker.advance_custom_word_point_by (-1); + return; + } + complete_files_symbols (tracker, text, word); } -- 2.46.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] gdb: Tab complete internalvars in expressions 2024-08-22 15:47 ` [PATCH 2/2] gdb: Tab complete internalvars in expressions Antonio Rische @ 2024-08-22 19:41 ` nt8r 2024-08-26 16:54 ` Keith Seitz 0 siblings, 1 reply; 7+ messages in thread From: nt8r @ 2024-08-22 19:41 UTC (permalink / raw) To: gdb-patches It seems I misunderstood the semantics of the 'word' and 'text' parameters here. I'll correct in v2; as written this doesn't work for completions not at the start of the text to complete (e.g. 'print 4+$fo<tab>' or 'print $fo<tab>+4'). On Thursday, August 22nd, 2024 at 3:47 PM, Antonio Rische <nt8r@protonmail.com> wrote: > For example, 'print $f<tab>' after running 'set $foo=0' now tab > > completes. > > 'print $_siginf<tab>' also now tab completes. > > --- > gdb/completer.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/gdb/completer.c b/gdb/completer.c > index 1008ec23b..6476ddf79 100644 > --- a/gdb/completer.c > +++ b/gdb/completer.c > @@ -1099,6 +1099,16 @@ complete_expression (completion_tracker &tracker, > && expr_completer->complete (exp.get (), tracker)) > > return; > > + if (text[0] == '$') > + { > + tracker.advance_custom_word_point_by (1); > + /* We don't support completion of history indices. */ > + if (!isdigit (text[1])) > + complete_internalvar (tracker, &text[1]); > + tracker.advance_custom_word_point_by (-1); > + return; > + } > + > complete_files_symbols (tracker, text, word); > } > > -- > 2.46.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] gdb: Tab complete internalvars in expressions 2024-08-22 19:41 ` nt8r @ 2024-08-26 16:54 ` Keith Seitz 2024-08-28 1:36 ` nt8r 0 siblings, 1 reply; 7+ messages in thread From: Keith Seitz @ 2024-08-26 16:54 UTC (permalink / raw) To: nt8r, gdb-patches Hi, On 8/22/24 12:41 PM, nt8r@protonmail.com wrote: > It seems I misunderstood the semantics of the 'word' and 'text' parameters here. I'll correct in v2; as written this doesn't work for completions not at the start of the text to complete (e.g. 'print 4+$fo<tab>' or 'print $fo<tab>+4'). Wow, thank you for taking a look at this! This is a most welcome submission. Is it possible to include any tests exercising this new feature? That would make review much easier for us. There are several examples in gdb/testsuite/ to follow. Grep for "test_gdb_complete" or take a look at the support routines in gdb/testsuite/lib/completion-support.exp. [Also see https://sourceware.org/gdb/wiki/GDBTestcaseCookbook and gdb/testsuite/README for add'l pointers/examples on writing and running tests.] Do you have an assignment on file? If not, in order for us to accept your patch, please see/follow https://sourceware.org/gdb/wiki/ContributionChecklist#FSF_copyright_Assignment Thank you again for submitting a patch to fix this. Keith ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] gdb: Tab complete internalvars in expressions 2024-08-26 16:54 ` Keith Seitz @ 2024-08-28 1:36 ` nt8r 2024-08-28 2:30 ` Eli Zaretskii 0 siblings, 1 reply; 7+ messages in thread From: nt8r @ 2024-08-28 1:36 UTC (permalink / raw) To: Keith Seitz; +Cc: gdb-patches Thanks for the enthusiasm! I'm adding some tests in v2. How do I go about copyright assignment? The documents I'm seeing seem to suggest getting in touch with a maintainer over e-mail. Thanks, Antonio On Monday, August 26th, 2024 at 4:54 PM, Keith Seitz <keiths@redhat.com> wrote: > Hi, > > On 8/22/24 12:41 PM, nt8r@protonmail.com wrote: > > > It seems I misunderstood the semantics of the 'word' and 'text' parameters here. I'll correct in v2; as written this doesn't work for completions not at the start of the text to complete (e.g. 'print 4+$fo<tab>' or 'print $fo<tab>+4'). > > > Wow, thank you for taking a look at this! This is a most welcome > submission. > > Is it possible to include any tests exercising this new feature? That > would make review much easier for us. > > There are several examples in gdb/testsuite/ to follow. Grep > for "test_gdb_complete" or take a look at the support routines > in gdb/testsuite/lib/completion-support.exp. [Also see > https://sourceware.org/gdb/wiki/GDBTestcaseCookbook and > gdb/testsuite/README for add'l pointers/examples on writing > and running tests.] > > Do you have an assignment on file? If not, in order for us to > accept your patch, please see/follow > > https://sourceware.org/gdb/wiki/ContributionChecklist#FSF_copyright_Assignment > > Thank you again for submitting a patch to fix this. > > Keith ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] gdb: Tab complete internalvars in expressions 2024-08-28 1:36 ` nt8r @ 2024-08-28 2:30 ` Eli Zaretskii 0 siblings, 0 replies; 7+ messages in thread From: Eli Zaretskii @ 2024-08-28 2:30 UTC (permalink / raw) To: nt8r; +Cc: keiths, gdb-patches > Date: Wed, 28 Aug 2024 01:36:28 +0000 > From: nt8r@protonmail.com > Cc: gdb-patches@sourceware.org > > Thanks for the enthusiasm! I'm adding some tests in v2. > > How do I go about copyright assignment? The documents I'm seeing seem to suggest getting in touch with a maintainer over e-mail. I've sent the assignment form off-list. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-08-28 2:30 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-08-22 15:47 [PATCH 0/2] Tab complete convenience variables Antonio Rische 2024-08-22 15:47 ` [PATCH 1/2] gdb: Do not create variables when parsing expressions Antonio Rische 2024-08-22 15:47 ` [PATCH 2/2] gdb: Tab complete internalvars in expressions Antonio Rische 2024-08-22 19:41 ` nt8r 2024-08-26 16:54 ` Keith Seitz 2024-08-28 1:36 ` nt8r 2024-08-28 2:30 ` Eli Zaretskii
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox