From 311a4e6b7b004617841f2a6c657e76dddd7d2249 Mon Sep 17 00:00:00 2001 From: Thiago Jung Bauermann Date: Sat, 16 Aug 2008 20:36:30 +0000 Subject: [PATCH] gdb/ 2008-08-16 Vladimir Prus Thiago Jung Bauermann * cli-script.c (read_next_line): Add parse_commands argument. (recurse_read_control_structure): Adapt to new read_next_line signature. (read_command_lines): Add parse_commands argument. (define_command): Adapt to new read_command_lines signature. (document_command): Likewise. * breakpoint.c (commands_command): Likewise. * defs.h (read_command_lines): Adjust function prototype. testsuite/ 2008-08-16 Thiago Jung Bauermann * gdb.base/define.exp: Test indented command documentation. * gdb.python/python.exp: Test indented multi-line command. --- gdb/ChangeLog | 12 ++ gdb/breakpoint.c | 2 +- gdb/cli/cli-script.c | 165 ++++++++++++++++------------ gdb/defs.h | 2 +- gdb/testsuite/ChangeLog | 5 + gdb/testsuite/gdb.base/define.exp | 25 +++++ gdb/testsuite/gdb.python/python.exp | 7 ++ 7 files changed, 143 insertions(+), 75 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9a90d50efa1..6b183d33d9a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2008-08-16 Vladimir Prus + Thiago Jung Bauermann + + * cli-script.c (read_next_line): Add parse_commands argument. + (recurse_read_control_structure): Adapt to new read_next_line + signature. + (read_command_lines): Add parse_commands argument. + (define_command): Adapt to new read_command_lines signature. + (document_command): Likewise. + * breakpoint.c (commands_command): Likewise. + * defs.h (read_command_lines): Adjust function prototype. + 2008-08-16 Paul N. Hilfinger * ada-lang.c (pos_atr): Account for the possibility that the diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 9bd8c6dd936..2ed27036d95 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -675,7 +675,7 @@ commands_command (char *arg, int from_tty) char *tmpbuf = xstrprintf ("Type commands for when breakpoint %d is hit, one per line.", bnum); struct cleanup *cleanups = make_cleanup (xfree, tmpbuf); - l = read_command_lines (tmpbuf, from_tty); + l = read_command_lines (tmpbuf, from_tty, 1); do_cleanups (cleanups); free_command_lines (&b->commands); b->commands = l; diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index 5aafc75ed9c..6bfff4046b2 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -839,14 +839,19 @@ realloc_body_list (struct command_line *command, int new_length) command->body_count = new_length; } -/* Read one line from the input stream. If the command is an "else" or - "end", return such an indication to the caller. */ +/* Read one line from the input stream. If the command is an "end", + return such an indication to the caller. If PARSE_COMMANDS is true, + strip leading whitespace (trailing whitespace is always stripped) + in the line, attempt to recognize GDB control commands, and also + return an indication if the command is an "else" or a nop. + Otherwise, only "end" is recognized. */ static enum misc_command_type -read_next_line (struct command_line **command) +read_next_line (struct command_line **command, int parse_commands) { char *p, *p1, *prompt_ptr, control_prompt[256]; int i = 0; + int not_handled = 0; if (control_level >= 254) error (_("Control nesting too deep!")); @@ -869,81 +874,91 @@ read_next_line (struct command_line **command) if (p == NULL) return end_command; - /* Strip leading and trailing whitespace. */ - while (*p == ' ' || *p == '\t') - p++; + if (parse_commands) + { + /* Strip leading whitespace. */ + while (*p == ' ' || *p == '\t') + p++; + } + /* Strip trailing whitespace. */ p1 = p + strlen (p); while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t')) p1--; - /* Blanks and comments don't really do anything, but we need to - distinguish them from else, end and other commands which can be - executed. */ - if (p1 == p || p[0] == '#') - return nop_command; - /* Is this the end of a simple, while, or if control structure? */ if (p1 - p == 3 && !strncmp (p, "end", 3)) return end_command; - /* Is the else clause of an if control structure? */ - if (p1 - p == 4 && !strncmp (p, "else", 4)) - return else_command; - - /* Check for while, if, break, continue, etc and build a new command - line structure for them. */ - if (p1 - p > 5 && !strncmp (p, "while", 5)) - { - char *first_arg; - first_arg = p + 5; - while (first_arg < p1 && isspace (*first_arg)) - first_arg++; - *command = build_command_line (while_control, first_arg); - } - else if (p1 - p > 2 && !strncmp (p, "if", 2)) - { - char *first_arg; - first_arg = p + 2; - while (first_arg < p1 && isspace (*first_arg)) - first_arg++; - *command = build_command_line (if_control, first_arg); - } - else if (p1 - p >= 8 && !strncmp (p, "commands", 8)) - { - char *first_arg; - first_arg = p + 8; - while (first_arg < p1 && isspace (*first_arg)) - first_arg++; - *command = build_command_line (commands_control, first_arg); - } - else if (p1 - p == 6 && !strncmp (p, "python", 6)) - { - /* Note that we ignore the inline "python command" form - here. */ - *command = build_command_line (python_control, ""); - } - else if (p1 - p == 10 && !strncmp (p, "loop_break", 10)) - { - *command = (struct command_line *) - xmalloc (sizeof (struct command_line)); - (*command)->next = NULL; - (*command)->line = NULL; - (*command)->control_type = break_control; - (*command)->body_count = 0; - (*command)->body_list = NULL; - } - else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13)) + if (parse_commands) { - *command = (struct command_line *) - xmalloc (sizeof (struct command_line)); - (*command)->next = NULL; - (*command)->line = NULL; - (*command)->control_type = continue_control; - (*command)->body_count = 0; - (*command)->body_list = NULL; + /* Blanks and comments don't really do anything, but we need to + distinguish them from else, end and other commands which can be + executed. */ + if (p1 == p || p[0] == '#') + return nop_command; + + /* Is the else clause of an if control structure? */ + if (p1 - p == 4 && !strncmp (p, "else", 4)) + return else_command; + + /* Check for while, if, break, continue, etc and build a new command + line structure for them. */ + if (p1 - p > 5 && !strncmp (p, "while", 5)) + { + char *first_arg; + first_arg = p + 5; + while (first_arg < p1 && isspace (*first_arg)) + first_arg++; + *command = build_command_line (while_control, first_arg); + } + else if (p1 - p > 2 && !strncmp (p, "if", 2)) + { + char *first_arg; + first_arg = p + 2; + while (first_arg < p1 && isspace (*first_arg)) + first_arg++; + *command = build_command_line (if_control, first_arg); + } + else if (p1 - p >= 8 && !strncmp (p, "commands", 8)) + { + char *first_arg; + first_arg = p + 8; + while (first_arg < p1 && isspace (*first_arg)) + first_arg++; + *command = build_command_line (commands_control, first_arg); + } + else if (p1 - p == 6 && !strncmp (p, "python", 6)) + { + /* Note that we ignore the inline "python command" form + here. */ + *command = build_command_line (python_control, ""); + } + else if (p1 - p == 10 && !strncmp (p, "loop_break", 10)) + { + *command = (struct command_line *) + xmalloc (sizeof (struct command_line)); + (*command)->next = NULL; + (*command)->line = NULL; + (*command)->control_type = break_control; + (*command)->body_count = 0; + (*command)->body_list = NULL; + } + else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13)) + { + *command = (struct command_line *) + xmalloc (sizeof (struct command_line)); + (*command)->next = NULL; + (*command)->line = NULL; + (*command)->control_type = continue_control; + (*command)->body_count = 0; + (*command)->body_list = NULL; + } + else + not_handled = 1; } - else + + if (!parse_commands || not_handled) { /* A normal command. */ *command = (struct command_line *) @@ -989,7 +1004,7 @@ recurse_read_control_structure (struct command_line *current_cmd) dont_repeat (); next = NULL; - val = read_next_line (&next); + val = read_next_line (&next, current_cmd->control_type != python_control); /* Just skip blanks and comments. */ if (val == nop_command) @@ -1071,12 +1086,16 @@ recurse_read_control_structure (struct command_line *current_cmd) /* Read lines from the input stream and accumulate them in a chain of struct command_line's, which is then returned. For input from a terminal, the special command "end" is used to mark the end of the - input, and is not included in the returned chain of commands. */ + input, and is not included in the returned chain of commands. + + If PARSE_COMMANDS is true, strip leading whitespace (trailing whitespace + is always stripped) in the line and attempt to recognize GDB control + commands. Otherwise, only "end" is recognized. */ #define END_MESSAGE "End with a line saying just \"end\"." struct command_line * -read_command_lines (char *prompt_arg, int from_tty) +read_command_lines (char *prompt_arg, int from_tty, int parse_commands) { struct command_line *head, *tail, *next; struct cleanup *old_chain; @@ -1105,7 +1124,7 @@ read_command_lines (char *prompt_arg, int from_tty) while (1) { dont_repeat (); - val = read_next_line (&next); + val = read_next_line (&next, parse_commands); /* Ignore blank lines or comments. */ if (val == nop_command) @@ -1339,7 +1358,7 @@ define_command (char *comname, int from_tty) *tem = tolower (*tem); sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname); - cmds = read_command_lines (tmpbuf, from_tty); + cmds = read_command_lines (tmpbuf, from_tty, 1); if (c && c->class == class_user) free_command_lines (&c->user_commands); @@ -1386,7 +1405,7 @@ document_command (char *comname, int from_tty) error (_("Command \"%s\" is built-in."), comname); sprintf (tmpbuf, "Type documentation for \"%s\".", comname); - doclines = read_command_lines (tmpbuf, from_tty); + doclines = read_command_lines (tmpbuf, from_tty, 0); if (c->doc) xfree (c->doc); diff --git a/gdb/defs.h b/gdb/defs.h index b4c5fa96eff..0521ec7c9d7 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -668,7 +668,7 @@ struct command_line struct command_line **body_list; }; -extern struct command_line *read_command_lines (char *, int); +extern struct command_line *read_command_lines (char *, int, int); extern void free_command_lines (struct command_line **); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 92dd07a3330..797d75d3337 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-08-16 Thiago Jung Bauermann + + * gdb.base/define.exp: Test indented command documentation. + * gdb.python/python.exp: Test indented multi-line command. + 2008-08-15 Luis Machado * testsuite/gdb.arch/vsx-regs.c: New source file. diff --git a/gdb/testsuite/gdb.base/define.exp b/gdb/testsuite/gdb.base/define.exp index 1368d44cf5b..743e3a9f126 100644 --- a/gdb/testsuite/gdb.base/define.exp +++ b/gdb/testsuite/gdb.base/define.exp @@ -200,6 +200,31 @@ gdb_expect { timeout {fail "(timeout) help user command: nextwhere"} } +# Verify that the document command preserves whitespace in the beginning of the line. +# +send_gdb "document nextwhere\n" +gdb_expect { + -re "Type documentation for \"nextwhere\".\r\nEnd with a line saying just \"end\".\r\n>$"\ + {send_gdb " A next command that first shows you where you're stepping from.\nend\n" + gdb_expect { + -re "$gdb_prompt $" {} + timeout {fail "(timeout) preserve whitespace in help string"} + } + } + -re "$gdb_prompt $"\ + {fail "preserve whitespace in help string"} + timeout {fail "(timeout) preserve whitespace in help string"} +} + +send_gdb "help nextwhere\n" +gdb_expect { + -re " A next command that first shows you where you're stepping from.\r\n$gdb_prompt $"\ + {pass "preserve whitespace in help string"} + -re "$gdb_prompt $"\ + {fail "preserve whitespace in help string"} + timeout {fail "(timeout) preserve whitespace in help string"} +} + # Verify that the command parser doesn't require a space after an 'if' # command in a user defined function. # diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp index 44037f29c40..677f8d2c891 100644 --- a/gdb/testsuite/gdb.python/python.exp +++ b/gdb/testsuite/gdb.python/python.exp @@ -64,3 +64,10 @@ gdb_py_test_multiple "show python command" \ "end" "" \ "end" "" \ "show user zzq" "User command zzq:.* python.*print 23.* end" + +gdb_py_test_multiple "indented multi-line python command" \ + "python" "" \ + "def foo ():" "" \ + " print 'hello, world!'" "" \ + "foo ()" "" \ + "end" "hello, world!" -- 2.30.2