diff options
author | Tom Tromey <tom@tromey.com> | 2017-04-23 10:54:33 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2018-03-26 21:57:09 -0600 |
commit | ea3b06874c8a1037bad4fd5b9396d196e6963ac6 (patch) | |
tree | 3992edee33959fb4062ff519bbea7ec663bcba4f /gdb/stack.c | |
parent | 07dca93f3bbc2426d89eba460c925863e4ebd636 (diff) | |
download | gdb-ea3b06874c8a1037bad4fd5b9396d196e6963ac6.zip gdb-ea3b06874c8a1037bad4fd5b9396d196e6963ac6.tar.gz gdb-ea3b06874c8a1037bad4fd5b9396d196e6963ac6.tar.bz2 |
Rationalize "backtrace" command line parsing
The backtrace command has peculiar command-line parsing. In
particular, it splits the command line, then loops over the arguments.
If it sees a word it recognizes, like "full", it effectively drops
this word from the argument vector. Then, it pastes together the
remaining arguments, passing them on to backtrace_command_1, which in
turn passes the resulting string to parse_and_eval_long.
The documentation doesn't mention the parse_and_eval_long at all, so
it is a bit of a hidden feature that you can "bt 3*2". The strange
algorithm above also means you can "bt 3 * no-filters 2" and get 6
frames...
This patch changes backtrace's command line parsing to be a bit more
rational. Now, special words like "full" are only recognized at the
start of the command.
This also updates the documentation to describe the various bt options
individually.
gdb/ChangeLog
2018-03-26 Tom Tromey <tom@tromey.com>
* stack.c (backtrace_command): Rewrite command line parsing.
gdb/doc/ChangeLog
2018-03-26 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Backtrace): Describe options individually.
Diffstat (limited to 'gdb/stack.c')
-rw-r--r-- | gdb/stack.c | 62 |
1 files changed, 20 insertions, 42 deletions
diff --git a/gdb/stack.c b/gdb/stack.c index aad8fcd..13af659 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1850,61 +1850,39 @@ backtrace_command_1 (const char *count_exp, int show_locals, int no_filters, static void backtrace_command (const char *arg, int from_tty) { - int fulltrace_arg = -1, arglen = 0, argc = 0, no_filters = -1; - int user_arg = 0; + bool fulltrace = false; + bool filters = true; - std::string reconstructed_arg; if (arg) { - char **argv; - int i; + bool done = false; - gdb_argv built_argv (arg); - argv = built_argv.get (); - argc = 0; - for (i = 0; argv[i]; i++) + while (!done) { - unsigned int j; + const char *save_arg = arg; + std::string this_arg = extract_arg (&arg); - for (j = 0; j < strlen (argv[i]); j++) - argv[i][j] = TOLOWER (argv[i][j]); + if (this_arg.empty ()) + break; - if (no_filters < 0 && subset_compare (argv[i], "no-filters")) - no_filters = argc; + if (subset_compare (this_arg.c_str (), "no-filters")) + filters = false; + else if (subset_compare (this_arg.c_str (), "full")) + fulltrace = true; else { - if (fulltrace_arg < 0 && subset_compare (argv[i], "full")) - fulltrace_arg = argc; - else - { - user_arg++; - arglen += strlen (argv[i]); - } - } - argc++; - } - arglen += user_arg; - if (fulltrace_arg >= 0 || no_filters >= 0) - { - if (arglen > 0) - { - for (i = 0; i < argc; i++) - { - if (i != fulltrace_arg && i != no_filters) - { - reconstructed_arg += argv[i]; - reconstructed_arg += " "; - } - } - arg = reconstructed_arg.c_str (); + /* Not a recognized argument, so stop. */ + arg = save_arg; + done = true; } - else - arg = NULL; } + + if (*arg == '\0') + arg = NULL; } - backtrace_command_1 (arg, fulltrace_arg >= 0 /* show_locals */, - no_filters >= 0 /* no frame-filters */, from_tty); + backtrace_command_1 (arg, fulltrace /* show_locals */, + !filters /* no frame-filters */, from_tty); } /* Iterate over the local variables of a block B, calling CB with |