diff options
author | Philippe Waroquiers <philippe.waroquiers@skynet.be> | 2019-06-19 12:49:55 +0200 |
---|---|---|
committer | Philippe Waroquiers <philippe.waroquiers@skynet.be> | 2020-06-22 21:14:13 +0200 |
commit | cf00cd6faf31c208bbfe107140c26895412214bb (patch) | |
tree | f4fc3fb4986a0c6eb48cd3f6ee380429a5f8301c /gdb/cli/cli-decode.c | |
parent | e822f2cda9bc484adb5f8860050640a5c6f1ced9 (diff) | |
download | binutils-cf00cd6faf31c208bbfe107140c26895412214bb.zip binutils-cf00cd6faf31c208bbfe107140c26895412214bb.tar.gz binutils-cf00cd6faf31c208bbfe107140c26895412214bb.tar.bz2 |
default-args: allow to define default arguments for aliases
Currently, a user can define an alias, but cannot have default
arguments for this alias.
This patch modifies the 'alias' command so that default args can
be provided.
(gdb) h alias
Define a new command that is an alias of an existing command.
Usage: alias [-a] [--] ALIAS = COMMAND [DEFAULT-ARGS...]
ALIAS is the name of the alias command to create.
COMMAND is the command being aliased to.
Options:
-a
Specify that ALIAS is an abbreviation of COMMAND.
Abbreviations are not used in command completion..
GDB will automatically prepend the provided DEFAULT-ARGS to the list
of arguments explicitly provided when using ALIAS.
Use "help aliases" to list all user defined aliases and their default args.
Examples:
Make "spe" an alias of "set print elements":
alias spe set print elements
Make "elms" an alias of "elements" in the "set print" command:
alias -a set print elms set print elements
Make "btf" an alias of "backtrace -full -past-entry -past-main" :
alias btf = backtrace -full -past-entry -past-main
Make "wLapPeu" an alias of 2 nested "with":
alias wLapPeu = with language pascal -- with print elements unlimited --
(gdb)
The way 'default-args' is implemented makes it trivial to set default
args also for GDB commands (such as "backtrace") and for GDB pre-defined
aliases (such as "bt"). It was however deemed better to not allow to
define default arguments for pre-defined commands and aliases, to avoid
users believing that e.g. default args for "backtrace" would apply to "bt".
If needed, default-args could be allowed for GDB predefined commands
and aliases by adding a command
'set default-args GDB_COMMAND_OR_PREDEFINED_ALIAS [DEFAULT-ARGS...]'.
* 'alias' command now has a completer that helps to complete:
- ALIAS (if the user defines an alias after a prefix),
- the aliased COMMAND
- the possible options for the aliased COMMAND.
* Help and apropos commands show the definitions of the aliases
that have default arguments, e.g.
(gdb) help backtrace
backtrace, btf, where, bt
alias btf = backtrace -full -past-entry -past-main
Print backtrace of all stack frames, or innermost COUNT frames.
Usage: backtrace [OPTION]... [QUALIFIER]... [COUNT | -COUNT]
Options:
-entry-values no|only|preferred|if-needed|both|compact|default
Set printing of function arguments at function entry.
...
gdb/ChangeLog
2020-06-22 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* cli/cli-cmds.c (lookup_cmd_for_default_args)
(alias_command_completer)
(make_alias_options_def_group): New functions.
(alias_opts, alias_option_defs): New struct and array.
(alias_usage_error): Update usage.
(alias_command): Handles optional DEFAULT-ARGS... arguments.
Use option framework.
(_initialize_cli_cmds): Update alias command help.
Update aliases command help.
(show_user):
Add NULL for new default_args lookup_cmd argument.
(valid_command_p): Rename to validate_aliased_command.
Add NULL for new default_args lookup_cmd argument. Verify that the
aliased_command has no default args.
* cli/cli-decode.c (help_cmd): Show aliases definitions.
(lookup_cmd_1, lookup_cmd): New argument default_args.
(add_alias_cmd):
Add NULL for new default_args lookup_cmd argument.
(print_help_for_command): Show default args under the layout
alias some_alias = some_aliased_cmd some_alias_default_arg.
* cli/cli-decode.h (struct cmd_list_element): New member default_args.
xfree default_args in destructor.
* cli/cli-script.c (process_next_line, do_define_command):
Add NULL for new default_args lookup_cmd argument.
* command.h: Declare new default_args argument in lookup_cmd
and lookup_cmd_1.
* completer.c (complete_line_internal_1):
Add NULL for new default_args lookup_cmd or lookup_cmd_1 argument.
* guile/scm-cmd.c (gdbscm_parse_command_name): Likewise.
* guile/scm-param.c (add_setshow_generic, pascm_parameter_defined_p):
Likewise.
* infcmd.c (_initialize_infcmd): Likewise.
* python/py-auto-load.c (gdbpy_initialize_auto_load): Likewise.
* python/py-cmd.c (gdbpy_parse_command_name): Likewise.
* python/py-param.c (add_setshow_generic): Likewise.
* remote.c (_initialize_remote): Likewise.
* top.c (execute_command): Prepend default_args if command has some.
(set_verbose):
Add NULL for new default_args lookup_cmd or lookup_cmd_1 argument.
* tracepoint.c (validate_actionline, encode_actions_1):
Add NULL for new default_args lookup_cmd or lookup_cmd_1 argument.
Diffstat (limited to 'gdb/cli/cli-decode.c')
-rw-r--r-- | gdb/cli/cli-decode.c | 110 |
1 files changed, 92 insertions, 18 deletions
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c index a4ef93c..85f50aa 100644 --- a/gdb/cli/cli-decode.c +++ b/gdb/cli/cli-decode.c @@ -337,7 +337,7 @@ add_alias_cmd (const char *name, const char *oldname, struct cmd_list_element *old; tmp = oldname; - old = lookup_cmd (&tmp, *list, "", 1, 1); + old = lookup_cmd (&tmp, *list, "", NULL, 1, 1); return add_alias_cmd (name, old, theclass, abbrev_flag, list); } @@ -1040,6 +1040,40 @@ fput_command_name_styled (struct cmd_list_element *c, struct ui_file *stream) fprintf_styled (stream, title_style.style (), "%s%s", prefixname, c->name); } +/* Print the definition of alias C using title style for alias + and aliased command. */ + +static void +fput_alias_definition_styled (struct cmd_list_element *c, + struct ui_file *stream) +{ + gdb_assert (c->cmd_pointer != nullptr); + fputs_filtered (" alias ", stream); + fput_command_name_styled (c, stream); + fprintf_filtered (stream, " = "); + fput_command_name_styled (c->cmd_pointer, stream); + fprintf_filtered (stream, " %s\n", c->default_args.c_str ()); +} + +/* Print the definition of the aliases of CMD that have default args. */ + +static void +fput_aliases_definition_styled (struct cmd_list_element *cmd, + struct ui_file *stream) +{ + if (cmd->aliases != nullptr) + { + for (cmd_list_element *iter = cmd->aliases; + iter; + iter = iter->alias_chain) + { + if (!iter->default_args.empty ()) + fput_alias_definition_styled (iter, stream); + } + } +} + + /* If C has one or more aliases, style print the name of C and the name of its aliases, separated by commas. If ALWAYS_FPUT_C_NAME, print the name of C even if it has no aliases. @@ -1081,12 +1115,21 @@ print_doc_of_command (struct cmd_list_element *c, const char *prefix, if (verbose) fputs_filtered ("\n", stream); - fput_command_names_styled (c, true, " -- ", stream); + fput_command_names_styled (c, true, + verbose ? "" : " -- ", stream); if (verbose) - fputs_highlighted (c->doc, highlight, stream); + { + fputs_filtered ("\n", stream); + fput_aliases_definition_styled (c, stream); + fputs_highlighted (c->doc, highlight, stream); + fputs_filtered ("\n", stream); + } else - print_doc_line (stream, c->doc, false); - fputs_filtered ("\n", stream); + { + print_doc_line (stream, c->doc, false); + fputs_filtered ("\n", stream); + fput_aliases_definition_styled (c, stream); + } } /* Recursively walk the commandlist structures, and print out the @@ -1183,7 +1226,7 @@ help_cmd (const char *command, struct ui_file *stream) } const char *orig_command = command; - c = lookup_cmd (&command, cmdlist, "", 0, 0); + c = lookup_cmd (&command, cmdlist, "", NULL, 0, 0); if (c == 0) return; @@ -1205,6 +1248,7 @@ help_cmd (const char *command, struct ui_file *stream) /* If the user asked 'help somecommand' and there is no alias, the false indicates to not output the (single) command name. */ fput_command_names_styled (c, false, "\n", stream); + fput_aliases_definition_styled (c, stream); fputs_filtered (c->doc, stream); fputs_filtered ("\n", stream); @@ -1341,7 +1385,7 @@ help_all (struct ui_file *stream) fprintf_filtered (stream, "\nUnclassified commands\n\n"); seen_unclassified = 1; } - print_help_for_command (c, 1, stream); + print_help_for_command (c, true, stream); } } @@ -1399,6 +1443,9 @@ print_help_for_command (struct cmd_list_element *c, fput_command_names_styled (c, true, " -- ", stream); print_doc_line (stream, c->doc, false); fputs_filtered ("\n", stream); + if (!c->default_args.empty ()) + fput_alias_definition_styled (c, stream); + fput_aliases_definition_styled (c, stream); if (recurse && c->prefixlist != 0 @@ -1582,8 +1629,12 @@ valid_user_defined_cmd_name_p (const char *name) the list in which there are ambiguous choices (and *TEXT will be set to the ambiguous text string). + if DEFAULT_ARGS is not null, *DEFAULT_ARGS is set to the found command + default args (possibly empty). + If the located command was an abbreviation, this routine returns the base - command of the abbreviation. + command of the abbreviation. Note that *DEFAULT_ARGS will contain the + default args defined for the alias. It does no error reporting whatsoever; control will always return to the superior routine. @@ -1610,11 +1661,13 @@ valid_user_defined_cmd_name_p (const char *name) struct cmd_list_element * lookup_cmd_1 (const char **text, struct cmd_list_element *clist, - struct cmd_list_element **result_list, int ignore_help_classes) + struct cmd_list_element **result_list, std::string *default_args, + int ignore_help_classes) { char *command; int len, nfound; struct cmd_list_element *found, *c; + bool found_alias = false; const char *line = *text; while (**text == ' ' || **text == '\t') @@ -1646,10 +1699,12 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist, if (nfound > 1) { - if (result_list != NULL) + if (result_list != nullptr) /* Will be modified in calling routine if we know what the prefix command is. */ *result_list = 0; + if (default_args != nullptr) + *default_args = std::string (); return CMD_LIST_AMBIGUOUS; /* Ambiguous. */ } @@ -1665,22 +1720,30 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist, are warning about the alias, we may also warn about the command itself and we will adjust the appropriate DEPRECATED_WARN_USER flags. */ - + if (found->deprecated_warn_user) deprecated_cmd_warning (line); + + /* Return the default_args of the alias, not the default_args + of the command it is pointing to. */ + if (default_args != nullptr) + *default_args = found->default_args; found = found->cmd_pointer; + found_alias = true; } /* If we found a prefix command, keep looking. */ if (found->prefixlist) { c = lookup_cmd_1 (text, *found->prefixlist, result_list, - ignore_help_classes); + default_args, ignore_help_classes); if (!c) { /* Didn't find anything; this is as far as we got. */ - if (result_list != NULL) + if (result_list != nullptr) *result_list = clist; + if (!found_alias && default_args != nullptr) + *default_args = found->default_args; return found; } else if (c == CMD_LIST_AMBIGUOUS) @@ -1688,13 +1751,16 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist, /* We've gotten this far properly, but the next step is ambiguous. We need to set the result list to the best we've found (if an inferior hasn't already set it). */ - if (result_list != NULL) + if (result_list != nullptr) if (!*result_list) /* This used to say *result_list = *found->prefixlist. If that was correct, need to modify the documentation at the top of this function to clarify what is supposed to be going on. */ *result_list = found; + /* For ambiguous commands, do not return any default_args args. */ + if (default_args != nullptr) + *default_args = std::string (); return c; } else @@ -1705,8 +1771,10 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist, } else { - if (result_list != NULL) + if (result_list != nullptr) *result_list = clist; + if (!found_alias && default_args != nullptr) + *default_args = found->default_args; return found; } } @@ -1726,8 +1794,13 @@ undef_cmd_error (const char *cmdtype, const char *q) /* Look up the contents of *LINE as a command in the command list LIST. LIST is a chain of struct cmd_list_element's. - If it is found, return the struct cmd_list_element for that command - and update *LINE to point after the command name, at the first argument. + If it is found, return the struct cmd_list_element for that command, + update *LINE to point after the command name, at the first argument + and update *DEFAULT_ARGS (if DEFAULT_ARGS is not null) to the default + args to prepend to the user provided args when running the command. + Note that if the found cmd_list_element is found via an alias, + the default args of the alias are returned. + If not found, call error if ALLOW_UNKNOWN is zero otherwise (or if error returns) return zero. Call error if specified command is ambiguous, @@ -1741,6 +1814,7 @@ undef_cmd_error (const char *cmdtype, const char *q) struct cmd_list_element * lookup_cmd (const char **line, struct cmd_list_element *list, const char *cmdtype, + std::string *default_args, int allow_unknown, int ignore_help_classes) { struct cmd_list_element *last_list = 0; @@ -1752,7 +1826,7 @@ lookup_cmd (const char **line, struct cmd_list_element *list, if (!*line) error (_("Lack of needed %scommand"), cmdtype); - c = lookup_cmd_1 (line, list, &last_list, ignore_help_classes); + c = lookup_cmd_1 (line, list, &last_list, default_args, ignore_help_classes); if (!c) { |