PR cli/21688: Fix multi-line/inline command differentiation
This bug is a regression caused by the following commit:604c4576fd
is the first bad commit commit604c4576fd
Author: Jerome Guitton <guitton@adacore.com> Date: Tue Jan 10 15:15:53 2017 +0100 The problem happens because, on cli/cli-script.c:process_next_line, GDB is not using the command line string to identify which command to run, but it instead using the 'struct cmd_list_element *' that is obtained by using the mentioned string. The problem with that is that the 'struct cmd_list_element *' doesn't have any information on whether the command issued by the user is a multi-line or inline one. A multi-line command is a command that will necessarily be composed of more than 1 line. For example: (gdb) if 1 >python >print ('hello') >end >end As can be seen in the example above, the 'python' command actually "opens" a new command line (represented by the change in the indentation) that will then be used to enter Python code. OTOH, an inline command is a command that is "self-contained" in a single line, for example: (gdb) if 1 >python print ('hello') >end This Python command is a one-liner, and therefore there is no other Python code that can be entered for this same block. There is also no change in the indentation. So, the fix is somewhat simple: we have to revert the change and use the full command line string passed to process_next_line in order to identify whether we're dealing with a multi-line or an inline command. This commit does just that. As can be seen, this regression also affects other languages, like guile or the compile framework. To make things clearer, I decided to create a new helper function responsible for identifying a non-inline command. Testcase is attached. gdb/ChangeLog: 2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com> PR cli/21688 * cli/cli-script.c (command_name_equals_not_inline): New function. (process_next_line): Adjust 'if' clauses for "python", "compile" and "guile" to use command_name_equals_not_inline. gdb/testsuite/ChangeLog: 2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com> PR cli/21688 * gdb.python/py-cmd.exp (test_python_inline_or_multiline): New procedure. Call it.
This commit is contained in:
parent
60a02042ba
commit
51ed89aa0d
4 changed files with 62 additions and 4 deletions
|
@ -1,3 +1,10 @@
|
|||
2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
|
||||
PR cli/21688
|
||||
* cli/cli-script.c (command_name_equals_not_inline): New function.
|
||||
(process_next_line): Adjust 'if' clauses for "python", "compile"
|
||||
and "guile" to use command_name_equals_not_inline.
|
||||
|
||||
2017-06-29 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* completer.c (expression_completer): Call
|
||||
|
|
|
@ -900,6 +900,20 @@ command_name_equals (struct cmd_list_element *cmd, const char *name)
|
|||
&& strcmp (cmd->name, name) == 0);
|
||||
}
|
||||
|
||||
/* Return true if NAME is the only command between COMMAND_START and
|
||||
COMMAND_END. This is useful when we want to know whether the
|
||||
command is inline (i.e., has arguments like 'python command1') or
|
||||
is the start of a multi-line command block. */
|
||||
|
||||
static bool
|
||||
command_name_equals_not_inline (const char *command_start,
|
||||
const char *command_end,
|
||||
const char *name)
|
||||
{
|
||||
return (command_end - command_start == strlen (name)
|
||||
&& startswith (command_start, name));
|
||||
}
|
||||
|
||||
/* Given an input line P, skip the command and return a pointer to the
|
||||
first argument. */
|
||||
|
||||
|
@ -997,21 +1011,20 @@ process_next_line (char *p, struct command_line **command, int parse_commands,
|
|||
{
|
||||
*command = build_command_line (commands_control, line_first_arg (p));
|
||||
}
|
||||
else if (command_name_equals (cmd, "python"))
|
||||
else if (command_name_equals_not_inline (p_start, p_end, "python"))
|
||||
{
|
||||
/* Note that we ignore the inline "python command" form
|
||||
here. */
|
||||
*command = build_command_line (python_control, "");
|
||||
}
|
||||
else if (command_name_equals (cmd, "compile"))
|
||||
else if (command_name_equals_not_inline (p_start, p_end, "compile"))
|
||||
{
|
||||
/* Note that we ignore the inline "compile command" form
|
||||
here. */
|
||||
*command = build_command_line (compile_control, "");
|
||||
(*command)->control_u.compile.scope = COMPILE_I_INVALID_SCOPE;
|
||||
}
|
||||
|
||||
else if (command_name_equals (cmd, "guile"))
|
||||
else if (command_name_equals_not_inline (p_start, p_end, "guile"))
|
||||
{
|
||||
/* Note that we ignore the inline "guile command" form here. */
|
||||
*command = build_command_line (guile_control, "");
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
|
||||
PR cli/21688
|
||||
* gdb.python/py-cmd.exp (test_python_inline_or_multiline): New
|
||||
procedure. Call it.
|
||||
|
||||
2017-06-29 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* gdb.base/printcmds.exp: Add tests.
|
||||
|
|
|
@ -181,6 +181,38 @@ gdb_test "complete expr_test bar\." \
|
|||
"expr_test bar\.bc.*expr_test bar\.ij.*" \
|
||||
"test completion through complete command"
|
||||
|
||||
# Test that the "python" command is correctly recognized as
|
||||
# inline/multi-line when entering a sequence of commands.
|
||||
#
|
||||
# This proc tests PR cli/21688. The PR is not language-specific, but
|
||||
# the easiest way is just to test with Python.
|
||||
proc test_python_inline_or_multiline { } {
|
||||
set define_cmd_not_inline {
|
||||
{ "if 1" " >$" "multi-line if 1" }
|
||||
{ "python" " >$" "multi-line python command" }
|
||||
{ "print ('hello')" " >$" "multi-line print" }
|
||||
{ "end" " >$" "multi-line first end" }
|
||||
{ "end" "hello\r\n" "multi-line last end" } }
|
||||
|
||||
set define_cmd_inline {
|
||||
{ "if 1" " >$" "inline if 1" }
|
||||
{ "python print ('hello')" " >$" "inline python command" }
|
||||
{ "end" "hello\r\n" "inline end" } }
|
||||
|
||||
foreach t [list $define_cmd_not_inline $define_cmd_inline] {
|
||||
foreach l $t {
|
||||
lassign $l command regex testmsg
|
||||
gdb_test_multiple "$command" "$testmsg" {
|
||||
-re "$regex" {
|
||||
pass "$testmsg"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_python_inline_or_multiline
|
||||
|
||||
if { [readline_is_used] } {
|
||||
set test "complete 'expr_test bar.i'"
|
||||
send_gdb "expr_test bar\.i\t\t"
|
||||
|
|
Loading…
Add table
Reference in a new issue